def __init__(self,N=100,L=10.0,d=1): self.N = N self.L = L self.d = d self.onedgrid = np.linspace(-L,L,N) self.x,self.y = np.meshgrid(self.onedgrid, self.onedgrid) self.r = np.sqrt(self.x**2 + self.y**2) self.theta = np.arctan2(self.x,self.y) self.delta = self.onedgrid[1] - self.onedgrid[0] Delta1D = functions.tridiag(N,-1,2,-1)/self.delta**2 eye = functions.tridiag(N,0,1,0) self.Delta = scipy.sparse.kron(Delta1D,eye,'csr') + scipy.sparse.kron(eye,Delta1D,'csr')
def fem_mult_op(self,V,l,Mass): # Vsqrtop = scipy.sparse.spdiags(np.sqrt(np.abs(V)),0,V.shape[0],V.shape[0],'csr') # return np.sign(V[1]) * np.dot(np.dot(Vsqrtop,Mass),Vsqrtop) params = self.fem_params(l) if not params['phi']: if not params['weight']: raise Exception("Not implemented") # the grid has been shifted x = np.zeros_like(self.x) x[1:] = self.x[:-1] deltap = self.deltam deltam = np.zeros_like(deltap) deltam[1:] = deltap[:-1] deltam[0] = np.NaN h = deltam[5] diag = V / 2 * x diag[1:] += 1/12*V[:-1] * (x[1:] - 2/5*h) diag[:-1] += 1/12*V[1:] * (x[:-1] + 2/5*h) diag[0] = h*(1/20*V[0] + 1/30 * V[1]) offdiag = 1/12*V * (x + 2/5*h) offdiag[:-1] += 1/12*V[1:] * (x[:-1] + 3/5*h) # debug diag = V/4*(deltam*(x-1/5*deltam) + deltap*(x+1/5*deltap)) diag[1:] += 1/12*V[:-1] * deltam[1:]*(x[1:] - 2/5*deltam[1:]) diag[:-1] += 1/12*V[1:] * deltap[:-1]*(x[:-1] + 2/5*deltap[:-1]) diag[0] = deltap[0]**2*(1/20*V[0] + 1/30 * V[1]) offdiag = 1/12*V * deltap*(x + 2/5*deltap) offdiag[:-1] += 1/12*V[1:] * deltap[:-1]*(x[:-1] + 3/5*deltap[:-1]) return functions.tridiag(self.N,offdiag,diag,offdiag) else: if params['fd']: return functions.tridiag(self.N,0,V,0) else: diag = V/4*(self.deltap + self.deltam) diag[1:] += 1/12*V[:-1]*self.deltam[1:] diag[:-1] += 1/12*V[1:]*self.deltap[:-1] offdiag = 1/12*V*self.deltap offdiag[:-1] += 1/12*V[1:]*self.deltap[:-1] return functions.tridiag(self.N,offdiag,diag,offdiag)
def build_rho_2D(g, V, gamma, sigma, numeigs=4): '''Construit rho à partir des premières fonctions propres de -Delta+V''' bigN = g.N**g.d H = g.Delta + functions.tridiag(bigN,0,V.flat,0) w,vs = scipy.sparse.linalg.eigsh(H,numeigs,sigma=sigma,which='LM') if w[-1] < 0: return build_rho_2D(g,V,gamma, sigma, numeigs*2) elif w[0] > 0: raise Exception('No negative eigenvalue') print 'Eigs', w vecs = [] for i in range(0,len(w)): if w[i] < 0: vecs.append(vs[:,i].reshape((g.N,g.N))) rho = np.zeros_like(V) for i in range(0,len(vecs)): rho = rho + np.abs(w[i])**(gamma-1)*vecs[i]**2 return rho, w[w < 0], vecs
# -*- coding: utf-8 -*- """ Standalone program for comparing Jacobi's Method to the Bisection Method for finding eigenvalues """ from functions import tridiag, jacobi_solver, bisect_eigens import numpy as np import matplotlib.pyplot as plt import time Ns = [5,10,15,20] t = np.zeros((2,len(Ns),1)) j = 0 for i in Ns: tt = time.perf_counter() jacobi_solver(tridiag(2,5,i)) t[0,j,0] = time.perf_counter() - tt tt = time.perf_counter() bisect_eigens(2,5,i) t[1,j,0] = time.perf_counter() - tt j += 1 plt.plot(Ns, t[0,:]) plt.plot(Ns, t[1,:]) plt.legend(['Jacobi','Bisection']) plt.xlabel('Square Matrix Length') plt.ylabel('Time to calculate eigenvalues [s]') plt.title('Time to calculate eigenvalues given a matrix length N') plt.show()
# -*- coding: utf-8 -*- """ Standalone program for plotting N versus Rotations Runtime is pretty long, beware! The "soft-cap" seems to be at around N = 100, so remove N = 150 if its taking too long """ from functions import tridiag, jacobi_solver import numpy as np import matplotlib.pyplot as plt Ns = [10, 20, 30, 50, 100, 150] #N values data = np.zeros((len(Ns), 2)) j = 0 for i in Ns: data[j][0] = i #x-axis data[j][1] = jacobi_solver(tridiag(-1, 2, i))[2] #y-axis, returns iterations j += 1 plt.xlabel('Square Matrix Length') plt.ylabel('Number of iterations needed') plt.title( 'Iterations needed with the Jacobi Rotation Algorithm given a length N') plt.plot(data[:, 0], data[:, 1]) plt.show()
""" Standalone program for testing and validating some functions used in this project """ """ Let us test if all our methods return the correct eigenvalues Let's assume we have the Matrix 5 2 0 0 0 2 5 2 0 0 0 2 5 2 0 0 0 2 5 0 This should return the eigenvalues: lambda = 7, 5, 3, 5 + 2*sqrt(3), 5 - 2*sqrt(3) """ rLambdas = np.sort([7,5,3,5 + 2*np.sqrt(3), 5 - 2*np.sqrt(3)]) A = tridiag(2,5,5) """ Let's now test each of our solutions """ nEigs = np.sort(np.linalg.eig(A)[0]) aEigs = np.sort(eigenvalues(2,5,5)) jEigs = np.sort(jacobi_solver(A)[0]) if np.allclose(rLambdas,nEigs) == True: print('Numpy Validated') if np.allclose(rLambdas,nEigs) == True: print('Analytical Validated') if np.allclose(rLambdas,nEigs) == True: print('Jacobi Validated') """ This can also be verified with any other Matrix
def fem_mats(self,l): # returns Delta, Mass N = self.N params = self.fem_params(l) if not params['phi']: if self.d != 2: raise Exception('Not implemented') # the grid has been shifted x = np.zeros_like(self.x) x[1:] = self.x[:-1] deltap = self.deltam deltam = np.zeros_like(deltap) deltam[1:] = deltap[:-1] deltam[0] = np.NaN if params['weight']: # integrate against r # Mdiag = h * 2/3 * x # Moffdiag = h * 1/6 * (x + h/2) # Mdiag[0] = h**2 / 12 # Ddiag = 2 / h * x #OK # Doffdiag = -1 / h * (x + h/2) #OK # Ddiag[0] = 1/2 #OK Mdiag = deltam/3*(x-deltam/4) + deltap/3*(x+deltap/4) Moffdiag = 1/6*deltap*(x+deltap/2) Mdiag[0] = deltap[0]**2/12 Ddiag = x*(1/deltam+1/deltap) Doffdiag = -1/deltap*(x+deltap/2) Ddiag[0] = 1/2 Delta = functions.tridiag(N,Doffdiag,Ddiag,Doffdiag) Mass = functions.tridiag(N,Moffdiag,Mdiag,Moffdiag) else: if l != 0: raise Exception('Not implemented') Delta = functions.tridiag(N,-1,2,-1) / self.delta Mass = functions.tridiag(N,1,4,1) * self.delta / 6 #neumann Delta[0,0] = 1/self.delta Mass[0,0] = 1/3*self.delta else: if params['fd']: Delta = functions.tridiag(N,-1,2,-1) / self.delta**2 # Mass = functions.tridiag(N,0,1,0) Mass = None # Delta[0,0] = 1/self.delta**2 else: # Delta = functions.tridiag(N,-1,2,-1) / self.delta # Mass = functions.tridiag(N,1,4,1) * self.delta / 6 # deltamat = functions.tridiag(N,0, np.sqrt(self.delta),0) # deltainvmat = functions.tridiag(N,0, 1/np.sqrt(self.delta),0) # Delta = np.dot(np.dot(deltainvmat,functions.tridiag(N,-1,2,-1)),deltainvmat) # Mass = np.dot(np.dot(deltamat,functions.tridiag(N,1,4,1)),deltamat) / 6 # if neumann: # Delta[0,0] = 1/self.delta # Mass[0,0] = 1/3*self.delta Ddiag = (self.deltap+self.deltam)/self.deltap/self.deltam Doffdiag = -1/self.deltap Mdiag = 1/3*(self.deltap + self.deltam) Moffdiag = 1/6 * self.deltap Delta = functions.tridiag(N,Doffdiag,Ddiag,Doffdiag) Mass = functions.tridiag(N,Moffdiag,Mdiag,Moffdiag) return Delta,Mass
# -*- coding: utf-8 -*- """ Standalone program for calculating runtime for three different algorithms for finding eigenvalues """ from functions import tridiag, eigenvalues, jacobi_solver import numpy as np import matplotlib.pyplot as plt import time Ns = [5, 10, 30, 50] t = np.zeros((3, len(Ns), 1)) j = 0 for i in Ns: tt = time.perf_counter() eigenvalues(-5, 10, i) t[0, j, 0] = time.perf_counter() - tt tt = time.perf_counter() np.linalg.eig(tridiag(-5, 10, i)) t[1, j, 0] = time.perf_counter() - tt tt = time.perf_counter() jacobi_solver(tridiag(-5, 10, i)) t[2, j, 0] = time.perf_counter() - tt j += 1 plt.plot(Ns, t[0, :]) plt.plot(Ns, t[1, :]) plt.plot(Ns, t[2, :]) plt.legend(['Analytical', 'Numpy', 'Jacobi']) plt.xlabel('Square Matrix Length') plt.ylabel('Time to calculate eigenvalues [s]') plt.title('Time to calculate eigenvalues given a matrix length N') plt.show()