forked from jkperin/optical-comm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAnalogSquaring.m
70 lines (58 loc) · 2.32 KB
/
AnalogSquaring.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
classdef AnalogSquaring < AnalogOperation % inherits properties and methods from class AnalogOperation
%% Output = (Input)^2
% Input1 -> Filter -> Squanring -> Add noise -> Filter -> Output
% If filt is empty, component is assumed to be ideal
methods
function obj = AnalogSquaring(filt, N0, fs)
%% Constructor
obj@AnalogOperation(filt, N0, fs); % calls constructor of parent class Analog Operation
end
function varargout = copy(self)
%% Deep copy of Squaring. Filters states aren't copied
for k = 1:nargout
varargout{k} = AnalogSquaring(self.filt, self.N0, self.fs);
end
end
function yf = square(self, x1)
%% Square function: Square signal and add noise. Inputs and output is filtered by filt.
if self.ideal
yf = self.ideal_square(x1);
return
end
% Filter inputs
x1f = self.filter_inputs(x1);
% Perform operation: squaring
y = x1f.^2;
% Add noise
yn = self.add_noise(y);
% Filter output
yf = self.filter_output(yn);
end
function y = ideal_square(~, x1)
%% Ideal squaring operation: no noise and no filtering
y = x1.^2;
end
function validate(self)
%% Validate operation for the non-ideal case, where filtering is performed
self.reset();
N = 100;
w = 2*pi*self.filt.fcnorm*self.fs/4;
[~, t] = freq_time(N, self.fs);
x1 = sin(w*t + pi*(2*rand(1)-1));
x1fref = filter(self.filt.num, self.filt.den, x1);
yref = self.ideal_square(x1fref);
ynref = self.add_noise(yref);
yfref = filter(self.filt.num, self.filt.den, ynref);
y = zeros(1, N);
for k = 1:N
y(k) = self.square(x1(k));
end
figure, clf, hold on, box on
plot(t, y)
plot(t, yfref, '--')
plot(t, x1.^2, ':');
legend('self.mix', 'reference', 'ideal')
self.reset();
end
end
end