def fst(nx,ny,dx,dy,f): data = f[1:-1,1:-1] # e = dst(data, type=2) # data = dst(data, axis = 1, type = 1) # data = dst(data, axis = 0, type = 1) data = dstn(data, type = 1) # data = dstn(data, axis = 0, type = 1) m = np.linspace(1,nx-1,nx-1).reshape([-1,1]) n = np.linspace(1,ny-1,ny-1).reshape([1,-1]) data1 = np.zeros((nx-1,ny-1)) # for i in range(1,nx): # for j in range(1,ny): alpha = (2.0/(dx*dx))*(np.cos(np.pi*m/nx) - 1.0) + (2.0/(dy*dy))*(np.cos(np.pi*n/ny) - 1.0) data1 = data/alpha # u = idst(data1, type=2)/((2.0*nx)*(2.0*ny)) # data1 = idst(data1, axis = 1, type = 1) # data1 = idst(data1, axis = 0, type = 1) data1 = idstn(data1, type = 1) # data1 = idstn(data1, axis = 0, type = 1) u = data1/((2.0*nx)*(2.0*ny)) ue = np.zeros((nx+1,ny+1)) ue[1:-1,1:-1] = u return ue
def random_initial_data(N, s): '''A function generating a random function on $[0,1]\times [0,1]$ with zero boundary conditions ampled from the random Fourier series $$\sum\limits_{n,m\geq 1}^N \frac{g_{nm}(\omega)}{\langle (n,m)\rangle^s}$$ Parameters ---------------------- N = The Fourier truncation parameter s = The regularity of the random data Returns --------------------- f = a random Fourier series as described above. ''' n = np.arange(1, N - 1) n = np.tile(n, (N - 2, 1)) + 0j m = np.arange(1, N - 1) m = np.tile(m, (N - 2, 1)).transpose() + 0j Ff = (np.random.randn(N - 2, N - 2) + np.complex(0, 1) * np.random.randn(N - 2, N - 2)) / ( (n**2 + m**2 + 1)**(s / 2)) f = fft.idstn(Ff, type=1, norm='ortho') f = np.pad(f, 1, mode='constant') f = np.real(f) return f
def BeamFFTxyInv(self, mpWeighGridOnZ): mpWeighGridOnZ = idstn(mpWeighGridOnZ, axes=[0, 1], type=1, overwrite_x=True) mpWeighGridOnZ /= ((2. * (self.weighDeltaX + 1.)) * (2. * (self.weighDeltaY + 1.))) return mpWeighGridOnZ
def nbFFT(data): data=dstn(data,axes=[0,1],type=1,overwrite_x=True) data=fft(data,axis=-1,overwrite_x=True) data=ifft(data,axis=-1,overwrite_x=True) data=idstn(data,axes=[0,1],type=1,overwrite_x=True) data/=4*(num+1)**2
def solve_poisson(n): step = 1 / n N = (n - 1)**2 eigenvalues = np.zeros((n - 1, n - 1)) g = np.zeros((n - 1, n - 1)) for k in range(1, n): for m in range(1, n): eigenvalues[k - 1, m - 1] = 4 / (step**2) * \ ((np.sin(np.pi * k * step / 2))**2 + (np.sin(np.pi * m * step / 2)) ** 2) g[k - 1, m - 1] = f(k, m, step) return dstn(idstn(g, norm='ortho', type=1) / eigenvalues, norm='ortho', type=1)
def _idstn(x, type=2, shape=None, axes=None, norm=None, overwrite_x=False): y = _fftpack.idstn(x, type, shape, axes, norm, overwrite_x) if norm is None: _normalize_inverse(y, 's', type, axes) return y
import numpy as np from scipy.fftpack import dstn, idstn, irfft, rfft, dst, idst, dct, idct, fft, ifft import time # 对应0.02s A=np.random.random((64,64,64)) tic=time.time() A=dstn(A,axes=[0,1],type=1,overwrite_x=True) A=fft(A,axis=-1,overwrite_x=True) #mpWeighGridOnX=mpWeighGridOnX/fftK2 B=np.random.random((64,64,64)) A/=B A=np.real(ifft(A,axis=-1,overwrite_x=True)) A=idstn(A,axes=[0,1],type=1,overwrite_x=True) toc=time.time() print(toc-tic)
from scipy.fftpack import dstn, dctn,idstn,idctn import numpy as np data=np.random.random((2,3,4)) print(data) #print(dstn(data,norm='ortho')) print('-'*50) #print(idstn(dstn(data,norm='ortho',axes=[0,1]),norm='ortho',axes=[0,1])) print(idstn(dstn(data,norm='ortho',axes=[0,1]),norm='ortho'))
from scipy.fftpack import dstn, dctn, idstn, idctn import numpy as np dataC = np.random.random((2, 2)) dataO = np.zeros((2, 2)) data1 = np.hstack((dataO, dataO, dataO)) data2 = np.hstack((dataO, dataC, dataO)) data = np.vstack((data1, data2, data1)) dataS2 = idstn(dstn(data, norm='ortho', axes=[0, 1]), norm='ortho', axes=[0, 1]) dataS2[dataS2 < 1e-6] = 0 dataS3 = idstn(dstn(data, norm='ortho'), norm='ortho') dataS3[dataS2 < 1e-6] = 0 print(data) #print(dstn(data,norm='ortho')) print('-' * 50) print(dataS2) print('-' * 50) print(dataS3)
def linear_wave_solver(t, u_0, v_0, c, b, a): '''A function to solve the linear wave equation $$\partial_t^2u = c^2\Delta u -\partial_t u -au$$ on $[0,1]\times [0,1]$ with zero Dirichlet boundary conditions and initial data $(u(0), \partial_t u(0)) = (u_0,v_0)$. This function uses a spectral method, inparticular the fast sine transform. Parameters ----------------------------- t = The time the solution is computed at, a real number. u_0 = The inital displacement, an array of real numbers. v_0 = The inital velcoty, a real number, an array of real numbers. c = The wave speed, a real number. b = The dissipation, a real number. a = The linear potential, a real number. Returns ------------------------------ u = The displacement at time t, an array. v = The velocity at time t, an array. ''' l = len(u_0[0, :]) f = u_0[1:l - 1, 1:l - 1] g = v_0[1:l - 1, 1:l - 1] Sf = fft.dstn(f, type=1, norm='ortho') Sg = fft.dstn(g, type=1, norm='ortho') n = np.arange(1, l - 1) n = np.tile(n, (l - 2, 1)) m = np.arange(1, l - 1) + 0j m = np.tile(m, (l - 2, 1)).transpose() + 0j lnmminus = (-b - np.sqrt(b**2 - 4 * (c**2 * (n**2 + m**2) * np.pi**2 + a))) / 2 lnmplus = (-b + np.sqrt(b**2 - 4 * (c**2 * (n**2 + m**2) * np.pi**2 + a))) / 2 Anmplus = (lnmminus * Sf - Sg) / (lnmminus - lnmplus) Anmminus = (Sg - lnmplus * Sf) / (lnmminus - lnmplus) #The Fourier transform of the solution Su = Anmplus * np.exp(lnmplus * t) + Anmminus * np.exp(lnmminus * t) Sv = lnmplus * Anmplus * np.exp( lnmplus * t) + lnmminus * Anmminus * np.exp(lnmminus * t) u = fft.idstn(Su, type=1, norm='ortho') v = fft.idstn(Sv, type=1, norm='ortho') #We need to add the zeros to the boundary of u and v. u = np.pad(u, 1, mode='constant') v = np.pad(v, 1, mode='constant') #Convert to real to get rid of the superfluous + \eps j terms where \eps is #a small real number u = np.real(u) v = np.real(v) return u, v