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_scalar(self, P_in, X, nu, P_window=None, C_window=None): pf, p, g_m, g_n, two_part_l, h_l = X if self.low_extrap is not None: P_in = self.EK.extrap_P_low(P_in) if self.high_extrap is not None: P_in = self.EK.extrap_P_high(P_in) P_b = P_in * self.k_old**(-nu) if self.n_pad is not None: 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) # We always filter the Fourier coefficients, so the last element is zero. # But in case someone does not filter, divide the end point by two 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 damp 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((pf.shape[0], self.k_size)) for i in range(pf.shape[0]): # 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 * g_m[i, :], c_m * g_n[i, :]) # multiply all l terms together C_l = C_l * h_l[i, :] * 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]) * pf[i] * self.k**(-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**nu * float(self.N) if self.n_pad is not None: # 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 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 J_k_scalar(self,P_in,X,nu,P_window=None,C_window=None): pf, p, g_m, g_n, two_part_l, h_l=X if(self.low_extrap is not None): P_in=self.EK.extrap_P_low(P_in) if(self.high_extrap is not None): P_in=self.EK.extrap_P_high(P_in) P_b=P_in*self.k_old**(-nu) if (self.n_pad is not None): 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) # We always filter the Fourier coefficients, so the last element is zero. # But in case someone does not filter, divide the end point by two 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 damp 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((pf.shape[0],self.k_size)) for i in range(pf.shape[0]): # 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*g_m[i,:],c_m*g_n[i,:]) # multiply all l terms together C_l=C_l*h_l[i,:]*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])*pf[i]*self.k**(-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**nu*float(self.N) if (self.n_pad is not None): # 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 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(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