-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate_signal.m
More file actions
236 lines (206 loc) · 8.21 KB
/
generate_signal.m
File metadata and controls
236 lines (206 loc) · 8.21 KB
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
function [K,ox,f] = generate_signal(N,r,m,varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Generate simulated (1D, 2D, 3D) spectrally sparse signals, with or without
%separation between the frequencies, with or without damping.
%
%Inputs
% N: a vector specify lengths of the signal in different dimensions,
% the number of dimensions <= 3.
% r: model order of the signal.
% m: number or percentage of observed entries. If less than 1, it's
% considered as a percentage.
% varargin: (optional) first specify whether to generate frequencies with
% separations. Input should be without (false,'false',0) or with
% (default, true,'true',1). Also specify whether the signal is
% damped. Either undamped (default, false,'false',0) or damped
% (true,'true',1).
%
%Outputs
% K: indices for the observed entries.
% ox: generated signal as a vector.
% f: frequencies in different dimensions, stored column by column.
%
%< Example 1 >
%[K,ox,f] = generate_signal(128,5,40) will generate a 1D undamped signal of
%length 128 with model order 5, with separation between frequencies and it
%is observed at 40 locations.
%< Example 2 >
%[K,ox,f] = generate_signal([128 64 32],10,0.04,false,true) will generate a
%3D damped signal of size 128*64*32 with model order 10, without separation
%between the frequencies and we have 4 percent samples.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nargs = nargin;
if nargs < 3
error('Not enough input parameters!');
end
switch nargs
case 3
separation = true;
damping = false;
case 4
separation = varargin{1};
damping = false;
case 5
separation = varargin{1};
damping = varargin{2};
otherwise
error('Too many input parameters!')
end
% Generate complex coefficients of the signal
dynamic_range = 10;
c = exp(1i*2*pi*rand(r,1)).*(1+10.^(rand(r,1).*(dynamic_range/20)));
dim = numel(N); % dimension of the signal
switch dim
case 1
N1 = N; s1 = 0:N1-1;
switch separation
case {false,'false',0} % without separation
f1 = rand(r,1);
case {true,'true',1} % with separation
d1 = 1.5/N1;
E1 = 1-r*d1; % excess space
if E1 < 0
error('Model order is too big, separation condition fails!')
else
f1 = rand(r+1,1); % wrap around distance
fs = E1*f1(1:r)/sum(f1);
fs = d1*ones(r,1)+fs;
f1 = cumsum(fs);
end
otherwise
error('Separation should either be true or false!')
end
switch damping
case {false,'false',0} % without damping
ox = exp(s1'*(1i*2*pi*f1'))*c;
case {true,'true',1} % with damping
d1 = round(N1/4)+round(N1/4)*rand(r,1);
d1 = -1./d1;
ox = exp(s1'*(d1'+1i*2*pi*f1'))*c;
otherwise
error('Damping should either be true or false!')
end
f = f1;
if m < 1
m = round(N1*m);
end
K = randsample(N1,m); % sample without replacement
case 2
N1 = N(1); s1 = 0:N1-1;
N2 = N(2); s2 = 0:N2-1;
switch separation
case {false,'false',0} % without separation
f1 = rand(r,1);
f2 = rand(r,1);
case {true,'true',1} % with separation
d1 = 1.5/N1;
E1 = 1-r*d1; % excess space
if E1 < 0
error('Model order is too big, separation condition fails!')
else
f1 = rand(r+1,1); % wrap around distance
fs = E1*f1(1:r)/sum(f1);
fs = d1*ones(r,1)+fs;
f1 = cumsum(fs);
end
d2 = 1.5/N2;
E2 = 1-r*d2; % excess space
if E2 < 0
error('Model order is too big, separation condition fails!')
else
f2 = rand(r+1,1); % wrap around distance
fs = E2*f2(1:r)/sum(f2);
fs = d2*ones(r,1)+fs;
f2 = cumsum(fs);
end
otherwise
error('Separation should either be true or false!')
end
switch damping
case {false,'false',0} % without damping
ox = exp(kron(ones(N2,1),s1')*(1i*2*pi*f1')+kron(s2',ones(N1,1))...
*(1i*2*pi*f2'))*c;
case {true,'true',1} % with damping
d1 = round(N1/4)+round(N1/4)*rand(r,1);
d1 = -1./d1;
d2 = round(N2/4)+round(N2/4)*rand(r,1);
d2 = -1./d2;
ox = exp(kron(ones(N2,1),s1')*(d1'+1i*2*pi*f1')+kron(s2',ones(N1,1))...
*(d2'+1i*2*pi*f2'))*c;
otherwise
error('Damping should either be true or false!')
end
f = [f1 f2];
if m < 1
m = round(N1*N2*m);
end
K = randsample(N1*N2,m); % sample without replacement
case 3
N1 = N(1); s1 = 0:N1-1;
N2 = N(2); s2 = 0:N2-1;
N3 = N(3); s3 = 0:N3-1;
switch separation
case {false,'false',0} % without separation
f1 = rand(r,1);
f2 = rand(r,1);
f3 = rand(r,1);
case {true,'true',1} % with separation
d1 = 1.5/N1;
E1 = 1-r*d1; % excess space
if E1 < 0
error('Model order is too big, separation condition fails!')
else
f1 = rand(r+1,1); % wrap around distance
fs = E1*f1(1:r)/sum(f1);
fs = d1*ones(r,1)+fs;
f1 = cumsum(fs);
end
d2 = 1.5/N2;
E2 = 1-r*d2; % excess space
if E2 < 0
error('Model order is too big, separation condition fails!')
else
f2 = rand(r+1,1); % wrap around distance
fs = E2*f2(1:r)/sum(f2);
fs = d2*ones(r,1)+fs;
f2 = cumsum(fs);
end
d3 = 1.5/N3;
E3 = 1-r*d3; % excess space
if E3 < 0
error('Model order is too big, separation condition fails!')
else
f3 = rand(r+1,1); % wrap around distance
fs = E3*f3(1:r)/sum(f3);
fs = d3*ones(r,1)+fs;
f3 = cumsum(fs);
end
otherwise
error('Separation should either be true or false!')
end
switch damping
case {false,'false',0} % without damping
ox = exp(kron(ones(N3,1),kron(ones(N2,1),s1'))*(1i*2*pi*f1')...
+kron(ones(N3,1),kron(s2',ones(N1,1)))*(1i*2*pi*f2')...
+kron(s3',kron(ones(N2,1),ones(N1,1)))*(1i*2*pi*f3'))*c;
case {true,'true',1} % with damping
d1 = round(N1/4)+round(N1/4)*rand(r,1);
d1 = -1./d1;
d2 = round(N2/4)+round(N2/4)*rand(r,1);
d2 = -1./d2;
d3 = round(N3/4)+round(N3/4)*rand(r,1);
d3 = -1./d3;
ox = exp(kron(ones(N3,1),kron(ones(N2,1),s1'))*(d1'+1i*2*pi*f1')...
+kron(ones(N3,1),kron(s2',ones(N1,1)))*(d2'+1i*2*pi*f2')...
+kron(s3',kron(ones(N2,1),ones(N1,1)))*(d3'+1i*2*pi*f3'))*c;
otherwise
error('Damping should either be true or false!')
end
f = [f1 f2 f3];
if m < 1
m = round(N1*N2*N3*m);
end
K = randsample(N1*N2*N3,m); % sample without replacement
otherwise
error('Dimension of the signal should be <= 3!')
end