def XIntegralsFFT(GF_A,Bubble_A,Lambda,BubZero): ''' calculate X integral to susceptibilities using FFT ''' N = int((len(En_A)-1)/2) Kappa_A = TwoParticleBubble(GF_A,GF_A**2,'eh') Bubble_A = TwoParticleBubble(GF_A,GF_A,'eh') #print(Kappa_A[N],Bubble_A[N]) V_A = 1.0/(1.0+Lambda*Bubble_A) KV_A = Lambda*Kappa_A*V_A**2 KmV_A = Lambda*sp.flipud(sp.conj(Kappa_A))*V_A**2 ## zero-padding the arrays exFD_A = sp.concatenate([FD_A[N:],sp.zeros(2*N+2),FD_A[:N+1]]) ImGF_A = sp.concatenate([sp.imag(GF_A[N:]),sp.zeros(2*N+2),sp.imag(GF_A[:N+1])]) ImGF2_A = sp.concatenate([sp.imag(GF_A[N:]**2),sp.zeros(2*N+2),sp.imag(GF_A[:N+1]**2)]) ImV_A = sp.concatenate([sp.imag(V_A[N:]),sp.zeros(2*N+2),sp.imag(V_A[:N+1])]) ImKV_A = sp.concatenate([sp.imag(KV_A[N:]),sp.zeros(2*N+2),sp.imag(KV_A[:N+1])]) ImKmV_A = sp.concatenate([sp.imag(KmV_A[N:]),sp.zeros(2*N+2),sp.imag(KmV_A[:N+1])]) ## performing the convolution ftImX11_A = -sp.conj(fft(exFD_A*ImV_A))*fft(ImGF2_A)*dE ftImX12_A = fft(exFD_A*ImGF2_A)*sp.conj(fft(ImV_A))*dE ftImX21_A = -sp.conj(fft(exFD_A*ImKV_A))*fft(ImGF_A)*dE ftImX22_A = fft(exFD_A*ImGF_A)*sp.conj(fft(ImKV_A))*dE ftImX31_A = -sp.conj(fft(exFD_A*ImKmV_A))*fft(ImGF_A)*dE ftImX32_A = fft(exFD_A*ImGF_A)*sp.conj(fft(ImKmV_A))*dE ## inverse transform ImX1_A = sp.real(ifft(ftImX11_A+ftImX12_A))/sp.pi ImX2_A = sp.real(ifft(ftImX21_A+ftImX22_A))/sp.pi ImX3_A = -sp.real(ifft(ftImX31_A+ftImX32_A))/sp.pi ImX1_A = sp.concatenate([ImX1_A[3*N+4:],ImX1_A[:N+1]]) ImX2_A = sp.concatenate([ImX2_A[3*N+4:],ImX2_A[:N+1]]) ImX3_A = sp.concatenate([ImX3_A[3*N+4:],ImX3_A[:N+1]]) ## getting real part from imaginary X1_A = KramersKronigFFT(ImX1_A) + 1.0j*ImX1_A + BubZero # constant part !!! X2_A = KramersKronigFFT(ImX2_A) + 1.0j*ImX2_A X3_A = KramersKronigFFT(ImX3_A) + 1.0j*ImX3_A return [X1_A,X2_A,X3_A]
def MoyalPropagation(W): """ Propagate wigner function W by the Moyal equation. This function is used to verify that the obtained wigner functions are steady state solutions of the Moyal equation. """ # Make a copy W = np.copy(W) dt = 0.005 # time increment TIterSteps = 2000 # Pre-calculate exp expIV = np.exp(-1j*dt*(V(X - 0.5*Theta) - V(X + 0.5*Theta))) expIK = np.exp(-1j*dt*(K(P + 0.5*Lambda) - K(P - 0.5*Lambda))) for _ in xrange(TIterSteps): # p x -> theta x W = fftpack.fft(W, axis=0, overwrite_x=True) W *= expIV # theta x -> p x W = fftpack.ifft(W, axis=0, overwrite_x=True) # p x -> p lambda W = fftpack.fft(W, axis=1, overwrite_x=True) W *= expIK # p lambda -> p x W = fftpack.ifft(W, axis=1, overwrite_x=True) # normalization W /= W.real.sum()*dX*dP return fftpack.fftshift(W.real)
def run(self): if self.filter_on == False: f = lambda x:random.random()+self.amp*np.sin(x) x = np.linspace(0, 10) fft_feature = fft.fft(map(f, x)) ifft_feature = fft.ifft(fft_feature) self.newSample.emit(map(f, x)) self.newSamplefft.emit(list(abs(fft_feature))) self.newSampleifft.emit(list(ifft_feature)) elif self.filter_on == True: f = lambda x:random.random()+self.amp*np.sin(x) x = np.linspace(0, 10) fft_feature = fft.fft(map(f, x)) mean = np.average(abs(fft_feature)) fft_feature_filter = fft_feature for i in range(len(fft_feature)): if abs(fft_feature[i]) >= mean: fft_feature_filter[i] = abs(fft_feature[i]) else: fft_feature_filter[i] = 0 ifft_feature = fft.ifft(fft_feature_filter) self.newSample.emit(map(f, x)) self.newSamplefft.emit(list(fft_feature_filter)) self.newSampleifft.emit(list(ifft_feature)) self.filter_on = False else: pass
def unScaled(): # Set up grid and two-soliton initial data: x = (2.*np.pi/N)*np.arange(-N/2,N/2).reshape(N,1) A, B = 25., 16. A_shift, B_shift = 2., 1. y0 = (3.*A**2.*np.cosh(.5*(A*(x+2.)))**(-2.) + 3*B**2.*np.cosh(.5*(B*(x+1.)))**(-2.)).reshape(N,) k = np.concatenate(( np.arange(0,N/2) , np.array([0]) , np.arange(-N/2+1,0,1) )).reshape(N,) ik3 = 1j*k**3. def F_unscaled(t,u): out = -.5*1j*k*fft(ifft(u,axis=0)**2.,axis=0) + ik3* u return out tmax = .006 dt = .01*N**(-2.) nmax = int(round(tmax/dt)) nplt = int(np.floor((tmax/25.)/dt)) y0 = fft(y0,axis=0) T,Y = RK4(F_unscaled, y0, t0=0, t1=tmax, n=nmax) udata, tdata = np.real(ifft(y0,axis=0)).reshape(N,1), np.array(0.).reshape(1,1) for n in range(1,nmax+1): if np.mod(n,nplt) == 0: t = n*dt u = np.real( ifft(Y[n], axis=0) ).reshape(N,1) udata = np.concatenate((udata,np.nan_to_num(u)),axis=1) tdata = np.concatenate((tdata,np.array(t).reshape(1,1)),axis=1) return x, tdata, udata
def xcorrnorm(tr1, tr2, pad=True): """ Compute normalized cross correlation of two traces maxcor, maxlag, maxdt, cc, lags, tlags = xcorr1x1(tr1, tr2) INPUTS tr1 - obspy trace1 tr2 - obspy trace2 NOT IMPLEMENTED YET freqmin, freqmax - optional, restrict frequency range to [freqmin, freqmax] lags = lag to compute if None, will compute all lags and find max, OUTPUTS maxcor - value of maximum correlation maxlag - lag of maximum correlation (in samples) - this is the number of samples to shift tr2 so it lines up with tr1 maxdt - time lag of max lag, in seconds cc - cross correlation value at each shift lags - lag at each cc value in samples tlags - lag at each cc value in seconds TODO add option to only compute certain lags add option to output entire cc function """ from scipy.fftpack import fft, ifft if tr1.stats.sampling_rate != tr2.stats.sampling_rate: raise RuntimeError('tr1 and tr2 have different sampling rates') return # make sure data is float dat1 = tr1.data*1. dat2 = tr2.data*1. if len(tr1) != len(tr2): if pad is True: print('tr1 and tr2 have different lengths, padding with zeros') if len(dat1) > len(dat2): dat2 = np.lib.pad(dat2, (0, len(dat1)-len(dat2)), 'constant', constant_values=(0., 0.)) else: dat1 = np.lib.pad(dat1, (0, len(dat2)-len(dat1)), 'constant', constant_values=(0., 0.)) else: raise RuntimeError('tr1 and tr2 are different lengths, set pad=True if you want to proceed') return # pad data to double number of samples to avoid wrap around and pad more to next closest power of 2 for fft n2 = nextpow2(len(dat1)) FFT1 = fft(dat1, n2) norm1 = np.sqrt(np.real(ifft(FFT1*np.conj(FFT1), n2))) FFT2 = fft(dat2, n2) norm2 = np.sqrt(np.real(ifft(FFT2*np.conj(FFT2), n2))) cctemp = np.real(ifft(FFT1*np.conj(FFT2), n2)) cc = cctemp/(norm1[0]*norm2[0]) M = len(FFT1) lags = np.roll(np.linspace(-M/2 + 1, M/2, M, endpoint=True), M/2 + 1).astype(int) indx = np.argmax(cc) maxcor = cc[indx] maxlag = lags[indx] maxdt = 1./tr1.stats.sampling_rate*maxlag tlags = 1./tr1.stats.sampling_rate*lags return maxcor, maxlag, maxdt, cc, lags, tlags
def freq_filter(f, dt, cutoff_freq, convention='math'): """ A digital filter that filters frequency below a cutoff frequency Parameters ---------- f : time signal dt : sampling period nu_cutoff : cutoff frequency Returns ------- The filtered time signal """ if convention == 'math': f_freq = fft(f) elif convention == 'physics': f_freq = ifft(f) Ns = np.size(f) freqs = fftfreq(Ns, dt) # filtering operation f_freq[np.where(np.abs(freqs) > cutoff_freq)] = 0 # go back to time domain if convention == 'math': f_filter_time = ifft(f_freq) elif convention == 'physics': f_filter_time = fft(f_freq) return f_filter_time
def idct(self, X): '''Compute inverse discrete cosine transform of a 1-d array X''' N = len(X) w = np.sqrt(2*N)*np.exp(1j*np.arange(N)*np.pi/(2.*N)) if (N%2==1) or (any(np.isreal(X))== False): w[0] = w[0] * np.sqrt(2) yy = np.zeros(2*N) yy[0:N] = w * X yy[N+1:2*N] = -1j * w[1:N] * X[1:N][::-1] y = fftpack.ifft(yy) x = y[0:N] else: w[0] = w[0]/np.sqrt(2) yy = X *w y = fftpack.ifft(yy) x = np.zeros(N) x[0:N:2] = y[0:N/2] x[1:N:2] = y[N:(N/2)-1:-1] if all(np.isreal(x)): x = np.real(x) return x
def bench_random(self): from numpy.fft import ifft as numpy_ifft print() print(' Inverse Fast Fourier Transform') print('===============================================') print(' | real input | complex input ') print('-----------------------------------------------') print(' size | scipy | numpy | scipy | numpy ') print('-----------------------------------------------') for size,repeat in [(100,7000),(1000,2000), (256,10000), (512,10000), (1024,1000), (2048,1000), (2048*2,500), (2048*4,500), ]: print('%5s' % size, end=' ') sys.stdout.flush() for x in [random([size]).astype(double), random([size]).astype(cdouble)+random([size]).astype(cdouble)*1j ]: if size > 500: y = ifft(x) else: y = direct_idft(x) assert_array_almost_equal(ifft(x),y) print('|%8.2f' % measure('ifft(x)',repeat), end=' ') sys.stdout.flush() assert_array_almost_equal(numpy_ifft(x),y) print('|%8.2f' % measure('numpy_ifft(x)',repeat), end=' ') sys.stdout.flush() print(' (secs for %s calls)' % (repeat)) sys.stdout.flush()
def ifcglt(A): # Lobatto Nodal to Modal Coefficients """ Fast Chebyshev-Gauss-Lobatto transformation from point space values (nodal) to Chebyshev expansion coefficients (modal). If I=numpy.identity(n), then Ti=chebyshev.ifcglt(I) will be the inverse of the Chebyshev Vandermonde matrix on the Lobatto nodes """ size = A.shape m = size[0] k = m-1-np.arange(m-1) if len(size) == 2: # Multiple vectors V = np.vstack((A[0:m-1,:],A[k,:])) F = ifft(V, n=None, axis=0) B = np.vstack((F[0,:],2*F[1:m-1,:],F[m-1,:])) else: # Single vector V = np.hstack((A[0:m-1],A[k])) F = ifft(V, n=None) B = np.hstack((F[0],2*F[1:m-1],F[m-1])) if A.dtype!='complex': return np.real(B) else: return B
def convolve_power(power_spectrum, window_power, axis=-1): """Convolve a power spectrum with a window function.""" data_corr = fft.ifft(power_spectrum, axis=axis) window_corr = fft.ifft(window_power, axis=axis) true_corr = data_corr * window_corr true_power = fft.fft(true_corr, axis=axis, overwrite_x=True) return true_power
def ImpulseResponse(H, F): """ Input: H = existing transferfunction spectrum F = [Hz] Frequency bins array output: IR = [sec] time signal of resultin impulse respose T = time of the total impusle response inluding silence fs = measured sample frequency Impulse response makes use of ifft method to calculate a time signal back from the transferfunction. fft of the form: n-1 m*k a_m =1/n * sum A_k * exp ( -2pi * i ----) for m = 0, ..., n-1 k=0 n Therefore fft * 1/N to correct amplitude TODO: - correction for N - Silence removal """ print("""This function works only correct when: - no smoothing or averaging is applied - full spectrum data is returned!""") from scipy.fftpack import ifft, fftshift, fftfreq # 2DO Check for full Spectrum if isinstance(H, tuple): # could also use assert # Check arrays for type of signal # Mag + Phase --> Mag is absolut no neg values # Check symetrie no symmerie is false info... # Without shift X[0] = F - 0Hz and X[fs/2] = # shift check on symmetry? H0even = Symmetry(H[0], 'even') H1odd = Symmetry(H[1], 'odd') if (H0even and H1odd): if H[0] == abs(H[0]): if max(abs(H[1])) <= np.pi: # check for phase RAD information pass elif max(abs(H[1])) <= 180: # check for phase DEG information H[1] = H[1] * np.pi / 180 pass # http://stackoverflow.com/questions/2598734/numpy-creating-a-complex-array-from-2-real-ones # elif ...: # check for complex paterns don't know how # pass else: pass else: raise MeasError.DataError(H, 'No valid frequency array') elif np.any(np.iscomplex(H)): IR = ifft(H) else: raise TypeError('Not right input type') IR = ifft(H) dF = F[1]-F[0] fs = np.round(len(F) * dF) T = len(F) * 1 / fs return(IR, fs, T)
def sprModel(x, fs, w, N, t): """ Analysis/synthesis of a sound using the sinusoidal plus residual model, one frame at a time x: input sound, fs: sampling rate, w: analysis window, N: FFT size (minimum 512), t: threshold in negative dB, returns y: output sound, ys: sinusoidal component, xr: residual component """ hN = N/2 # size of positive spectrum hM1 = int(math.floor((w.size+1)/2)) # half analysis window size by rounding hM2 = int(math.floor(w.size/2)) # half analysis window size by floor Ns = 512 # FFT size for synthesis (even) H = Ns/4 # Hop size used for analysis and synthesis hNs = Ns/2 pin = max(hNs, hM1) # initialize sound pointer in middle of analysis window pend = x.size - max(hNs, hM1) # last sample to start a frame fftbuffer = np.zeros(N) # initialize buffer for FFT ysw = np.zeros(Ns) # initialize output sound frame xrw = np.zeros(Ns) # initialize output sound frame ys = np.zeros(x.size) # initialize output array xr = np.zeros(x.size) # initialize output array w = w / sum(w) # normalize analysis window sw = np.zeros(Ns) ow = triang(2*H) # overlapping window sw[hNs-H:hNs+H] = ow bh = blackmanharris(Ns) # synthesis window bh = bh / sum(bh) # normalize synthesis window wr = bh # window for residual sw[hNs-H:hNs+H] = sw[hNs-H:hNs+H] / bh[hNs-H:hNs+H] while pin<pend: #-----analysis----- x1 = x[pin-hM1:pin+hM2] # select frame mX, pX = DFT.dftAnal(x1, w, N) # compute dft ploc = UF.peakDetection(mX, t) # find peaks iploc, ipmag, ipphase = UF.peakInterp(mX, pX, ploc) # refine peak values iploc, ipmag, ipphase = UF.peakInterp(mX, pX, ploc) # refine peak values ipfreq = fs*iploc/float(N) # convert peak locations to Hertz ri = pin-hNs-1 # input sound pointer for residual analysis xw2 = x[ri:ri+Ns]*wr # window the input sound fftbuffer = np.zeros(Ns) # reset buffer fftbuffer[:hNs] = xw2[hNs:] # zero-phase window in fftbuffer fftbuffer[hNs:] = xw2[:hNs] X2 = fft(fftbuffer) # compute FFT for residual analysis #-----synthesis----- Ys = UF.genSpecSines(ipfreq, ipmag, ipphase, Ns, fs) # generate spec of sinusoidal component Xr = X2-Ys; # get the residual complex spectrum fftbuffer = np.zeros(Ns) fftbuffer = np.real(ifft(Ys)) # inverse FFT of sinusoidal spectrum ysw[:hNs-1] = fftbuffer[hNs+1:] # undo zero-phase window ysw[hNs-1:] = fftbuffer[:hNs+1] fftbuffer = np.zeros(Ns) fftbuffer = np.real(ifft(Xr)) # inverse FFT of residual spectrum xrw[:hNs-1] = fftbuffer[hNs+1:] # undo zero-phase window xrw[hNs-1:] = fftbuffer[:hNs+1] ys[ri:ri+Ns] += sw*ysw # overlap-add for sines xr[ri:ri+Ns] += sw*xrw # overlap-add for residual pin += H # advance sound pointer y = ys+xr # sum of sinusoidal and residual components return y, ys, xr
def test_random_real(self): for size in [1, 51, 111, 100, 200, 64, 128, 256, 1024]: x = random([size]).astype(self.rdt) y1 = ifft(fft(x)) y2 = fft(ifft(x)) assert_equal(y1.dtype, self.cdt) assert_equal(y2.dtype, self.cdt) assert_array_almost_equal(y1, x) assert_array_almost_equal(y2, x)
def test_definition(self): x = np.array([1, 2, 3, 4 + 1j, 1, 2, 3, 4 + 2j], self.cdt) y = ifft(x) y1 = direct_idft(x) assert_equal(y.dtype, self.cdt) assert_array_almost_equal(y, y1) x = np.array([1, 2, 3, 4 + 0j, 5], self.cdt) assert_array_almost_equal(ifft(x), direct_idft(x))
def rceps(x): y = sp.real(ifft(sp.log(sp.absolute(fft(x))))) n = len(x) if (n%2) == 1: ym = np.hstack((y[0], 2*y[1:n/2], np.zeros(n/2-1))) else: ym = np.hstack((y[0], 2*y[1:n/2], y[n/2+1], np.zeros(n/2-1))) ym = sp.real(ifft(sp.exp(fft(ym)))) return (y, ym)
def g(v): v_hat = fft(v) vp_hat = (1j*k1)*v_hat vpp_hat = (1j*k2)**2*v_hat vpp = ifft(vpp_hat) vp = ifft(vp_hat) w = np.real(vpp + np.sin(v) + vp) w[-1] = v[-1]-.1 return w
def ACF_scargle(t, y, dy, n_omega=2 ** 10, omega_max=100): """Compute the Auto-correlation function via Scargle's method Parameters ---------- t : array_like times of observation. Assumed to be in increasing order. y : array_like values of each observation. Should be same shape as t dy : float or array_like errors in each observation. n_omega : int (optional) number of angular frequencies at which to evaluate the periodogram default is 2^10 omega_max : float (optional) maximum value of omega at which to evaluate the periodogram default is 100 Returns ------- ACF, t : ndarrays The auto-correlation function and associated times """ t = np.asarray(t) y = np.asarray(y) if y.shape != t.shape: raise ValueError("shapes of t and y must match") dy = np.asarray(dy) * np.ones(y.shape) d_omega = omega_max * 1. / (n_omega + 1) omega = d_omega * np.arange(1, n_omega + 1) # recall that P(omega = 0) = (chi^2(0) - chi^2(0)) / chi^2(0) # = 0 # compute P and shifted full-frequency array P = lomb_scargle(t, y, dy, omega, generalized=True) P = np.concatenate([[0], P, P[-2::-1]]) # compute PW, the power of the window function PW = lomb_scargle(t, np.ones(len(t)), dy, omega, generalized=False, subtract_mean=False) PW = np.concatenate([[0], PW, PW[-2::-1]]) # compute the inverse fourier transform of P and PW rho = fftpack.ifft(P).real rhoW = fftpack.ifft(PW).real ACF = fftpack.fftshift(rho / rhoW) / np.sqrt(2) N = len(ACF) dt = 2 * np.pi / N / (omega[1] - omega[0]) t = dt * (np.arange(N) - N // 2) return ACF, t
def deconvf(rsp_list, src, sampling_rate, water=0.05, gauss=2., tshift=10., pad=0, length=None, normalize=True, normalize_to_src=False, returnall=False): """ Frequency-domain deconvolution using waterlevel method. rsp, src data containing the response and source functions, respectively water waterlevel to stabilize the deconvolution gauss Gauss parameter of Low-pass filter tshift shift the resulting function by that amount pad multiply number of samples used for fft by 2**pad """ if length == None: length = len(src) N = length nfft = nextpow2(N) * 2 ** pad freq = np.fft.fftfreq(nfft, d=1. / sampling_rate) gauss = np.exp(np.maximum(-(0.5 * 2 * pi * freq / gauss) ** 2, -700.) - 1j * tshift * 2 * pi * freq) spec_src = fft(src, nfft) spec_src_conj = np.conjugate(spec_src) spec_src_water = np.abs(spec_src * spec_src_conj) spec_src_water = np.maximum(spec_src_water, max(spec_src_water) * water) if normalize_to_src: spec_src = gauss * spec_src * spec_src_conj / spec_src_water rf_src = ifft(spec_src, nfft)[:N] #i1 = int((tshift-1)*sampling_rate) #i2 = int((tshift+1)*sampling_rate) norm = 1 / max(rf_src) rf_src = norm * rf_src flag = False if not isinstance(rsp_list, (list, tuple)): flag = True rsp_list = [rsp_list] rf_list = [ifft(gauss * fft(rsp, nfft) * spec_src_conj / spec_src_water, nfft)[:N] for rsp in rsp_list] if normalize: if not normalize_to_src: norm = 1. / max(rf_list[0]) for rf in rf_list: rf *= norm if returnall: if not normalize_to_src: spec_src = gauss * spec_src * spec_src_conj / spec_src_water rf_src = ifft(spec_src, nfft)[:N] norm = 1 / max(rf_src) rf_src = norm * rf_src return rf_list, rf_src, spec_src_conj, spec_src_water, freq, gauss, norm, N, nfft elif flag: return rf else: return rf_list
def test_definition_real(self): x = np.array([1, 2, 3, 4, 1, 2, 3, 4], self.rdt) y = ifft(x) assert_equal(y.dtype, self.cdt) y1 = direct_idft(x) assert_array_almost_equal(y, y1) x = np.array([1, 2, 3, 4, 5], dtype=self.rdt) assert_equal(y.dtype, self.cdt) assert_array_almost_equal(ifft(x), direct_idft(x))
def test_definition(self): x = np.array([1,2,3,4+1j,1,2,3,4+2j], self.cdt) y = ifft(x) y1 = direct_idft(x) self.assertTrue(y.dtype == self.cdt, "Output dtype is %s, expected %s" % (y.dtype, self.cdt)) assert_array_almost_equal(y,y1) x = np.array([1,2,3,4+0j,5], self.cdt) assert_array_almost_equal(ifft(x),direct_idft(x))
def test_random_real(self): for size in [1,51,111,100,200,64,128,256,1024]: x = random([size]).astype(self.rdt) y1 = ifft(fft(x)) y2 = fft(ifft(x)) self.assertTrue(y1.dtype == self.cdt, "Output dtype is %s, expected %s" % (y1.dtype, self.cdt)) self.assertTrue(y2.dtype == self.cdt, "Output dtype is %s, expected %s" % (y2.dtype, self.cdt)) assert_array_almost_equal (y1, x) assert_array_almost_equal (y2, x)
def animate(i): global c psi=ifft(T_K(Dtr)*c)*Npoint c=T_K(Dtr)*fft(T_R_psi(t0,Dtr,psi))/Npoint c = normaliza(c); # check norm in the wf #prepare to plot cc = ifft(c)*Npoint*NormWF**0.5 # FFT from K3 to R3 and include the wf norm psi = changeFFTposition(cc,Npoint,0) # psi is the final wave function # plot features line.set_data(z, abs(psi)**2) return line,
def test_definition_real(self): x = np.array([1,2,3,4,1,2,3,4], self.rdt) y = ifft(x) self.failUnless(y.dtype == self.cdt, "Output dtype is %s, expected %s" % (y.dtype, self.cdt)) y1 = direct_idft(x) assert_array_almost_equal(y,y1) x = np.array([1,2,3,4,5], dtype=self.rdt) self.failUnless(y.dtype == self.cdt, "Output dtype is %s, expected %s" % (y.dtype, self.cdt)) assert_array_almost_equal(ifft(x),direct_idft(x))
def test_random_complex(self): for size in [1,51,111,100,200,64,128,256,1024]: x = random([size]).astype(self.cdt) x = random([size]).astype(self.cdt) +1j*x y1 = ifft(fft(x)) y2 = fft(ifft(x)) self.failUnless(y1.dtype == self.cdt, "Output dtype is %s, expected %s" % (y1.dtype, self.cdt)) self.failUnless(y2.dtype == self.cdt, "Output dtype is %s, expected %s" % (y2.dtype, self.cdt)) assert_array_almost_equal (y1, x) assert_array_almost_equal (y2, x)
def hpsModelSynth(hfreq, hmag, hphase, mYst, N, H, fs): # Synthesis of a sound using the harmonic plus stochastic model # hfreq: harmonic frequencies, hmag:harmonic amplitudes, mYst: stochastic envelope # Ns: synthesis FFT size, H: hop size, fs: sampling rate # y: output sound, yh: harmonic component, yst: stochastic component hN = N/2 # half of FFT size for synthesis L = hfreq[:,0].size # number of frames nH = hfreq[0,:].size # number of harmonics pout = 0 # initialize output sound pointer ysize = H*(L+4) # output sound size yhw = np.zeros(N) # initialize output sound frame ysw = np.zeros(N) # initialize output sound frame yh = np.zeros(ysize) # initialize output array yst = np.zeros(ysize) # initialize output array sw = np.zeros(N) ow = triang(2*H) # overlapping window sw[hN-H:hN+H] = ow bh = blackmanharris(N) # synthesis window bh = bh / sum(bh) # normalize synthesis window wr = bh # window for residual sw[hN-H:hN+H] = sw[hN-H:hN+H] / bh[hN-H:hN+H] # synthesis window for harmonic component sws = H*hanning(N)/2 # synthesis window for stochastic component lastyhfreq = hfreq[0,:] # initialize synthesis harmonic frequencies yhphase = 2*np.pi*np.random.rand(nH) # initialize synthesis harmonic phases for l in range(L): yhfreq = hfreq[l,:] # synthesis harmonics frequencies yhmag = hmag[l,:] # synthesis harmonic amplitudes mYrenv = mYst[l,:] # synthesis residual envelope if (hphase.size > 0): yhphase = hphase[l,:] else: yhphase += (np.pi*(lastyhfreq+yhfreq)/fs)*H # propagate phases lastyhfreq = yhfreq Yh = UF.genSpecSines(yhfreq, yhmag, yhphase, N, fs) # generate spec sines mYs = resample(mYrenv, hN) # interpolate to original size mYs = 10**(mYs/20) # dB to linear magnitude pYs = 2*np.pi*np.random.rand(hN) # generate phase random values Ys = np.zeros(N, dtype = complex) Ys[:hN] = mYs * np.exp(1j*pYs) # generate positive freq. Ys[hN+1:] = mYs[:0:-1] * np.exp(-1j*pYs[:0:-1]) # generate negative freq. fftbuffer = np.zeros(N) fftbuffer = np.real(ifft(Yh)) # inverse FFT of harm spectrum yhw[:hN-1] = fftbuffer[hN+1:] # undo zer-phase window yhw[hN-1:] = fftbuffer[:hN+1] fftbuffer = np.zeros(N) fftbuffer = np.real(ifft(Ys)) # inverse FFT of stochastic approximation spectrum ysw[:hN-1] = fftbuffer[hN+1:] # undo zero-phase window ysw[hN-1:] = fftbuffer[:hN+1] yh[pout:pout+N] += sw*yhw # overlap-add for sines yst[pout:pout+N] += sws*ysw # overlap-add for stoch pout += H # advance sound pointer y = yh+yst # sum harmonic and stochastic components return y, yh, yst
def minimum_phase(h): """Convert a linear-phase FIR filter to minimum phase. Parameters ---------- h : array Linear-phase FIR filter coefficients. Returns ------- h_minimum : array The minimum-phase version of the filter, with length ``(length(h) + 1) // 2``. """ try: from scipy.signal import minimum_phase except Exception: pass else: return minimum_phase(h) from scipy.fftpack import fft, ifft h = np.asarray(h) if np.iscomplexobj(h): raise ValueError('Complex filters not supported') if h.ndim != 1 or h.size <= 2: raise ValueError('h must be 1D and at least 2 samples long') n_half = len(h) // 2 if not np.allclose(h[-n_half:][::-1], h[:n_half]): warnings.warn('h does not appear to by symmetric, conversion may ' 'fail', RuntimeWarning) n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01))) # zero-pad; calculate the DFT h_temp = np.abs(fft(h, n_fft)) # take 0.25*log(|H|**2) = 0.5*log(|H|) h_temp += 1e-7 * h_temp[h_temp > 0].min() # don't let log blow up np.log(h_temp, out=h_temp) h_temp *= 0.5 # IDFT h_temp = ifft(h_temp).real # multiply pointwise by the homomorphic filter # lmin[n] = 2u[n] - d[n] win = np.zeros(n_fft) win[0] = 1 stop = (len(h) + 1) // 2 win[1:stop] = 2 if len(h) % 2: win[stop] = 1 h_temp *= win h_temp = ifft(np.exp(fft(h_temp))) h_minimum = h_temp.real n_out = n_half + len(h) % 2 return h_minimum[:n_out]
def single_step_propagation(self): """ Perform single step propagation. The final Wigner functions are not normalized. """ ################ p x -> theta x ################ self.wigner_ge = fftpack.fft(self.wigner_ge, axis=0, overwrite_x=True) self.wigner_g = fftpack.fft(self.wigner_g, axis=0, overwrite_x=True) self.wigner_e = fftpack.fft(self.wigner_e, axis=0, overwrite_x=True) # Construct T matricies TgL, TgeL, TeL = self.get_T_left(self.t) TgR, TgeR, TeR = self.get_T_right(self.t) # Save previous version of the Wigner function Wg, Wge, We = self.wigner_g, self.wigner_ge, self.wigner_e # First update the complex valued off diagonal wigner function self.wigner_ge = (TgL*Wg + TgeL*Wge.conj())*TgeR + (TgL*Wge + TgeL*We)*TeR # Slice arrays to employ the symmetry (savings in speed) TgL, TgeL, TeL = self.theta_slice(TgL, TgeL, TeL) TgR, TgeR, TeR = self.theta_slice(TgR, TgeR, TeR) Wg, Wge, We = self.theta_slice(Wg, Wge, We) # Calculate the remaning real valued Wigner functions self.wigner_g = (TgL*Wg + TgeL*Wge.conj())*TgR + (TgL*Wge + TgeL*We)*TgeR self.wigner_e = (TgeL*Wg + TeL*Wge.conj())*TgeR + (TgeL*Wge + TeL*We)*TeR ################ Apply the phase factor ################ self.wigner_ge *= self.expV self.wigner_g *= self.expV[:(1 + self.P_gridDIM//2), :] self.wigner_e *= self.expV[:(1 + self.P_gridDIM//2), :] ################ theta x -> p x ################ self.wigner_ge = fftpack.ifft(self.wigner_ge, axis=0, overwrite_x=True) self.wigner_g = fft.irfft(self.wigner_g, axis=0) self.wigner_e = fft.irfft(self.wigner_e, axis=0) ################ p x -> p lambda ################ self.wigner_ge = fftpack.fft(self.wigner_ge, axis=1, overwrite_x=True) self.wigner_g = fft.rfft(self.wigner_g, axis=1) self.wigner_e = fft.rfft(self.wigner_e, axis=1) ################ Apply the phase factor ################ self.wigner_ge *= self.expK self.wigner_g *= self.expK[:, :(1 + self.X_gridDIM//2)] self.wigner_e *= self.expK[:, :(1 + self.X_gridDIM//2)] ################ p lambda -> p x ################ self.wigner_ge = fftpack.ifft(self.wigner_ge, axis=1, overwrite_x=True) self.wigner_g = fft.irfft(self.wigner_g, axis=1) self.wigner_e = fft.irfft(self.wigner_e, axis=1)
def test_definition(self): x = [1,2,3,4+1j,1,2,3,4+2j] y = ifft(x) y1 = direct_idft(x) assert_array_almost_equal(y,y1) x = [1,2,3,4+0j,5] assert_array_almost_equal(ifft(x),direct_idft(x)) x = [1,2,3,4,1,2,3,4] y = ifft(x) y1 = direct_idft(x) assert_array_almost_equal(y,y1) x = [1,2,3,4,5] assert_array_almost_equal(ifft(x),direct_idft(x))
def test_definition(self): x = [1,2,3,4,1,2,3,4] x1 = [1,2+3j,4+1j,2+3j,4,2-3j,4-1j,2-3j] y = irfft(x) y1 = direct_irdft(x) assert_array_almost_equal(y,y1) assert_array_almost_equal(y,ifft(x1)) x = [1,2,3,4,1,2,3,4,5] x1 = [1,2+3j,4+1j,2+3j,4+5j,4-5j,2-3j,4-1j,2-3j] y = irfft(x) y1 = direct_irdft(x) assert_array_almost_equal(y,y1) assert_array_almost_equal(y,ifft(x1))
def idft_2d_from_1d(arr): """ Compute 2d IDFT from 1d IDFT. First, compute 1d IDFT of every rows. Then, compute 1d IDFT of every column of resulting matrix""" from scipy.fftpack import ifft r,c = arr.shape idftArr = zeros((r,c), dtype=complex) idftArr1 = zeros((r,c), dtype=complex).T for ind, row in enumerate(arr): idftArr[ind] = ifft(row) for ind, col in enumerate(idftArr.T): idftArr1[ind] = ifft(col) return idftArr1.T
def d1_getInverseFourierCoeffs(fft_x): """ returns the function samples given its 1d Fourier coeffs """ f_x = fftpack.ifft(fftpack.ifftshift(fft_x)) * len(fft_x) return f_x
numpy_mat = np.array([[3, 2, 2], [5, 5, 2], [7, 8, 69]]) print(linalg.det(numpy_mat)) EW, EV = linalg.eig(numpy_mat) print(EW, EV) from numpy import poly1d p = poly1d([3, 2, 1]) print(p) print(p * p) print(p.deriv()) #fft from scipy.fftpack import fft, ifft x = np.array([1.0, 2.0, 3.0, 4.0]) y = fft(x) print(y) print(ifft(y)) x = np.array([[1.0 + 1j, 2.0 + 2j], [3.0 + 3j, 4.0 + 4j]]) y = fft(x) print(y) print(ifft(y)) import pandas as pd df = pd.DataFrame({ 'Marks': [44, 55, 66, 46, 34], 'Name': ['abc', 'def', 'ghi', 'jkl', 'mno'] }) print(df.head()) print(df['Marks'].value_counts()) print(df['Name'].nunique()) print(df['Name'].unique())
def fft_resample(x, W, new_len, npad, to_remove, cuda_dict=dict(use_cuda=False)): """Do FFT resampling with a filter function (possibly using CUDA) Parameters ---------- x : 1-d array The array to resample. W : 1-d array or gpuarray The filtering function to apply. new_len : int The size of the output array (before removing padding). npad : int Amount of padding to apply before resampling. to_remove : int Number of samples to remove after resampling. cuda_dict : dict Dictionary constructed using setup_cuda_multiply_repeated(). Returns ------- x : 1-d array Filtered version of x. """ # add some padding at beginning and end to make this work a little cleaner x = _smart_pad(x, npad) old_len = len(x) shorter = new_len < old_len if not cuda_dict['use_cuda']: N = int(min(new_len, old_len)) sl_1 = slice((N + 1) // 2) y_fft = np.zeros(new_len, np.complex128) x_fft = fft(x).ravel() * W y_fft[sl_1] = x_fft[sl_1] sl_2 = slice(-(N - 1) // 2, None) y_fft[sl_2] = x_fft[sl_2] y = np.real(ifft(y_fft, overwrite_x=True)).ravel() else: cuda_dict['x'].set( np.concatenate((x, np.zeros(max(new_len - old_len, 0), x.dtype)))) # do the fourier-domain operations, results put in second param cudafft.fft(cuda_dict['x'], cuda_dict['x_fft'], cuda_dict['fft_plan']) cuda_multiply_inplace_c128(W, cuda_dict['x_fft']) # This is not straightforward, but because x_fft and y_fft share # the same data (and only one half of the full DFT is stored), we # don't have to transfer the slice like we do in scipy. All we # need to worry about is the Nyquist component, either halving it # or taking just the real component... use_len = new_len if shorter else old_len func = cuda_real_c128 if shorter else cuda_halve_c128 if use_len % 2 == 0: nyq = int((use_len - (use_len % 2)) // 2) func(cuda_dict['x_fft'], slice=slice(nyq, nyq + 1)) cudafft.ifft(cuda_dict['x_fft'], cuda_dict['x'], cuda_dict['ifft_plan'], scale=False) y = cuda_dict['x'].get()[:new_len if shorter else None] # now let's trim it back to the correct size (if there was padding) if to_remove > 0: keep = np.ones((new_len), dtype='bool') keep[:to_remove] = False keep[-to_remove:] = False y = np.compress(keep, y) return y
def hb_time(sdfunc, x0=None, omega=1, method='newton_krylov', num_harmonics=1, num_variables=None, eqform='second_order', params={}, realify=True, **kwargs): r"""Harmonic balance solver for first and second order ODEs. Obtains the solution of a first-order and second-order differential equation under the presumption that the solution is harmonic using an algebraic time method. Returns `t` (time), `x` (displacement), `v` (velocity), and `a` (acceleration) response of a first- or second- order linear ordinary differential equation defined by :math:`\ddot{\mathbf{x}}=f(\mathbf{x},\mathbf{v},\omega)` or :math:`\dot{\mathbf{x}}=f(\mathbf{x},\omega)`. For the state space form, the function `sdfunc` should have the form:: def duff_osc_ss(x, params): # params is a dictionary of parameters omega = params['omega'] # `omega` will be put into the dictionary # for you t = params['cur_time'] # The time value is available as # `cur_time` in the dictionary xdot = np.array([[x[1]],[-x[0]-.1*x[0]**3-.1*x[1]+1*sin(omega*t)]]) return xdot In a state space form solution, the function must take the states and the `params` dictionary. This dictionary should be used to obtain the prescribed response frequency and the current time. These plus any other parameters are used to calculate the state derivatives which are returned by the function. For the second order form the function `sdfunc` should have the form:: def duff_osc(x, v, params): # params is a dictionary of parameters omega = params['omega'] # `omega` will be put into the dictionary # for you t = params['cur_time'] # The time value is available as # `cur_time` in the dictionary return np.array([[-x-.1*x**3-.2*v+sin(omega*t)]]) In a second-order form solution the function must take the states and the `params` dictionary. This dictionary should be used to obtain the prescribed response frequency and the current time. These plus any other parameters are used to calculate the state derivatives which are returned by the function. Parameters ---------- sdfunc : function For `eqform='first_order'`, name of function that returns **column vector** first derivative given `x`, `omega` and \*\*kwargs. This is *NOT* a string. :math:`\dot{\mathbf{x}}=f(\mathbf{x},\omega)` For `eqform='second_order'`, name of function that returns **column vector** second derivative given `x`, `v`, `omega` and \*\*kwargs. This is *NOT* a string. :math:`\ddot{\mathbf{x}}=f(\mathbf{x},\mathbf{v},\omega)` x0 : array_like, somewhat optional n x m array where n is the number of equations and m is the number of values representing the repeating solution. It is required that :math:`m = 1 + 2 num_{harmonics}`. (we will generalize allowable default values later.) omega : float assumed fundamental response frequency in radians per second. method : str, optional Name of optimization method to be used. num_harmonics : int, optional Number of harmonics to presume. The omega = 0 constant term is always presumed to exist. Minimum (and default) is 1. If num_harmonics*2+1 exceeds the number of columns of `x0` then `x0` will be expanded, using Fourier analaysis, to include additional harmonics with the starting presumption of zero values. num_variables : int, somewhat optional Number of states for a state space model, or number of generalized dispacements for a second order form. If `x0` is defined, num_variables is inferred. An error will result if both `x0` and num_variables are left out of the function call. `num_variables` must be defined if `x0` is not. eqform : str, optional `second_order` or `first_order`. (second order is default) params : dict, optional Dictionary of parameters needed by sdfunc. realify : boolean, optional Force the returned results to be real. other : any Other keyword arguments available to nonlinear solvers in `scipy.optimize.nonlin <https://docs.scipy.org/doc/scipy/reference/optimize.nonlin.html>`_. See `Notes`. Returns ------- t, x, e, amps, phases : array_like time, displacement history (time steps along columns), errors, amps : float array amplitudes of displacement (primary harmonic) in column vector format. phases : float array amplitudes of displacement (primary harmonic) in column vector format. Examples -------- >>> import mousai as ms >>> t, x, e, amps, phases = ms.hb_time(ms.duff_osc, ... np.array([[0,1,-1]]), ... omega = 0.7) Notes ----- .. seealso:: ``hb_freq`` This method is not reliable for a low number of harmonics. Calls a linear algebra function from `scipy.optimize.nonlin <https://docs.scipy.org/doc/scipy/reference/optimize.nonlin.html>`_ with `newton_krylov` as the default. Evaluates the differential equation/s at evenly spaced points in time. Each point in time yields a single equation. One harmonic plus the constant term results in 3 points in time over the cycle. Solver should gently "walk" solution up to get to nonlinearities for hard nonlinearities. Algorithm: 1. calls `hb_err` with `x` as the variable to solve for. 2. `hb_err` uses a Fourier representation of `x` to obtain velocities (after an inverse FFT) then calls `sdfunc` to determine accelerations. 3. Accelerations are also obtained using a Fourier representation of x 4. Error in the accelerations (or state derivatives) are the functional error used by the nonlinear algebraic solver (default `newton_krylov`) to be minimized by the solver. Options to the nonlinear solvers can be passed in by \*\*kwargs (keyward arguments) identical to those available to the nonlinear solver. """ # Initial conditions exist? if x0 is None: if num_variables is not None: x0 = np.zeros((num_variables, 1 + num_harmonics * 2)) else: print('Error: Must either define number of variables or initial\ guess for x.') return elif num_harmonics is None: num_harmonics = int((x0.shape[1] - 1) / 2) elif 1 + 2 * num_harmonics > x0.shape[1]: x_freq = fftp.fft(x0) x_zeros = np.zeros((x0.shape[0], 1 + num_harmonics * 2 - x0.shape[1])) x_freq = np.insert(x_freq, [x0.shape[1] - x0.shape[1] // 2], x_zeros, axis=1) x0 = fftp.ifft(x_freq) * (1 + num_harmonics * 2) / x0.shape[1] x0 = np.real(x0) if isinstance(sdfunc, str): sdfunc = globals()[sdfunc] print("`sdfunc` is expected to be a function name, not a string") params['function'] = sdfunc # function that returns SO derivative time = np.linspace(0, 2 * np.pi / omega, num=x0.shape[1], endpoint=False) params['time'] = time params['omega'] = omega params['n_har'] = num_harmonics def hb_err(x): r"""Array (vector) of hamonic balance second order algebraic errors. Given a set of second order equations :math:`\ddot{x} = f(x, \dot{x}, \omega, t)` calculate the error :math:`E = \ddot{x} - f(x, \dot{x}, \omega, t)` presuming that :math:`x` can be represented as a Fourier series, and thus :math:`\dot{x}` and :math:`\ddot{x}` can be obtained from the Fourier series representation of :math:`x`. Parameters ---------- x : array_like x is an :math:`n \\times m` by 1 array of presumed displacements. It must be a "list" array (not a linear algebra vector). Here :math:`n` is the number of displacements and :math:`m` is the number of times per cycle at which the displacement is guessed (minimum of 3) **kwargs : string, float, variable **kwargs is a packed set of keyword arguments with 3 required arguments. 1. `function`: a string name of the function which returned the numerically calculated acceleration. 2. `omega`: which is the defined fundamental harmonic at which the is desired. 3. `n_har`: an integer representing the number of harmonics. Note that `m` above is equal to 1 + 2 * `n_har`. Returns ------- e : array_like 2d array of numerical error of presumed solution(s) `x`. Notes ----- `function` and `omega` are not separately defined arguments so as to enable algebraic solver functions to call `hb_time_err` cleanly. The algorithm is as follows: 1. The velocity and accelerations are calculated in the same shape as `x` as `vel` and `accel`. 3. Each column of `x` and `v` are sent with `t`, `omega`, and other `**kwargs** to `function` one at a time with the results agregated into the columns of `accel_num`. 4. The difference between `accel_num` and `accel` is reshaped to be :math:`n \\times m` by 1 and returned as the vector error used by the numerical algebraic equation solver. """ nonlocal params # Will stay out of global/conflicts n_har = params['n_har'] omega = params['omega'] time = params['time'] m = 1 + 2 * n_har vel = harmonic_deriv(omega, x) if eqform == 'second_order': accel = harmonic_deriv(omega, vel) accel_from_deriv = np.zeros_like(accel) # Should subtract in place below to save memory for large problems for i in np.arange(m): # This should enable t to be used for current time in loops # might be able to be commented out, left as example t = time[i] params['cur_time'] = time[i] # loops # Note that everything in params can be accessed within # `function`. accel_from_deriv[:, i] = params['function'](x[:, i], vel[:, i], params)[:, 0] e = accel_from_deriv - accel elif eqform == 'first_order': vel_from_deriv = np.zeros_like(vel) # Should subtract in place below to save memory for large problems for i in np.arange(m): # This should enable t to be used for current time in loops t = time[i] params['cur_time'] = time[i] # Note that everything in params can be accessed within # `function`. vel_from_deriv[:, i] =\ params['function'](x[:, i], params)[:, 0] e = vel_from_deriv - vel else: print('eqform cannot have a value of ', eqform) return 0, 0, 0, 0, 0 return e try: x = globals()[method](hb_err, x0, **kwargs) except: x = x0 # np.full([x0.shape[0],x0.shape[1]],np.nan) amps = np.full([ x0.shape[0], ], np.nan) phases = np.full([ x0.shape[0], ], np.nan) e = hb_err(x) # np.full([x0.shape[0],x0.shape[1]],np.nan) raise else: xhar = fftp.fft(x) * 2 / len(time) amps = np.absolute(xhar[:, 1]) phases = np.angle(xhar[:, 1]) e = hb_err(x) if realify is True: x = np.real(x) else: print('x was real') return time, x, e, amps, phases
def fft_to_rfft(X_real): """Switch from complex form fft form to SciPy rfft form.""" X_complex = fftp.rfft(np.real(fftp.ifft(X_real))) return X_complex
def my_ifft(A): a = ifft(A, axis = -1) return a
#! /usr/bin/env python # author [email protected] # Date 2015-04-28 import matplotlib.pyplot as plt import numpy as np from scipy.fftpack import fft, ifft #x = np.array([1.0, 2.0, 1.0, -1.0, 1.5]) x = np.array([0.0, 1.0, 0.0, -1.0]) y = fft(x) print y yinv = ifft(x) print yinv #N = 600 #T = 1.0 / 800.0 #x = np.linspace(0.0, N * T, N) #y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x) #yf = fft(y) #xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
better_exceptions.hook() import numpy as np # 从fftpack中导入fft(快速傅里叶变化)和ifft(快速傅里叶逆变换)函数 from scipy.fftpack import fft, ifft # 创建一个随机值数组 x = np.array([1.0, 2.0, 1.0, -1.0, 1.5]) # 对数组数据进行傅里叶变换 y = fft(x) print('fft: ') print(y) # 快速傅里叶逆变换 yinv = ifft(y) print('ifft: ') print(yinv) import numpy as np from scipy.fftpack import fft # 采样点数 N = 4000 # 采样频率 (根据采样定理,采样频率必须大于信号最高频率的2倍,信号才不会失真) Fs = 8000 x = np.linspace(0.0, N / Fs, N) # 时域信号,包含:直流分量振幅1.0,正弦波分量频率100hz/振幅2.0, 正弦波分量频率150Hz/振幅0.5/相位np.pi y = 1.0 + 2.0 * np.sin(100.0 * 2.0 * np.pi * x) + 0.5 * np.sin(150.0 * 2.0 * np.pi * x + np.pi)
plt.style.use('ggplot') #problem 1 - FFT and IFFT #make the time domain signal. 1000 data points, 2 seconds in duration x_index = np.linspace(0, 2, 1000) #define the input signal (xt) input_singal = np.cos(2 * np.pi * 10 * x_index) + np.cos( 2 * np.pi * 100 * x_index) + np.cos(2 * np.pi * 200 * x_index) #the fft of the input signal x_index_frequency = np.linspace(0, 500, 1000) fft_input_out = fft(input_singal) #the inverse fft of the fft (meta) i_fft_input_out = ifft(fft_input_out) #create three graphs for plotting #graph of first plot f, xarr = plt.subplots(3) plt.tight_layout() xarr[0].set_title('noisy signal') xarr[0].plot(x_index, input_singal) #graph of fft of first xarr[1].set_title('fft out') #https://stackoverflow.com/questions/15858192/how-to-set-xlim-and-ylim-for-a-subplot-in-matplotlib xarr[1].set_xlim([0, 250]) xarr[1].plot(x_index_frequency, np.abs(fft_input_out)) #graph of inverse of fftr
def ccf(self, xS, yS, xA, yA, xB, yB, delta=0.05, derivate=True, geometrical_spreading=True): """compute synthetic cross correlation functions for a pointwise source adjusts the lag time automatically to prevent wrapping :param xS: source x coordinate, km :param yS: source y coordinate, km :param xA: A station x coordinate, km :param yA: A station y coordinate, km :param xB: B station x coordinate, km :param yB: B station x coordinate, km :param delta: coefficient for lag time adjustment :param derivate: if you want to derivate the correlation functions :param geometrical_spreading: if you want to include geometrical attenuations :return starttime: starttime of the trace in s :return npts: number of samples in the trace :return dt: sampling interval (s) :return y: data array """ assert np.all( [not hasattr(w, "__iter__") for w in xS, yS, xA, yA, xB, yB]) # if switch(lon1=xA, lat1=yA, lon2=xB, lat2=yB, chnl1=None, chnl2=None): # return self.ccf(xS, yS, # xA=xB, yA=yB, zA=zB, # xB=xA, yB=yA, zB=zA, # networkA=networkB, # stationA=stationB, # locationA=locationB, # networkB=networkA, # stationB=stationA, # locationB=locationA, # derivate=derivate, **kwargs) # ---------------------- SA = ((xS - xA)**2. + (yS - yA)**2.)**0.5 SB = ((xS - xB)**2. + (yS - yB)**2.)**0.5 distance = ((xA - xB)**2. + (yA - yB)**2.)**0.5 if SA >= SB: # tmin = (SA - SB) / self.umax - 3. / self.fmin # tmax = (SA - SB) / self.umin + 3. / self.fmin tmin = (SA - SB) / (self.umax * (1. + delta)) - 3. / self.fmin tmax = (SA - SB) / (self.umin / (1. + delta)) + 3. / self.fmin else: tmin = (SA - SB) / (self.umin / (1. + delta)) - 3. / self.fmin tmax = (SA - SB) / (self.umax * (1. + delta)) + 3. / self.fmin tmin = np.floor(tmin / self.dt) * self.dt npts = int(np.ceil((tmax - tmin) / self.dt)) if npts % 2: npts += 1 tmax = tmin + npts * self.dt # ---------------------------- starttime = tmin # ---------------------------- nu = fftfreq(npts, self.dt) Y = np.zeros(npts, complex) for nclaw in self.claws: # sum over modal contributions cn = nclaw(nu) In = ~np.isnan(cn) for mclaw in self.claws: # sum over modal contributions cm = nclaw(nu) Im = ~np.isnan(cm) I = In & Im if I.any(): # computes uA * conj(uB) Y[I] += np.exp(-2.j * np.pi * nu[I] * (SA / cn[I] - SB / cm[I] - tmin)) if derivate: Y *= 2.j * np.pi * nu if SA and geometrical_spreading: Y /= float(np.sqrt(SA)) if SB and geometrical_spreading: Y /= float(np.sqrt(SB)) y = np.real(ifft(Y)) # ---------------------------- y = detrend(y) y *= taperwidth(y, 1. / self.dt, .5 / self.fmin) if self.fmin == self.fmax: y = gaussbandpass(y, 1. / self.dt, self.fmin, self.order) else: y = bandpass(y, 1. / self.dt, self.fmin, self.fmax, self.order, True) return starttime, npts, self.dt, y
plt.title('[Fig 3]: Hxy_abs; Cosine tapered window') plt.grid(True) plt.legend(['Hxy_abs', 'wintapcos']) plt.show() # # # # Dalla funzione di trasferimento ricavo la risposta impulsiva # fig_4 = plt.figure() plt.subplot(211) plt.plot(t[sel], y1_M[sel, :]) plt.title('[Fig 4]: y1_M: All Inputs') plt.grid(True) # # Retreive the pulse from the Complex Hxy hxy = ifft(Hxy).real plt.subplot(212) plt.plot(t[sel], hxy[sel]) plt.title('[Fig 5]: h_xy: from transfer function') plt.grid(True) plt.show() Hxy_inv = Hxy.conj() / (Hxy.conj() * Hxy + 1e-15) H_short = Hxy_inv * Hxy hxy_inv = ifft(H_short).real # fig_5 = plt.figure() plt.subplot(211) plt.plot(t[sel], hxy_inv[sel]) plt.title('[Fig 5]: hxy_inv: Deconvolved Impulse')
def direct_hilbert(x): fx = fft(x) n = len(fx) w = fftfreq(n) * n w = 1j * sign(w) return ifft(w * fx)
def autocorrelate(y, max_size=None, axis=-1): """Bounded auto-correlation Parameters ---------- y : np.ndarray array to autocorrelate max_size : int > 0 or None maximum correlation lag. If unspecified, defaults to `y.shape[axis]` (unbounded) axis : int The axis along which to autocorrelate. By default, the last axis (-1) is taken. Returns ------- z : np.ndarray truncated autocorrelation `y*y` along the specified axis. If `max_size` is specified, then `z.shape[axis]` is bounded to `max_size`. Notes ----- This function caches at level 20. Examples -------- Compute full autocorrelation of y >>> y, sr = librosa.load(librosa.util.example_audio_file(), offset=20, duration=10) >>> librosa.autocorrelate(y) array([ 3.226e+03, 3.217e+03, ..., 8.277e-04, 3.575e-04], dtype=float32) Compute onset strength auto-correlation up to 4 seconds >>> import matplotlib.pyplot as plt >>> odf = librosa.onset.onset_strength(y=y, sr=sr, hop_length=512) >>> ac = librosa.autocorrelate(odf, max_size=4* sr / 512) >>> plt.plot(ac) >>> plt.title('Auto-correlation') >>> plt.xlabel('Lag (frames)') """ if max_size is None: max_size = y.shape[axis] max_size = int(min(max_size, y.shape[axis])) # Compute the power spectrum along the chosen axis # Pad out the signal to support full-length auto-correlation. powspec = np.abs(fft.fft(y, n=2 * y.shape[axis] + 1, axis=axis))**2 # Convert back to time domain autocorr = fft.ifft(powspec, axis=axis, overwrite_x=True) # Slice down to max_size subslice = [slice(None)] * autocorr.ndim subslice[axis] = slice(max_size) autocorr = autocorr[subslice] if not np.iscomplexobj(y): autocorr = autocorr.real return autocorr
def min_component_filter(x, y, feature_mask, p=1, fcut=None, Q=None): """Minimum component filtering Minimum component filtering is useful for determining the background component of a signal in the presence of spikes Parameters ---------- x : array_like 1D array of evenly spaced x values y : array_like 1D array of y values corresponding to x feature_mask : array_like 1D mask array giving the locations of features in the data which should be ignored for smoothing p : integer (optional) polynomial degree to be used for the fit (default = 1) fcut : float (optional) the cutoff frequency for the low-pass filter. Default value is f_nyq / sqrt(N) Q : float (optional) the strength of the low-pass filter. Larger Q means a steeper cutoff default value is 0.1 * fcut Returns ------- y_filtered : ndarray The filtered version of y. Notes ----- This code follows the procedure explained in the book "Practical Statistics for Astronomers" by Wall & Jenkins book, as well as in Wall, J, A&A 122:371, 1997 """ x = np.asarray(x, dtype=float) y = np.asarray(y, dtype=float) feature_mask = np.asarray(feature_mask, dtype=bool) if ((x.ndim != 1) or (x.shape != y.shape) or (y.shape != feature_mask.shape)): raise ValueError('x, y, and feature_mask must be 1 dimensional ' 'with matching lengths') if fcut is None: f_nyquist = 1. / (x[1] - x[0]) fcut = f_nyquist / np.sqrt(len(x)) if Q is None: Q = 0.1 * fcut # compute polynomial features XX = x[:, None] ** np.arange(p + 1) # compute least-squares fit to non-masked data beta = np.linalg.lstsq(XX[~feature_mask], y[~feature_mask])[0] # subtract polynomial fit and mask the data y_mask = y - np.dot(XX, beta) y_mask[feature_mask] = 0 # get Fourier transforms of arrays yFT_mask = fftpack.fft(y_mask) # compute (shifted) frequency array for filter N = len(x) f = fftpack.ifftshift((np.arange(N) - N / 2.) * 1. / N / (x[1] - x[0])) # construct low-pass filter filt = np.exp(- (Q * (abs(f) - fcut) / fcut) ** 2) filt[abs(f) < fcut] = 1 # reconstruct filtered signal y_filtered = fftpack.ifft(yFT_mask * filt).real + np.dot(XX, beta) return y_filtered
def get_psi_mod_x(psi_mod_k): psi_mod_x = fftpack.ifft(psi_mod_k) return psi_mod_x
print("Lines proportion:", mu / float(N)) #------------- # Measure finite slice from scipy import ndimage print("Measuring slices") drtSpace = np.zeros((p + 1, p), floatType) for lines, mValues in zip(subsetsLines, subsetsMValues): for i, line in enumerate(lines): u, v = line sliceReal = ndimage.map_coordinates(np.real(fftLenaShifted), [u, v]) sliceImag = ndimage.map_coordinates(np.imag(fftLenaShifted), [u, v]) slice = sliceReal + 1j * sliceImag # print("slice", i, ":", slice) finiteProjection = fftpack.ifft( slice) # recover projection using slice theorem drtSpace[mValues[i], :] = finiteProjection #print("drtSpace:", drtSpace) #------------------------------- #define MLEM def osem_expand_complex(iterations, p, g_j, os_mValues, projector, backprojector, image, mask, epsilon=1e3,
#振幅スペクトルらしい ampL = np.array([np.sqrt(c.real**2 + c.imag**2) for c in spL]) ampR = np.array([np.sqrt(c.real**2 + c.imag**2) for c in spR]) nspL = spL / ampL nspR = spR / ampR sds, = spL.shape ws = sds - 100 #C1 = nspL[:ws]np.conj(nspR[:sds]) #C2 = CCF(nspL[:sds],np.conj(nspR[:ws])) #C = CCF(spL[:ws],spR[:sds]) C1 = sig.correlate(nspR[:sds], nspL[:ws], mode="valid") C2 = sig.correlate(nspL[:sds], nspR[:ws], mode="valid") csp1 = ifft(C1) csp2 = ifft(C2) #print "ds:",sds,", ws:",ws #print "c1 max index:",C1.index(max(C1)),", max:",max(C1) #print "c2 max index:",C2.index(max(C2)),", max:",max(C2) print "csp1 max index:", np.argmax(csp1), ", max:", max(csp1) print "csp2 max index:", np.argmax(csp2), ", max:", max(csp2) # #print "c.shape:",C.shape #print "dL.shape:",dL.shape #print "spL.shape:",spL.shape plt.plot(csp1, "r") plt.plot(csp2, "b") #plt.plot(C2,"b")
def propagate(self, zeta): self.z = zeta * self.wavelength * self.l**2 rg = self.wavelength**2 * self.z / self.N**2 # ((lambda*sqrt(z))/length)^2 w = np.exp(1j * np.pi * (.25 - rg * self.j**2)) #propagation term self.A_z = ifft(w * fft(self.A)) self.I = np.abs(self.A_z)**2
def wiener_filter(t, h, signal='gaussian', noise='flat', return_PSDs=False, signal_params=None, noise_params=None): """Compute a Wiener-filtered time-series Parameters ---------- t : array_like evenly-sampled time series, length N h : array_like observations at each t signal : str (optional) currently only 'gaussian' is supported noise : str (optional) currently only 'flat' is supported return_PSDs : bool (optional) if True, then return (PSD, P_S, P_N) signal_guess : tuple (optional) A starting guess at the parameters for the signal. If not specified, a suitable guess will be estimated from the data itself. (see Notes below) noise_guess : tuple (optional) A starting guess at the parameters for the noise. If not specified, a suitable guess will be estimated from the data itself. (see Notes below) Returns ------- h_smooth : ndarray a smoothed version of h, length N Notes ----- The Wiener filter operates by fitting a functional form to the PSD:: PSD = P_S + P_N The resulting frequency-space filter is given by:: Phi = P_S / (P_S + P_N) This entire operation is equivalent to a kernel smoothing by a kernel whose Fourier transform is Phi. Choosing Signal/Noise Parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ the arguments ``signal_guess`` and ``noise_guess`` specify the initial guess for the characteristics of signal and noise used in the minimization. They are generally expected to be tuples, and the meaning varies depending on the form of signal and noise used. For ``gaussian``, the params are (amplitude, width). For ``flat``, the params are (amplitude,). See Also -------- scipy.signal.wiener : a static (non-adaptive) wiener filter """ # Validate signal if signal != 'gaussian': raise ValueError("only signal='gaussian' is supported") if signal_params is not None and len(signal_params) != 2: raise ValueError("signal_params should be length 2") # Validate noise if noise != 'flat': raise ValueError("only noise='flat' is supported") if noise_params is not None and len(noise_params) != 1: raise ValueError("noise_params should be length 1") # Validate t and hd t = np.asarray(t) h = np.asarray(h) if (t.ndim != 1) or (t.shape != h.shape): raise ValueError('t and h must be equal-length 1-dimensional arrays') # compute the PSD of the input N = len(t) Df = 1. / N / (t[1] - t[0]) f = fftpack.ifftshift(Df * (np.arange(N) - N / 2)) H = fftpack.fft(h) PSD = abs(H) ** 2 # fit signal/noise params if necessary if signal_params is None: amp_guess = np.max(PSD[1:]) width_guess = np.min(np.abs(f[PSD < np.mean(PSD[1:])])) signal_params = (amp_guess, width_guess) if noise_params is None: noise_params = (np.mean(PSD[1:]),) # Set up the Wiener filter: # fit a model to the PSD: sum of signal form and noise form def signal(x, A, width): width = abs(width) + 1E-99 # prevent divide-by-zero errors return A * np.exp(-0.5 * (x / width) ** 2) def noise(x, n): return n * np.ones(x.shape) # use [1:] here to remove the zero-frequency term: we don't want to # fit to this for data with an offset. min_func = lambda v: np.sum((PSD[1:] - signal(f[1:], v[0], v[1]) - noise(f[1:], v[2])) ** 2) v0 = tuple(signal_params) + tuple(noise_params) v = optimize.fmin(min_func, v0) P_S = signal(f, v[0], v[1]) P_N = noise(f, v[2]) Phi = P_S / (P_S + P_N) Phi[0] = 1 # correct for DC offset # Use Phi to filter and smooth the values h_smooth = fftpack.ifft(Phi * H) if not np.iscomplexobj(h): h_smooth = h_smooth.real if return_PSDs: return h_smooth, PSD, P_S, P_N, Phi else: return h_smooth
intercept = test_answers[k][1][j], N = len(spliced[k]), meaned = means[k][j]) for j in range(240)] for k in range(len(spliced))] t_tosub = [np.transpose(sublist) for sublist in tosub] # get correct values adjusted_lists = [np.subtract(spliced[i], t_tosub[i]) for i in range(len(spliced))] adjusted_totals = [[[adjusted_lists[group][day][lon]*np.exp(1j*phases_grouped[group][day][lon]) for lon in range(240)] for day in range(len(adjusted_lists[group]))] for group in range(len(adjusted_lists))] new_values = [[ifft(item) for item in sublist] for sublist in adjusted_totals] #make indexing dataframe lon_df_list = [] year_df_list = [] season_df_list = [] testind = 0 testdate_df = [] for group_ind in range(len(spliced)): ## FIX!! for day_ind in range(len(spliced[group_ind])): maydate = tarray[testind] testind = testind + 1
ht = list(map(h, t)) #u is here generated with parameters a. In the real world these parameters need to be estimated a = [1, -2.21, 2.94, -2.17, 0.96] u = signal.lfilter([1], a, [wnu])[0] # output yt = signal.convolve(u, ht, mode='full')[:t.size] yt = list(map(lambda y, n: y+n, yt, nk)) # Fourier Transform: Ys = fftpack.fft(yt) Hs = fftpack.fft(ht) # Transfer function #inverse naive method Ns = fftpack.fft(nk) Us = list(map(lambda y, h: y/h, Ys, Hs)) naive = fftpack.ifft(Us) naive[0] = 0 #wiener Hs_conj = list(map(lambda h: np.conj(h), Hs)) Hs_squ = list(map(lambda h: h*np.conj(h), Hs)) def autocorr(x): result = np.correlate(x, x, mode="full") return result[result.size // 2:] Ss = fftpack.fft(autocorr(u)) Ns = fftpack.fft(autocorr(nk)) Gs = list(map(lambda hc, hs, s, n: hc*s / (hs * s + n) , Hs_conj, Hs_squ, Ss, Ns)) Us = list(map(lambda g, y: g*y, Gs, Ys)) wiener = fftpack.ifft(Us)
subgrid_prev_n = subgrid_prev_n * std_output + mean_output for i in range(maxit): subgrid_n = model.predict(((u - mean_input) / std_input).reshape( (1, NX))).reshape(NX, 1) subgrid_n = subgrid_n * std_output + mean_output force = force_bar[:, i].reshape((NX, 1)) F = D1 * fft(.5 * (u**2), axis=0) F0 = D1 * fft(.5 * (u_old**2), axis=0) uRHS = -0.5*dt*(3*F- F0) - 0.5*dt*nu*(D2*u_fft) + u_fft + dt*fft(force,axis=0) \ -fft(dt*3/2*subgrid_n + 1/2*dt*subgrid_prev_n,axis = 0) subgrid_prev_n = subgrid_n u_old_fft = u_fft u_old = u u_fft = uRHS / D2x.reshape([NX, 1]) u = np.real(ifft(u_fft, axis=0)) u_store[:, i] = u.squeeze() sub_store[:, i] = subgrid_n.squeeze() sio.savemat('./DDP_results_transfer.mat', { 'u_pred': u_store, 'sub_pred': sub_store })
def hb_freq(sdfunc, x0=None, omega=1, method='newton_krylov', num_harmonics=1, num_variables=None, mask_constant=True, eqform='second_order', params={}, realify=True, num_time_steps=51, **kwargs): r"""Harmonic balance solver for first and second order ODEs. Obtains the solution of a first-order and second-order differential equation under the presumption that the solution is harmonic using an algebraic time method. Returns `t` (time), `x` (displacement), `v` (velocity), and `a` (acceleration) response of a first or second order linear ordinary differential equation defined by :math:`\ddot{\mathbf{x}}=f(\mathbf{x},\mathbf{v},\omega)` or :math:`\dot{\mathbf{x}}=f(\mathbf{x},\omega)`. For the state space form, the function `sdfunc` should have the form:: def duff_osc_ss(x, params): # params is a dictionary of parameters omega = params['omega'] # `omega` will be put into the dictionary # for you t = params['cur_time'] # The time value is available as # `cur_time` in the dictionary x_dot = np.array([[x[1]], [-x[0]-.1*x[0]**3-.1*x[1]+1*sin(omega*t)]]) return xdot In a state space form solution, the function must take the states and the `params` dictionary. This dictionary should be used to obtain the prescribed response frequency and the current time. These plus any other parameters are used to calculate the state derivatives which are returned by the function. For the second order form the function `sdfunc` should have the form:: def duff_osc(x, v, params): # params is a dictionary of parameters omega = params['omega'] # `omega` will be put into the dictionary # for you t = params['cur_time'] # The time value is available as # `cur_time` in the dictionary return np.array([[-x-.1*x**3-.2*v+sin(omega*t)]]) In a second-order form solution the function must take the states and the `params` dictionary. This dictionary should be used to obtain the prescribed response frequency and the current time. These plus any other parameters are used to calculate the state derivatives which are returned by the function. Parameters ---------- sdfunc : function For `eqform='first_order'`, name of function that returns **column vector** first derivative given `x`, `omega` and \*\*kwargs. This is *NOT* a string. :math:`\dot{\mathbf{x}}=f(\mathbf{x},\omega)` For `eqform='second_order'`, name of function that returns **column vector** second derivative given `x`, `v`, `omega` and \*\*kwargs. This is *NOT* a string. :math:`\ddot{\mathbf{x}}=f(\mathbf{x},\mathbf{v},\omega)` x0 : array_like, somewhat optional n x m array where n is the number of equations and m is the number of values representing the repeating solution. It is required that :math:`m = 1 + 2 num_{harmonics}`. (we will generalize allowable default values later.) omega : float assumed fundamental response frequency in radians per second. method : str, optional Name of optimization method to be used. num_harmonics : int, optional Number of harmonics to presume. The `omega` = 0 constant term is always presumed to exist. Minimum (and default) is 1. If num_harmonics*2+1 exceeds the number of columns of `x0` then `x0` will be expanded, using Fourier analaysis, to include additional harmonics with the starting presumption of zero values. num_variables : int, somewhat optional Number of states for a state space model, or number of generalized dispacements for a second order form. If `x0` is defined, num_variables is inferred. An error will result if both `x0` and num_variables are left out of the function call. `num_variables` must be defined if `x0` is not. eqform : str, optional `second_order` or `first_order`. (`second order` is default) params : dict, optional Dictionary of parameters needed by sdfunc. realify : boolean, optional Force the returned results to be real. mask_constant : boolean, optional Force the constant term of the series representation to be zero. num_time_steps : int, default = 51 number of time steps to use in time histories for derivative calculations. other : any Other keyword arguments available to nonlinear solvers in `scipy.optimize.nonlin <https://docs.scipy.org/doc/scipy/reference/optimize.nonlin.html>`_. See Notes. Returns ------- t, x, e, amps, phases : array_like time, displacement history (time steps along columns), errors, amps : float array amplitudes of displacement (primary harmonic) in column vector format. phases : float array amplitudes of displacement (primary harmonic) in column vector format. Examples -------- >>> import mousai as ms >>> t, x, e, amps, phases = ms.hb_freq(ms.duff_osc, ... np.array([[0,1,-1]]), ... omega = 0.7) Notes ----- .. seealso:: `hb_time` Calls a linear algebra function from `scipy.optimize.nonlin <https://docs.scipy.org/doc/scipy/reference/optimize.nonlin.html>`_ with `newton_krylov` as the default. Evaluates the differential equation/s at evenly spaced points in time defined by the user (default 51). Uses error in FFT of derivative (acceeration or state equations) calculated based on: 1. governing equations 2. derivative of `x` (second derivative for state method) Solver should gently "walk" solution up to get to nonlinearities for hard nonlinearities. Algorithm: 1. calls `hb_time_err` with x as the variable to solve for. 2. `hb_time_err` uses a Fourier representation of x to obtain velocities (after an inverse FFT) then calls `sdfunc` to determine accelerations. 3. Accelerations are also obtained using a Fourier representation of x 4. Error in the accelerations (or state derivatives) are the functional error used by the nonlinear algebraic solver (default `newton_krylov`) to be minimized by the solver. Options to the nonlinear solvers can be passed in by \*\*kwargs. """ # Initial conditions exist? if x0 is None: if num_variables is not None: x0 = np.zeros((num_variables, 1 + num_harmonics * 2)) else: print('Error: Must either define number of variables or initial\ guess for x.') return elif num_harmonics is None: num_harmonics = int((x0.shape[1] - 1) / 2) elif 1 + 2 * num_harmonics > x0.shape[1]: x_freq = fftp.fft(x0) x_zeros = np.zeros((x0.shape[0], 1 + num_harmonics * 2 - x0.shape[1])) x_freq = np.insert(x_freq, [x0.shape[1] - x0.shape[1] // 2], x_zeros, axis=1) x0 = fftp.ifft(x_freq) * (1 + num_harmonics * 2) / x0.shape[1] x0 = np.real(x0) if isinstance(sdfunc, str): sdfunc = globals()[sdfunc] print("`sdfunc` is expected to be a function name, not a string") params['function'] = sdfunc # function that returns SO derivative time = np.linspace(0, 2 * np.pi / omega, num=x0.shape[1], endpoint=False) params['time'] = time params['omega'] = omega params['n_har'] = num_harmonics X0 = fftp.rfft(x0) if mask_constant is True: X0 = X0[:, 1:] params['mask_constant'] = mask_constant def hb_err(X): """Return errors in equation eval versus derivative calculation.""" # r"""Array (vector) of hamonic balance second order algebraic errors. # # Given a set of second order equations # :math:`\ddot{x} = f(x, \dot{x}, \omega, t)` # calculate the error :math:`E = \mathcal{F}(\ddot{x} # - \mathcal{F}\left(f(x, \dot{x}, \omega, t)\right)` # presuming that :math:`x` can be represented as a Fourier series, and # thus :math:`\dot{x}` and :math:`\ddot{x}` can be obtained from the # Fourier series representation of :math:`x` and :math:`\mathcal{F}(x)` # represents the Fourier series of :math:`x(t)` # # Parameters # ---------- # X : float array # X is an :math:`n \\times m` by 1 array of sp.fft.rfft # fft coefficients lacking the constant (first) element. # Here :math:`n` is the number of displacements and :math:`m` 2 # times the number of harmonics to be solved for. # # **kwargs : string, float, variable # **kwargs is a packed set of keyword arguments with 3 required # arguments. # 1. `function`: a string name of the function which returned # the numerically calculated acceleration. # # 2. `omega`: which is the defined fundamental harmonic # at which the is desired. # # 3. `n_har`: an integer representing the number of harmonics. # Note that `m` above is equal to 2 * `n_har`. # # Returns # ------- # e : float array # 2d array of numerical errors of presumed solution(s) `X`. Error # between first (or second) derivative via Fourier analysis and via # solution of the governing equation. # # Notes # ----- # `function` and `omega` are not separately defined arguments so as to # enable algebraic solver functions to call `hb_err` cleanly. # # The algorithm is as follows: # 1. X is prepended with a zero vector (to represent the constant # value) # 2. `x` is calculated via an inverse `numpy.fft.rfft` # 1. The velocity and accelerations are calculated in the same # shape as `x` as `vel` and `accel`. # 3. Each column of `x` and `v` are sent with `t`, `omega`, and # other `**kwargs** to `function` one at a time with the results # agregated into the columns of `accel_num`. # 4. The rfft is taken of `accel_num` and `accel`. # 5. The first column is stripped out of both `accel_num_freq and # `accel_freq`. # """ nonlocal params # Will stay out of global/conflicts omega = params['omega'] time = params['time'] mask_constant = params['mask_constant'] if mask_constant is True: X = np.hstack((np.zeros_like(X[:, 0]).reshape(-1, 1), X)) x = fftp.irfft(X) time_e, x = time_history(time, x, num_time_points=num_time_steps) # m = 2 * n_har vel = harmonic_deriv(omega, x) # print('vel = ', vel) m = num_time_steps if eqform == 'second_order': accel = harmonic_deriv(omega, vel) accel_from_deriv = np.zeros_like(accel) # Should subtract in place below to save memory for large problems for i in np.arange(m): # This should enable t to be used for current time in loops # might be able to be commented out, left as example t = time_e[i] params['cur_time'] = time_e[i] # loops # Note that everything in params can be accessed within # `function`. accel_from_deriv[:, i] = params['function'](x[:, i], vel[:, i], params)[:, 0] e = accel_from_deriv - accel # print('accel from derive = ', accel_from_deriv) # print('accel = ', accel) # print(e) elif eqform == 'first_order': vel_from_deriv = np.zeros_like(vel) # Should subtract in place below to save memory for large problems for i in np.arange(m): # This should enable t to be used for current time in loops t = time_e[i] params['cur_time'] = time_e[i] # Note that everything in params can be accessed within # `function`. vel_from_deriv[:, i] =\ params['function'](x[:, i], params)[:, 0] e = vel_from_deriv - vel else: print('eqform cannot have a value of ', eqform) return 0, 0, 0, 0, 0 e_fft = fftp.fft(e) # print(e_fft) e_fft_condensed = condense_fft(e_fft, num_harmonics) # print(e_fft_condensed) e = fft_to_rfft(e_fft_condensed) if mask_constant is True: e = e[:, 1:] # print('e ', e, ' X ', X) # print('1 eval') return e try: X = globals()[method](hb_err, X0, **kwargs) # print('tried') except: # Catches and raises errors- needs actual error listed. print( 'Excepted- search failed for omega = {:6.4f} rad/s.'.format(omega)) print("""What ever error this is, please put into har_bal after the excepts (2 of them)""") X = X0 if mask_constant is True: X = np.hstack((np.zeros_like(X[:, 0]).reshape(-1, 1), X)) amps = np.full([ X0.shape[0], ], np.nan) phases = np.full([ X0.shape[0], ], np.nan) e = hb_err(X) # np.full([x0.shape[0],X0.shape[1]],np.nan) raise else: # Runs if there are no errors if mask_constant is True: X = np.hstack((np.zeros_like(X[:, 0]).reshape(-1, 1), X)) xhar = rfft_to_fft(X) * 2 / len(time) amps = np.absolute(xhar[:, 1]) phases = np.angle(xhar[:, 1]) e = hb_err(X) # if mask_constant is True: # X = np.hstack((np.zeros_like(X[:, 0]).reshape(-1, 1), X)) # print('\n\n\n\n', X) # print(e) # amps = np.sqrt(X[:, 1]**2 + X[:, 2]**2) # phases = np.arctan2(X[:, 2], X[:, 1]) # e = hb_err(X) x = fftp.irfft(X) if realify is True: x = np.real(x) else: print('x was real') return time, x, e, amps, phases
def istft(stft_matrix, hop_length=None, win_length=None, window='hann', center=True, dtype=np.float32, length=None): """ Inverse short-time Fourier transform (ISTFT). Converts a complex-valued spectrogram `stft_matrix` to time-series `y` by minimizing the mean squared error between `stft_matrix` and STFT of `y` as described in [1]_. In general, window function, hop length and other parameters should be same as in stft, which mostly leads to perfect reconstruction of a signal from unmodified `stft_matrix`. .. [1] D. W. Griffin and J. S. Lim, "Signal estimation from modified short-time Fourier transform," IEEE Trans. ASSP, vol.32, no.2, pp.236–243, Apr. 1984. Parameters ---------- stft_matrix : np.ndarray [shape=(1 + n_fft/2, t)] STFT matrix from `stft` hop_length : int > 0 [scalar] Number of frames between STFT columns. If unspecified, defaults to `win_length / 4`. win_length : int <= n_fft = 2 * (stft_matrix.shape[0] - 1) When reconstructing the time series, each frame is windowed and each sample is normalized by the sum of squared window according to the `window` function (see below). If unspecified, defaults to `n_fft`. window : string, tuple, number, function, np.ndarray [shape=(n_fft,)] - a window specification (string, tuple, or number); see `scipy.signal.get_window` - a window function, such as `scipy.signal.hanning` - a user-specified window vector of length `n_fft` .. see also:: `filters.get_window` center : boolean - If `True`, `D` is assumed to have centered frames. - If `False`, `D` is assumed to have left-aligned frames. dtype : numeric type Real numeric type for `y`. Default is 32-bit float. length : int > 0, optional If provided, the output `y` is zero-padded or clipped to exactly `length` samples. Returns ------- y : np.ndarray [shape=(n,)] time domain signal reconstructed from `stft_matrix` See Also -------- stft : Short-time Fourier Transform Notes ----- This function caches at level 30. Examples -------- >>> y, sr = librosa.load(librosa.util.example_audio_file()) >>> D = librosa.stft(y) >>> y_hat = librosa.istft(D) >>> y_hat array([ -4.812e-06, -4.267e-06, ..., 6.271e-06, 2.827e-07], dtype=float32) Exactly preserving length of the input signal requires explicit padding. Otherwise, a partial frame at the end of `y` will not be represented. >>> n = len(y) >>> n_fft = 2048 >>> y_pad = librosa.util.fix_length(y, n + n_fft // 2) >>> D = librosa.stft(y_pad, n_fft=n_fft) >>> y_out = librosa.istft(D, length=n) >>> np.max(np.abs(y - y_out)) 1.4901161e-07 """ n_fft = 2 * (stft_matrix.shape[0] - 1) # By default, use the entire frame if win_length is None: win_length = n_fft # Set the default hop, if it's not already specified if hop_length is None: hop_length = int(win_length // 4) ifft_window = get_window(window, win_length, fftbins=True) # Pad out to match n_fft ifft_window = util.pad_center(ifft_window, n_fft) n_frames = stft_matrix.shape[1] expected_signal_len = n_fft + hop_length * (n_frames - 1) y = np.zeros(expected_signal_len, dtype=dtype) for i in range(n_frames): sample = i * hop_length spec = stft_matrix[:, i].flatten() spec = np.concatenate((spec, spec[-2:0:-1].conj()), 0) ytmp = ifft_window * fft.ifft(spec).real y[sample:(sample + n_fft)] = y[sample:(sample + n_fft)] + ytmp # Normalize by sum of squared window ifft_window_sum = window_sumsquare(window, n_frames, win_length=win_length, n_fft=n_fft, hop_length=hop_length, dtype=dtype) approx_nonzero_indices = ifft_window_sum > util.tiny(ifft_window_sum) y[approx_nonzero_indices] /= ifft_window_sum[approx_nonzero_indices] if length is None: # If we don't need to control length, just do the usual center trimming # to eliminate padded data if center: y = y[int(n_fft // 2):-int(n_fft // 2)] else: if center: # If we're centering, crop off the first n_fft//2 samples # and then trim/pad to the target length. # We don't trim the end here, so that if the signal is zero-padded # to a longer duration, the decay is smooth by windowing start = int(n_fft // 2) else: # If we're not centering, start at 0 and trim/pad as necessary start = 0 y = util.fix_length(y[start:], length) return y
def iradon(radon_image, theta=None, output_size=None, filter="ramp", interpolation="linear", circle=False): """ Inverse radon transform. Reconstruct an image from the radon transform, using the filtered back projection algorithm. Parameters ---------- radon_image : array_like, dtype=float Image containing radon transform (sinogram). Each column of the image corresponds to a projection along a different angle. theta : array_like, dtype=float, optional Reconstruction angles (in degrees). Default: m angles evenly spaced between 0 and 180 (if the shape of `radon_image` is (N, M)). output_size : int Number of rows and columns in the reconstruction. filter : str, optional (default ramp) Filter used in frequency domain filtering. Ramp filter used by default. Filters available: ramp, shepp-logan, cosine, hamming, hann Assign None to use no filter. interpolation : str, optional (default linear) Interpolation method used in reconstruction. Methods available: nearest, linear. circle : boolean, optional Assume the reconstructed image is zero outside the inscribed circle. Also changes the default output_size to match the behaviour of ``radon`` called with ``circle=True``. Returns ------- output : ndarray Reconstructed image. Notes ----- It applies the fourier slice theorem to reconstruct an image by multiplying the frequency domain of the filter with the FFT of the projection data. This algorithm is called filtered back projection. """ if radon_image.ndim != 2: raise ValueError('The input image must be 2-D') if theta is None: m, n = radon_image.shape theta = np.linspace(0, 180, n, endpoint=False) else: theta = np.asarray(theta) if len(theta) != radon_image.shape[1]: raise ValueError("The given ``theta`` does not match the number of " "projections in ``radon_image``.") th = (np.pi / 180.0) * theta # if output size not specified, estimate from input radon image if not output_size: if circle: output_size = radon_image.shape[0] else: output_size = int(np.floor(np.sqrt((radon_image.shape[0])**2 / 2.0))) if circle: radon_size = int(np.ceil(np.sqrt(2) * radon_image.shape[0])) radon_image_padded = np.zeros((radon_size, radon_image.shape[1])) radon_pad = (radon_size - radon_image.shape[0]) // 2 radon_image_padded[radon_pad:radon_pad + radon_image.shape[0], :] \ = radon_image radon_image = radon_image_padded n = radon_image.shape[0] img = radon_image.copy() # resize image to next power of two for fourier analysis # speeds up fourier and lessens artifacts order = max(64., 2**np.ceil(np.log(2 * n) / np.log(2))) # zero pad input image img.resize((order, img.shape[1])) # construct the fourier filter f = fftshift(abs(np.mgrid[-1:1:2 / order])).reshape(-1, 1) w = 2 * np.pi * f # start from first element to avoid divide by zero if filter == "ramp": pass elif filter == "shepp-logan": f[1:] = f[1:] * np.sin(w[1:] / 2) / (w[1:] / 2) elif filter == "cosine": f[1:] = f[1:] * np.cos(w[1:] / 2) elif filter == "hamming": f[1:] = f[1:] * (0.54 + 0.46 * np.cos(w[1:])) elif filter == "hann": f[1:] = f[1:] * (1 + np.cos(w[1:])) / 2 elif filter is None: f[1:] = 1 else: raise ValueError("Unknown filter: %s" % filter) filter_ft = np.tile(f, (1, len(theta))) # apply filter in fourier domain projection = fft(img, axis=0) * filter_ft radon_filtered = np.real(ifft(projection, axis=0)) # resize filtered image back to original size radon_filtered = radon_filtered[:radon_image.shape[0], :] reconstructed = np.zeros((output_size, output_size)) mid_index = np.ceil(n / 2.0) x = output_size y = output_size [X, Y] = np.mgrid[0.0:x, 0.0:y] xpr = X - int(output_size) // 2 ypr = Y - int(output_size) // 2 if circle: radius = (output_size - 1) // 2 reconstruction_circle = (xpr**2 + ypr**2) < radius**2 # reconstruct image by interpolation if interpolation == "nearest": for i in range(len(theta)): k = np.round(mid_index + xpr * np.sin(th[i]) - ypr * np.cos(th[i])) backprojected = radon_filtered[ ((((k > 0) & (k < n)) * k) - 1).astype(np.int), i] if circle: backprojected[~reconstruction_circle] = 0. reconstructed += backprojected elif interpolation == "linear": for i in range(len(theta)): t = xpr * np.sin(th[i]) - ypr * np.cos(th[i]) a = np.floor(t) b = mid_index + a b0 = ((((b + 1 > 0) & (b + 1 < n)) * (b + 1)) - 1).astype(np.int) b1 = ((((b > 0) & (b < n)) * b) - 1).astype(np.int) backprojected = (t - a) * radon_filtered[b0, i] + \ (a - t + 1) * radon_filtered[b1, i] if circle: backprojected[~reconstruction_circle] = 0. reconstructed += backprojected else: raise ValueError("Unknown interpolation: %s" % interpolation) return reconstructed * np.pi / (2 * len(th))
import matplotlib.pyplot as plt import numpy as np from scipy.fftpack import ifft from Senal.Funciones import Funciones tiempo = np.linspace(0, 1, 5000) senal = Funciones.generar_senoidal(tiempo, 3, 20, 0) senal_fft = Funciones.transformada_de_fourier(senal) senal_fft_plot, frecuencia = Funciones.linspace_transformada(senal_fft, tiempo) senal_ifft = Funciones.antitrasformada_de_fourier(senal_fft) senal_ifft_scipy = ifft(senal_fft) Funciones.plot(1, senal, tiempo, 'Original: Sin', 'Tiempo (en segundos)', 'Amplitud') Funciones.plot(2, senal_fft_plot, frecuencia, 'Transformada: F(Sin)', 'Frecuencia (en hertz)', 'Amplitud') Funciones.plot(3, senal_ifft, tiempo, 'Anti-Transformada: F-1(F(Sin))', 'Tiempo (en segundos)', 'Amplitud') Funciones.plot( 4, senal_ifft_scipy, tiempo, 'Anti-Transformada: F-1(F(Sin)). Mediante scipy, como referencia', 'Tiempo (en segundos)', 'Amplitud') plt.show()
import numpy as np import matplotlib.pyplot as plt from scipy.signal import blackman from scipy.fftpack import fft, ifft # 0 _x = np.asarray([1.0, 2.0, 1.0, -1.0, 1.5, -1.0]) print(_x) # 1.快速傅里叶变换 x = _x y = fft(x) print(y) # 2.快速傅里叶逆变换 y_i = ifft(y) print(y_i) # 3.Example N = 600 T = 1.0 / 800.0 x = np.linspace(0.0, N * T, N) y = np.sin(50.0 * 2.0 * np.pi * x) + 0.5 * np.sin(80.0 * 2.0 * np.pi * x) yf = fft(y) xf = np.linspace(0.0, 1.0 / (2.0 * T), N / 2) plt.plot(xf, 2.0 / N * np.abs(yf[0:N // 2])) plt.grid() # plt.show() # 4.Example w = blackman(N)
fftMap = abs(f[j]) fft_maximus.append(fftMap.max()) else: fft_maximus.append(0) peaks, properties = signal.find_peaks(fft_maximus) max_peak = -1 max_freq = 0 for peak in peaks: if fft_maximus[peak] > max_freq: max_freq = fft_maximus[peak] max_peak = peak print(frequencies[max_peak] * 60) iff = fftpack.ifft(f, axis=0) iff = np.abs(iff) iff *= 100 kd[i] += iff # print(find_heart_rate(f,frequencies,low,high)) final = [] for i in range(framecnt): prev_frame = kd[-1][i] for l in range(len(kd)-1, 0, -1): pyr_up_frame = cv2.pyrUp(prev_frame) (height, width) = pyr_up_frame.shape prev_level_frame = kd[l-1][i] prev_level_frame = cv2.resize(prev_level_frame, (height, width)) prev_frame = pyr_up_frame + prev_level_frame
def _auto_correlation(data, axis=-1): n_time_samples_per_window = data.shape[axis] n_fft_samples = next_fast_len(2 * n_time_samples_per_window - 1) dpss_fft = fft(data, n_fft_samples, axis=axis) power = dpss_fft * dpss_fft.conj() return np.real(ifft(power, axis=axis))
# data[i*chunk_size:(i+1) * chunk_size] = segment.T ffts = np.asarray(ffts) # pca.fit(ffts) nearest_neighbors = sklearn.neighbors.NearestNeighbors(n_neighbors=2) nearest_neighbors.fit(ffts) print "finishing fitting pca" rate, data = wavfile.read("amelie.wav") for i in range(len(data) / chunk_size): print i segment = data[i * chunk_size:(i + 1) * chunk_size] # print segment.shape [left, right] = fft(segment.T) transform = np.concatenate((left, right)) _, indices = nearest_neighbors.kneighbors(transform) transform = np.mean(ffts[indices], axis=1) transform = transform.reshape(-1, 1) print transform.shape transform = transform.reshape(2, -1) # transform = pca.inverse_transform(pca.transform(transform)) data[i * chunk_size:(i + 1) * chunk_size] = ifft(transform).T # print transform.shape wavfile.write("song2.wav", rate, data)