|
@@ -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
|
|
- #A[irow, 0::2] = np.cos( np.arange(nK)*2*np.pi*(f0/fs)*irow )
|
113
|
|
- #A[irow, 1::2] = np.sin( np.arange(nK)*2*np.pi*(f0/fs)*irow )
|
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) # rcond=None) #, rcond=1e-8)
|
118
|
|
- #v = sclstsq(A, sN) #, rcond=1e-6)
|
119
|
115
|
alpha = np.real(v[0]) #[0::2]
|
120
|
116
|
beta = np.imag(v[0]) #[1::2]
|
121
|
|
-
|
122
|
|
- #print("Solving A A.T")
|
123
|
|
- #v = lin.solve(np.dot(A,A.T).T, sN) #, rcond=1e-6)
|
124
|
|
- #v = np.dot(A.T, v)
|
125
|
|
- #v = np.dot(np.linalg.inv(np.dot(A.T, A)), np.dot(A.T, sN))
|
126
|
|
- #alpha = v[0::2]
|
127
|
|
- #beta = v[1::2]
|
128
|
117
|
|
129
|
118
|
amp = np.abs(v[0]) #np.sqrt( alpha**2 + beta**2 )
|
130
|
119
|
phase = np.angle(v[0]) # np.arctan(- beta/alpha)
|
131
|
120
|
|
132
|
|
- #print("amp:", amp, " phase", phase)
|
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
|
|
- #plt.matshow(np.imag(A), aspect='auto')
|
139
|
|
- #plt.colorbar()
|
|
125
|
+ return sN-h
|
140
|
126
|
|
141
|
|
- #plt.figure()
|
142
|
|
- #plt.plot(alpha)
|
143
|
|
- #plt.plot(beta)
|
144
|
|
- #plt.plot(amp)
|
|
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) # rcond=None) #, rcond=1e-8)
|
|
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
|
|
- #plt.figure()
|
147
|
|
- #plt.plot(h)
|
148
|
|
- #plt.title("modelled noise")
|
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
|
|
- #A[irow, 0::2] = np.cos( np.arange(nK)*2*np.pi*(f0/fs)*irow )
|
156
|
|
- #A[irow, 1::2] = np.sin( np.arange(nK)*2*np.pi*(f0/fs)*irow )
|
157
|
|
- # brutal
|
158
|
|
- for k, ik in enumerate( np.arange(0, 2*nK, 2) ):
|
159
|
|
- #A[irow, ik ] = np.cos( k*2*np.pi*(f0/fs)*irow )
|
160
|
|
- #A[irow, ik+1] = np.sin( k*2*np.pi*(f0/fs)*irow )
|
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
|
+ #plt.matshow(np.imag(J), aspect='auto')
|
|
165
|
+ #plt.show()
|
|
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)) #, method='Nelder-Mead' )# jac=None, hess=None, bounds=None )
|
|
177
|
+ # CG, BFGS, Newton-CG, L-BFGS-B, TNC, SLSQP, dogleg, trust-ncg, trust-krylov, trust-exact and trust-constr
|
|
178
|
+ res = minimize( harmonicNorm, np.array((f0)), args=(sN, fs, nK, t)) #, method='CG', jac=jacEuler) #, hess=None, bounds=None )
|
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
|
#methods with bounds, L-BFGS-B, TNC, SLSQP
|
182
|
186
|
res = minimize( harmonic2Norm, np.array((f1,f2)), args=(sN, fs, nK, t)) #, bounds=((f1-1.,f1+1.0),(f2-1.0,f2+1.0)), method='TNC' )
|
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 # Hz
|
201
|
|
- f1 = 60 # Hz
|
|
205
|
+ f1 = 62 # Hz
|
202
|
206
|
delta = np.random.rand()
|
203
|
|
- delta2 = 0 #np.random.rand()
|
|
207
|
+ delta2 = np.random.rand()
|
204
|
208
|
print("delta", delta)
|
205
|
209
|
fs = 10000 # GMR
|
206
|
210
|
t = np.arange(0, 1, 1/fs)
|
207
|
|
- phi = np.random.rand()
|
208
|
|
- phi2 = 0 # np.random.rand()
|
|
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
|
+ # single freq
|
226
|
231
|
#h = harmonicEuler( f0, sN, fs, nK, t)
|
227
|
|
- #h = minHarmonic2( f0, f1, sN, fs, nK, t)
|
228
|
|
- #h = harmonic2( f0, f1, sN, fs, nK, t)
|
|
232
|
+ #h = minHarmonic( f0, sN, fs, nK, t)
|
229
|
233
|
|
230
|
|
- h = minHarmonic( f0, sN, fs, nK, t)
|
|
234
|
+ # two freqs
|
|
235
|
+ h = minHarmonic2( f0, f1, sN, fs, nK, t)
|
|
236
|
+ #h = harmonic2( f0, f1, sN, fs, nK, t)
|
|
237
|
+ #h = harmonicEuler2( f0, f1, sN, fs, nK, t)
|
231
|
238
|
|
232
|
239
|
plt.figure()
|
233
|
240
|
plt.plot(t, sN, label="sN")
|