def RG_STS(STS_params,name,k,P,d_lambda,max,n_pad,P_window,C_window): stage, mu, dlambda_CFL=STS_params #save name name='RG_STS_'+name print('save name=', name) # The spacing in log(k) Delta=np.log(k[1])-np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to STS # You could change it here. W=p_window(k,P_window[0],P_window[1]) #W=1 t1=time.time() # windowed initial power spectrum P_0=P*W # standard 1-loop parameters nu=-2 fastpt=FASTPT.FASTPT(k,nu=nu,n_pad=n_pad) P_spt=fastpt.one_loop(P_0,C_window=C_window) P_spt=P_0+P_spt # initial lambda Lambda=0 d_out=np.zeros((3,k.size+1)) d_out[0,:]=np.append(Lambda,k) d_out[2,:]=np.append(Lambda,P_0) d_out[1,:]=np.append(Lambda,P_spt) dt_j=np.zeros(stage) for j in range(stage): arg =np.pi*(2*j-1)/(2*stage) dt_j[j]=(dlambda_CFL)*((1.+mu)-(1.-mu)*np.cos(arg))**(-1.) i=0 while (Lambda <= max): t_step =0 for j in range(stage): K=fastpt.one_loop(P,C_window=C_window) K=K*W P=P+ dt_j[j]*K t_step=t_step+dt_j[j] d_lambda=t_step # check for failure. if (np.any(np.isnan(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') print('iteration number and lambda', i, Lambda) sys.exit() if (np.any(np.isinf(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') print('iteration number and lambda', i, Lambda) sys.exit() #update lambda and the iteration i=i+1 Lambda+=d_lambda # break if the next step is already passed lambda max if (Lambda >=max): break #print('lambda', Lambda ) # update data for saving d_update=np.append(Lambda,P) d_out=np.row_stack((d_out,d_update)) # set to True to check at each step if(False): ax=plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k,P) ax.plot(k,P_0, color='red') plt.grid() plt.show() ''' Since STS method computes its own Delta Lambda. So,this routine will not end exaclty at max. Therefore, take Euler steps to reach the end ''' last_step=np.absolute(Lambda-d_lambda-max) #print('Lambda', Lambda-d_lambda) #print('last step', last_step) k1=fastpt.one_loop(P,C_window=C_window) k1=k1*W k2=fastpt.one_loop(k1*last_step/2.+ P,C_window=C_window) k2=k2*W k3=fastpt.one_loop(k2*last_step/2. +P,C_window=C_window) k3=k3*W k4=fastpt.one_loop(k3*last_step +P,C_window=C_window) k4=k4*W # full step P=P+1/6.*(k1+2*k2+2*k3+k4)*last_step Lambda=Lambda-d_lambda+last_step # update data for saving d_update=np.append(Lambda,P) d_out=np.row_stack((d_out,d_update)) # save the data t2=time.time() print('time to run seconds', t2-t1) print('time to run minutes', (t2-t1)/60.) print('iteration', i ) print('save name', name) print('shape', d_out.shape) np.save(name,d_out) print('number of iterations and output shape', i, d_out.shape) # return last step return P
def J_k(k, P, param_matrix, nu=-2, P2=None, P_window=None, C_window=None, n_pad=500, verbose=False): # size of input array must be an even number if (k.size % 2 != 0): raise ValueError( 'Input array must contain an even number of elements.') alpha = param_matrix[:, 0] beta = param_matrix[:, 1] l_Bessel = param_matrix[:, 2] type = param_matrix[:, 3] N = k.size delta_L = (log(np.max(k)) - log(np.min(k))) / (N - 1) P_b = P * k**(-nu) if P_window is not None: # window the input power spectrum, so that at high and low k # the signal smoothly tappers to zero. This make the input # more "like" a periodic signal if (verbose): print('smoothing biased power spectrum') W = p_window(k, P_window[0], P_window[1]) P_b = P_b * W if (n_pad != None): # pad the edges. This helps with edge effects in Fourier space if (verbose): print('padding the input signal with'), n_pad, 'zeros.' id_pad = np.arange(k.size) k, P_b = pad_left(k, P_b, n_pad) _, P = pad_left(k, P, n_pad) k, P_b = pad_right(k, P_b, n_pad) _, P = pad_right(k, P, n_pad) N = k.size id_pad = id_pad + n_pad # I take the real Fourier transform and then take the conjugate to # obtain the negative frequencies. The convolution latter in the code requires # the negative frequencies. c_m_positive = rfft(P_b) c_m_negative = np.conjugate(c_m_positive[1:]) c_m = np.hstack((c_m_negative[::-1], c_m_positive)) / float(N) # frequency integers n_c = c_m_positive.size m = np.arange(-n_c + 1, n_c) # define eta_m and eta_n=eta_m omega = 2 * pi / (float(N) * delta_L) eta_m = omega * m # define l and tau_l n_l = c_m.size + c_m.size - 1 l = l = np.arange(-n_l // 2 + 1, n_l // 2 + 1) tau_l = omega * l if (C_window != None): # window the Fourier coefficients. # This will damping the highest frequencies if (verbose): print('smoothing the Fourier coefficients') c_m = c_m * c_window(m, int(C_window * N // 2.)) # matrix for output A_out = np.zeros((param_matrix.shape[0], k.size)) for i in range(param_matrix.shape[0]): sigma = l_Bessel[i] + 1 / 2. # Define Q_m and Q_n and p # use eta_m for Q_n, the value is the same Q_m = 3 / 2. + nu + alpha[i] + 1j * eta_m Q_n = 3 / 2. + nu + beta[i] + 1j * eta_m p = -5 - 2 * nu - alpha[i] - beta[i] g_m = g_m_vals(sigma, Q_m) if (type[i] == 1): # this is the special case, Corresponding to the regularized version of # J_{2,-2,0,reg}(k) # get values for g_n # again use eta_m. s = 2 + nu + beta[i] Q_n = s + 1j * eta_m g_n = gamsn(Q_n) #two_part_m=2**Q_m g_m = g_m * 2.**Q_m # prefactor pf = (-1)**l_Bessel[i] / pi**3 * np.sqrt(pi / 2.) two_part_l = 1 else: g_n = g_m_vals(sigma, Q_n) # pre factor pf = (-1)**l_Bessel[i] / pi**2 * 2.**(2 + 2 * nu + alpha[i] + beta[i]) two_part_l = exp(1j * tau_l * log2) # convolve f_c and g_c C_l = np.convolve(c_m * g_m, c_m * g_n) # calculate h_l #arg=(p+1-1j*tau_l) h_l = gamsn(p + 1 - 1j * tau_l) # multiply all l terms together C_l = C_l * h_l * two_part_l # set up to feed ifft an array ordered with l=0,1,...,-1,...,N/2-1 c_plus = C_l[l >= 0] c_minus = C_l[l < 0] C_l = np.hstack((c_plus[:-1], c_minus)) A_k = ifft( C_l ) * C_l.size # multiply by size to get rid of the normalization in ifft A_out[i, :] = np.real(A_k[::2]) * pf * k**( -p - 2) # note that you have to take every other element # in A_k, due to the extended array created from the # discrete convolution P_out = irfft(c_m[m >= 0]) * k**nu * float(N) if (n_pad != 0): # get rid of the elements created from padding P_out = P_out[id_pad] A_out = A_out[:, id_pad] return P_out, A_out
def RG_STS(STS_params, name, k, P, d_lambda, max, n_pad, P_window, C_window): stage, mu, dlambda_CFL = STS_params #save name name = 'RG_STS_' + name print('save name=', name) # The spacing in log(k) Delta = np.log(k[1]) - np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to STS # You could change it here. W = p_window(k, P_window[0], P_window[1]) #W=1 t1 = time.time() # windowed initial power spectrum P_0 = P * W # standard 1-loop parameters nu = -2 fastpt = FASTPT.FASTPT(k, nu=nu, n_pad=n_pad) P_spt = fastpt.one_loop(P_0, C_window=C_window) P_spt = P_0 + P_spt # initial lambda Lambda = 0 d_out = np.zeros((3, k.size + 1)) d_out[0, :] = np.append(Lambda, k) d_out[2, :] = np.append(Lambda, P_0) d_out[1, :] = np.append(Lambda, P_spt) dt_j = np.zeros(stage) for j in range(stage): arg = np.pi * (2 * j - 1) / (2 * stage) dt_j[j] = (dlambda_CFL) * ((1. + mu) - (1. - mu) * np.cos(arg))**(-1.) i = 0 while (Lambda <= max): t_step = 0 for j in range(stage): K = fastpt.one_loop(P, C_window=C_window) K = K * W P = P + dt_j[j] * K t_step = t_step + dt_j[j] d_lambda = t_step # check for failure. if (np.any(np.isnan(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') print('iteration number and lambda', i, Lambda) sys.exit() if (np.any(np.isinf(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') print('iteration number and lambda', i, Lambda) sys.exit() #update lambda and the iteration i = i + 1 Lambda += d_lambda # break if the next step is already passed lambda max if (Lambda >= max): break #print('lambda', Lambda ) # update data for saving d_update = np.append(Lambda, P) d_out = np.row_stack((d_out, d_update)) # set to True to check at each step if (False): ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k, P) ax.plot(k, P_0, color='red') plt.grid() plt.show() ''' Since STS method computes its own Delta Lambda. So,this routine will not end exaclty at max. Therefore, take Euler steps to reach the end ''' last_step = np.absolute(Lambda - d_lambda - max) #print('Lambda', Lambda-d_lambda) #print('last step', last_step) k1 = fastpt.one_loop(P, C_window=C_window) k1 = k1 * W k2 = fastpt.one_loop(k1 * last_step / 2. + P, C_window=C_window) k2 = k2 * W k3 = fastpt.one_loop(k2 * last_step / 2. + P, C_window=C_window) k3 = k3 * W k4 = fastpt.one_loop(k3 * last_step + P, C_window=C_window) k4 = k4 * W # full step P = P + 1 / 6. * (k1 + 2 * k2 + 2 * k3 + k4) * last_step Lambda = Lambda - d_lambda + last_step # update data for saving d_update = np.append(Lambda, P) d_out = np.row_stack((d_out, d_update)) # save the data t2 = time.time() print('time to run seconds', t2 - t1) print('time to run minutes', (t2 - t1) / 60.) print('iteration', i) print('save name', name) print('shape', d_out.shape) np.save(name, d_out) print('number of iterations and output shape', i, d_out.shape) # return last step return P
def J_k_tensor(self, P, X, P_window=None, C_window=None): pf, p, nu1, nu2, g_m, g_n, h_l = X if self.low_extrap is not None: P = self.EK.extrap_P_low(P) if self.high_extrap is not None: P = self.EK.extrap_P_high(P) A_out = np.zeros((pf.size, self.k_size)) P_fin = np.zeros(self.k_size) for i in range(pf.size): P_b1 = P * self.k_old**(-nu1[i]) P_b2 = P * self.k_old**(-nu2[i]) if P_window != None: # window the input power spectrum, so that at high and low k # the signal smoothly tappers to zero. This make the input # more "like" a periodic signal if self.verbose: print('windowing biased power spectrum') W = p_window(self.k_old, P_window[0], P_window[1]) P_b1 = P_b1 * W P_b2 = P_b2 * W if self.n_pad != 0: P_b1 = np.pad(P_b1, pad_width=(self.n_pad, self.n_pad), mode='constant', constant_values=0) P_b2 = np.pad(P_b2, pad_width=(self.n_pad, self.n_pad), mode='constant', constant_values=0) c_m_positive = rfft(P_b1) c_n_positive = rfft(P_b2) c_m_negative = np.conjugate(c_m_positive[1:]) c_n_negative = np.conjugate(c_n_positive[1:]) c_m = np.hstack((c_m_negative[::-1], c_m_positive)) / float(self.N) c_n = np.hstack((c_n_negative[::-1], c_n_positive)) / float(self.N) if C_window != None: # window the Fourier coefficients. # This will damping the highest frequencies if self.verbose: print('windowing the Fourier coefficients') c_m = c_m * c_window(self.m, int(C_window * self.N / 2.)) c_n = c_n * c_window(self.m, int(C_window * self.N / 2.)) # convolve f_c and g_c C_l = fftconvolve(c_m * g_m[i, :], c_n * g_n[i, :]) # C_l=convolve(c_m*self.g_m[i,:],c_m*self.g_n[i,:]) # multiply all l terms together # C_l=C_l*self.h_l[i,:]*self.two_part_l[i] C_l = C_l * h_l[i, :] # set up to feed ifft an array ordered with l=0,1,...,-1,...,N/2-1 c_plus = C_l[self.l >= 0] c_minus = C_l[self.l < 0] C_l = np.hstack((c_plus[:-1], c_minus)) A_k = ifft( C_l ) * C_l.size # multiply by size to get rid of the normalization in ifft A_out[i, :] = np.real(A_k[::2]) * pf[i] * self.k**(p[i]) # note that you have to take every other element # in A_k, due to the extended array created from the # discrete convolution P_fin += A_out[i, :] # P_out=irfft(c_m[self.m>=0])*self.k**self.nu*float(self.N) if self.n_pad != 0: # get rid of the elements created from padding # P_out=P_out[self.id_pad] A_out = A_out[:, self.id_pad] P_fin = P_fin[self.id_pad] return P_fin, A_out
def J_k(k,P,param_matrix,nu=-2,P2=None,P_window=None, C_window=None,n_pad=500,verbose=False): # size of input array must be an even number if (k.size % 2 != 0): raise ValueError('Input array must contain an even number of elements.') alpha=param_matrix[:,0] beta=param_matrix[:,1] l_Bessel=param_matrix[:,2] type=param_matrix[:,3] N=k.size delta_L=(log(np.max(k))-log(np.min(k)))/(N-1) P_b=P*k**(-nu) if P_window is not None: # window the input power spectrum, so that at high and low k # the signal smoothly tappers to zero. This make the input # more "like" a periodic signal if (verbose): print('smoothing biased power spectrum') W=p_window(k,P_window[0],P_window[1]) P_b=P_b*W if (n_pad !=None): # pad the edges. This helps with edge effects in Fourier space if (verbose): print('padding the input signal with'), n_pad, 'zeros.' id_pad=np.arange(k.size) k,P_b=pad_left(k,P_b,n_pad) _,P=pad_left(k,P,n_pad) k,P_b=pad_right(k,P_b,n_pad) _,P=pad_right(k,P,n_pad) N=k.size id_pad=id_pad+n_pad # I take the real Fourier transform and then take the conjugate to # obtain the negative frequencies. The convolution latter in the code requires # the negative frequencies. c_m_positive=rfft(P_b) c_m_negative=np.conjugate(c_m_positive[1:]) c_m=np.hstack((c_m_negative[::-1], c_m_positive))/float(N) # frequency integers n_c=c_m_positive.size m=np.arange(-n_c+1,n_c) # define eta_m and eta_n=eta_m omega=2*pi/(float(N)*delta_L) eta_m=omega*m # define l and tau_l n_l=c_m.size + c_m.size - 1 l=l=np.arange(-n_l//2+1,n_l//2+1) tau_l=omega*l if (C_window != None): # window the Fourier coefficients. # This will damping the highest frequencies if (verbose): print('smoothing the Fourier coefficients') c_m=c_m*c_window(m,int(C_window*N//2.)) # matrix for output A_out=np.zeros((param_matrix.shape[0],k.size)) for i in range(param_matrix.shape[0]): sigma=l_Bessel[i]+1/2. # Define Q_m and Q_n and p # use eta_m for Q_n, the value is the same Q_m=3/2.+ nu + alpha[i] + 1j*eta_m Q_n=3/2.+ nu + beta[i] + 1j*eta_m p=-5-2*nu-alpha[i]-beta[i] g_m=g_m_vals(sigma,Q_m) if (type[i]==1): # this is the special case, Corresponding to the regularized version of # J_{2,-2,0,reg}(k) # get values for g_n # again use eta_m. s=2+nu + beta[i] Q_n=s+ 1j*eta_m g_n=gamsn(Q_n) #two_part_m=2**Q_m g_m=g_m*2.**Q_m # prefactor pf=(-1)**l_Bessel[i]/pi**3*np.sqrt(pi/2.) two_part_l=1 else: g_n=g_m_vals(sigma,Q_n) # pre factor pf=(-1)**l_Bessel[i]/pi**2*2.**(2+2*nu+alpha[i]+beta[i]) two_part_l=exp(1j*tau_l*log2) # convolve f_c and g_c C_l=np.convolve(c_m*g_m,c_m*g_n) # calculate h_l #arg=(p+1-1j*tau_l) h_l=gamsn(p+1-1j*tau_l) # multiply all l terms together C_l=C_l*h_l*two_part_l # set up to feed ifft an array ordered with l=0,1,...,-1,...,N/2-1 c_plus=C_l[l>=0] c_minus=C_l[l< 0] C_l=np.hstack((c_plus[:-1],c_minus)) A_k=ifft(C_l)*C_l.size # multiply by size to get rid of the normalization in ifft A_out[i,:]=np.real(A_k[::2])*pf*k**(-p-2) # note that you have to take every other element # in A_k, due to the extended array created from the # discrete convolution P_out=irfft(c_m[m>=0])*k**nu*float(N) if (n_pad !=0): # get rid of the elements created from padding P_out=P_out[id_pad] A_out=A_out[:,id_pad] return P_out, A_out
def J_k_tensor(self,P,X,P_window=None,C_window=None): pf, p, nu1, nu2, g_m, g_n, h_l=X if(self.low_extrap is not None): P=self.EK.extrap_P_low(P) if(self.high_extrap is not None): P=self.EK.extrap_P_high(P) A_out=np.zeros((pf.size,self.k_size)) P_fin=np.zeros(self.k_size) for i in range(pf.size): P_b1=P*self.k_old**(-nu1[i]) P_b2=P*self.k_old**(-nu2[i]) if (P_window != None): # window the input power spectrum, so that at high and low k # the signal smoothly tapers to zero. This makes the input # more like a periodic signal if (self.verbose): print('windowing biased power spectrum') W=p_window(self.k_old,P_window[0],P_window[1]) P_b1=P_b1*W P_b2=P_b2*W if (self.n_pad !=0): P_b1=np.pad(P_b1, pad_width=(self.n_pad,self.n_pad), mode='constant', constant_values=0) P_b2=np.pad(P_b2, pad_width=(self.n_pad,self.n_pad), mode='constant', constant_values=0) c_m_positive=rfft(P_b1) c_n_positive=rfft(P_b2) c_m_negative=np.conjugate(c_m_positive[1:]) c_n_negative=np.conjugate(c_n_positive[1:]) c_m=np.hstack((c_m_negative[::-1], c_m_positive))/float(self.N) c_n=np.hstack((c_n_negative[::-1], c_n_positive))/float(self.N) if (C_window != None): # window the Fourier coefficients. # This will damping the highest frequencies if (self.verbose): print('windowing the Fourier coefficients') c_m=c_m*c_window(self.m,int(C_window*self.N/2.)) c_n=c_n*c_window(self.m,int(C_window*self.N/2.)) # convolve f_c and g_c C_l=fftconvolve(c_m*g_m[i,:],c_n*g_n[i,:]) #C_l=convolve(c_m*self.g_m[i,:],c_m*self.g_n[i,:]) # multiply all l terms together #C_l=C_l*self.h_l[i,:]*self.two_part_l[i] C_l=C_l*h_l[i,:] # set up to feed ifft an array ordered with l=0,1,...,-1,...,N/2-1 c_plus=C_l[self.l>=0] c_minus=C_l[self.l< 0] C_l=np.hstack((c_plus[:-1],c_minus)) A_k=ifft(C_l)*C_l.size # multiply by size to get rid of the normalization in ifft A_out[i,:]=np.real(A_k[::2])*pf[i]*self.k**(p[i]) # note that you have to take every other element # in A_k, due to the extended array created from the # discrete convolution P_fin += A_out[i,:] # P_out=irfft(c_m[self.m>=0])*self.k**self.nu*float(self.N) if (self.n_pad !=0): # get rid of the elements created from padding # P_out=P_out[self.id_pad] A_out=A_out[:,self.id_pad] P_fin=P_fin[self.id_pad] return P_fin, A_out
def RG_RK4_filt(name, k, P, d_lambda, max, n_pad, P_window, C_window): x = max / d_lambda - int(max / d_lambda) if (x != 0.0): raise ValueError( 'You need to send a d_lambda step so that max/d_lambda has no remainder to reach Lambda=max' ) #save name name = 'RG_RK4_filt_' + name # The spacing in log(k) Delta = np.log(k[1]) - np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to each Runge-Kutta step. # You could change it here. W = p_window(k, P_window[0], P_window[1]) #W=1 t1 = time.time() # windowed initial power spectrum P_0 = P * W nu = -2 fastpt = FASTPT.FASTPT(k, nu, n_pad=n_pad) P_spt = fastpt.one_loop(P_0, C_window=C_window) P_spt = P_0 + P_spt # initial lambda Lambda = 0 d_out = np.zeros((3, k.size + 1)) d_out[0, 1:] = k d_out[2, 1:] = P_0 d_out[1, 1:] = P_spt # filtering specific k_start = 1 k_end = 5 id1 = np.where(k > k_end)[0] id2 = np.where(k <= k_end)[0] id3 = np.where(k > k_start)[0] #id4=np.where( k <= k_start)[0] id4 = np.where((k > k_start) & (k <= k_end))[0] order = 6 wn = .1 B, A = butter(order, wn, btype='low', analog=False) theta = np.linspace(1, 0, id4.size) W_fad = theta - 1 / 2. / np.pi * np.sin(2 * np.pi * theta) filt_pad = id3.size # end filtering specific def filt_zp(k, P_filt): def zero_phase(sig): sig = np.pad(sig, (filt_pad, filt_pad), 'constant', constant_values=(0, 0)) #zi=lfilter_zi(B,A) #x,_=lfilter(B,A,sig, zi=zi*sig[0]) x = lfilter(B, A, sig) #y,_=lfilter(B,A,x,zi=zi*x[0]) y = lfilter(B, A, x[::-1]) y = y[::-1] #return y return y[filt_pad:id3.size + filt_pad] P_smoothed = zero_phase(P_filt[id3]) P_patch = P_filt[id4] * W_fad P_filt[id3] = P_smoothed P_filt[id4] = P_patch + (1 - W_fad) * P_filt[id4] return P_filt i = 0 while Lambda <= max: k1 = fastpt.one_loop(P, C_window=C_window) k1 = filt_zp(k, k1) k2 = fastpt.one_loop(k1 * d_lambda / 2. + P, C_window=C_window) k2 = filt_zp(k, k2) k3 = fastpt.one_loop(k2 * d_lambda / 2. + P, C_window=C_window) k3 = filt_zp(k, k3) k4 = fastpt.one_loop(k3 * d_lambda + P, C_window=C_window) k4 = filt_zp(k, k4) # full Runge-Kutta step P = P + 1 / 6. * (k1 + 2 * k2 + 2 * k3 + k4) * d_lambda # check for failure. if (np.any(np.isnan(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') print('Failure at lambda =', Lambda) sys.exit() if (np.any(np.isinf(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') print('Failure at lambda =', Lambda) sys.exit() #update lambda and the iteration i = i + 1 Lambda += d_lambda # update data for saving d_update = np.append(Lambda, P) d_out = np.row_stack((d_out, d_update)) if (False): ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k, P) ax.plot(k, P_0, color='red') plt.grid() plt.show() # save the data t2 = time.time() print('time to run seconds', t2 - t1) print('time to run minutes', (t2 - t1) / 60.) print('number of iterations and output shape', i, d_out.shape) np.save(name, d_out) return P
def RG_RK4(name, k, P, d_lambda, max, n_pad, P_window, C_window): x = max / d_lambda - int(max / d_lambda) if (x != 0.0): raise ValueError( 'You need to send a d_lambda step so that max/d_lambda has no remainder to reach Lambda=max' ) #save name name = 'RG_RK4_' + name # The spacing in log(k) Delta = np.log(k[1]) - np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to each Runge-Kutta step. # You could change it here. W = p_window(k, P_window[0], P_window[1]) #W=1 t1 = time.time() # windowed initial power spectrum P_0 = P * W nu = -2 fastpt = FASTPT.FASTPT(k, nu=nu, n_pad=n_pad) P_spt = fastpt.one_loop(P_0, C_window=C_window) P_spt = P_0 + P_spt # initial lambda Lambda = 0 d_out = np.zeros((3, k.size + 1)) d_out[0, :] = np.append(Lambda, k) d_out[2, :] = np.append(Lambda, P_0) d_out[1, :] = np.append(Lambda, P_spt) i = 0 while (Lambda <= max): #for i in range(N_steps): k1 = fastpt.one_loop(P, C_window=C_window) k1 = k1 * W k2 = fastpt.one_loop(k1 * d_lambda / 2. + P, C_window=C_window) k2 = k2 * W k3 = fastpt.one_loop(k2 * d_lambda / 2. + P, C_window=C_window) k3 = k3 * W k4 = fastpt.one_loop(k3 * d_lambda + P, C_window=C_window) k4 = k4 * W # full step P = P + 1 / 6. * (k1 + 2 * k2 + 2 * k3 + k4) * d_lambda # check for failure. if (np.any(np.isnan(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') sys.exit() if (np.any(np.isinf(P))): print( 'RG flow has failed. It could be that you have not chosen a step size well.' ) print('You may want to consider a smaller step size.') sys.exit() #update lambda and the iteration i = i + 1 Lambda += d_lambda #print 'lambda', Lambda # update data for saving d_update = np.append(Lambda, P) d_out = np.row_stack((d_out, d_update)) # set to True to check at each step if (False): ax = plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k, P) ax.plot(k, P_0, color='red') plt.grid() plt.show() # save the data t2 = time.time() print('time to run seconds', t2 - t1) print('time to run minutes', (t2 - t1) / 60.) print('number of iterations and output shape', i, d_out.shape) np.save(name, d_out) # return last step return P
def J_k(self,P,P_window=None,C_window=None): if(self.low_extrap is not None): P=self.EK.extrap_P_low(P) if(self.high_extrap is not None): P=self.EK.extrap_P_high(P) P_b=P*self.k_old**(-self.nu) if P_window is not None: # window the input power spectrum, so that at high and low k # the signal smoothly tapers to zero. This make the input # more like a periodic signal if (self.verbose): print('windowing biased power spectrum') W=p_window(self.k_old,P_window[0],P_window[1]) P_b=P_b*W if (self.n_pad !=0): P_b=np.pad(P_b, pad_width=(self.n_pad,self.n_pad), mode='constant', constant_values=0) c_m_positive=rfft(P_b) # End point should be divided by two. However, we always filter the Fourier coefficients (the last element is set to # zero), so this really has no effect. c_m_positive[-1]=c_m_positive[-1]/2. c_m_negative=np.conjugate(c_m_positive[1:]) c_m=np.hstack((c_m_negative[::-1], c_m_positive))/float(self.N) if (C_window != None): # window the Fourier coefficients. # This will damping the highest frequencies if (self.verbose): print('windowing the Fourier coefficients') c_m=c_m*c_window(self.m,int(C_window*self.N//2.)) A_out=np.zeros((self.p_size,self.k_size)) for i in range(self.p_size): # convolve f_c and g_c #C_l=np.convolve(c_m*self.g_m[i,:],c_m*self.g_n[i,:]) C_l=fftconvolve(c_m*self.g_m[i,:],c_m*self.g_n[i,:]) # multiply all l terms together C_l=C_l*self.h_l[i,:]*self.two_part_l[i] # set up to feed ifft an array ordered with l=0,1,...,-1,...,N/2-1 c_plus=C_l[self.l>=0] c_minus=C_l[self.l< 0] C_l=np.hstack((c_plus[:-1],c_minus)) A_k=ifft(C_l)*C_l.size # multiply by size to get rid of the normalization in ifft A_out[i,:]=np.real(A_k[::2])*self.pf[i]*self.k**(-self.p[i]-2) # note that you have to take every other element # in A_k, due to the extended array created from the # discrete convolution P_out=irfft(c_m[self.m>=0])*self.k**self.nu*float(self.N) if (self.n_pad !=0): # get rid of the elements created from padding P_out=P_out[self.id_pad] A_out=A_out[:,self.id_pad] return P_out, A_out
def RG_RK4(name,k,P,d_lambda,max,n_pad,P_window,C_window): x=max/d_lambda-int(max/d_lambda) if ( x !=0.0 ): raise ValueError('You need to send a d_lambda step so that max/d_lambda has no remainder to reach Lambda=max') #save name name='RG_RK4_'+name # The spacing in log(k) Delta=np.log(k[1])-np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to each Runge-Kutta step. # You could change it here. W=p_window(k,P_window[0],P_window[1]) #W=1 t1=time.time() # windowed initial power spectrum P_0=P*W nu=-2 fastpt=FASTPT.FASTPT(k,nu=nu,n_pad=n_pad) P_spt=fastpt.one_loop(P_0,C_window=C_window) P_spt=P_0+P_spt # initial lambda Lambda=0 d_out=np.zeros((3,k.size+1)) d_out[0,:]=np.append(Lambda,k) d_out[2,:]=np.append(Lambda,P_0) d_out[1,:]=np.append(Lambda,P_spt) i=0 while (Lambda <= max): #for i in range(N_steps): k1=fastpt.one_loop(P,C_window=C_window) k1=k1*W k2=fastpt.one_loop(k1*d_lambda/2.+ P,C_window=C_window) k2=k2*W k3=fastpt.one_loop(k2*d_lambda/2. +P,C_window=C_window) k3=k3*W k4=fastpt.one_loop(k3*d_lambda +P,C_window=C_window) k4=k4*W # full step P=P+1/6.*(k1+2*k2+2*k3+k4)*d_lambda # check for failure. if (np.any(np.isnan(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') sys.exit() if (np.any(np.isinf(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') sys.exit() #update lambda and the iteration i=i+1 Lambda+=d_lambda #print 'lambda', Lambda # update data for saving d_update=np.append(Lambda,P) d_out=np.row_stack((d_out,d_update)) # set to True to check at each step if (False): ax=plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k,P) ax.plot(k,P_0, color='red') plt.grid() plt.show() # save the data t2=time.time() print('time to run seconds', t2-t1) print('time to run minutes', (t2-t1)/60.) print('number of iterations and output shape', i, d_out.shape) np.save(name,d_out) # return last step return P
def RG_RK4_filt(name,k,P,d_lambda,max,n_pad,P_window,C_window): x=max/d_lambda-int(max/d_lambda) if ( x !=0.0 ): raise ValueError('You need to send a d_lambda step so that max/d_lambda has no remainder to reach Lambda=max') #save name name='RG_RK4_filt_'+name # The spacing in log(k) Delta=np.log(k[1])-np.log(k[0]) # This window function tapers the edge of the power spectrum. # It is applied to each Runge-Kutta step. # You could change it here. W=p_window(k,P_window[0],P_window[1]) #W=1 t1=time.time() # windowed initial power spectrum P_0=P*W nu=-2 fastpt=FASTPT.FASTPT(k,nu=nu,n_pad=n_pad) P_spt=fastpt.one_loop(P_0,C_window=C_window) P_spt=P_0+P_spt # initial lambda Lambda=0 d_out=np.zeros((3,k.size+1)) d_out[0,1:]=k d_out[2,1:]=P_0 d_out[1,1:]=P_spt # filtering specific k_start=1; k_end=5 id1=np.where( k > k_end)[0] id2=np.where( k <= k_end)[0] id3=np.where( k > k_start)[0] #id4=np.where( k <= k_start)[0] id4=np.where( (k > k_start) & ( k<= k_end))[0] order=6; wn=.1 B,A=butter(order,wn, btype='low', analog=False) theta=np.linspace(1,0,id4.size) W_fad=theta - 1/2./np.pi*np.sin(2*np.pi*theta) filt_pad=id3.size # end filtering specific def filt_zp(k,P_filt): def zero_phase(sig): sig=np.pad(sig,(filt_pad,filt_pad), 'constant', constant_values=(0, 0)) #zi=lfilter_zi(B,A) #x,_=lfilter(B,A,sig, zi=zi*sig[0]) x=lfilter(B,A,sig) #y,_=lfilter(B,A,x,zi=zi*x[0]) y=lfilter(B,A,x[::-1]) y=y[::-1] #return y return y[filt_pad:id3.size+filt_pad] P_smoothed=zero_phase(P_filt[id3]) P_patch=P_filt[id4]*W_fad P_filt[id3]=P_smoothed P_filt[id4]=P_patch+(1-W_fad)*P_filt[id4] return P_filt i=0 while Lambda <= max: k1=fastpt.one_loop(P,C_window=C_window) k1=filt_zp(k,k1) k2=fastpt.one_loop(k1*d_lambda/2.+ P,C_window=C_window) k2=filt_zp(k,k2) k3=fastpt.one_loop(k2*d_lambda/2. +P,C_window=C_window) k3=filt_zp(k,k3) k4=fastpt.one_loop(k3*d_lambda +P,C_window=C_window) k4=filt_zp(k,k4) # full Runge-Kutta step P=P+1/6.*(k1+2*k2+2*k3+k4)*d_lambda # check for failure. if (np.any(np.isnan(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') print('Failure at lambda =', Lambda) sys.exit() if (np.any(np.isinf(P))): print('RG flow has failed. It could be that you have not chosen a step size well.') print('You may want to consider a smaller step size.') print('Failure at lambda =', Lambda) sys.exit() #update lambda and the iteration i=i+1 Lambda+=d_lambda # update data for saving d_update=np.append(Lambda,P) d_out=np.row_stack((d_out,d_update)) if(False): ax=plt.subplot(111) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel('k') ax.plot(k,P) ax.plot(k,P_0, color='red') plt.grid() plt.show() # save the data t2=time.time() print('time to run seconds', t2-t1) print('time to run minutes', (t2-t1)/60.) print('number of iterations and output shape', i, d_out.shape) np.save(name,d_out) return P