def fst_whole_domain(nx, ny, dx, dy, f): fd = f[2:nx + 3, 2:ny + 3] data = fd[:, :] # e = dst(data, type=2) data = dst(data, axis=1, type=1) data = dst(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) u = data1 / ((2.0 * nx) * (2.0 * ny)) ue = np.zeros((nx + 5, ny + 5)) ue[2:nx + 3, 2:ny + 3] = u return ue
def fste(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) 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) u = data1 / ((2.0 * nx) * (2.0 * ny)) return u
def _fast_poisson(self, gx, gy): ydim, xdim = np.shape(gx) gxx = np.zeros((ydim, xdim)) gyy = np.zeros((ydim, xdim)) f = np.zeros((ydim, xdim)) gyy[1:ydim, 0:xdim - 1] = gy[1:ydim, 0:xdim - 1] - gy[0:ydim - 1, 0:xdim - 1] gxx[0:ydim - 1, 1:xdim] = gx[0:ydim - 1, 1:xdim] - gx[0:ydim - 1, 0:xdim - 1] f = gxx + gyy height, width = f.shape[:2] f2 = f[1:height - 1, 1:width - 1] tt = dst(f2.T, type=1).T / 2 f2sin = (dst(tt, type=1) / 2) x, y = np.meshgrid(np.arange(1, xdim - 1), np.arange(1, ydim - 1)) denom = (2 * np.cos(np.pi * x / (xdim - 1)) - 2) + (2 * np.cos(np.pi * y / (ydim - 1)) - 2) f3 = f2sin / denom tt = np.real(idst(f3, type=1, axis=0)) / (f3.shape[0] + 1) img_tt = (np.real(idst(tt.T, type=1, axis=0)) / (tt.T.shape[0] + 1)).T img_direct = np.zeros((ydim, xdim)) height, width = img_direct.shape[:2] img_direct[1:height - 1, 1:width - 1] = img_tt return img_direct
def fst4c(nx, ny, dx, dy, f): alpha_ = 1.0 / 10.0 a = (-12.0 / 5.0) * (1.0 / dx**2 + 1.0 / dy**2) b = (6.0 / 25.0) * (5.0 / dx**2 - 1 / (dy**2)) c = (6.0 / 25.0) * (5.0 / dy**2 - 1 / (dx**2)) d = (3.0 / 25.0) * (1.0 / dx**2 + 1.0 / dy**2) data = f[1:-1, 1:-1] data = dst(data, axis=1, type=1) data = dst(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)) beta = a + 2.0*b*np.cos(np.pi*m/nx) + 2.0*c*np.cos(np.pi*n/ny) + \ 4.0*d*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) gamma = 1.0 + 2.0*alpha_*np.cos(np.pi*m/nx) + 2.0*alpha_*np.cos(np.pi*n/ny) + \ 4.0*(alpha_**2)*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) data1 = data * gamma / (beta) data1 = idst(data1, axis=1, type=1) data1 = idst(data1, axis=0, type=1) data1 = data1 / ((2.0 * nx) * (2.0 * ny)) ue = np.zeros((nx + 1, ny + 1)) ue[1:-1, 1:-1] = data1 return ue
def fst4(nx, ny, dx, dy, f): beta = dx / dy a = -10.0 * (1.0 + beta**2) b = 5.0 - beta**2 c = 5.0 * beta**2 - 1.0 d = 0.5 * (1.0 + beta**2) data = f[1:-1, 1:-1] data = dst(data, axis=1, type=1) data = dst(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)) alpha = a + 2.0*b*np.cos(np.pi*m/nx) + 2.0*c*np.cos(np.pi*n/ny) + \ 4.0*d*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) gamma = 8.0 + 2.0 * np.cos(np.pi * m / nx) + 2.0 * np.cos(np.pi * n / ny) data1 = data * (dx**2) * 0.5 * gamma / alpha data1 = idst(data1, axis=1, type=1) data1 = idst(data1, axis=0, type=1) data1 = data1 / ((2.0 * nx) * (2.0 * ny)) ue = np.zeros((nx + 1, ny + 1)) ue[1:-1, 1:-1] = data1 return ue
def compute_IDST(N): plt.figure() t = np.linspace(0,20,N) x = np.exp(-t/3)*np.cos(2*t) y = dst(x, norm='ortho') window = np.zeros(N) window[:20] = 1 yr = idst(y*window, norm='ortho') sum(abs(x-yr)**2) / sum(abs(x)**2) plt.plot(t, x, '-bx') plt.plot(t, yr, 'ro') window = np.zeros(N) window[:15] = 1 yr = idst(y*window, norm='ortho') sum(abs(x-yr)**2) / sum(abs(x)**2) # 0.0718818065008 plt.plot(t, yr, 'g+') plt.legend(['x', '$x_{20}$', '$x_{15}$']) if not os.path.isdir('static'): os.mkdir('static') else: # Remove old plot files for filename in glob.glob(os.path.join('static', '*.png')): os.remove(filename) # Use time since Jan 1, 1970 in filename in order make # a unique filename that the browser has not chached plotfile = os.path.join('static', str(time.time()) + '.png') #Name of file - unique and uncached by the browser plt.savefig(plotfile) return plotfile
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) 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)) 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 data1 = idst(data1, axis=1, type=1) data1 = idst(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 fst6(nx, ny, dx, dy, f): lambda_ = 1.0 / 10.0 a = (-12.0 / 5.0) * (1.0 / dx**2 + 1.0 / dy**2) b = (6.0 / 25.0) * (5.0 / dx**2 - 1 / (dy**2)) c = (6.0 / 25.0) * (5.0 / dy**2 - 1 / (dx**2)) d = (3.0 / 25.0) * (1.0 / dx**2 + 1.0 / dy**2) alpha_ = 2.0 / 11.0 center = (-51.0 / 22.0) * (1.0 / dx**2 + 1.0 / dy**2) ew = (1.0 / 11.0) * (12.0 / dx**2 - alpha_ * 51.0 / (2.0 * dy**2)) ns = (1.0 / 11.0) * (12.0 / dy**2 - alpha_ * 51.0 / (2.0 * dx**2)) corners = alpha_ * (12.0 / 11.0) * (1.0 / dx**2 + 1.0 / dy**2) ew_far = alpha_ * 3.0 / (44.0 * dx**2) ns_far = alpha_ * 3.0 / (44.0 * dy**2) data = f[1:-1, 1:-1] data = dst(data, axis=1, type=1) data = dst(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)) data2 = np.zeros((nx - 1, ny - 1)) data3 = np.zeros((nx - 1, ny - 1)) beta = a + 2.0*b*np.cos(np.pi*m/nx) + 2.0*c*np.cos(np.pi*n/ny) + \ 4.0*d*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) gamma = 1.0 + 2.0*lambda_*np.cos(np.pi*m/nx) + 2.0*lambda_*np.cos(np.pi*n/ny) + \ 4.0*(lambda_**2)*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) data2 = data * gamma / (beta) lhs_near = center + 2.0*ew*np.cos(np.pi*m/nx) + 2.0*ns*np.cos(np.pi*n/ny) + \ 4.0*corners*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) lhs_far = 2.0*ew_far*(1.0 + 2.0*np.cos(np.pi*n/ny))*np.cos(2.0*np.pi*m/nx) + \ 2.0*ns_far*(1.0 + 2.0*np.cos(np.pi*m/nx))*np.cos(2.0*np.pi*n/ny) rhs = 1.0 + 2.0*alpha_*np.cos(np.pi*m/nx) + 2.0*alpha_*np.cos(np.pi*n/ny) + \ 4.0*(alpha_**2)*np.cos(np.pi*m/nx)*np.cos(np.pi*n/ny) data3 = data * rhs / (lhs_near + lhs_far) data1 = np.copy(data2) data1[1:-1, 1:-1] = np.copy(data3[1:-1, 1:-1]) data1 = idst(data1, axis=1, type=1) data1 = idst(data1, axis=0, type=1) data1 = data1 / ((2.0 * nx) * (2.0 * ny)) ue = np.zeros((nx + 1, ny + 1)) ue[1:-1, 1:-1] = data1 return ue
def solve_min_laplacian(boundary_image): (H, W) = np.shape(boundary_image) # Laplacian f = np.zeros((H, W)) # boundary image contains image intensities at boundaries boundary_image[1:-1, 1:-1] = 0 j = np.arange(2, H)-1 k = np.arange(2, W)-1 f_bp = np.zeros((H, W)) f_bp[np.ix_(j, k)] = -4*boundary_image[np.ix_(j, k)] + boundary_image[np.ix_(j, k+1)] + boundary_image[np.ix_(j, k-1)] + boundary_image[np.ix_(j-1, k)] + boundary_image[np.ix_(j+1, k)] del(j, k) f1 = f - f_bp # subtract boundary points contribution del(f_bp, f) # DST Sine Transform algo starts here f2 = f1[1:-1,1:-1] del(f1) # compute sine tranform if f2.shape[1] == 1: tt = fftpack.dst(f2, type=1, axis=0)/2 else: tt = fftpack.dst(f2, type=1)/2 if tt.shape[0] == 1: f2sin = np.transpose(fftpack.dst(np.transpose(tt), type=1, axis=0)/2) else: f2sin = np.transpose(fftpack.dst(np.transpose(tt), type=1)/2) del(f2) # compute Eigen Values [x, y] = np.meshgrid(np.arange(1, W-1), np.arange(1, H-1)) denom = (2*np.cos(np.pi*x/(W-1))-2) + (2*np.cos(np.pi*y/(H-1)) - 2) # divide f3 = f2sin/denom del(f2sin, x, y) # compute Inverse Sine Transform if f3.shape[0] == 1: tt = fftpack.idst(f3*2, type=1, axis=1)/(2*(f3.shape[1]+1)) else: tt = fftpack.idst(f3*2, type=1, axis=0)/(2*(f3.shape[0]+1)) del(f3) if tt.shape[1] == 1: img_tt = np.transpose(fftpack.idst(np.transpose(tt)*2, type=1)/(2*(tt.shape[0]+1))) else: img_tt = np.transpose(fftpack.idst(np.transpose(tt)*2, type=1, axis=0)/(2*(tt.shape[1]+1))) del(tt) # put solution in inner points; outer points obtained from boundary image img_direct = boundary_image img_direct[1:-1, 1:-1] = 0 img_direct[1:-1, 1:-1] = img_tt return img_direct
def omp_batch_recon(signal, ind, target_pts, n_nonzero_coefs=20, transform='dct', retCoefs=False): """ Performs an Orthogonal Matching Pursuit technique, with batch approach This algorithm is based on Compressed sensing theory and works as a greedy algorithm to find the sparsest coefficients in a given transform that fit the input signal. Then it returns the inverse transform of these coefficients Parameters ---------- signal : list the downsampled signal to reconstruct ind : list the list of indices corresponding to the position of the downsampled points target_pts : integer the number of points the reconstructed signal should have n_nonzero_coefs : integer the number of nonzeros that are supposed to be in the original signal's transform. transform : 'dct' or 'dst' the type of transform to use (discrete cosine or sine transform) retCeofs : boolean if True, will return the coefficients of the transform Returns ------- x : list the reconstructed signal coef : list the coefficients of the reconstructed signal's transform """ if transform == 'dst': phi = spfft.idst(np.identity(target_pts), axis=0) else: phi = spfft.idct(np.identity(target_pts), axis=0) phi = phi[ind] omp = OrthogonalMatchingPursuit(n_nonzero_coefs=n_nonzero_coefs) omp.fit(phi, signal) coef = omp.coef_ if transform == 'dst': x = spfft.idst(coef, axis=0) + np.mean(signal) else: x = spfft.idct(coef, axis=0) + np.mean(signal) x = utils.normalize(x) if retCoefs: return (x, coef) else: return x
def idst2(b): M = b.shape[0] N = b.shape[1] a = np.empty([M, N], float) y = np.empty([M, N], float) for i in range(M): a[i, :] = idst(b[i, :], type=1) for j in range(N): y[:, j] = idst(a[:, j], type=1) return y
def hr_to_cr(bins, rho, data, radius, error=None, axis=1): """ This function takes h(r) and uses the OZ equation to find c(r) this is done via a 3D fourier transform that is detailed in LADO paper. The transform is the the DST of f(r)*r. The function is rearranged in fourier space to find c(k) and then the inverse transform is taken to get back to c(r). """ # setup scales dk = np.pi / radius[-1] k = dk * np.arange(1, bins + 1, dtype=np.float) # Transform into fourier components FT = dst(data * radius[0:bins], type=1, axis=axis) normalisation = 2 * np.pi * radius[0] / k H_k = normalisation * FT # Rearrange to find direct correlation function C_k = H_k / (1 + rho * H_k) # # Transform back to real space iFT = idst(C_k * k, type=1) normalisation = k[-1] / (4 * np.pi**2 * radius[0:bins]) / (bins + 1) c_r = normalisation * iFT return c_r, radius
def inv_discrete_sine(t): """ Inverse discrete sine at a specific time of a wave function """ sin_cos = t * (((np.pi ** 2) * H_BAR * (position_k ** 2)) / (2 * ELECTRON_MASS * (L ** 2))) a_term = np.cos(sin_cos) * c_real b_term = np.sin(sin_cos) * c_imag z = a_term - b_term inverse_z = fft.idst(z) / N_SLICES return inverse_z
def linear_wave_solution(t, u_0, v_0, c=1, b=0, a=0): '''This function uses the fast sine transform to return the soluton to the linear wave equation $\partial_t^2 u = \Delta u - b\partial_t u - au$ given an initial displacement, $u_0$ and an initial velocity, $v_0$. ''' #The DST doesn't take as input the zeros at the start and end of the #displacement and velocity vectors. Below k needs to be complex so np.sqrt #will return a complex number instead of an error N = np.size(u_0) - 1 k = np.arange(1, N) + 0j f = u_0[1:len(u_0) - 1] g = v_0[1:len(u_0) - 1] Sf = fft.dst(f, type=1) Sg = fft.dst(g, type=1) lkminus = (-b - np.sqrt(b**2 - 4 * (c**2 * k**2 * np.pi**2 + a))) / 2 lkplus = (-b + np.sqrt(b**2 - 4 * (c**2 * k**2 * np.pi**2 + a))) / 2 Akplus = (lkminus * Sf - Sg) / (lkminus - lkplus) Akminus = (Sg - lkplus * Sf) / (lkminus - lkplus) #The Fourier transform of the solution Su = Akplus * np.exp(lkplus * t) + Akminus * np.exp(lkminus * t) Sv = lkplus * Akplus * np.exp(lkplus * t) + lkminus * Akminus * np.exp( lkminus * t) u = fft.idst(Su, type=1) / (2 * N) v = fft.idst(Sv, type=1) / (2 * N) #We need to add the zeros back to the start and end of the displacement and #velocity vectors. u = np.insert(u, 0, 0) u = np.insert(u, len(u), 0) v = np.insert(v, 0, 0) v = np.insert(v, len(v), 0) #Convert to real to get rid of the superfluous + 0j terms u = np.real(u) v = np.real(v) return u, v
def propagate_step(self, u, problem): if self._linear == 0: return u max_iters = 100 tolerance = 1e-10 v0 = u - self._left - self._xs * self._right(u[:, -1]) v0hat = dst(v0, type=3, norm='ortho') import matplotlib.pyplot as plt u_boundary = u[:, -1] ut_boundary = 0 thetahat = np.zeros(u.shape) for it in range(max_iters): vhat = self._propagator * v0hat + (1 - self._propagator) * self._d_inv * thetahat dvhat_dt = -self._d * vhat + thetahat v = idst(vhat, type=3, norm='ortho') dvdt = idst(dvhat_dt, type=3, norm='ortho') u_boundary_old = u_boundary # newton iteration p = v[:, -1] + self._left u_boundary = u_boundary \ - (p + self._xs[-1]*self._right(u_boundary) - u_boundary) / (self._xs[-1]*self._gderiv(u_boundary) - 1) ut_boundary = dvdt[:, -1] + self._xs[-1]*self._gderiv(u_boundary)*ut_boundary thetahat = -self._gderiv(u_boundary)*ut_boundary*dst(self._xs, type=3, norm='ortho') if abs(u_boundary - u_boundary_old) < tolerance: break if it == max_iters-1: print("WARNING: max iters reached") out = self._left + self._xs.T*self._right(u_boundary) + idst(vhat, type=3, norm='ortho') return out.reshape(u.shape)
def adjoint_static(x, type=2, axes=None): if axes == None: axes = np.arange(len(x.shape)) # make a copy of the input y = x # apply the dct for each axis for axis in axes: y = scft.idst(y, type=type, axis=axis, norm="ortho") return y
def iFFT_FST_ZZ8(N1, N2, F_hat, kk_cosine): F = np.zeros((N1, N2)) for k in range(N2): F[:, k] = np.fft.ifft(F_hat[:, k]).real for ll in range(N1): fac = kk_cosine[1:N2 - 1]**8 F[ll, 1:N2 - 1] = fftpack.idst(fac * F[ll, 1:N2 - 1], type=1) * .5 F[ll, 0] = 0. F[ll, N2 - 1] = 0. return F
def iFFT_FST_XX8(N1, N2, F_hat, kk): F = np.zeros((N1, N2)) for k in range(N2): F[:, k] = np.fft.ifft(kk**8 * F_hat[:, k]).real for ll in range(N1): F[ll, 1:N2 - 1] = fftpack.idst(F[ll, 1:N2 - 1], type=1) * .5 F[ll, 0] = 0. F[ll, N2 - 1] = 0. return F
def fast_poisson(gx, gy): # j = 1:ydim-1; # k = 1:xdim-1; # # % Laplacian # gyy(j+1,k) = gy(j+1,k) - gy(j,k); # gxx(j,k+1) = gx(j,k+1) - gx(j,k); m, n = gx.shape gxx = np.zeros((m, n)) gyy = np.zeros((m, n)) f = np.zeros((m, n)) img = np.zeros((m, n)) gyy[1:, :-1] = gy[1:, :-1] - gy[:-1, :-1] gxx[:-1, 1:] = gx[:-1, 1:] - gx[:-1, :-1] f = gxx + gyy f2 = f[1:-1, 1:-1].copy() f_sinx = dst(f2) f_sinxy = dst(f_sinx.T).T x_mesh, y_mesh = np.meshgrid(range(n - 2), range(m - 2)) x_mesh = x_mesh + 1 y_mesh = y_mesh + 1 denom = (2 * np.cos(np.pi * x_mesh / (m - 1)) - 2) + (2 * np.cos(np.pi * y_mesh / (n - 1)) - 2) f3 = f_sinxy / denom # plt.figure(10) # plt.imshow(denom) # plt.show() f_realx = idst(f3) f_realxy = idst(f_realx.T).T img[1:-1, 1:-1] = f_realxy.copy() return img #%%
def getIDST(matrix): for x in range(64): i1 = 8 * x i2 = 8 * (x + 1) for y in range(64): j1 = 8 * y j2 = 8 * (y + 1) block = matrix[i1:i2, j1:j2] matrix[i1:i2, j1:j2] = idst(block) # matrix[i1:i2,j1:j2] = dct(dct(block, axis=0, norm="ortho"), axis=1, norm="ortho") # print np.max(matrix) return matrix
def test_idstRandom(self): N = 4 x = torch.empty(N, N, dtype=dtype).uniform_(0, 10.0) #x = Variable(torch.tensor([[1, 2, 7, 9, 20, 31], [4, 5, 9, 2, 1, 6]], dtype=dtype)) print("x") print(x) import scipy from scipy import fftpack #y = discrete_spectral_transform.dst(x) y = torch.from_numpy(fftpack.dst(x.data.numpy())) print("y") print(y.data.numpy()) #golden_value = discrete_spectral_transform.idst(y).data.numpy() golden_value = torch.from_numpy(fftpack.idst(y.data.numpy())).data.numpy() print("2D golden_value") print(golden_value) # test cpu # pdb.set_trace() custom = dct.IDST() dst_value = custom.forward(y) print("idst_value") print(dst_value.data.numpy()) np.testing.assert_allclose(dst_value.data.numpy(), golden_value, rtol=1e-5) # test cpu # pdb.set_trace() custom = dct_lee.IDST() dst_value = custom.forward(y) print("idst_value") print(dst_value.data.numpy()) np.testing.assert_allclose(dst_value.data.numpy(), golden_value, rtol=1e-5) if torch.cuda.device_count(): # test gpu custom = dct.IDST() dst_value = custom.forward(y.cuda()).cpu() print("idst_value cuda") print(dst_value.data.numpy()) np.testing.assert_allclose(dst_value.data.numpy(), golden_value, rtol=1e-5) # test gpu custom = dct_lee.IDST() dst_value = custom.forward(y.cuda()).cpu() print("idst_value cuda") print(dst_value.data.numpy()) np.testing.assert_allclose(dst_value.data.numpy(), golden_value, rtol=1e-5)
def random_initial_data(N, s): '''Using the DST, randomly generates a funcion of the form $\sum\limits_{k=1}^{N-2} \frac{g_k}{\langle k\rangle^s}\sin(k\pi x)$ where $g_n$ is a sequence of independent identically distributed random variables. ''' k = np.arange(1, N - 1) Ff = np.random.randn(N - 2) / ((k**2 + 1)**(s / 2)) f = fft.idst(Ff, type=1) #The DST/IDST doesn't include the zeros at the start and end. f = np.insert(f, 0, 0) f = np.insert(f, len(f), 0) return f
def Z(t): ''' This returns the inverse discrete sine transform at a specific time giving a value of the wave function. ''' cos_term = t * (((np.pi**2) * hbar * (k**2)) / (2 * m * (L**2))) sin_term = t * (((np.pi**2) * hbar * (k**2)) / (2 * m * (L**2))) alpha_term = np.cos(cos_term) * coefficents_real eta_term = np.sin(sin_term) * coefficents_imag z = alpha_term - eta_term inverse_z = fft.idst(z) / N return inverse_z
def sq_and_hr_to_cr(bins, rho, hr, r, S_k, k, axis=1): """ Takes the structure factor s(q) and computes the direct correlation function in real space c(r) """ # setup scales dr = np.pi / (bins * k[0]) radius = dr * np.arange(1, bins + 1, dtype=np.float) assert (np.all(np.abs(radius - r) < 1e-12)) iFT = idst(k[:bins] * np.square(S_k - 1.) / (rho * S_k), type=1, axis=axis) cr = hr - iFT return cr
def sq_to_hr(bins, rho, S_k, k, axis=1): """ Takes the structure factor s(q) and computes the real space total correlation function h(r) """ # setup scales dr = np.pi / (k[0] * bins) radius = dr * np.arange(1, bins + 1, dtype=np.float) # Rearrange to find total correlation function from structure factor H_k = (S_k - 1.) / rho # # Transform back to real space iFT = idst(H_k * k[:bins], type=1, axis=axis) normalisation = bins * k[0] / (4 * np.pi**2 * radius) / (bins + 1) h_r = normalisation * iFT return h_r, radius
def sq_to_cr(bins, rho, S_k, k, axis=1): """ Takes the structure factor s(q) and computes the direct correlation function in real space c(r) """ # setup scales dr = np.pi / (bins * k[0]) radius = dr * np.arange(1, bins + 1, dtype=np.float) # Rearrange to find direct correlation function from structure factor # C_k = (S_k-1.)/(S_k) # 1.-(1./S_k) what is better C_k = (S_k - 1.) / (rho * S_k) # # Transform back to real space iFT = idst(k[:bins] * C_k, type=1, axis=axis) normalisation = bins * k[0] / (4 * np.pi**2 * radius) / (bins + 1) c_r = normalisation * iFT return c_r, radius
def solve(self, w, u0, q=None): ''' dq/dt = Dq + Wq = Dq - wq ''' u = u0.copy() v = u[1:-1] # v = {u[1], u[2], ..., u[N-1]} expw = np.exp(-0.5 * self.h * w[1:-1]) for i in xrange(self.Ns - 1): v = expw * v ak = dst(v, type=1) / self.N * self.expd v = 0.5 * idst(ak, type=1) v = expw * v if q is not None: q[i + 1, 1:-1] = v u[1:-1] = v u[0] = 0. u[-1] = 0. return (u, self.x)
def fst4_tdma(nx, ny, dx, dy, f): beta = dx / dy a4 = -10.0 * (1.0 + beta**2) b4 = 5.0 - beta**2 c4 = 5.0 * beta**2 - 1.0 d4 = 0.5 * (1.0 + beta**2) e4 = 0.5 * (dx**2) data = f[1:-1, :] data = dst(data, axis=0, type=1) kx = np.linspace(1, nx - 1, nx - 1) kx = np.reshape(kx, [-1, 1]) cos_kx = np.cos(np.pi * kx / nx) alpha_k = c4 + 2.0 * d4 * cos_kx beta_k = a4 + 2.0 * b4 * cos_kx jj = np.arange(1, ny) alpha = np.zeros((nx - 1, ny + 1)) beta = np.zeros((nx - 1, ny + 1)) rr = np.zeros((nx - 1, ny + 1), dtype='complex128') alpha[:, jj] = alpha_k beta[:, jj] = beta_k rr[:, jj] = e4 * (data[:, jj - 1] + (8.0 + 2.0 * cos_kx) * data[:, jj] + data[:, jj + 1]) data_f = tdma(alpha.T, beta.T, alpha.T, rr.T, 1, ny - 1) data_ft = data_f.T data_i = idst(data_ft[:, 1:-1], axis=0, type=1) data_i = np.real(data_i) / ((2.0 * nx)) ue = np.zeros((nx + 1, ny + 1)) ue[1:-1, 1:-1] = data_i return ue
def iFFT_FST(N1, N2, F_hat): F = np.zeros((N1, N2)) for k in range(N2): F[:, k] = np.fft.ifft(F_hat[:, k]).real # # The F's are reals once we take the ifft, but they have complex parts that won't work # with the sine transform, so we set them all real # # F = real(F) # # Now that you have Reals take the inverse sine transform # for l in range(N1): F[l, 1:N2 - 1] = fftpack.idst(F[l, 1:N2 - 1], type=1) * .5 # # Normalize for the inverse cosine transform # # F = F/2./N2 return F
def cheb_mde_oss(W, u0, Lx, Ns): ''' Solution of modified diffusion equation (MDE) via Strang operator splitting as time-stepping scheme and fast sine transform. The MDE is: dq/dt = Dq - Wq in the interval [0, L], with Dirichlet boundary conditions, where D is Laplace operator. Discretization: x_j = j*L_x/N, j = 0, 1, 2, ..., N :param:W: W_j, j = 0, 1, ..., N :param:u0: u0_j, j = 0, 1, ..., N :param:Lx: the physical length of the interval [0, L_x] :param:Ns: contour index, s_j, j = 0, 1, ..., N_s ''' ds = 1. / (Ns - 1) N = np.size(u0) - 1 v = np.zeros(N - 1) v = u0[1:N] # v = {u[1], u[2], ..., u[N-1]} k2 = (np.pi / Lx)**2 * np.arange(1, N)**2 expd = np.exp(-ds * k2) expw = np.exp(-0.5 * ds * W[1:N]) for i in xrange(Ns - 1): v = expw * v ak = dst(v, type=1) / N * expd v = 0.5 * idst(ak, type=1) v = expw * v ii = np.arange(N + 1) x = 1. * ii * Lx / N u = u0.copy() u[1:N] = v u[0] = 0. u[N] = 0. return (u, x)
def idst2d(X): N = X.shape return fft.idst(fft.idst(X,1, axis = 1),1, axis = 0)/(4*(N[0]+1)*(N[1]+1))