def STRW(x, om, OM, up): M = len(x) N = len(x[0]) # 2d convolution: y = np.ndarray(shape=(M, N), dtype='complex') h = get_wavelet(om, OM, up, M, N) # temporal convolution: for m in range(M): X = fft(x[m]) H = fft(h[m]) Z = X*H z = ifft(Z) y[m] = z # spectral convolution x = y.transpose() h = h.transpose() y = y.transpose() for n in range(N): X = fft(x[n]) H = fft(h[n]) Z = X*H z = ifft(Z) y[n] = z y = y.transpose() return y
def test_whitenize_with_decorator_size_4_without_fft_window(self, strategy): @strategy(size=4, hop=4) def whitenize(blk): return cexp(phase(blk) * 1j) sig = Stream(0, 3, 4, 0) # fft([0, 3, 4, 0]) is [7, -4.-3.j, 1, -4.+3.j] # fft([4, 0, 0, 3]) is [7, 4.+3.j, 1, 4.-3.j] data4003 = ifft([1, (4+3j)/5, 1, (4-3j)/5]) # From block [4, 0, 0, 3] data0340 = ifft([1, (-4-3j)/5, 1, (-4+3j)/5]) # From block [0, 3, 4, 0] result = whitenize(sig) # No overlap-add window (default behavior) assert isinstance(result, Stream) expected = Stream(*data0340) assert almost_eq(result.take(64), expected.take(64)) # Using a "triangle" as the overlap-add window wnd = [0.5, 1, 1, 0.5] # Normalized triangle new_result = whitenize(sig, ola_wnd=[1, 2, 2, 1]) assert isinstance(result, Stream) new_expected = Stream(*data0340) * Stream(*wnd) assert almost_eq(new_result.take(64), new_expected.take(64)) # With real overlap wnd_hop2 = [1/3, 2/3, 2/3, 1/3] # Normalized triangle for the new hop overlap_result = whitenize(sig, hop=2, ola_wnd=[1, 2, 2, 1]) assert isinstance(result, Stream) overlap_expected = Stream(*data0340) * Stream(*wnd_hop2) \ + chain([0, 0], Stream(*data4003) * Stream(*wnd_hop2)) assert almost_eq(overlap_result.take(64), overlap_expected.take(64))
def f(A_t, A_w, dz=delta_z): f.w_exp = exp(-1j * delta_z/2 * w_op) if f.delta_z != dz: f.initF() f.delta_z = dz ## Dispersion (I pass) f.A_w = A_w * f.w_exp f.A_t = ifft(f.A_w) / dt ## Constant potential term f.A_t = f.A_t * f.t_exp ## Nonlinear operator as intensity dependency if nlin != 0: f.A_t *= exp(-1j * delta_z * nlin * absolute(f.A_t)**2) ## Additional nonlinear terms as a function t_nl_op(A(t),dt,z) if t_nl_op != None: f.A_t *= exp(-1j * delta_z * t_nl_op(f.A_t, dt, z0+delta_z/2) ) ## Apodization if apod: f.A_t *= apod_array f.A_w = fft(f.A_t) * dt ## Dispersion (II pass) f.A_w *= f.w_exp f.A_t = ifft(f.A_w) / dt return f.A_t[:], f.A_w[:]
def DiffusiveFilter(sc,T,rho,c,L,dt=0.001,BW=0.7): # from numpy import linspace,zeros,vstack,array,dot,conj,pi # from scipy.signal import gausspulse # from numpy.fft import rfft,ifft t=linspace(0,T,round(T/dt)) X=rfft(gausspulse((t-0.25*T),sc,bw=BW)) s=linspace(0.,1/(2*dt),len(X)) s[0]=1e-6 RT=TransmissionReflection(s,rho,c,L) Y=X*RT s[0]=0. Y[:,0] = Y[:,1] y=ifft(2*Y,axis=1,n=2*Y.shape[1]-1) x=ifft(2*X,n=2*len(X)-1) t=linspace(0,T,y.shape[1]) return t,vstack((x,y)),s,vstack((X,Y)),RT
def fwgn_model(fm,fs,N): N = int(N) Nfft = 2**max(3,nextpow2(2*fm/fs*N)) Nifft = math.ceil(Nfft*fs/(2*fm)) doppler_coeff = np.sqrt(doppler_filter(fm,Nfft)) CGI, CGQ = fft(randn(Nfft)), fft(randn(Nfft)) f_CGI = CGI * doppler_coeff f_CGQ = CGQ * doppler_coeff del CGI, CGQ, doppler_coeff gc.collect() tzeros = np.zeros(abs(Nifft-Nfft)) filtered_CGI = np.hstack((f_CGI[:Nfft//2], tzeros, f_CGI[Nfft//2:])) filtered_CGQ = np.hstack((f_CGQ[:Nfft//2], tzeros, f_CGQ[Nfft//2:])) del tzeros, f_CGI, f_CGQ gc.collect() hI, hQ = ifft(filtered_CGI), ifft(filtered_CGQ) del filtered_CGI, filtered_CGQ gc.collect() rayEnvelope = np.abs(np.abs(hI) + 1j * hQ) rayRMS = math.sqrt(np.mean(rayEnvelope[:N]**2)) # h_{I}(t) - jh_{Q}(t) # Here we have the phase shift of pi/2 when multiplying the imaginary # portion by -1j h = (np.real(hI[:N]) - 1j * np.real(hQ[:N]))/rayRMS return h
def InvPotentialVorticity(self,field, length=None): if length is None: length = 2*pi; N = shape(field)[0]; k = array(range(N),dtype=complex128); k = concatenate((range(0,N/2),range(-N/2,0))); k *= (2*pi)/length; [KX, KY] = meshgrid(k,k); """ We are trying to solve d_yy(eta) + d_xx(eta) - eta = p Therefore, in Fourier space, it will become (-(kx^2 + ky^2) - 1)etaHat = pHat """ delsq = -(KX*KX + KY*KY) - 1 ; delsq[0,0] = 1; tmp = fft(field,axis=0); tmp = fft(tmp,axis=1); tmp = tmp/delsq; tmp = ifft(tmp,axis=1); tmp = ifft(tmp,axis=0); return tmp.real;
def autocorr_fft(signal, axis = -1): """Return full autocorrelation along specified axis. Use fft for computation.""" if N.ndim(signal) == 0: return signal elif signal.ndim == 1: n = signal.shape[0] nfft = int(2 ** nextpow2(2 * n - 1)) lag = n - 1 a = fft(signal, n = nfft, axis = -1) au = ifft(a * N.conj(a), n = nfft, axis = -1) return N.require(N.concatenate((au[-lag:], au[:lag+1])), dtype = signal.dtype) elif signal.ndim == 2: n = signal.shape[axis] lag = n - 1 nfft = int(2 ** nextpow2(2 * n - 1)) a = fft(signal, n = nfft, axis = axis) au = ifft(a * N.conj(a), n = nfft, axis = axis) if axis == 0: return N.require(N.concatenate( (au[-lag:], au[:lag+1]), axis = axis), \ dtype = signal.dtype) else: return N.require(N.concatenate( (au[:, -lag:], au[:, :lag+1]), axis = axis), dtype = signal.dtype) else: raise RuntimeError("rank >2 not supported yet")
def magabs_cs(): #b.line_plot("magabs_cs", a.frequency, a.MagAbs[:, 0]) #b.line_plot("magabs_cs", a.frequency, a.MagAbs[:, 257]) if 0: myifft=fft.ifft(a.Magcom[:,500]) myifft[50:-50]=0.0 #myifft[:20]=0.0 #myifft[-20:]=0.0 bg=fft.fft(myifft) filt=[] for n in range(len(a.yoko)): myifft=fft.ifft(a.Magcom[:,n]) #b.line_plot("ifft", absolute(myifft)) myifft[50:-50]=0.0 #myifft[:20]=0.0 #myifft[-20:]=0.0 filt.append(absolute(fft.fft(myifft)-bg)) b.colormesh("filt", a.frequency, a.yoko, filt) if 1: myifft=fft.ifft(mag[:,500]) myifft[40:-40]=0.0 myifft[:20]=0.0 myifft[-20:]=0.0 bg=fft.fft(myifft) filt=[] for n in range(len(yok)): myifft=fft.ifft(mag[:,n]) #b.line_plot("ifft", absolute(myifft)) myifft[50:-50]=0.0 #myifft[:20]=0.0 #myifft[-20:]=0.0 filt.append(absolute(fft.fft(myifft))) b.colormesh("filt", frq, yok, filt)
def error_test(vel, epsilon): sigma = 7.0 tmax = 4 * L / vel dt = ((L / 2) / kmax) / 18 psi[:] = exact(x, vel, 0.0, sigma) # exp(-1.0*(x*x/16.0)+complex(0,vel)*x) psil[:] = exact(xl, vel, 0.0, sigma) m0 = sqrt(abs(psi[npoints / 4 : -npoints / 4] ** 2).sum()) prop = exp(complex(0, -dt / 2.0) * k * k) propl = exp(complex(0, -dt / 2.0) * kl * kl) fil = tdpsf(npoints, dx, epsilon) nsteps = int(tmax / dt) + 1 err = 0.0 for i in range(nsteps): psi[:] = dft.ifft(prop * dft.fft(psi)) # Calculate TDPSF approximation fil(psi) psil[:] = dft.ifft(propl * dft.fft(psil)) # Calculate large box solution rem = abs( psil[npointsl / 2 - npoints / 4 : npointsl / 2 + npoints / 4] - psi[npoints / 2 - npoints / 4 : npoints / 2 + npoints / 4] ) local_err = sqrt((rem * rem).sum()) / m0 if local_err > err: err = local_err # print str(v) +", " + str(i*dt) + ", " + str(err) # print "T="+str(i*dt) + ", M = " + str(sqrt(abs(psi*psi).sum()*dx)/m0) print "k = " + str(vel) + ", epsilon = " + str(epsilon) + ", err = " + str(err) return err
def lms(self): global wf_ech, wf_ref M = int(2 ** np.ceil(np.log2(self.M))) u = util.enframe(np.append(wf_ref, np.zeros(M)), 2 * M, M) d = util.enframe(wf_ech, M, 0) uf = nf.fft(u, 2 * M, 1) W = nf.fft(self.w, 2 * M) wf_ech = np.array([], np.complex128) for ii in range(0, u.shape[0]): mu_bar = (110 * np.exp(-(ii) / self.estep) + 1) * self.mu yfi = W * uf[ii, :] # 1x2M yi = nf.ifft(yfi, 2 * M) # 1x2M yi = yi[-M:] # 1xM ei = d[ii, :] - yi # 1xM efi = nf.fft(np.append(np.zeros(M), ei), 2 * M) # 1x2M uefi = nf.ifft(np.conj(uf[ii, :]) * efi, 2 * M) uefi[-M:] = 0 uei = nf.fft(uefi, 2 * M) W = W + 2 * mu_bar * uei wf_ech = np.append(wf_ech, ei) self.w = nf.ifft(W, 2 * M)
def generateSweepIR(self): Lsig=len(self.signal) Lavg=len(self.average[0,:]) NFFTsig=nextpow2(Lsig) NFFTavg=nextpow2(Lavg) if NFFTsig != NFFTavg: raise Exception('NFFTsig != NFFTavg') else: NFFT=int(NFFTsig) sigfft=fft(self.signal,n=NFFT) print(self.average.shape) N=self.average.shape[0] avgfft=fftn(self.average,s=[NFFT]) imp=np.array(np.zeros(avgfft.shape)) #maximum=0 for i in range(0,N): #imp[i,:]=np.real(fftshift(ifft(avgfft[i,:]/sigfft))) imp[i,:]=np.real(ifft(avgfft[i,:]/sigfft)) imp[i,:]=fftshift(avgfft[:,i]/sigfft) imp[i,:find_nearest(f,-20000)]=0 imp[i,find_nearest(f,-20):find_nearest(f,20)]=0 imp[i,find_nearest(f,20000):]=0 imp[i,:]=np.real(ifft(ifftshift(impfft))) # if max(imp[i,:])>maximum: # maximum=max(imp[i,:]) #imp=imp/maximum #imp=imp/np.max(imp) toSave=np.array(imp.transpose(), dtype=np.float32) impfile=self.getImpFilename()#self.filepath.get()+os.sep+self.prefix.get()+'_IR_'+self.counter.get()+'.wav' scipy.io.wavfile.write(impfile,int(self.fs),toSave) raw=[] imp=[]
def FFT_Correlation(x,y): """ FFT-based correlation, much faster than numpy autocorr. x and y are row-based vectors of arbitrary lengths. This is a vectorized implementation of O(N*log(N)) flops. """ lengthx = x.shape[0] lengthy = y.shape[0] x = np.reshape(x,(1,lengthx)) y = np.reshape(y,(1,lengthy)) length = np.array([lengthx, lengthy]).min() x = x[:length] y = y[:length] fftx = fft(x, 2 * length - 1, axis=1) #pad with zeros ffty = fft(y, 2 * length - 1, axis=1) corr_xy = fft.ifft(fftx * np.conjugate(ffty), axis=1) corr_xy = np.real(fft.fftshift(corr_xy, axes=1)) #should be no imaginary part corr_yx = fft.ifft(ffty * np.conjugate(fftx), axis=1) corr_yx = np.real(fft.fftshift(corr_yx, axes=1)) corr = 0.5 * (corr_xy[:,length:] + corr_yx[:,length:]) / range(1,length)[::-1] return np.reshape(corr,corr.shape[1])
def _direct_fft_conv(log_pmf1, pmf1, fft1, log_pmf2, true_conv_len, fft_conv_len, alpha, delta): if log_pmf2 is None: norms = np.linalg.norm(pmf1)**2 fft_conv = fft1**2 else: pmf2 = np.exp(log_pmf2) fft2 = fft.fft(pmf2, n = fft_conv_len) norms = np.linalg.norm(pmf1) * np.linalg.norm(pmf2) fft_conv = fft1 * fft2 raw_conv = np.abs(fft.ifft(fft_conv)[:true_conv_len]) error_level = utils.error_threshold_factor(fft_conv_len) * norms threshold = error_level * (alpha + 1) places_of_interest = raw_conv <= threshold if delta > error_level: ignore_level = delta - error_level conv_to_ignore = raw_conv < ignore_level raw_conv[conv_to_ignore] = 0.0 places_of_interest &= ~conv_to_ignore log_conv = np.log(raw_conv) # the convolution is totally right, already: no need to consult # the support if not places_of_interest.any(): return log_conv, [] Q = 2 * len(log_pmf1) - 1 if log_pmf2 is None else len(log_pmf1) + len(log_pmf2) - 1 support1 = log_pmf1 > NEG_INF if log_pmf2 is None: support2 = np.array([]) else: support2 = log_pmf2 > NEG_INF if Q <= 2**42 and (not support1.all() or not support2.all()): # quickly compute the support; this is accurate given the # bound (if the vectors have no zeros, then the convolution # has no zeros, so we can skip this) fft_support1 = fft.fft(support1, n = fft_conv_len) if log_pmf2 is None: fft_support = fft_support1**2 else: support2 = log_pmf2 > NEG_INF fft_support2 = fft.fft(support2, n = fft_conv_len) fft_support = fft_support1 * fft_support2 raw_support = np.abs(fft.ifft(fft_support)[:true_conv_len]) threshold = utils.error_threshold_factor(fft_conv_len) * 2 * Q zeros = raw_support <= threshold log_conv[zeros] = NEG_INF bad_places = np.where(~zeros & places_of_interest)[0] else: # can't/don't need to compute the support accurately. bad_places = np.where(places_of_interest)[0] return log_conv, bad_places
def backward (self, f): from numpy import exp from numpy.fft import ifft f = ifft (fk, axis=1) f *= exp (-1j*St*self.phase) return ifft (f, axis=0)
def ifft_plot(self): p, pf=line(absolute(fft.ifft(self.Magcom[:,self.on_res_ind])), plotter="ifft_{}".format(self.name), plot_name="onres_{}".format(self.on_res_ind),label="i {}".format(self.on_res_ind), color="red") line(absolute(fft.ifft(self.Magcom[:,self.start_ind])), plotter=p, linewidth=1.0, plot_name="strt {}".format(self.start_ind), label="i {}".format(self.start_ind)) line(absolute(fft.ifft(self.Magcom[:,self.stop_ind])), plotter=p, linewidth=1.0, plot_name="stop {}".format(self.stop_ind), label="i {}".format(self.stop_ind)) return p
def ifft_plot(self): Magcom=(self.Magcom.transpose()-self.Magcom[:, 0]).transpose() p, pf=line(absolute(fft.ifft(Magcom[:,self.on_res_ind])), plotter="ifft_{}".format(self.name), plot_name="onres_{}".format(self.on_res_ind),label="i {}".format(self.on_res_ind)) line(absolute(fft.ifft(Magcom[:,self.start_ind])), plotter=p, plot_name="strt {}".format(self.start_ind), label="i {}".format(self.start_ind)) line(absolute(fft.ifft(Magcom[:,self.stop_ind])), plotter=p, plot_name="stop {}".format(self.stop_ind), label="i {}".format(self.stop_ind))
def OFDM_tx(IQ_data, Nf, N, Np=0, cp=False, Ncp=0): """ Parameters ---------- IQ_data : +/-1, +/-3, etc complex QAM symbol sample inputs Nf : number of filled carriers, must be even and Nf < N N : total number of carriers; generally a power 2, e.g., 64, 1024, etc Np : Period of pilot code blocks; 0 <=> no pilots cp : False/True <=> bypass cp insertion entirely if False Ncp : the length of the cyclic prefix Returns ------- x_out : complex baseband OFDM waveform output after P/S and CP insertion Examples -------- >>> import matplotlib.pyplot as plt >>> from sk_dsp_comm import digitalcom as dc >>> x1,b1,IQ_data1 = dc.QAM_bb(50000,1,'16qam') >>> x_out = dc.OFDM_tx(IQ_data1,32,64) >>> plt.psd(x_out,2**10,1); >>> plt.xlabel(r'Normalized Frequency ($\omega/(2\pi)=f/f_s$)') >>> plt.ylim([-40,0]) >>> plt.xlim([-.5,.5]) >>> plt.show() """ N_symb = len(IQ_data) N_OFDM = N_symb // Nf IQ_data = IQ_data[:N_OFDM * Nf] IQ_s2p = np.reshape(IQ_data, (N_OFDM, Nf)) # carrier symbols by column print(IQ_s2p.shape) if Np > 0: IQ_s2p = mux_pilot_blocks(IQ_s2p, Np) N_OFDM = IQ_s2p.shape[0] print(IQ_s2p.shape) if cp: x_out = np.zeros(N_OFDM * (N + Ncp), dtype=np.complex128) else: x_out = np.zeros(N_OFDM * N, dtype=np.complex128) for k in range(N_OFDM): buff = np.zeros(N, dtype=np.complex128) for n in range(-Nf // 2, Nf // 2 + 1): if n == 0: # Modulate carrier f = 0 buff[0] = 0 # This can be a pilot carrier elif n > 0: # Modulate carriers f = 1:Nf/2 buff[n] = IQ_s2p[k, n - 1] else: # Modulate carriers f = -Nf/2:-1 buff[N + n] = IQ_s2p[k, Nf + n] if cp: # With cyclic prefix x_out_buff = fft.ifft(buff) x_out[k * (N + Ncp):(k + 1) * (N + Ncp)] = np.concatenate((x_out_buff[N - Ncp:], x_out_buff)) else: # No cyclic prefix included x_out[k * N:(k + 1) * N] = fft.ifft(buff) return x_out
def ComputeResponse(sc,T,rho,c,alpha,d): # from numpy import tan,pi,linspace,exp,zeros,hstack,vstack,array # from scipy.signal import gausspulse # from numpy.fft import rfft,ifft dt=1/(10*sc) t=linspace(0,T,round(T/dt)) X=rfft(gausspulse((t-0.25*T),sc)) Z=[] for i in range(len(rho)): Z.append(rho[i]*c[i]) w=2*pi*linspace(0,1/(2*dt),len(X)) R01=(Z[1]-Z[0])/(Z[1]+Z[0]) T01=R01+1 T10=1-R01 R12=(Z[2]-Z[1])/(Z[1]+Z[2]) T12=R12+1 T21=1-R12 Z234=Z[3]*(Z[4]-1j*Z[3]*tan(w*d[3]/c[3]))/(Z[3]-1j*Z[4]*tan(w*d[3]/c[3])) R234=(Z234-Z[2])/(Z234+Z[2]) T234=R234+1 R45=(Z[5]-Z[4])/(Z[5]+Z[4]) T45=R45+1 Z432=Z[3]*(Z[2]-1j*Z[3]*tan(w*d[3]/c[3]))/(Z[3]-1j*Z[2]*tan(w*d[3]/c[3])) R432=(Z432-Z[4])/(Z432+Z[4]) T432=R432+1 Y0=exp(-2*d[0]*alpha[0])*exp(-1j*w*2*d[0]/c[0])*R01*X Y1=exp(-2*d[1]*alpha[1])*exp(-1j*w*2*d[1]/c[1])*T01*T10*R12*Y0/R01 Y2=exp(-2*d[2]*alpha[2])*exp(-1j*w*2*d[2]/c[2])*T12*T21*R234*Y1/R12 Y3=exp(-2*d[4]*alpha[4])*exp(-1j*w*2*d[4]/c[4])*T234*T432*R45*Y2/R234 Y4=exp(-2*d[4]*alpha[4])*exp(-1j*w*2*d[4]/c[4])*R432*R45*Y3 Y5=exp(-2*d[4]*alpha[4])*exp(-1j*w*2*d[4]/c[4])*R432*R45*Y4 y=2*ifft(vstack((Y0,Y1,Y2,Y3,Y4,Y5)),n=2*len(X)-1).transpose() x=2*ifft(X,n=2*len(X)-1) t=linspace(0,T,len(x)) return t,x,y
def D(uhat,kx,N,filt): """ Function that computes the non linear term for the Burgers equation given the spectra of the variable. The dealiasing cuts the half of the spectra. """ u = fft.ifft(uhat) dudx = fft.ifft(1.0j * kx * uhat) return fft.fft(u*dudx)*filt
def compute_solution(): # frequency & start time f0 = f0_dominant_frequency t0 = t0_start_time # Size of the fourier transform N = 32*32*8 T = T_length # Length of the time signal t = linspace(0.,T,N) dt = t[1]-t[0] # source time function Rick = RickerF(t,t0,f0) # in frequency-domain Sf = f.fft(Rick) freq = f.fftfreq(N,d=dt) # plots figure fig = figure() ax = plot(freq[0:N/2],Sf[0:N/2],freq[0:N/2],abs(Sf[0:N/2])) # c0 = 1500 k0 = 2*pi*f0/c0 a0 = 0.000002 print 'Q =',1/(c0*a0) # Position of the receiver PosX = receiver_X # Modification of the spectrum to include linear attenuation attf = k0*freq/f0 - 4 * a0 * freq * log((freq+0.0000001)/f0) Sf_att = Sf * exp(-1j * attf * PosX) * exp(-a0 * 2 * pi * freq * PosX) # Spectrum of the non attenuated signal Sf_0 = Sf * exp(-1j * 2 * pi * freq/c0 * PosX) # Sf_att_nan = nan_to_num(Sf_att) # plots figure plot(freq[0:N/2],Sf_att_nan[0:N/2],freq[0:N/2],abs(Sf_att_nan[0:N/2])) xlim(xmax=100) title('Spectra with and without attenuation') # signal in time-domain Sig_attn = f.ifft(Sf_att_nan) # plots figure figure(11) plot(t,Sig_attn) plot(t,f.ifft(Sf_0)) grid() title('Snapshots with and without attenuation') show()
def ifft_plot(self): pl=Plotter(fig_width=6, fig_height=4) line("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,self.on_res_ind])), label="On resonance") line("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,0])), label="Off resonance", color="red") pl.legend() pl.set_xlim(0, 100) pl.xlabel="Time (#)" pl.ylabel="Absolute Magnitude" return pl
def helper(self, length): spectrum = np.random.random(length) + 1j * np.random.random(length) signal = fft.ifft(spectrum) signal_padded_incorrect = fft.ifft(spectrum, length * 2) signal_padded_correct = fft.ifft(fft.ifftpad(spectrum, length * 2)) assert_array_almost_equal(signal, signal_padded_correct[::2]) with assert_raises(AssertionError): assert_array_almost_equal(signal, signal_padded_incorrect[::2])
def func(s): N = len(s) Fs = fft.fft(s, 2*N) a = fft.ifft(Fs * conj(Fs)) a[self.__Qr] = 0; a[-self.__Qr] = 0 # see eq.33 Fa = fft.fft(a) Fa.imag = 0 s = fft.ifft(sqrt(Fa) * \ exp(1j * angle(Fs)))[:N] # see eq.23 return s
def vectorCrossCorrelate(vec1,vec2,axis=-1,normalize=False): try: sy1 = vec1.shape[0] except: sy1 = 1 try: sx1 = vec1.shape[1] except: sx1 = 1 try: sy2 = vec2.shape[0] except: sy2 = 1 try: sx2 = vec2.shape[1] except: sx2 = 1 vec1 = (vec1 - np.mean(vec1))/np.std(vec1) vec2 = (vec2 - np.mean(vec2))/np.std(vec2) if axis==-1: temp1 = np.zeros([sy1+sy2-1,sx1+sx2-1]) temp2 = np.zeros([sy1+sy2-1,sx1+sx2-1]) temp1[0:sy1,0:sx1] = vec1 temp2[0:sy2,0:sx2] = vec2 nxcval = np.real(fftshift(ifft2(fft2(temp1)*np.conj(fft2(temp2))))) if normalize: nxcval = nxcval/np.max(nxcval) elif axis==0: if not sx1==sx2: sys.exit('For axis 0 nxc, vec1.shape[0] must equal vec2.shape[0]') else: temp1 = np.zeros([sy1+sy2-1,sx1]) temp2 = np.zeros([sy1+sy2-1,sx1]) temp1[0:sy1,0:sx1] = vec1 temp2[0:sy2,0:sx2] = vec2 nxcval = np.real(fftshift(ifft(fft(temp1,axis=0)*np.conj(fft(temp2,axis=0)),axis=0),axes=(0,))) if normalize: nxcval = nxcval/np.max(nxcval) elif axis==1: if not sy1==sy2: sys.exit('For axis 1 nxc, vec1.shape[1] must equal vec2.shape[1]') else: temp1 = np.zeros([sy1,sx1+sx2-1]) temp2 = np.zeros([sy1,sx1+sx2-1]) temp1[0:sy1,0:sx1] = vec1 temp2[0:sy2,0:sx2] = vec2 nxcval = np.real(fftshift(ifft(fft(temp1,axis=1)*np.conj(fft(temp2,axis=1)),axis=1),axes=(1,))) if normalize: nxcval = nxcval/np.max(nxcval) return nxcval
def crossCorrelate(im1,im2,axis=-1,normalize=False): try: sy1 = im1.shape[0] except: sy1 = 1 try: sx1 = im1.shape[1] except: sx1 = 1 try: sy2 = im2.shape[0] except: sy2 = 1 try: sx2 = im2.shape[1] except: sx2 = 1 im1 = (im1 - np.mean(im1))/np.std(im1) im2 = (im2 - np.mean(im2))/np.std(im2) if axis==-1: temp1 = np.zeros([sy1+sy2-1,sx1+sx2-1]) temp2 = np.zeros([sy1+sy2-1,sx1+sx2-1]) temp1[0:sy1,0:sx1] = im1 temp2[0:sy2,0:sx2] = im2 nxcval = np.real(fftshift(ifft2(fft2(temp1)*np.conj(fft2(temp2))))) if normalize: nxcval = nxcval/(sx1*sy1) elif axis==0: if not sx1==sx2: sys.exit('For axis 0 nxc, im1.shape[0] must equal im2.shape[0]') else: temp1 = np.zeros([sy1+sy2-1,sx1]) temp2 = np.zeros([sy1+sy2-1,sx1]) temp1[0:sy1,0:sx1] = im1 temp2[0:sy2,0:sx2] = im2 nxcval = np.real(fftshift(ifft(fft(temp1,axis=0)*np.conj(fft(temp2,axis=0)),axis=0),axes=(0,))) if normalize: nxcval = nxcval/np.max(nxcval) elif axis==1: if not sy1==sy2: sys.exit('For axis 1 nxc, im1.shape[1] must equal im2.shape[1]') else: temp1 = np.zeros([sy1,sx1+sx2-1]) temp2 = np.zeros([sy1,sx1+sx2-1]) temp1[0:sy1,0:sx1] = im1 temp2[0:sy2,0:sx2] = im2 nxcval = np.real(fftshift(ifft(fft(temp1,axis=1)*np.conj(fft(temp2,axis=1)),axis=1),axes=(1,))) if normalize: nxcval = nxcval/np.max(nxcval) return nxcval
def bopm(k): """ Compute the option price for an option expiring in 'k' timesteps. """ # Obtain the leaf prices as a NumPy array and create the q vector leafValues = array(list(reversed(leaves(k)))) q = array([p, 1-p] + [0] * (k - 1)) # Compute the options price via the fast Fourier transform C = ifft(fft(leafValues) * ((k + 1) * exp(-r * dt) * ifft(q)) ** k) # Return the first component, which is the only important one return C[0]
def ifft_plot(self): pl=Plotter(fig_width=6, fig_height=4) line("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,self.on_res_ind])), label="On resonance") line("ifft_{}".format(self.name), absolute(fft.ifft(self.Magcom[:,0])), label="Off resonance", color="red") pl.legend() pl.set_xlim(0, 100) pl.xlabel="Time (#)" pl.ylabel="Absolute Magnitude" return pl #ifft_plot(s4a1_mp).show() #d.savefig("/Users/thomasaref/Dropbox/Current stuff/Linneaus180416/", "trans_ifft.pdf") #d.show()
def f2_solve(self, rhs, y, t, dt, f2, **kwargs): n = y.shape[0] z = fft.fft(rhs) invop = 1.0 / (1.0 - self.nu*dt*self.laplacian) z = invop * z y[:] = np.real(fft.ifft(z)) op = self.nu * self.laplacian z = op * z f2[:] = np.real(fft.ifft(z))
def ceps(frame, fft_N = -1, kind = 'cmplx'): if fft_N == -1: fft_N = 1 << int(np.log2(len(frame)) + 1) fft_frame = fft.fft(frame, fft_N) angle_frame = np.angle(fft_frame) # We will return the angle as well. if kind == 'cmplx': ceps_frame = fft.ifft(np.log10(fft_frame), fft_N) else: ceps_frame = fft.ifft(np.log10(abs(fft_frame)), fft_N) return ceps_frame, fft_frame, angle_frame
def make_unitary(self): fft_val = fft(self.v) fft_imag = fft_val.imag fft_real = fft_val.real fft_norms = np.sqrt(fft_imag**2 + fft_real**2) fft_unit = fft_val / fft_norms self.v = (ifft(fft_unit)).real
def filter(dat, xb=None, min_sig=0, sub_band=None, pol_deg=2, min_ampl=1., init_wid=0, enlarg=4, do_ints=True, min_wid=0, rep=None, clean=True, weight=False, resid=False): '''looks for peaks in fourier image erases all but the first one subtracts polynomial fit first (of degree pol_deg) init_wid: width of initial (low freq) peak to be preserved (auto-estimated if zero) in FFT: freq=(2*pi)*max(fft)/(t_max-t_min)*n_bin_time/n_bin_freq (the last ratio is usually 1. - FFT returns array of the same number of samples) ''' global sele, foure from numpy import array, arange, polyfit, polyval, real, convolve, ones, argmax, abs, iterable from numpy.fft import fft, ifft if not iterable(xb): xb = base if xb != None: if sub_band != None: amin, amax = get_ids(xb, sub_band) ib = xb[amin:amax] ae = dat[amin:amax] print('selecting bins %i:%i' % (amin, amax)) else: ib = xb ae = dat else: ib = arange(len(dat)) ae = dat ids = polyfit(ib, ae, pol_deg) scal = ae.mean() be = ae - polyval(ids, ib) foure = fft(be / scal) re = abs(foure) #rep=[] if min_ampl < 0: return re if min_ampl == 0: min_ampl = re.mean() * 5. print('setting peak lower limit to %.2f' % min_ampl) if do_ints: import extra reg = extra.ints( re, -min_ampl, min_wid=min_wid) # intervals of Four. spec. above min_ampl print('found %i intervals [%i bins] - sample length %.1f' % (len(reg), sum([a[1] - a[0] for a in reg]), (ib[-1] - ib[0]))) if rep == 'ints': return reg if clean: if len(reg) < 2: print('no frequency cleaned (max. %.2f)' % re[10:-10].max()) if rep == None: return ae if reg[0][0] <= 1: del reg[0] del reg[-1] for r in reg: if clean: if enlarg >= 0: foure[r[0] - enlarg:r[1] + enlarg] = 0j else: # tracing if enlarg <= -2: # from top cent = r[0] + argmax(re[r[0]:r[1]]) r = (cent, cent) for i in range(r[0], 0, -1): if re[i] < re[i - 1]: break for j in range(r[1], len(re)): if re[j] > re[j - 1]: break r = (i, j) foure[r[0]:r[1]] = 0j wei = re[r[0]:r[1]].sum() cent = (arange(r[0], r[1]) * re[r[0]:r[1]]).sum() / wei #barycenter if rep != None: if weight: rep.append([2 * pi * cent / (ib[-1] - ib[0]), wei]) else: rep.append(2 * pi * cent / (ib[-1] - ib[0])) if 2 * r[1] < len(ae): print('%i bins cent %.2f [%.2f] max %.2f' % (r[1] - r[0], cent, 2 * pi * cent / (ib[-1] - ib[0]), re[r[0]:r[1]].max())) #rep.append(cent*(ib[-1]-ib[0])/len(re)) if enlarg < -2: reg2 = extra.ints(re, -min_ampl, min_wid=min_wid) print('found %i extra peaks' % len(reg2)) reg += reg2 if rep != None: for r in reg2: wei = re[r[0]:r[1]].sum() cent = (arange(r[0], r[1]) * re[r[0]:r[1]]).sum() / wei #barycenter if weight: rep.append([2 * pi * cent / (ib[-1] - ib[0]), wei]) else: rep.append(2 * pi * cent / (ib[-1] - ib[0])) #if resid: else: sele = real(foure) > min_ampl if init_wid == 0: init_wid = list(sele).index(False) # where ends initial peak sele[:init_wid] = False sele[-init_wid:] = False isum = sum(sele) if isum == 0: print('no frequency cleaned') return ae if enlarg > 0: sele = convolve(sele, ones(2 * enlarg + 1), 'same') > 0 print('cleaning %i (prev %i) tim. bins' % (sum(sele), isum)) foure[sele] = 0j if rep != None: return rep ge = ifft(foure) * scal return real(ge) + polyval(ids, ib)
def ift(x, axis=[-1]): return ifftshift(ifft(ifftshift(x, axes=axis), axis=axis[0]), axes=axis)
def my_run_simulation(self, initial_run=False, update_plots=True): """ Runs the simulation. Args: self(PyBERT): Reference to an instance of the *PyBERT* class. initial_run(Bool): If True, don't update the eye diagrams, since they haven't been created, yet. (Optional; default = False.) update_plots(Bool): If True, update the plots, after simulation completes. This option can be used by larger scripts, which import *pybert*, in order to avoid graphical back-end conflicts and speed up this function's execution time. (Optional; default = True.) """ num_sweeps = self.num_sweeps sweep_num = self.sweep_num start_time = clock() self.status = 'Running channel...(sweep %d of %d)' % (sweep_num, num_sweeps) self.run_count += 1 # Force regeneration of bit stream. # Pull class variables into local storage, performing unit conversion where necessary. t = self.t t_ns = self.t_ns f = self.f w = self.w bits = self.bits symbols = self.symbols ffe = self.ffe nbits = self.nbits nui = self.nui bit_rate = self.bit_rate * 1.e9 eye_bits = self.eye_bits eye_uis = self.eye_uis nspb = self.nspb nspui = self.nspui rn = self.rn pn_mag = self.pn_mag pn_freq = self.pn_freq * 1.e6 Vod = self.vod Rs = self.rs Cs = self.cout * 1.e-12 RL = self.rin CL = self.cac * 1.e-6 Cp = self.cin * 1.e-12 R0 = self.R0 w0 = self.w0 Rdc = self.Rdc Z0 = self.Z0 v0 = self.v0 * 3.e8 Theta0 = self.Theta0 l_ch = self.l_ch pattern_len = self.pattern_len rx_bw = self.rx_bw * 1.e9 peak_freq = self.peak_freq * 1.e9 peak_mag = self.peak_mag ctle_offset = self.ctle_offset ctle_mode = self.ctle_mode delta_t = self.delta_t * 1.e-12 alpha = self.alpha ui = self.ui n_taps = self.n_taps gain = self.gain n_ave = self.n_ave decision_scaler = self.decision_scaler n_lock_ave = self.n_lock_ave rel_lock_tol = self.rel_lock_tol lock_sustain = self.lock_sustain bandwidth = self.sum_bw * 1.e9 rel_thresh = self.thresh mod_type = self.mod_type[0] try: # Calculate misc. values. fs = bit_rate * nspb Ts = t[1] ts = Ts # Generate the ideal over-sampled signal. # # Duo-binary is problematic, in that it requires convolution with the ideal duobinary # impulse response, in order to produce the proper ideal signal. x = repeat(symbols, nspui) self.x = x if(mod_type == 1): # Handle duo-binary case. duob_h = array(([0.5] + [0.] * (nspui - 1)) * 2) x = convolve(x, duob_h)[:len(t)] self.ideal_signal = x # Find the ideal crossing times, for subsequent jitter analysis of transmitted signal. ideal_xings = find_crossings(t, x, decision_scaler, min_delay=(ui / 2.), mod_type=mod_type) self.ideal_xings = ideal_xings # Calculate the channel output. # # Note: We're not using 'self.ideal_signal', because we rely on the system response to # create the duobinary waveform. We only create it explicitly, above, # so that we'll have an ideal reference for comparison. chnl_h = self.calc_chnl_h() chnl_out = convolve(self.x, chnl_h)[:len(x)] self.channel_perf = nbits * nspb / (clock() - start_time) split_time = clock() self.status = 'Running Tx...(sweep %d of %d)' % (sweep_num, num_sweeps) except Exception: self.status = 'Exception: channel' raise self.chnl_out = chnl_out self.chnl_out_H = fft(chnl_out) # Generate the output from, and the incremental/cumulative impulse/step/frequency responses of, the Tx. try: if(self.tx_use_ami): # Note: Within the PyBERT computational environment, we use normalized impulse responses, # which have units of (V/ts), where 'ts' is the sample interval. However, IBIS-AMI models expect # units of (V/s). So, we have to scale accordingly, as we transit the boundary between these two worlds. tx_cfg = self._tx_cfg # Grab the 'AMIParamConfigurator' instance for this model. # Get the model invoked and initialized, except for 'channel_response', which # we need to do several different ways, in order to gather all the data we need. tx_param_dict = tx_cfg.input_ami_params tx_model_init = AMIModelInitializer(tx_param_dict) tx_model_init.sample_interval = ts # Must be set, before 'channel_response'! tx_model_init.channel_response = [1. / ts] + [0.] * (len(chnl_h) - 1) # Start with a delta function, to capture the model's impulse response. tx_model_init.bit_time = ui tx_model = AMIModel(self.tx_dll_file) tx_model.initialize(tx_model_init) self.log("Tx IBIS-AMI model initialization results:\nInput parameters: {}\nOutput parameters: {}\nMessage: {}".format( tx_model.ami_params_in, tx_model.ami_params_out, tx_model.msg)) if(tx_cfg.fetch_param_val(['Reserved_Parameters', 'Init_Returns_Impulse'])): tx_h = array(tx_model.initOut) * ts elif(not tx_cfg.fetch_param_val(['Reserved_Parameters', 'GetWave_Exists'])): error("ERROR: Both 'Init_Returns_Impulse' and 'GetWave_Exists' are False!\n \ I cannot continue.\nThis condition is supposed to be caught sooner in the flow.") self.status = "Simulation Error." return elif(not self.tx_use_getwave): error("ERROR: You have elected not to use GetWave for a model, which does not return an impulse response!\n \ I cannot continue.\nPlease, select 'Use GetWave' and try again.", 'PyBERT Alert') self.status = "Simulation Error." return if(self.tx_use_getwave): # For GetWave, use a step to extract the model's native properties. # Position the input edge at the center of the vector, in # order to minimize high frequency artifactual energy # introduced by frequency domain processing in some models. half_len = len(chnl_h) // 2 tx_s = tx_model.getWave(array([0.] * half_len + [1.] * half_len)) # Shift the result back to the correct location, extending the last sample. tx_s = pad(tx_s[half_len:], (0, half_len), 'edge') tx_h = diff(concatenate((array([0.0]), tx_s))) # Without the leading 0, we miss the pre-tap. tx_out = tx_model.getWave(self.x) else: # Init()-only. tx_s = tx_h.cumsum() tx_out = convolve(tx_h, self.x)[:len(self.x)] else: # - Generate the ideal, post-preemphasis signal. # To consider: use 'scipy.interp()'. This is what Mark does, in order to induce jitter in the Tx output. ffe_out = convolve(symbols, ffe)[:len(symbols)] self.rel_power = mean(ffe_out ** 2) # Store the relative average power dissipated in the Tx. tx_out = repeat(ffe_out, nspui) # oversampled output # - Calculate the responses. # - (The Tx is unique in that the calculated responses aren't used to form the output. # This is partly due to the out of order nature in which we combine the Tx and channel, # and partly due to the fact that we're adding noise to the Tx output.) tx_h = array(sum([[x] + list(zeros(nspui - 1)) for x in ffe], [])) # Using sum to concatenate. tx_h.resize(len(chnl_h)) tx_s = tx_h.cumsum() temp = tx_h.copy() temp.resize(len(w)) tx_H = fft(temp) tx_H *= tx_s[-1] / abs(tx_H[0]) # - Generate the uncorrelated periodic noise. (Assume capacitive coupling.) # - Generate the ideal rectangular aggressor waveform. pn_period = 1. / pn_freq pn_samps = int(pn_period / Ts + 0.5) pn = zeros(pn_samps) pn[pn_samps // 2:] = pn_mag pn = resize(pn, len(tx_out)) # - High pass filter it. (Simulating capacitive coupling.) (b, a) = iirfilter(2, gFc/(fs/2), btype='highpass') pn = lfilter(b, a, pn)[:len(pn)] # - Add the uncorrelated periodic and random noise to the Tx output. tx_out += pn tx_out += normal(scale=rn, size=(len(tx_out),)) # - Convolve w/ channel. tx_out_h = convolve(tx_h, chnl_h)[:len(chnl_h)] temp = tx_out_h.copy() temp.resize(len(w)) tx_out_H = fft(temp) rx_in = convolve(tx_out, chnl_h)[:len(tx_out)] self.tx_s = tx_s self.tx_out = tx_out self.rx_in = rx_in self.tx_out_s = tx_out_h.cumsum() self.tx_out_p = self.tx_out_s[nspui:] - self.tx_out_s[:-nspui] self.tx_H = tx_H self.tx_h = tx_h self.tx_out_H = tx_out_H self.tx_out_h = tx_out_h self.tx_perf = nbits * nspb / (clock() - split_time) split_time = clock() self.status = 'Running CTLE...(sweep %d of %d)' % (sweep_num, num_sweeps) except Exception: self.status = 'Exception: Tx' raise # Generate the output from, and the incremental/cumulative impulse/step/frequency responses of, the CTLE. try: if(self.rx_use_ami): rx_cfg = self._rx_cfg # Grab the 'AMIParamConfigurator' instance for this model. # Get the model invoked and initialized, except for 'channel_response', which # we need to do several different ways, in order to gather all the data we need. rx_param_dict = rx_cfg.input_ami_params rx_model_init = AMIModelInitializer(rx_param_dict) rx_model_init.sample_interval = ts # Must be set, before 'channel_response'! rx_model_init.channel_response = tx_out_h / ts rx_model_init.bit_time = ui rx_model = AMIModel(self.rx_dll_file) rx_model.initialize(rx_model_init) self.log("Rx IBIS-AMI model initialization results:\nInput parameters: {}\nMessage: {}\nOutput parameters: {}".format( rx_model.ami_params_in, rx_model.msg, rx_model.ami_params_out)) if(rx_cfg.fetch_param_val(['Reserved_Parameters', 'Init_Returns_Impulse'])): ctle_out_h = array(rx_model.initOut) * ts elif(not rx_cfg.fetch_param_val(['Reserved_Parameters', 'GetWave_Exists'])): error("ERROR: Both 'Init_Returns_Impulse' and 'GetWave_Exists' are False!\n \ I cannot continue.\nThis condition is supposed to be caught sooner in the flow.") self.status = "Simulation Error." return elif(not self.rx_use_getwave): error("ERROR: You have elected not to use GetWave for a model, which does not return an impulse response!\n \ I cannot continue.\nPlease, select 'Use GetWave' and try again.", 'PyBERT Alert') self.status = "Simulation Error." return if(self.rx_use_getwave): if(False): ctle_out, clock_times = rx_model.getWave(rx_in, 32) else: ctle_out, clock_times = rx_model.getWave(rx_in, len(rx_in)) self.log(rx_model.ami_params_out) ctle_H = fft(ctle_out * signal.hann(len(ctle_out))) / fft(rx_in * signal.hann(len(rx_in))) ctle_h = real(ifft(ctle_H)[:len(chnl_h)]) ctle_out_h = convolve(ctle_h, tx_out_h)[:len(chnl_h)] else: # Init() only. ctle_out_h_padded = pad(ctle_out_h, (nspb, len(rx_in) - nspb - len(ctle_out_h)), 'linear_ramp', end_values=(0., 0.)) tx_out_h_padded = pad(tx_out_h, (nspb, len(rx_in) - nspb - len(tx_out_h)), 'linear_ramp', end_values=(0., 0.)) ctle_H = fft(ctle_out_h_padded) / fft(tx_out_h_padded) ctle_h = real(ifft(ctle_H)[:len(chnl_h)]) ctle_out = convolve(rx_in, ctle_h)[:len(tx_out)] ctle_s = ctle_h.cumsum() else: if(self.use_ctle_file): ctle_h = import_channel(self.ctle_file, ts) if(max(abs(ctle_h)) < 100.): # step response? ctle_h = diff(ctle_h) # impulse response is derivative of step response. else: ctle_h *= ts # Normalize to (V/sample) ctle_h.resize(len(t)) ctle_H = fft(ctle_h) ctle_H *= sum(ctle_h) / ctle_H[0] else: w_dummy, ctle_H = make_ctle(rx_bw, peak_freq, peak_mag, w, ctle_mode, ctle_offset) ctle_h = real(ifft(ctle_H))[:len(chnl_h)] ctle_h *= abs(ctle_H[0]) / sum(ctle_h) ctle_out = convolve(rx_in, ctle_h)[:len(tx_out)] ctle_out -= mean(ctle_out) # Force zero mean. if(self.ctle_mode == 'AGC'): # Automatic gain control engaged? ctle_out *= 2. * decision_scaler / ctle_out.ptp() ctle_s = ctle_h.cumsum() ctle_out_h = convolve(tx_out_h, ctle_h)[:len(tx_out_h)] self.ctle_s = ctle_s ctle_out_h_main_lobe = where(ctle_out_h >= max(ctle_out_h) / 2.)[0] if(len(ctle_out_h_main_lobe)): conv_dly_ix = ctle_out_h_main_lobe[0] else: conv_dly_ix = self.chnl_dly / Ts conv_dly = t[conv_dly_ix] ctle_out_s = ctle_out_h.cumsum() temp = ctle_out_h.copy() temp.resize(len(w)) ctle_out_H = fft(temp) # - Store local variables to class instance. self.ctle_out_s = ctle_out_s # Consider changing this; it could be sensitive to insufficient "front porch" in the CTLE output step response. self.ctle_out_p = self.ctle_out_s[nspui:] - self.ctle_out_s[:-nspui] self.ctle_H = ctle_H self.ctle_h = ctle_h self.ctle_out_H = ctle_out_H self.ctle_out_h = ctle_out_h self.ctle_out = ctle_out self.conv_dly = conv_dly self.conv_dly_ix = conv_dly_ix self.ctle_perf = nbits * nspb / (clock() - split_time) split_time = clock() self.status = 'Running DFE/CDR...(sweep %d of %d)' % (sweep_num, num_sweeps) except Exception: self.status = 'Exception: Rx' raise # Generate the output from, and the incremental/cumulative impulse/step/frequency responses of, the DFE. try: if(self.use_dfe): dfe = DFE(n_taps, gain, delta_t, alpha, ui, nspui, decision_scaler, mod_type, n_ave=n_ave, n_lock_ave=n_lock_ave, rel_lock_tol=rel_lock_tol, lock_sustain=lock_sustain, bandwidth=bandwidth, ideal=self.sum_ideal) else: dfe = DFE(n_taps, 0., delta_t, alpha, ui, nspui, decision_scaler, mod_type, n_ave=n_ave, n_lock_ave=n_lock_ave, rel_lock_tol=rel_lock_tol, lock_sustain=lock_sustain, bandwidth=bandwidth, ideal=True) (dfe_out, tap_weights, ui_ests, clocks, lockeds, clock_times, bits_out) = dfe.run(t, ctle_out) bits_out = array(bits_out) auto_corr = 1. * correlate(bits_out[(nbits - eye_bits):], bits[(nbits - eye_bits):], mode='same') \ / sum(bits[(nbits - eye_bits):]) auto_corr = auto_corr[len(auto_corr) // 2 :] self.auto_corr = auto_corr bit_dly = where(auto_corr == max(auto_corr))[0][0] bits_ref = bits[(nbits - eye_bits) :] bits_tst = bits_out[(nbits + bit_dly - eye_bits) :] if(len(bits_ref) > len(bits_tst)): bits_ref = bits_ref[: len(bits_tst)] elif(len(bits_tst) > len(bits_ref)): bits_tst = bits_tst[: len(bits_ref)] bit_errs = where(bits_tst ^ bits_ref)[0] self.bit_errs = len(bit_errs) dfe_h = array([1.] + list(zeros(nspb - 1)) + sum([[-x] + list(zeros(nspb - 1)) for x in tap_weights[-1]], [])) dfe_h.resize(len(ctle_out_h)) temp = dfe_h.copy() temp.resize(len(w)) dfe_H = fft(temp) self.dfe_s = dfe_h.cumsum() dfe_out_H = ctle_out_H * dfe_H dfe_out_h = convolve(ctle_out_h, dfe_h)[:len(ctle_out_h)] dfe_out_s = dfe_out_h.cumsum() self.dfe_out_p = dfe_out_s - pad(dfe_out_s[:-nspui], (nspui,0), 'constant', constant_values=(0,0)) self.dfe_H = dfe_H self.dfe_h = dfe_h self.dfe_out_H = dfe_out_H self.dfe_out_h = dfe_out_h self.dfe_out_s = dfe_out_s self.dfe_out = dfe_out self.dfe_perf = nbits * nspb / (clock() - split_time) split_time = clock() self.status = 'Analyzing jitter...(sweep %d of %d)' % (sweep_num, num_sweeps) except Exception: self.status = 'Exception: DFE' raise # Save local variables to class instance for state preservation, performing unit conversion where necessary. self.adaptation = tap_weights self.ui_ests = array(ui_ests) * 1.e12 # (ps) self.clocks = clocks self.lockeds = lockeds self.clock_times = clock_times # Analyze the jitter. self.thresh_tx = array([]) self.jitter_ext_tx = array([]) self.jitter_tx = array([]) self.jitter_spectrum_tx = array([]) self.jitter_ind_spectrum_tx = array([]) self.thresh_ctle = array([]) self.jitter_ext_ctle = array([]) self.jitter_ctle = array([]) self.jitter_spectrum_ctle = array([]) self.jitter_ind_spectrum_ctle = array([]) self.thresh_dfe = array([]) self.jitter_ext_dfe = array([]) self.jitter_dfe = array([]) self.jitter_spectrum_dfe = array([]) self.jitter_ind_spectrum_dfe = array([]) self.f_MHz_dfe = array([]) self.jitter_rejection_ratio = array([]) try: if(mod_type == 1): # Handle duo-binary case. pattern_len *= 2 # Because, the XOR pre-coding can invert every other pattern rep. if(mod_type == 2): # Handle PAM-4 case. if(pattern_len % 2): pattern_len *= 2 # Because, the bits are taken in pairs, to form the symbols. # - channel output actual_xings = find_crossings(t, chnl_out, decision_scaler, mod_type=mod_type) (jitter, t_jitter, isi, dcd, pj, rj, jitter_ext, \ thresh, jitter_spectrum, jitter_ind_spectrum, spectrum_freqs, \ hist, hist_synth, bin_centers) = calc_jitter(ui, nui, pattern_len, ideal_xings, actual_xings, rel_thresh) self.t_jitter = t_jitter self.isi_chnl = isi self.dcd_chnl = dcd self.pj_chnl = pj self.rj_chnl = rj self.thresh_chnl = thresh self.jitter_chnl = hist self.jitter_ext_chnl = hist_synth self.jitter_bins = bin_centers self.jitter_spectrum_chnl = jitter_spectrum self.jitter_ind_spectrum_chnl = jitter_ind_spectrum self.f_MHz = array(spectrum_freqs) * 1.e-6 # - Tx output actual_xings = find_crossings(t, rx_in, decision_scaler, mod_type=mod_type) (jitter, t_jitter, isi, dcd, pj, rj, jitter_ext, \ thresh, jitter_spectrum, jitter_ind_spectrum, spectrum_freqs, \ hist, hist_synth, bin_centers) = calc_jitter(ui, nui, pattern_len, ideal_xings, actual_xings, rel_thresh) self.isi_tx = isi self.dcd_tx = dcd self.pj_tx = pj self.rj_tx = rj self.thresh_tx = thresh self.jitter_tx = hist self.jitter_ext_tx = hist_synth self.jitter_spectrum_tx = jitter_spectrum self.jitter_ind_spectrum_tx = jitter_ind_spectrum # - CTLE output actual_xings = find_crossings(t, ctle_out, decision_scaler, mod_type=mod_type) (jitter, t_jitter, isi, dcd, pj, rj, jitter_ext, \ thresh, jitter_spectrum, jitter_ind_spectrum, spectrum_freqs, \ hist, hist_synth, bin_centers) = calc_jitter(ui, nui, pattern_len, ideal_xings, actual_xings, rel_thresh) self.isi_ctle = isi self.dcd_ctle = dcd self.pj_ctle = pj self.rj_ctle = rj self.thresh_ctle = thresh self.jitter_ctle = hist self.jitter_ext_ctle = hist_synth self.jitter_spectrum_ctle = jitter_spectrum self.jitter_ind_spectrum_ctle = jitter_ind_spectrum # - DFE output ignore_until = (nui - eye_uis) * ui + 0.75 * ui # 0.5 was causing an occasional misalignment. ideal_xings = array(filter(lambda x: x > ignore_until, list(ideal_xings))) min_delay = ignore_until + conv_dly actual_xings = find_crossings(t, dfe_out, decision_scaler, min_delay=min_delay, mod_type=mod_type, rising_first=False, ) (jitter, t_jitter, isi, dcd, pj, rj, jitter_ext, \ thresh, jitter_spectrum, jitter_ind_spectrum, spectrum_freqs, \ hist, hist_synth, bin_centers) = calc_jitter(ui, eye_uis, pattern_len, ideal_xings, actual_xings, rel_thresh) self.isi_dfe = isi self.dcd_dfe = dcd self.pj_dfe = pj self.rj_dfe = rj self.thresh_dfe = thresh self.jitter_dfe = hist self.jitter_ext_dfe = hist_synth self.jitter_spectrum_dfe = jitter_spectrum self.jitter_ind_spectrum_dfe = jitter_ind_spectrum self.f_MHz_dfe = array(spectrum_freqs) * 1.e-6 skip_factor = nbits / eye_bits ctle_spec = self.jitter_spectrum_ctle dfe_spec = self.jitter_spectrum_dfe self.jitter_rejection_ratio = zeros(len(dfe_spec)) self.jitter_perf = nbits * nspb / (clock() - split_time) self.total_perf = nbits * nspb / (clock() - start_time) split_time = clock() self.status = 'Updating plots...(sweep %d of %d)' % (sweep_num, num_sweeps) except Exception: self.status = 'Exception: jitter' # raise # Update plots. try: if(update_plots): update_results(self) if(not initial_run): update_eyes(self) self.plotting_perf = nbits * nspb / (clock() - split_time) self.status = 'Ready.' except Exception: self.status = 'Exception: plotting' raise
def update_g(F, G, C): F_rev = fft(ifft(F)[::-1]) G_k1 = (C / (G * F)) * F_rev * G return ifft(G_k1)
y2 = 4 / 3 * np.pi * np.sin(3 * x) y3 = 4 / 5 * np.pi * np.sin(5 * x) # 叠加1000条线 n = 1000 y = np.zeros(n) for i in range(1, n + 1): y += 4 / (2 * i - 1) * np.pi * np.sin((2 * i - 1) * x) mp.subplot(121) mp.grid(linestyle=':') mp.plot(x, y1, label='y1', alpha=0.2) mp.plot(x, y2, label='y2', alpha=0.2) mp.plot(x, y3, label='y3', alpha=0.2) mp.plot(x, y, label='y') # 针对合成的方波傅里叶变换 import numpy.fft as nf complex_ary = nf.fft(y) y_ = nf.ifft(complex_ary).real # 合成波 print(y_.dtype) mp.plot(x, y_, label='y_', color='red', linewidth=7, alpha=0.2) mp.tight_layout() # 绘制频域图像 频率/能量图像 # 通过采样数量与采样周期获取fft的频率数组 freqs = nf.fftfreq(y_.size, x[1] - x[0]) pows = np.abs(complex_ary) # 复数的模->能量 mp.subplot(122) mp.grid(linestyle=':') mp.plot(freqs[freqs > 0], pows[freqs > 0], color='orangered', label='Freqency') mp.legend() mp.tight_layout() mp.legend() mp.show()
def der_fft(u, expconsts, n): # n is the number of derivatives to take return ifft((expconsts**n) * fft(u))
import numpy as np import matplotlib.pyplot as plt from numpy.fft import fft, ifft import wavio t = np.linspace(0, 5, 44100 * 5) x = 2 * np.sin(2 * np.pi * 400 * t) + np.sin(2 * np.pi * 10000 * t) + np.sin( 2 * np.pi * 16000 * t) f = np.linspace(0, 22050, len(x) // 2) X = fft(x, len(x))[:len(x) // 2] print(ifft(X, len(x)).real) # cls = wavio.read("sine4003000.wav") # print(x) # print("WIDTH ={}".format(cls.sampwidth)) # print(cls.data[:, 0]) wavio.write("eds.wav", data=x.astype(np.int32), rate=44100, sampwidth=4) data = wavio.read("eds.wav") print(data.data)
# projection_size_padded = max(64, int(2 ** np.ceil(np.log2(2 * radon_image.shape[0])))) # #projection_size_padded = 1024 # pad_width = ((0, projection_size_padded - radon_image.shape[0]), (0, 0)) # img = np.pad(radon_image, pad_width, mode='constant', constant_values=0) # Construct the Fourier filter projection_size = radon_image.shape[0] f = fftfreq(projection_size).reshape(-1, 1) # digital frequency omega = 2 * np.pi * f # angular frequency fourier_filter = 2 * np.abs(f) # ramp filter # Apply filter in Fourier domain # projection = fft(radon_image, axis=0) * fourier_filter # radon_filtered = np.real(ifft(projection, axis=0)) time_filter = np.fft.fftshift(ifft(fourier_filter, axis=0).real) sig = radon_image[:, 0] fourier_res = ifft(fft(sig) * fourier_filter[:, 0]).real time_res = np.convolve(np.concatenate([sig, sig]), np.flipud(time_filter[:, 0]), 'same') first_half_projection_size = projection_size // 2 time_res_best = np.fft.fftshift( time_res[first_half_projection_size:(first_half_projection_size + projection_size)]) plt.plot(fourier_res - time_res_best) plt.show()
def ift(F, ax=-1): f = fftshift(ifft(fftshift(F), axis=ax)) return f
def process_group(group, config, metadata): # Create folder, if necessary if not os.path.exists(debugFolder): os.makedirs(debugFolder) logging.debug("Created folder " + debugFolder + " for debug output files") # Format data into single [cha RO PE] array data = [acquisition.data for acquisition in group] data = np.stack(data, axis=-1) logging.debug("Raw data is size %s" % (data.shape, )) np.save(debugFolder + "/" + "raw.npy", data) # Remove readout oversampling data = fft.ifft(data, axis=1) data = np.delete( data, np.arange(int(data.shape[1] * 1 / 4), int(data.shape[1] * 3 / 4)), 1) data = fft.fft(data, axis=1) logging.debug("Raw data is size after readout oversampling removal %s" % (data.shape, )) np.save(debugFolder + "/" + "rawNoOS.npy", data) # Fourier Transform data = fft.fftshift(data, axes=(1, 2)) data = fft.ifft2(data, axes=(1, 2)) data = fft.ifftshift(data, axes=(1, 2)) # Sum of squares coil combination data = np.abs(data) data = np.square(data) data = np.sum(data, axis=0) data = np.sqrt(data) logging.debug("Image data is size %s" % (data.shape, )) np.save(debugFolder + "/" + "img.npy", data) # Normalize and convert to int16 data *= 32767 / data.max() data = np.around(data) data = data.astype(np.int16) # Remove readout oversampling offset = int( (data.shape[0] - metadata.encoding[0].reconSpace.matrixSize.x) / 2) data = data[offset:offset + metadata.encoding[0].reconSpace.matrixSize.x, :] # Remove phase oversampling offset = int( (data.shape[1] - metadata.encoding[0].reconSpace.matrixSize.y) / 2) data = data[:, offset:offset + metadata.encoding[0].reconSpace.matrixSize.y] logging.debug("Image without oversampling is size %s" % (data.shape, )) np.save(debugFolder + "/" + "imgCrop.npy", data) # Format as ISMRMRD image data image = ismrmrd.Image.from_array(data, acquisition=group[0]) image.image_index = 1 # Set field of view image.field_of_view = ( ctypes.c_float(metadata.encoding[0].reconSpace.fieldOfView_mm.x), ctypes.c_float(metadata.encoding[0].reconSpace.fieldOfView_mm.y), ctypes.c_float(metadata.encoding[0].reconSpace.fieldOfView_mm.z)) # Set ISMRMRD Meta Attributes meta = ismrmrd.Meta({ 'DataRole': 'Image', 'ImageProcessingHistory': ['FIRE', 'PYTHON'], 'WindowCenter': '16384', 'WindowWidth': '32768' }) # Add image orientation directions to MetaAttributes if not already present if meta.get('ImageRowDir') is None: meta['ImageRowDir'] = [ "{:.18f}".format(image.getHead().read_dir[0]), "{:.18f}".format(image.getHead().read_dir[1]), "{:.18f}".format(image.getHead().read_dir[2]) ] if meta.get('ImageColumnDir') is None: meta['ImageColumnDir'] = [ "{:.18f}".format(image.getHead().phase_dir[0]), "{:.18f}".format(image.getHead().phase_dir[1]), "{:.18f}".format(image.getHead().phase_dir[2]) ] xml = meta.serialize() logging.debug("Image MetaAttributes: %s", xml) logging.debug("Image data has %d elements", image.data.size) image.attribute_string = xml return image
def ls_grad(loss_grad, ndim, order, sigma): vec = make_vec(order, ndim) coef = (-1)**order * sigma denom = 1 + coef * fft(vec) return (lambda x: np.squeeze(np.real(ifft(fft(loss_grad(x)) / denom))))
#!/usr/bin/python from numpy.fft import ifft def printResult(arr): assert len(arr) == 16 for i in xrange(16): i2 = (i % 4) * 4 + (i / 4) x = arr[i2] # numpy ifft scales values by 1/n, but our library # scales it by 1/sqrt(n) print int(round(x.real * 4)), int(round(x.imag * 4)) #printResult(ifft([0,64,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0])) arr = [] for i in xrange(16): re = i * 6 im = i * 7 arr.append(re + 1j * im) printResult(ifft(arr))
def deltaphiqqdiff(img1, img2, mask=None, noqs=None, nophis=None, x0=None, y0=None, PF=False): ''' A delta phi difference correlation. This one returns a: q1,q2,dphi matrix where each element is <(I(q1,phi)-I(q2,phi+dphi))^2>_phi img1, img2 : used for the correlations (set to equal if same image) this is a 2nd moment calc so you need two quantities mask : the mask for the data set It uses the binning scheme only in one step. It transforms the image to a qphi square grid. It then uses FFT's to transform to a qphi correlation. ''' if (x0 is None): x0 = img1.shape[1] / 2 if (y0 is None): y0 = img1.shape[0] / 2 if (mask is None): mask = np.ones(IMG.shape) if (noqs is None): noqs = 800 if (nophis is None): nophis = 360 # 0. get pixellist and relevant data pxlst = np.where(mask.ravel() == 1) data1 = img1.ravel()[pxlst] data2 = img2.ravel()[pxlst] # 1. Make coord system and grab selected pixels QS, PHIS = mkpolar(img1, x0=x0, y0=y0) qs, phis = QS.ravel()[pxlst], PHIS.ravel()[pxlst] # 2. make the lists for selection qlist_m1 = linplist(np.min(qs), np.max(qs), noqs) philist_m1 = linplist(np.min(phis), np.max(phis), nophis) # 3. partition according to the lists, 2D here, make bin id 1 dimensional qid, pid, pselect = partition2D(qlist_m1, philist_m1, qs, phis) bid = (qid * nophis + pid).astype(int) # the sqphi here sq1 = np.zeros((noqs, nophis)) sq2 = np.zeros((noqs, nophis)) sq_qs = np.zeros((noqs, nophis)) sq_phis = np.zeros((noqs, nophis)) sqmask = np.zeros((noqs, nophis)) maxid = np.max(bid) sq1.ravel()[:maxid + 1] = partition_avg(data1[pselect], bid) sq2.ravel()[:maxid + 1] = partition_avg(data2[pselect], bid) sq_qs.ravel()[:maxid + 1] = partition_avg(qs[pselect], bid) sq_phis.ravel()[:maxid + 1] = partition_avg(phis[pselect], bid) sqmask.ravel()[:maxid + 1] = partition_avg(pselect * 0 + 1, bid) sq_qs = np.sum(sq_qs, axis=1) / np.sum(sqmask, axis=1) sq_phis = np.sum(sq_phis, axis=1) / np.sum(sqmask, axis=1) sqcphitot = np.zeros((noqs, noqs, nophis)) tx = np.arange(noqs) ty = np.arange(noqs) TX, TY = np.meshgrid(tx, ty) # perform convolution for i in np.arange(-noqs + 1, noqs): if (PF is True): print("Iterating over slice {} of {}".format( noqs + i, 2 * noqs + 1)) # grab the slice in q w = np.where(TX - TY == i) rngbeg = np.maximum(i, 0) rngend = np.minimum(noqs, noqs + i) sq1tmp = np.roll(sq1, i, axis=0)[rngbeg:rngend, :] sq2tmp = sq2[rngbeg:rngend] sqmask1 = np.roll(sqmask, i, axis=0)[rngbeg:rngend, :] sqmask2 = sqmask[rngbeg:rngend, :] sqcphi = ifft(fft(sq2tmp, axis=1) * np.conj(fft(sq1tmp, axis=1)), axis=1).real sqcphimask = ifft(fft(sqmask1, axis=1) * np.conj(fft(sqmask2, axis=1)), axis=1).real sqcphi /= sqcphimask sqcphitot[w[0], w[1], :] = sqcphi return sq_qs, sq_phis, sqcphitot
def dedekind(freqs, ydata, flags, filter_factor=1e-6, patch_c=[0.], patch_w=[100e-9], weights="WTL", zero_flags=True, output_domain='delay', taper='boxcar', cache=WMAT_CACHE): ''' a linear delay filter that suppresses modes within rectangular windows in delay space listed in list "patch_c" by a factor of "filter_factor" Args: freqs, numpy float array of frequency values flags, numpy bool (or int) array of flags filter_factor, float, factor by which to suppress modes specified in patch_c and patch_w patch_c, a list of window centers for delay values (floats) to filter. patch_w, a list of window widths for delay values (floats) to filter. weights, string, use "WTL" to filter regions specified in patch_c and patch_w or "I" to do not filtering (just a straight fft) renormalize, EXPERIMENTAL bool, try to restore filtered regions after FT. zero_flags, bool, if true, set values in flagged frequency channels to zero, even if not filtering. output_domain, string, specify "frequency" or "delay" taper, string, specify the multiplicative tapering function to apply before filtering. cache, optional dictionary to store precomputed filter matrices. Default, use dictionary in this namespace. Returns: if output_domain == 'delay', returns delays, output where output is the filtered delay transformed data set. if output_domain == 'frequency' returns frequencies, output where output is the filtered frequency domain data set. Example: linear_filter(x, y, f, 1e-6, patch_c = [0.], patch_w = 100e-9) will filter out modes (including flagged sidelobes) within a window centered at delay = 0. ns with width of 200 ns (region between -100 and 100 ns). ''' nf = len(freqs) taper = signal.windows.get_window(taper, nf) taper /= np.sqrt((taper * taper).mean()) taper_mat = np.diag(taper) if weights == 'I': wmat = np.identity(nf) if zero_flags: wmat[:, flags] = 0. wmat[flags, :] = 0. elif weights == 'WTL': wmat = linear_filter_matrix(nf=len(freqs), df=freqs[1] - freqs[0], patch_c=patch_c, patch_w=patch_w, filter_factor=filter_factor, zero_flags=zero_flags, flags=flags, cache=cache) output = ydata output = np.dot(wmat, output) output = fft.fft(output * taper) #if renormalize: # igrid,jgrid = np.meshgrid(np.arange(-nf/2,nf/2),np.arange(-nf/2,nf/2)) # fftmat = np.exp(-2j*np.pi*igrid*jgrid/nf) #fftmat[flags,:]=0. #fftmat[:,flags]=0. # mmat = np.dot(fftmat,np.dot(wmat,np.conj(fftmat).T)) #print(np.linalg.cond(mmat)) # mmat_inv = np.linalg.pinv(mmat) #else: # mmat_inv = np.identity(nf) #output=np.dot(mmat_inv,output) if output_domain == 'frequency': output = fft.ifft(output) / taper x = freqs else: x = np.arange(-nf / 2, nf / 2) / ((freqs[1] - freqs[0]) * nf) output = fft.fftshift(output) #print(output.shape) return x, output
import math import numpy as np from numpy.fft import fft, ifft from convolution import revnp from parameters import * # Parameter Adjustments M = 3 #numberoftimesteps dt, df, u, d, q = get_binomial_parameters(M) # Array Generation for Stock Prices mu = np.arange(M + 1) mu = np.resize(mu, (M + 1, M + 1)) md = np.transpose(mu) mu = u**(mu - md) md = d**md S = S0 * mu * md # Valuation by fft CT = np.maximum(S[:, -1] - K, 0) qv = np.zeros(M + 1, dtype=np.float) qv[0] = q qv[1] = 1 - q C0_a = fft(math.exp(-r * T) * ifft(CT) * ((M + 1) * ifft(revnp(qv)))**M) C0_b = fft(math.exp(-r * T) * ifft(CT) * fft(qv)**M) C0_c = ifft(math.exp(-r * T) * fft(CT) * fft(revnp(qv))**M) print("Value of European option is %8.3f" % np.real(C0_a[0])) print("Value of European option is %8.3f" % np.real(C0_b[0])) print("Value of European option is %8.3f" % np.real(C0_c[0]))
def multisine(f1=0, f2=None, N=1024, fs=None, R=1, P=1, lines='full', rms=1, ngroup=4): """Random periodic excitation Generates R realizations of a zero-mean random phase multisine with specified rms(amplitude). Random phase multisine signal is a periodic random signal with a user-controlled amplitude spectrum and a random phase spectrum drawn from a uniform distribution. If an integer number of periods is measured, the amplitude spectrum is perfectly realized, unlike classical Gaussian noise. Another advantage is that the periodic nature can help help separate signal from noise. The amplitude spectrum is flat between f1 and f2. Parameters ---------- f1 : float, optional Starting frequency in Hz. Default 0 Hz f2 : float, optional Ending frequency in Hz. Default 0.9* `nyquist frequency` N : int, optional Number of points per period. default = 1024 fs : float, optional Sample frequency. Default fs=N P : int, optional Number of periods. default = 1 R : int, optional Number of realizations. default = 1 lines : array_like or str: {'full', 'odd', 'oddrandom'}, optional For characterization of NLs, only selected lines are excited. rms : float, optional rms(amplitude) of the generated signals. default = 1. Note that since the signal is zero-mean, the std and rms is equal. ngroup : int, optional In case of ftype = oddrandom, 1 out of ngroup odd lines is discarded. Returns ------- u: RxNP record of the generated signals lines: excited frequency lines -> 1 = dc, 2 = fs/N freq: frequency vector Examples -------- Generate two realizations of a full multisine with 1000 samples and excitation up to one third of the Nyquist frequency. The two realizations have the same amplitude spectrum, but different phase realizations (uniformly distributed between [-π,π)) >>> N = 1000 # One thousand samples >>> kind = 'full' # Full multisine >>> f2 = round(N//6) # Excitation up to one sixth of the sample frequency >>> R = 2 # Two phase realizations >>> u, lines, freq = multisine(f2=f2,N=N,lines=kind,R=R) Generate a random odd multisine where the excited odd lines are split in groups of three consecutive lines and where one line is randomly chosen in each group to be a detection line (i.e. without excitation) >>> kind = 'oddrandom' >>> u1,lines, freq = multisine(f2=f2,N=N,lines=kind,R=1,ngroup=3) Generate another phase realization of this multisine with the same excited lines and detection lines >>> u2,*_ = multisine(N=N,lines=lines,R=1) Notes ----- J.Schoukens, M. Vaes, and R. Pintelon: Linear System Identification in a Nonlinear Setting: Nonparametric Analysis of the Nonlinear Distortions and Their Impact on the Best Linear Approximation. https://arxiv.org/pdf/1804.09587.pdf """ if fs is None: fs = N if f2 is None: f2 = np.floor(0.9 * N / 2) if not fs >= 2 * f2: raise AssertionError(f"fs should be {fs} >= {2*f2}") if not N >= 2 * f2: raise AssertionError('N should be higher than Nyquist freq, ' 'N >= 2*f2. N={}, f2={}'.format(N, f2)) VALID_LINES = {'full', 'odd', 'oddrandom'} if isinstance(lines, str) and lines.lower() in VALID_LINES: lines = lines.lower() # frequency resolution f0 = fs / N # lines selection - select which frequencies to excite lines_min = np.ceil(f1 / f0).astype('int') lines_max = np.floor(f2 / f0).astype('int') _lines = np.arange(lines_min, lines_max, dtype=int) elif isinstance(lines, (np.ndarray, list)): # user specified lines _lines = np.array(lines) else: raise ValueError(f"Invalid lines-type. Should be one of {VALID_LINES}" f" or array of frequency lines. Is {lines}") # remove dc if _lines[0] == 0: _lines = _lines[1:] if isinstance(lines, str): if lines == 'full': pass # do nothing elif lines == 'odd': # remove even lines if np.remainder(_lines[0], 2): # lines[0] is even _lines = _lines[::2] else: _lines = _lines[1::2] elif lines == 'oddrandom': if np.remainder(_lines[0], 2): _lines = _lines[::2] else: _lines = _lines[1::2] # remove 1 out of ngroup lines nlines = len(_lines) nremove = np.floor(nlines / ngroup).astype('int') idx = np.random.randint(ngroup, size=nremove) idx = idx + ngroup * np.arange(nremove) _lines = np.delete(_lines, idx) nlines = len(_lines) # multisine generation - frequency domain implementation U = np.zeros((R, N), dtype=complex) # excite the selected frequencies U[:, _lines] = np.exp(2j * np.pi * np.random.rand(R, nlines)) u = 2 * np.real(ifft(U, axis=1)) # go to time domain u = rms * u / np.std(u[0]) # rescale to obtain desired rms/std # Because the ifft is for [0,2*pi[, there is no need to remove any point # when the generated signal is repeated. u = np.tile(u, (1, P)) # generate P periods freq = np.arange(N) / N * fs return u, _lines, freq
def pcal_delay(ifile, ntones, dbg, qwerty, write, mode_filtration): global ph if mode_filtration == 'true': new_ph = pcal_phaseresponse(ifile, ntones, 'false', mode_filtration) ph = new_ph li = [] if dbg == 'true': f, axar = plt.subplots(2) axar[0].grid() time = np.linspace((1 / counter), 1, counter) ampls = [] xlist = [] if dbg == 'true': axar[0].set_xlabel(u'время, мкс') axar[0].set_ylabel(u'амплитуда, усл.ед.') for j in range(acc_periods): ph1 = abs(fft.ifft(ph[(j * counter):(j * counter + counter)])) if dbg == 'true': axar[0].plot(time, ph1) plt.pause(0.001) number = max(izip(ph1, count()))[1] j0 = number res = (np.asarray(ph).real)[(j * counter):(j * counter + counter)] ims = (np.asarray(ph).imag)[(j * counter):(j * counter + counter)] if j == 0: j1 = ("%.7f" % (((j0 * 1e-6) / 512) * 1e6)) print '\nThe time delay is about', j1, 'microseconds \n' print 'Starting the calculation...' tau_min = j0 - 1 tau_max = j0 + 1 delta_tau = 0.1 while delta_tau >= 5e-5: tau = tau_min tau_list = [] cj = [] while tau <= tau_max: im, re = Fraq_FFT(file_read(ifile), res, ims, tau, 1) cj.append(complex(re, im)) tau_list.append(tau) tau = tau + delta_tau cj = abs(np.asarray(cj)) number = max(izip(cj, count()))[1] tau = tau_list[number] tau_min = tau - delta_tau * 2 tau_max = tau + delta_tau * 2 if delta_tau == 1e-4: delta_tau = delta_tau / 2 else: delta_tau = delta_tau / 10 tau = tau / 512 tau = float("%.7f" % (tau)) sys.stdout.write(' accumulation periods have been processed...' + ('\r%d' % (j + 1) + '/' + str(acc_periods))) sys.stdout.flush() li.append(tau) if dbg == 'true': xlist.append(j * 0.5) axar[1].cla() plt.pause(0.001) axar[1].plot(xlist, np.asarray(li) * 1e6, 'o') axar[1].grid() axar[1].set_xlabel(u'время, с') axar[1].set_ylabel(u'задержка, пс') plt.gcf().canvas.set_window_title(ifile) plt.draw() tau = "%.7f" % (np.mean(li)) print '\nAnd the clarified time delay is', tau, 'microseconds' if dbg == 'true': plt.gcf().canvas.set_window_title(ifile) if qwerty == '0': plt.show(block=False) elif qwerty == '1': plt.show() if write == 'true': name = ifile + '_delays.txt' f = open(name, 'w') for k in range(len(li)): f.write(str(li[k])) f.write('\n') return li
def der_hil(u0, expconsts, k, n): #n is the number of derivatives to take; n=1 is a first derivative return ifft(-1j * np.sign(k) * expconsts**n * fft(u0))
g_k = np.concatenate((g, np.zeros(f.shape[0] - g.shape[0]))) F, G_k = fft(f), fft(g_k) # observations C = (F * G_k) + 0.0 * fft(np.random.rand(*F.shape)) F_k = F + 0.0 * np.random.rand(*F.shape) for k in range(int(max_its)): G_k1 = update_g(F_k, G_k, C) F_k1 = update_f(F_k, G_k, C) print("MSE_f = {}".format(norm(F - F_k) / norm(F))) #print("MSE_g = {}".format(norm(G - G_k) / norm(G))) F_k = F_k1 G_k = G_k1 c, f_k, g_k = ifft(C), ifft(ifft(F_k)), ifft(G_k) plt.figure() plt.subplot(2, 2, 1) plt.plot(t, f, label='Ground truth') plt.plot(t, ifft(C), label='Observations') plt.legend(loc='best') plt.subplot(2, 2, 2) plt.plot(t, np.abs(f_k), label='Estimation') plt.legend(loc='best') plt.subplot(2, 2, 3) plt.plot(g, label='Ground truth') plt.legend(loc='best')
def freqSDoF(M, C, K, F, dT): force_DFT = fft(F) freq = 2.0*pi*fftfreq(len(F),dT) Hw = 1/(-M*freq**2+C*freq*1j+K) response_DFT = Hw*force_DFT return real(ifft(response_DFT)),real(ifft((0+freq*1j)*response_DFT)),real(ifft((0+freq*1j)**2*response_DFT))
#Window length nw = 30 n = len(y) t = (np.arange(0, 2 * nw) - (nw)) / nw / 2 w = np.exp(-np.power(t, 2) * 18) w = np.concatenate([w[nw:], np.zeros(n + nw * 2), w[:nw]]) W = toeplitz(w) W = W[:n, :n] / np.linalg.norm(w) # # Sparse Time-Frequency representation f, u = sparseTF(y, W, epsilon, gamma, verbose=True, cgIter=cgIter) # Signal reconstruction from TF domain yrec = np.real(np.sum(W * ifft(f, axis=0), keepdims=True, axis=1)) #%% fig, (ax, ax1, ax2) = plt.subplots(3, 1, figsize=(7, 8)) t = np.arange(n) fmin = 0 nyqn = n // 2 ax.plot(t, y, 'k', lw=1) ax.set_title('Signal', fontsize=16) ax.set_xticks([]) ax.set_xlim(0, n) ax1.imshow(abs(f[nyqn + 1:, :]),
# dydx3 = derivative(f, x, dx=dx, order=3) # dydx5 = derivative(f, x, dx=dx, order=5) # dydx7 = derivative(f, x, dx=dx, order=7) from numpy import gradient grad = gradient(y, x) from numpy.fft import fft, ifft, ifftshift, fftshift, fftfreq N = int((np.abs(xleft) + np.abs(xright)) / dx) if N != x.size: raise ValueError("N != x.size") nu = fftfreq(N, dx) kx = 1j * 2 * np.pi * nu grad_fft = ifft(kx * fft(y)).real if SHIFT_GRID: x -= x0 ax.plot(x, y, label='y=f(x)') # ax.plot(x, dydx3, '-*', label='y=f\'(x) order=3 scipy') # ax.plot(x, dydx5, '-*', label='y=f\'(x) order=5 scipy') # ax.plot(x, dydx7, '-*', label='y=f\'(x) order=7 scipy') ax.plot(x, grad, '-', label='y=f\'(x) numpy') ax.plot(x, grad_fft, '-', label='y=f\'(x) fft') ax.legend() ax.grid() # ax.text(xleft, a-.65, f"A = {a}\nx0 = {x0}\nw = {wx}") # 2-мерный график if MODE == 2: ax = plt.axes(projection='3d')
def update_f(F, G, C): G_rev = fft(ifft(G)[::-1]) F_k1 = (C / (F * G)) * G_rev * F return ifft(F_k1)
def whiten(self, string): str_fft = fft(string, axis=1) spectrum = np.sqrt(np.mean(np.absolute(str_fft)**2)) return np.absolute(ifft(str_fft * (1. / spectrum), axis=1))
def minimum_phase(h, method='homomorphic', n_fft=None): """Convert a linear-phase FIR filter to minimum phase Parameters ---------- h : array Linear-phase FIR filter coefficients. method : {'hilbert', 'homomorphic'} The method to use: 'homomorphic' (default) This method [4]_ [5]_ works best with filters with an odd number of taps, and the resulting minimum phase filter will have a magnitude response that approximates the square root of the the original filter's magnitude response. 'hilbert' This method [1]_ is designed to be used with equiripple filters (e.g., from `remez`) with unity or zero gain regions. n_fft : int The number of points to use for the FFT. Should be at least a few times larger than the signal length (see Notes). Returns ------- h_minimum : array The minimum-phase version of the filter, with length ``(length(h) + 1) // 2``. See Also -------- firwin firwin2 remez Notes ----- Both the Hilbert [1]_ or homomorphic [4]_ [5]_ methods require selection of an FFT length to estimate the complex cepstrum of the filter. In the case of the Hilbert method, the deviation from the ideal spectrum ``epsilon`` is related to the number of stopband zeros ``n_stop`` and FFT length ``n_fft`` as:: epsilon = 2. * n_stop / n_fft For example, with 100 stopband zeros and a FFT length of 2048, ``epsilon = 0.0976``. If we conservatively assume that the number of stopband zeros is one less than the filter length, we can take the FFT length to be the next power of 2 that satisfies ``epsilon=0.01`` as:: n_fft = 2 ** int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01))) This gives reasonable results for both the Hilbert and homomorphic methods, and gives the value used when ``n_fft=None``. Alternative implementations exist for creating minimum-phase filters, including zero inversion [2]_ and spectral factorization [3]_ [4]_. For more information, see: http://dspguru.com/dsp/howtos/how-to-design-minimum-phase-fir-filters Examples -------- Create an optimal linear-phase filter, then convert it to minimum phase: >>> from scipy.signal import remez, minimum_phase, freqz, group_delay >>> import matplotlib.pyplot as plt >>> freq = [0, 0.2, 0.3, 1.0] >>> desired = [1, 0] >>> h_linear = remez(151, freq, desired, fs=2.) Convert it to minimum phase: >>> h_min_hom = minimum_phase(h_linear, method='homomorphic') >>> h_min_hil = minimum_phase(h_linear, method='hilbert') Compare the three filters: >>> fig, axs = plt.subplots(4, figsize=(4, 8)) >>> for h, style, color in zip((h_linear, h_min_hom, h_min_hil), ... ('-', '-', '--'), ('k', 'r', 'c')): ... w, H = freqz(h) ... w, gd = group_delay((h, 1)) ... w /= np.pi ... axs[0].plot(h, color=color, linestyle=style) ... axs[1].plot(w, np.abs(H), color=color, linestyle=style) ... axs[2].plot(w, 20 * np.log10(np.abs(H)), color=color, linestyle=style) ... axs[3].plot(w, gd, color=color, linestyle=style) >>> for ax in axs: ... ax.grid(True, color='0.5') ... ax.fill_between(freq[1:3], *ax.get_ylim(), color='#ffeeaa', zorder=1) >>> axs[0].set(xlim=[0, len(h_linear) - 1], ylabel='Amplitude', xlabel='Samples') >>> axs[1].legend(['Linear', 'Min-Hom', 'Min-Hil'], title='Phase') >>> for ax, ylim in zip(axs[1:], ([0, 1.1], [-150, 10], [-60, 60])): ... ax.set(xlim=[0, 1], ylim=ylim, xlabel='Frequency') >>> axs[1].set(ylabel='Magnitude') >>> axs[2].set(ylabel='Magnitude (dB)') >>> axs[3].set(ylabel='Group delay') >>> plt.tight_layout() References ---------- .. [1] N. Damera-Venkata and B. L. Evans, "Optimal design of real and complex minimum phase digital FIR filters," Acoustics, Speech, and Signal Processing, 1999. Proceedings., 1999 IEEE International Conference on, Phoenix, AZ, 1999, pp. 1145-1148 vol.3. :doi:`10.1109/ICASSP.1999.756179` .. [2] X. Chen and T. W. Parks, "Design of optimal minimum phase FIR filters by direct factorization," Signal Processing, vol. 10, no. 4, pp. 369-383, Jun. 1986. .. [3] T. Saramaki, "Finite Impulse Response Filter Design," in Handbook for Digital Signal Processing, chapter 4, New York: Wiley-Interscience, 1993. .. [4] J. S. Lim, Advanced Topics in Signal Processing. Englewood Cliffs, N.J.: Prentice Hall, 1988. .. [5] A. V. Oppenheim, R. W. Schafer, and J. R. Buck, "Discrete-Time Signal Processing," 2nd edition. Upper Saddle River, N.J.: Prentice Hall, 1999. """ # noqa 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 1-D 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) if not isinstance(method, str) or method not in \ ('homomorphic', 'hilbert',): raise ValueError('method must be "homomorphic" or "hilbert", got %r' % (method, )) if n_fft is None: n_fft = 2**int(np.ceil(np.log2(2 * (len(h) - 1) / 0.01))) n_fft = int(n_fft) if n_fft < len(h): raise ValueError('n_fft must be at least len(h)==%s' % len(h)) if method == 'hilbert': w = np.arange(n_fft) * (2 * np.pi / n_fft * n_half) H = np.real(fft(h, n_fft) * np.exp(1j * w)) dp = max(H) - 1 ds = 0 - min(H) S = 4. / (np.sqrt(1 + dp + ds) + np.sqrt(1 - dp + ds))**2 H += ds H *= S H = np.sqrt(H, out=H) H += 1e-10 # ensure that the log does not explode h_minimum = _dhtm(H) else: # method == 'homomorphic' # 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 apply_taper(complex_array, taper): # Use fft for vis -> lag and ifft for lag -> vis return ifft(fft(complex_array, axis=1)*(fftshift(taper)[newaxis,:,newaxis]),axis=1)
def pattern_1d(N_sim=1024, FOV=20, N_mri=100, omega=0.5, phi=0, rect_shape=True, beta=0.05, fwhm_bold=1.02, fwhm_noise=0.001, a_mask=1000, b_mask=1000): """ This function geometrical stripe pattern in 1D. The rest is similar to the stripe pattern generation in 2D. Inputs: *N_sim: array size of the simulated patch (use only even integers). *FOV: field of view (mm). *N_mri: array size of the MR image. *omega: frequency in cycles/mm. *phi: phase in deg. *theta: rotation angle in deg. *rect_shape (boolean): rectangular or sine pattern. *beta: maximal BOLD response corresponding to neural response of 1. *fwhm_bold: BOLD point-spread width in mm. *fwhm_noise: measurement noise of BOLD response. *a_mask: left side length of mask. *b_mask: right side length of mask. Outputs: *pattern_img: neural map. *y_img: BOLD response with measurement noise. *ymri_img: sampled MRI signal. *F_bold_fft: BOLD filter in spatial frequency representation. created by Daniel Haenelt Date created: 07-01-2019 Last modified: 07-01-2019 """ # add path of the executed script to the interpreter's search path import sys sys.path.append(sys.argv[0]) import numpy as np from numpy.fft import fft, ifft from lib.simulation.get_white import get_white_1d from lib.simulation.filter_bold import filter_bold_1d from lib.simulation.mask_pattern import mask_pattern_1d # generate geometrical pattern x = np.linspace(0, FOV, N_sim) # convert phase from deg to rad phi = np.radians(phi) pattern_img = np.cos(2 * np.pi * omega * x + phi) # generate rect or sine pattern if rect_shape: pattern_img[pattern_img > 0] = 1 pattern_img[pattern_img != 1] = -1 # BOLD response F_bold_fft = filter_bold_1d(N_sim, FOV, fwhm_bold, beta) y_img = np.real(ifft(fft(pattern_img) * F_bold_fft)) # add measurement noise noise_img = get_white_1d(N_sim, 0, fwhm_noise / (2 * np.sqrt(2 * np.log(2)))) y_img = noise_img + y_img # voxel sampling y_fft = fft(y_img) k_sample = np.round(N_mri / 2).astype(int) ymri_fft = np.zeros(N_mri, dtype=complex) ymri_fft[:k_sample] = y_fft[:k_sample] ymri_fft[-1:-k_sample - 1:-1] = y_fft[-1:-k_sample - 1:-1] ymri_img = np.real(ifft(ymri_fft)) # mask voxel sampling ymri_img = ymri_img * mask_pattern_1d(len(ymri_img), a_mask, b_mask) return pattern_img, y_img, ymri_img, F_bold_fft
def rhs_advection1D_periodic(self, q): c = self.advection_speed K = self.geom.K[0] qhat = fft(q) qhat_x = K * qhat * (1j) return -c * np.real(ifft(qhat_x))
plt.subplot(311) y = 75 * np.sin(omg * 250 * t) + 100 * np.sin(omg * 5 * t) + 15 * np.cos( omg * 10 * t) + 50 * np.cos(omg * 400 * t) plt.plot(t, y) freqs = fftfreq(N) mask = freqs > 0 fft_vals = np.asarray(fft(y)) actual_fft = 2.0 * np.abs(fft_vals / N) FFT = actual_fft plt.subplot(312) plt.plot(fft_vals) plt.subplot(313) plt.plot(ifft(fft_vals)) print(ifft(fft_vals)) f = np.arange(0, 1000) def step(f): low_filter = np.zeros(len(f)) ind = np.where((f > 75) & (f < 350)) low_filter[ind] = 1 ind2 = np.where((f > 650) & (f < 925)) low_filter[ind2] = 1 return low_filter
def window_ifft(Magcom, window): """windows the data before applying an ifft""" return fft.ifft(Magcom * window)