|
@@ -109,69 +109,73 @@ def harmonicEuler ( f0, sN, fs, nK, t ):
|
109
|
109
|
print("building Euler matrix ")
|
110
|
110
|
A = np.zeros( (len(t), nK), dtype=np.complex64)
|
111
|
111
|
for irow, tt in enumerate(t):
|
112
|
|
-
|
113
|
|
-
|
114
|
|
- A[irow,:] = np.exp( 1j* np.arange(nK)*2*np.pi*(f0/fs)*irow )
|
115
|
|
-
|
|
112
|
+ A[irow,:] = np.exp(1j* np.arange(1,nK+1) * 2*np.pi* (f0/fs) * irow)
|
116
|
113
|
|
117
|
114
|
v = np.linalg.lstsq(A, sN, rcond=None)
|
118
|
|
-
|
119
|
115
|
alpha = np.real(v[0])
|
120
|
116
|
beta = np.imag(v[0])
|
121
|
|
-
|
122
|
|
-
|
123
|
|
-
|
124
|
|
-
|
125
|
|
-
|
126
|
|
-
|
127
|
|
-
|
128
|
117
|
|
129
|
118
|
amp = np.abs(v[0])
|
130
|
119
|
phase = np.angle(v[0])
|
131
|
120
|
|
132
|
|
-
|
133
|
|
-
|
134
|
121
|
h = np.zeros(len(t))
|
135
|
122
|
for ik in range(nK):
|
136
|
|
- h += 2*amp[ik] * np.cos( 2.*np.pi*ik * (f0/fs) * np.arange(0, len(t), 1 ) + phase[ik] )
|
|
123
|
+ h += 2*amp[ik] * np.cos( 2.*np.pi*(ik+1) * (f0/fs) * np.arange(0, len(t), 1 ) + phase[ik] )
|
137
|
124
|
|
138
|
|
-
|
139
|
|
-
|
|
125
|
+ return sN-h
|
140
|
126
|
|
141
|
|
-
|
142
|
|
-
|
143
|
|
-
|
144
|
|
-
|
|
127
|
+def harmonicEuler2 ( f0, f1, sN, fs, nK, t ):
|
|
128
|
+ """
|
|
129
|
+ Performs inverse calculation of harmonics contaminating a signal.
|
|
130
|
+ Args:
|
|
131
|
+ f0 = base frequency of the sinusoidal noise
|
|
132
|
+ sN = signal containing noise
|
|
133
|
+ fs = sampling frequency
|
|
134
|
+ nK = number of harmonics to calculate
|
|
135
|
+ t = time samples
|
|
136
|
+ """
|
|
137
|
+ print("building Euler matrix 2 ")
|
|
138
|
+ A = np.zeros( (len(t), 2*nK), dtype=np.complex64)
|
|
139
|
+ for irow, tt in enumerate(t):
|
|
140
|
+ A[irow,0:nK] = np.exp( 1j* np.arange(1,nK+1)*2*np.pi*(f0/fs)*irow )
|
|
141
|
+ A[irow,nK:2*nK] = np.exp( 1j* np.arange(1,nK+1)*2*np.pi*(f1/fs)*irow )
|
|
142
|
+
|
|
143
|
+ v = np.linalg.lstsq(A, sN, rcond=None)
|
|
144
|
+
|
|
145
|
+ amp = np.abs(v[0][0:nK])
|
|
146
|
+ phase = np.angle(v[0][0:nK])
|
|
147
|
+ amp1 = np.abs(v[0][nK:2*nK])
|
|
148
|
+ phase1 = np.angle(v[0][nK:2*nK])
|
|
149
|
+
|
|
150
|
+ h = np.zeros(len(t))
|
|
151
|
+ for ik in range(nK):
|
|
152
|
+ h += 2*amp[ik] * np.cos( 2.*np.pi*(ik+1) * (f0/fs) * np.arange(0, len(t), 1 ) + phase[ik] ) + \
|
|
153
|
+ 2*amp1[ik] * np.cos( 2.*np.pi*(ik+1) * (f1/fs) * np.arange(0, len(t), 1 ) + phase1[ik] )
|
145
|
154
|
|
146
|
|
-
|
147
|
|
-
|
148
|
|
-
|
149
|
155
|
return sN-h
|
150
|
156
|
|
151
|
|
-def jacobian( f0, sN, fs, nK, t):
|
|
157
|
+def jacEuler( f0, sN, fs, nK, t):
|
152
|
158
|
print("building Jacobian matrix ")
|
153
|
|
- A = np.zeros( (len(t), 2*nK) )
|
154
|
|
- for irow, tt in enumerate(t):
|
155
|
|
-
|
156
|
|
-
|
157
|
|
-
|
158
|
|
- for k, ik in enumerate( np.arange(0, 2*nK, 2) ):
|
159
|
|
-
|
160
|
|
-
|
161
|
|
- A[irow, ik ] = - (2.*np.pi*k*irow * sin((2.*np.pi*irow*f0)/fs)) / fs
|
162
|
|
- A[irow, ik+1] = (2.*np.pi*k*irow * cos((2.*np.pi*irow*f0)/fs)) / fs
|
163
|
|
-
|
|
159
|
+ J = np.zeros( (len(t), nK), dtype=np.complex64 )
|
|
160
|
+ for it, tt in enumerate(t):
|
|
161
|
+ for ik, k in enumerate( np.arange(0, nK) ):
|
|
162
|
+ c = 1j*2.*np.pi*(ik+1.)*it
|
|
163
|
+ J[it, ik] = c*np.exp( c*f0/fs ) / fs
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+ return J
|
164
|
167
|
|
165
|
168
|
def harmonicNorm ( f0, sN, fs, nK, t ):
|
166
|
|
- return np.linalg.norm( harmonicEuler(f0, sN, fs, nK, t))
|
|
169
|
+ return np.linalg.norm( harmonicEuler(f0, sN, fs, nK, t) )
|
167
|
170
|
|
168
|
171
|
def harmonic2Norm ( f0, sN, fs, nK, t ):
|
169
|
|
- return np.linalg.norm(harmonic2(f0[0], f0[1], sN, fs, nK, t))
|
|
172
|
+ return np.linalg.norm(harmonicEuler2(f0[0], f0[1], sN, fs, nK, t))
|
170
|
173
|
|
171
|
174
|
def minHarmonic(f0, sN, fs, nK, t):
|
172
|
175
|
f02 = guessf0(sN, fs)
|
173
|
176
|
print("minHarmonic", f0, fs, nK, " guess=", f02)
|
174
|
|
- res = minimize( harmonicNorm, np.array((f0)), args=(sN, fs, nK, t))
|
|
177
|
+
|
|
178
|
+ res = minimize( harmonicNorm, np.array((f0)), args=(sN, fs, nK, t))
|
175
|
179
|
print(res)
|
176
|
180
|
return harmonicEuler(res.x[0], sN, fs, nK, t)
|
177
|
181
|
|
|
@@ -181,7 +185,7 @@ def minHarmonic2(f1, f2, sN, fs, nK, t):
|
181
|
185
|
|
182
|
186
|
res = minimize( harmonic2Norm, np.array((f1,f2)), args=(sN, fs, nK, t))
|
183
|
187
|
print(res)
|
184
|
|
- return harmonic2(res.x[0], res.x[1], sN, fs, nK, t)
|
|
188
|
+ return harmonicEuler2(res.x[0], res.x[1], sN, fs, nK, t)
|
185
|
189
|
|
186
|
190
|
def guessf0( sN, fs ):
|
187
|
191
|
S = np.fft.fft(sN)
|
|
@@ -198,17 +202,17 @@ if __name__ == "__main__":
|
198
|
202
|
import matplotlib.pyplot as plt
|
199
|
203
|
|
200
|
204
|
f0 = 60
|
201
|
|
- f1 = 60
|
|
205
|
+ f1 = 62
|
202
|
206
|
delta = np.random.rand()
|
203
|
|
- delta2 = 0
|
|
207
|
+ delta2 = np.random.rand()
|
204
|
208
|
print("delta", delta)
|
205
|
209
|
fs = 10000
|
206
|
210
|
t = np.arange(0, 1, 1/fs)
|
207
|
|
- phi = np.random.rand()
|
208
|
|
- phi2 = 0
|
|
211
|
+ phi = np.random.rand()
|
|
212
|
+ phi2 = np.random.rand()
|
209
|
213
|
A = 1.0
|
210
|
|
- A2 = 0.0
|
211
|
|
- A3 = 0.0
|
|
214
|
+ A2 = 0.25
|
|
215
|
+ A3 = 1.0
|
212
|
216
|
nK = 35
|
213
|
217
|
T2 = .200
|
214
|
218
|
sN = A *np.sin( ( 1*(delta +f0))*2*np.pi*t + phi ) + \
|
|
@@ -223,11 +227,14 @@ if __name__ == "__main__":
|
223
|
227
|
|
224
|
228
|
guessf0(sN, fs)
|
225
|
229
|
|
|
230
|
+
|
226
|
231
|
|
227
|
|
-
|
228
|
|
-
|
|
232
|
+
|
229
|
233
|
|
230
|
|
- h = minHarmonic( f0, sN, fs, nK, t)
|
|
234
|
+
|
|
235
|
+ h = minHarmonic2( f0, f1, sN, fs, nK, t)
|
|
236
|
+
|
|
237
|
+
|
231
|
238
|
|
232
|
239
|
plt.figure()
|
233
|
240
|
plt.plot(t, sN, label="sN")
|