def eval_evec(self, d, typ, k, which): a = d['mat'].astype(typ) # get exact eigenvalues exact_eval = d['eval'].astype(typ.upper()) ind = self.sort_choose(exact_eval, typ, k, which) exact_eval = exact_eval[ind] if verbose >= 3: print "exact" print exact_eval # compute eigenvalues eval, evec = eigen(a, k, which=which) ind = self.sort_choose(eval, typ, k, which) eval = eval[ind] evec = evec[:, ind] if verbose >= 3: print eval # check eigenvalues # check eigenvectors A*evec=eval*evec for i in range(k): assert_almost_equal_cc(eval[i], exact_eval[i], decimal=_ndigits[typ]) assert_array_almost_equal_cc(dot(a, evec[:, i]), eval[i] * evec[:, i], decimal=_ndigits[typ])
def eval_evec(self,d,typ,k,which): a=d['mat'].astype(typ) # get exact eigenvalues exact_eval=d['eval'].astype(typ.upper()) ind=self.sort_choose(exact_eval,typ,k,which) exact_eval=exact_eval[ind] if verbose >= 3: print "exact" print exact_eval # compute eigenvalues eval,evec=eigen(a,k,which=which) ind=self.sort_choose(eval,typ,k,which) eval=eval[ind] evec=evec[:,ind] if verbose >= 3: print eval # check eigenvalues # check eigenvectors A*evec=eval*evec for i in range(k): assert_almost_equal_cc(eval[i],exact_eval[i],decimal=_ndigits[typ]) assert_array_almost_equal_cc(dot(a,evec[:,i]), eval[i]*evec[:,i], decimal=_ndigits[typ])
def calculate(self, number=inf): m0=self.m0; k0=self.k0 number = min(number, self.totalnumber) logging.info( "Center solver. Finding modes, m0=%d, wl=%.3g" % (m0, self.wl) ) #Create new matrix if there is no existing one if self.si is None: self.si = ShiftInvertBlock(overwrite=self.overwrite) self.create() #Time mode solve tick = timer.timer() tick.start() #Array to store solved modes evrange = array(self.bracket)**2*self.k0**2 #Update equation with new BCs and update LU decomp self.update_lambda(self.evapprox, not self.overwrite) self.si.set_shift(self.matrix, self.evapprox+0j) #Find modes of linearized system if use_arpack: cev = eigen(self.si, k=self.totalnumber, which='LM', return_eigenvectors=False) cev = self.si.eigenvalue_transform(cev) else: cev, cvecs = eigs(self.si, self.totalnumber, tol=1e-6) #Filter cev within range if self.ignore_outside_interval: cev = filter(lambda x: min(evrange)<=real(x)<=max(evrange), cev) #Refine modes for ii in range(len(cev)): evsearch = cev[ii] #If the matrix is overwritten we must recreate it if self.overwrite: self.generate() self.si.set_shift(self.matrix, evsearch+0j) #Calculate next mode mode, evals = self.calculate_one(evsearch, self.searchnumber) #Add mode to list if (mode.residue<self.abc_convergence) or self.add_if_unconverged: self.modes += [ mode ] avtime = tick.lap()/(ii+1) logging.info( "Mode #%d [%d/%.3gs], neff=%s, res: %.2e" % \ (self.numbersolved, mode.iterations, avtime, mode.neff, mode.residue) ) self.add_time(tick.lap()) #Clean up if calculation is finished! if self.isfinished(): self.finalize() return self.modes
def eigs_sparse(M, k): #M = M.astype(float) #return scipy.linalg.eig(M) try: return scipy.sparse.linalg.eigs(M, k=k, which='LR') except AttributeError: # Older scipy: should be removed once possible import scipy.sparse.linalg.eigen.arpack as arpack return arpack.eigen(M, k=k, which='LR')
def calculate_one(self, evsearch, searchnum): """ Calculate single mode using fixed point iterations calculate_one(evsearch, searchnum) """ m0 = self.m0; k0 = self.k0 wl = self.wl bcstart, bcend = self.equation.diff.bc_extents() coord = self.wg.get_coord(self.base_shape, border=1) #Create new mode mode = self.mode_class(coord=coord, symmetry=self.wg.symmetry, m0=m0, wl=wl, evalue=evsearch, wg=self.wg) mode.right = ones(mode.shape, dtype=self.dtype) mode.discard_vectors = self.discard_vectors residue = inf; numit=0; evtol=1e-10 while residue>self.abc_convergence and numit<self.abc_iterations: numit+=1 #Update equation with new BCs and update LU decomp self.update_lambda(mode.evalue) if self.equation.coord.rmin==0: self.si.update(self.matrix, uprows=bcend) else: self.si.set_shift(self.matrix, complex(mode.evalue)) #Solve linear eigenproblem if use_arpack: evals, revecs = eigen(self.si, k=searchnum, \ which='LM', return_eigenvectors=True) evals = self.si.eigenvalue_transform(evals) else: evals, revecs = eigs(self.si, searchnum, tol=evtol) revecs = revecs.T #Locate closest eigenvalue itrack = absolute(evals-mode.evalue).argmin() mode.evalue = evals[itrack] mode.right = asarray(revecs)[:,itrack] #Residue and convergence evconverge = abs(mode.evalue - evals[itrack]) residue = mode.residue = self.residue(mode) mode.convergence += [ residue ] mode.track += [ mode.evalue ] logging.debug( "[%d] neff: %s conv: %.3g, res:%.3g" % (numit, mode.neff, evconverge, mode.residue) ) mode.iterations = numit #Discard vectors at this stage, to free up memory if we can mode.compress() return mode, evals
def eval_evec(self,d,typ,k,which): a=d['mat'].astype(typ) # get exact eigenvalues exact_eval=d['eval'].astype(typ) ind=self.sort_choose(exact_eval,typ,k,which) exact_eval=exact_eval[ind] # compute eigenvalues eval,evec=eigen(a,k,which=which) ind=self.sort_choose(eval,typ,k,which) eval=eval[ind] evec=evec[:,ind] # check eigenvalues assert_array_almost_equal(eval,exact_eval,decimal=_ndigits[typ]) # check eigenvectors A*evec=eval*evec for i in range(k): assert_array_almost_equal(dot(a,evec[:,i]), eval[i]*evec[:,i], decimal=_ndigits[typ])
def eval_evec(self, d, typ, k, which): a = d['mat'].astype(typ) # get exact eigenvalues exact_eval = d['eval'].astype(typ) ind = self.sort_choose(exact_eval, typ, k, which) exact_eval = exact_eval[ind] # compute eigenvalues eval, evec = eigen(a, k, which=which) ind = self.sort_choose(eval, typ, k, which) eval = eval[ind] evec = evec[:, ind] # check eigenvalues assert_array_almost_equal(eval, exact_eval, decimal=_ndigits[typ]) # check eigenvectors A*evec=eval*evec for i in range(k): assert_array_almost_equal(dot(a, evec[:, i]), eval[i] * evec[:, i], decimal=_ndigits[typ])
def estimate_condition_number(P_kd, P_gk, S_dd, N, alpha, compute_exact = False): P_kd = as_Lens3D_matrix(P_kd) P_gk = as_Lens3D_matrix(P_gk) S_dd = as_Lens3D_matrix(S_dd) N = as_Lens3D_matrix(N) P_gk_cross = P_gk.conj_transpose() P_kd_T = P_kd.transpose() def matvec(v): v0 = P_gk_cross.view_as_Lens3D_vec(v) v2 = P_gk_cross.matvec( v0 ) v2 = P_kd_T.matvec( v2 ) v2 = S_dd.matvec( v2 ) v2 = P_kd.matvec( v2 ) v2 = P_gk.matvec( v2 ) v1 = N.matvec(v0) v1 *= alpha ret = numpy.zeros(v.shape,dtype=complex) ret += v1.vec ret += v2.vec return P_gk_cross.view_as_same_type( ret , v ) M = LinearOperator(P_gk.shape, matvec=matvec, dtype=complex) #compute the exact condition number if compute_exact: v = numpy.random.random(M.shape[1]) t0 = time() v2 = M.matvec(v) t = time()-t0 print " - constructing matrix representation (est. %s)" \ % printtime(t*M.shape[0]) t0 = time() M_rep = get_mat_rep(M) print " time to get mat rep: %.2g sec" % (time()-t0) print " - computing SVD" t0 = time() sig = numpy.linalg.svd(M_rep,compute_uv=False) print " time for SVD: %.2g sec" % (time()-t0) print 'true condition number: %.2e / %.2e = %.2e' \ % (sig[0],sig[-1], sig[0]/sig[-1]) #estimate condition number, assuming the noiseless matrix # is rank-deficient. This will be true if there are more # source lens-planes than mass lens-planes eval_max,evec_max = arpack.eigen(M,1) print 'estimated condition number: %.2e / %.2e = %.2e' \ % ( abs(eval_max[0]) , numpy.min(N.data), abs(eval_max[0]) / numpy.min(N.data) )
#Labs = abs(Ldense) I = numpy.argsort(Ldense) II = I[0:13] Ldensef = Ldense[II] for i in II: eval = Ldense[i] evec = Xdense[:,i] print eval print "computing eigenvalues..." st = time() fac = (1/dx)**2 #Evals,Evecs = arpack.eigen(-M, k=16, which="SM", tol=1e-15, maxiter=200000, ncv=128) Evals,Evecs = arpack.eigen(-M, k=16, which="SM", maxiter=200000, ncv=128) print "found eigenvalues in time = " + str(time() - st) # gives very poor results (as expected, our matrix is not symmetric) #L,X = arpack.eigen_symmetric(M, k=50, which="SM") #for i,lam in enumerate(L): #print i,lam #evec = X[:,i] pylab.figure(1) pylab.clf() pylab.plot(real(Evals),imag(Evals),'rx') pylab.title('spectrum')
def calculate_delta_arpack(gamma, P_gk, P_kd, N_angular, N_los, border_size, border_noise, sig_cuts): """ gamma should be a vector of length (Nx*Ny*Nz) N_angular is a vector of length (Nx*Ny) N_los is a vector of length Nz sigma gives the percentage of variance to cut out of the inversion """ Nx = gamma.Nx Ny = gamma.Ny Nz1 = P_kd.Nz_in Nz2 = P_kd.Nz_out #for all the lens-plane operations, we'll need two versions of # Lens3D matrices, with Nz1 and Nz2 source planes. P_gk1 = Lens3D_lp_conv(Nz1,Nx,Ny, P_gk.dx_,P_gk.dy_, func=P_gk.func_[0], func_ft=P_gk.func_ft_[0]) P_gk2 = P_gk #get a single convolution plane P_gk_one = Lens3D_lp_conv(1,Nx,Ny, P_gk.dx_,P_gk.dy_, func=P_gk.func_[0], func_ft=P_gk.func_ft_[0]) P_gk_one_H = P_gk_one.H N_a = Lens3D_vector(1,Nx,Ny,N_angular) N_a.set_border(border_size,border_noise) N1I = 1./N_a.vec N2I = 1./N_los NI = Lens3D_vector(Nz2,Nx,Ny,numpy.outer(N2I,N1I)) #use arpack to find singular vectors num_sing_vals = (Nx-2*border_size)*(Ny-2*border_size)+1 use_arpack = True if use_arpack: #define the function to send to ARPACK def matvec(v): matvec.N += 1 if matvec.N % 100 == 0: print matvec.N vv = v*N1I #vv = P_gk_one.view_as_Lens3D_vec(vv) vv = P_gk_one_H.matvec(vv) vv = P_gk_one.matvec(vv) #vv = P_gk_one.view_as_same_type(vv,v) vv *= N1I return vv matvec.N = 0 DMMD = LinearOperator(shape = (Nx*Ny,Nx*Ny), matvec = matvec, dtype = complex) print "ARPACK: finding %i singular values of [%ix%i] matrix" \ % (num_sing_vals,DMMD.shape[0],DMMD.shape[1]) t = time() S1_2,U1 = arpack.eigen(DMMD,num_sing_vals,which='LR') t = time()-t print " finished in %i iterations" % matvec.N print " (time: %.3g sec: %.2g sec per iteration)" \ % (t,t*1./matvec.N) exit() S1 = numpy.sqrt(S1_2.real) else: P_gk_r = P_gk.as_Lens3D_lp_mat() U1,S1,V1 = numpy.linalg.svd(N1I[:,None]*P_gk_r.mat_list_[0], full_matrices=0) S1 = S1[:num_sing_vals] U1 = U1[:,:num_sing_vals] compare_to_direct = False if compare_to_direct: print "compare to direct svd" print "computing svds" S1.sort() pylab.plot( S1[::-1] ) P_gk_r = P_gk.as_Lens3D_lp_mat() U1,S1,V1 = numpy.linalg.svd(N1I[:,None]*P_gk_r.mat_list_[0], full_matrices=0) pylab.plot( S1[:num_sing_vals] ) pylab.show() exit() U2,S2,V2 = numpy.linalg.svd(N2I[:,None]*P_kd.data_, full_matrices=0) Nz1 = P_kd.Nz_in Nz2 = P_kd.Nz_out U_gk1 = Lens3D_lp_mat(Nz1, num_sing_vals,1,Nx, Ny, mat_list=U1) U_gk2 = Lens3D_lp_mat(Nz2, num_sing_vals,1,Nx, Ny, mat_list=U1) S_gk1 = Lens3D_lp_diag(Nz1, num_sing_vals, 1, S1) S_gk2 = Lens3D_lp_diag(Nz2, num_sing_vals, 1, S1) #V_gk will be S_gk^-1 * U_gk^H * N1I * N1I * P_gk V_gk = Lens3D_multi(Lens3D_lp_diag(Nz1, num_sing_vals, 1, 1./S1), U_gk1.H, Lens3D_lp_diag(Nz1,Nx,Ny,N1I), P_gk1) U_kd = Lens3D_los_mat(Nz1, Nx, Ny, Nz2, U2) S_kd = Lens3D_diag(Nz1, Nx, Ny, numpy.outer(S2,numpy.ones(Nx*Ny)).ravel() ) V_kd = Lens3D_los_mat(Nz1, Nx, Ny, Nz1, V2) U = Lens3D_multi(U_kd,U_gk1) S = Lens3D_diag(Nz1, num_sing_vals,1, numpy.outer(S2,S1).ravel() ) V = Lens3D_multi(V_gk,V_kd) i_sort = numpy.argsort(S.data_) sig = S.data_[i_sort] sig *= sig sig_cumsum = sig.cumsum() sig_sum = sig.sum() N_tot = len(sig) N_cuts = [] v_cuts = [] deltas = [] for sig_cut in sig_cuts: N_cut = sig_cumsum.searchsorted(sig_sum*sig_cut) v_cut = numpy.sqrt( sig[N_cut] ) SI = Lens3D_diag(Nzd,Nx,Ny, 1./S.data_) SI.data_[i_sort[:N_cut]] = 0 #compute delta print "computing delta" v1 = Lens3D_vector(Nzg,Nx,Ny,gamma.vec*NI.vec) v1 = U.H.matvec(v1) v1 = SI.matvec(v1) delta = V.H.matvec(v1) N_cuts.append(N_cut) v_cuts.append(v_cut) deltas.append(delta) return deltas,N_cuts,v_cuts,S1,S2
from numpy import * from math import atan2 from pylab import * from solver1 import * from solver2 import * import scipy.sparse.linalg.eigen.arpack as arp import pickle #Load mesh fin = open("mesh.pkl", "rb") mesh = pickle.load(fin) pts = pickle.load(fin) boundary = pickle.load(fin) fin.close() #Construct matrix U, A, b = fe_solve(mesh, pts[:,0], pts[:,1], lambda x,y:0, boundary, zeros((len(pts)))) #Compute top 4 Eigen values of A w, v = arp.eigen(A, 4) #Plot results for k in range(4): clf() plot_mesh(mesh, abs(v[:,k])) savefig("prob4_eig" + str(k) + ".png") show()
def calculate(self, number=inf): m0 = self.m0 k0 = self.k0 number = min(number, self.totalnumber) logging.info("Center solver. Finding modes, m0=%d, wl=%.3g" % (m0, self.wl)) #Create new matrix if there is no existing one if self.si is None: self.si = ShiftInvertBlock(overwrite=self.overwrite) self.create() #Time mode solve tick = timer.timer() tick.start() #Array to store solved modes evrange = array(self.bracket)**2 * self.k0**2 #Update equation with new BCs and update LU decomp self.update_lambda(self.evapprox, not self.overwrite) self.si.set_shift(self.matrix, self.evapprox + 0j) #Find modes of linearized system if use_arpack: cev = eigen(self.si, k=self.totalnumber, which='LM', return_eigenvectors=False) cev = self.si.eigenvalue_transform(cev) else: cev, cvecs = eigs(self.si, self.totalnumber, tol=1e-6) #Filter cev within range if self.ignore_outside_interval: cev = filter(lambda x: min(evrange) <= real(x) <= max(evrange), cev) #Refine modes for ii in range(len(cev)): evsearch = cev[ii] #If the matrix is overwritten we must recreate it if self.overwrite: self.generate() self.si.set_shift(self.matrix, evsearch + 0j) #Calculate next mode mode, evals = self.calculate_one(evsearch, self.searchnumber) #Add mode to list if (mode.residue < self.abc_convergence) or self.add_if_unconverged: self.modes += [mode] avtime = tick.lap() / (ii + 1) logging.info( "Mode #%d [%d/%.3gs], neff=%s, res: %.2e" % \ (self.numbersolved, mode.iterations, avtime, mode.neff, mode.residue) ) self.add_time(tick.lap()) #Clean up if calculation is finished! if self.isfinished(): self.finalize() return self.modes
def calculate_one(self, evsearch, searchnum): """ Calculate single mode using fixed point iterations calculate_one(evsearch, searchnum) """ m0 = self.m0 k0 = self.k0 wl = self.wl bcstart, bcend = self.equation.diff.bc_extents() coord = self.wg.get_coord(self.base_shape, border=1) #Create new mode mode = self.mode_class(coord=coord, symmetry=self.wg.symmetry, m0=m0, wl=wl, evalue=evsearch, wg=self.wg) mode.right = ones(mode.shape, dtype=self.dtype) mode.discard_vectors = self.discard_vectors residue = inf numit = 0 evtol = 1e-10 while residue > self.abc_convergence and numit < self.abc_iterations: numit += 1 #Update equation with new BCs and update LU decomp self.update_lambda(mode.evalue) if self.equation.coord.rmin == 0: self.si.update(self.matrix, uprows=bcend) else: self.si.set_shift(self.matrix, complex(mode.evalue)) #Solve linear eigenproblem if use_arpack: evals, revecs = eigen(self.si, k=searchnum, \ which='LM', return_eigenvectors=True) evals = self.si.eigenvalue_transform(evals) else: evals, revecs = eigs(self.si, searchnum, tol=evtol) revecs = revecs.T #Locate closest eigenvalue itrack = absolute(evals - mode.evalue).argmin() mode.evalue = evals[itrack] mode.right = asarray(revecs)[:, itrack] #Residue and convergence evconverge = abs(mode.evalue - evals[itrack]) residue = mode.residue = self.residue(mode) mode.convergence += [residue] mode.track += [mode.evalue] logging.debug("[%d] neff: %s conv: %.3g, res:%.3g" % (numit, mode.neff, evconverge, mode.residue)) mode.iterations = numit #Discard vectors at this stage, to free up memory if we can mode.compress() return mode, evals