def linop_solve(operator, arr): """Solve `operator @ x = arr`. deal with arr possibly having multiple columns. Parameters ---------- operator: LinearOperator arr: array_like Returns ------- array_like The solution to the linear equation. """ _asarray = np.asarray def toarray(arr): """Make `arr` an array.""" try: return arr.todense() except AttributeError: return _asarray(arr) if arr.ndim == 1: return asarray(lgmres(operator, toarray(arr), atol=1e-7)[0]) return asarray( stack([lgmres(operator, toarray(col), atol=1e-7)[0] for col in arr.T], axis=1))
def disk_conformal_mapping(mesh, lap_type='conformal', boundary=None, boundary_coords=None): """ Computes comformal mapping of a mesh to a disk, see the following references: Ulrich Pinkall and Konrad Polthier, “Computing Discrete Minimal Surfaces and Their Conjugates,” Experimental Mathematics, 1993, 1–33. and Mathieu Desbrun, Mark Meyer, and Pierre Alliez, “Intrinsic Parameterizations of Surface Meshes,” Computer Graphics Forum 21, no. 3 (2002): 209–18, https://doi.org/10.1111/1467-8659.00580. :param mesh: a trimesh object :param lap_type: type of mesh Laplacian to be used, see the function differential_geometry/compute_mesh_weights for more informations :param boundary: boundary of the mesh, resulting from the function topology/mesh_boundary :param boundary_coords: coordindates of the boundary vertices on the output disk, if None then uniform sampling :return: a trimesh object, planar disk representation of the input mesh """ if boundary is None: boundary_t = stop.mesh_boundary(mesh) boundary = boundary_t[0] boundary = np.array(boundary) if boundary_coords is None: p = boundary.size t = np.arange(0, 2 * np.math.pi, (2 * np.math.pi / p)) boundary_coords = np.array([np.cos(t), np.sin(t)]) L, LB = sdg.compute_mesh_laplacian(mesh, lap_type=lap_type) Nv = len(mesh.vertices) # np.array(mesh.vertex()).shape[0] print('Boundary Size:', boundary.shape) print('Laplacian Size:', L.shape) for i in boundary: L[i, :] = 0 L[i, i] = 1 L = L.tocsr() Rx = np.zeros(Nv) Ry = np.zeros(Nv) Rx[boundary] = boundary_coords[0, :] Ry[boundary] = boundary_coords[1, :] x, info = lgmres(L, Rx, tol=solver_tolerance) y, info = lgmres(L, Ry, tol=solver_tolerance) z = np.zeros(Nv) return trimesh.Trimesh(faces=mesh.faces, vertices=np.array([x, y, z]).T, metadata=mesh.metadata, process=False)
def time_solve(self, n, solver): if solver == 'dense': linalg.solve(self.P_dense, self.b) elif solver == 'cg': cg(self.P_sparse, self.b) elif solver == 'minres': minres(self.P_sparse, self.b) elif solver == 'lgmres': lgmres(self.P_sparse, self.b) elif solver == 'spsolve': spsolve(self.P_sparse, self.b) else: raise ValueError('Unknown solver: %r' % solver)
def laplacian_smoothing(texture_data, lap, lap_b, nb_iter, dt): """ sub-function for smoothing using fem Laplacian :param texture_data: :param lap: :param lap_b: :param nb_iter: :param dt: :return: """ mod = 1 if nb_iter > 10: mod = 10 if nb_iter > 100: mod = 100 if nb_iter > 1000: mod = 1000 # print(tex.shape[0]) # print(tex.ndim) # if tex.ndim < 2: # Mtex = tex.reshape(tex.shape[0],1) # else: # Mtex = tex # using Implicit scheme # B(X^(n+1)-X^n)/dt+L(X^(n+1))=0 M = lap_b + dt * lap for i in range(nb_iter): texture_data = lap_b * texture_data if texture_data.ndim > 1: for d in range(texture_data.shape[1]): texture_data[:, d], infos = lgmres(M.tocsr(), texture_data[:, d], tol=solver_tolerance) else: texture_data, infos = lgmres(M.tocsr(), texture_data, tol=solver_tolerance) if i % mod == 0: print(i) # using Explicit scheme, convergence guaranteed only for dt<1 and not # faster than implicit when using fem Laplacian # B(X^(n+1)-X^n)/dt+L(X^n)=0 # M = B-dt*L # for i in range(Niter): # Mtex = M * Mtex # Mtex, infos = lgmres(B.tocsr(), Mtex, tol=solver_tolerance) # if (i % mod == 0): # print(i) print(' OK') return texture_data
def calcHmeanval(MPS, R, C, guess): chir, chic, aux = MPS.shape QHAAAAR = getQHaaaaR(MPS, R, C) if (chir, chic) < guess.shape: guess = guess[-chir:, -chic:] linOpWrapped = functools.partial(linearOpForK, MPS, R) linOpForLsol = spspla.LinearOperator((chir * chir, chic * chic), matvec=linOpWrapped, dtype=MPS.dtype) K, info = spspla.lgmres(linOpForLsol, QHAAAAR, tol=1.e-13, maxiter=maxIter, x0=guess.reshape(chir * chic)) if info > 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol=expS, x0=K, maxiter=maxIter) elif info < 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol=expS, maxiter=maxIter) if info != 0: print >> sys.stderr, "calcHmeanval: Error", I, "lgmres and gmres failed" K = np.reshape(K, (chir, chic)) print "QHAAAAR", QHAAAAR.shape, "info", info, np.isfinite( K).all(), "K\n", K return K
def calcHmeanval(MPS, R, C, guess): chir, chic, aux = MPS.shape QHAAAAR = getQHaaaaR(MPS, R, C) if (chir, chic) < guess.shape: guess = guess[-chir:, -chic:] linOpWrapped = functools.partial(linearOpForK, MPS, R) linOpForLsol = spspla.LinearOperator((chir * chir, chic * chic), matvec = linOpWrapped, dtype = MPS.dtype) K, info = spspla.lgmres(linOpForLsol, QHAAAAR, tol = 1.e-13, maxiter = maxIter, x0 = guess.reshape(chir * chic)) if info > 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol = expS, x0 = K, maxiter = maxIter) elif info < 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol = expS, maxiter = maxIter) if info != 0: print >> sys.stderr, "calcHmeanval: Error", I, "lgmres and gmres failed" K = np.reshape(K, (chir, chic)) print "QHAAAAR", QHAAAAR.shape, "info", info, np.isfinite(K).all(), "K\n", K return K
def solveNonlinear1(A, u_n, F_b, lam=1.5, tol=10e-10, maxiter=100): """ Solve the nonlinear eqation Au = \lambda/u^2 + F_b using Newton's method. :param A: descretization of the problem :param u_n: The inial guess for the solution u :param F_b: Right hand side, using boundary points :param lam: \lambda as described :param tol: tolerance of max(abs( Au -\lambda/u^2 - F_b)) :param maxiter: maximum number of iterations of Newton's method. :return U: solution :return error : max(abs( Au -\lambda/u^2 - F_b)) :return iter: iterations """ du = np.copy(u_n) error = 100 iter = 0 F = A @ u_n - lam / u_n ** 2 - F_b while iter < maxiter and error > tol: #Standard newthons method jacobian = A + np.diag(lam / u_n) du = splin.lgmres(jacobian, -F, du)[0] u_n += du F = A @ u_n - lam / u_n **2 - F_b error = np.nanmax(np.abs(F)) iter += 1 return u_n, error, iter
def calculate_pi(cls): if not FORCE_REBUILD: try: with open(cls.steady_filename, 'rb') as file: cls.pi = pickle.load(file) if __debug__: print("Loaded steady state from", cls.steady_filename) return except FileNotFoundError: pass if __debug__: print("Calculating steady state") # Ax = b A = cls.tpm.transpose() - identity(cls.size) A = vstack([A[:-1, :], np.ones(cls.size)], format='csr') b = np.zeros(cls.size) b[-1] = 1 x, info = lgmres(A, b, tol=1e-14, atol=1e-14, maxiter=5000) # Check if there are any negative values, but tolerate errors smaller than 1e-10 assert np.allclose(x[x < 0], 0, rtol=0, atol=1e-10), "Steady State with negative values" assert info == 0, "The iterative method did not converge" cls.pi = x if __debug__: print("Steady state calculated") os.makedirs(os.path.dirname(cls.steady_filename), exist_ok=True) with open(cls.steady_filename, 'wb') as file: pickle.dump(cls.pi, file, pickle.HIGHEST_PROTOCOL)
def diffuse(labelVector, ps): svSum = labelVector.sum() if (svSum == 0): return lil_matrix(shape=(1, len(labelVector)), dtype=np.float64) y = labelVector f = lgmres(ps, y)[0] return f
def calcF(Q_, R_, way, rho_, muL_, guess): chi, chi = Q_.shape rhs = -getQrhsQ(Q_, R_, way, rho_, muL_) if (guess == None): guess = np.random.rand(chi * chi) - .5 guess = guess.reshape(chi * chi) linOpWrap = functools.partial(linOpForF, Q_, R_, way, rho_) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec=linOpWrap, dtype='float64') try: F, info = spspla.lgmres(linOpForSol, rhs, tol=expS, x0=guess, maxiter=maxIter, outer_k=6) except (ArpackError, ArpackNoConvergence): print "calcF: bicgstab failed, trying gmres\n" guess = F if info > 0 else guess try: F, info = spspla.bicgstab(linOpForSol, rhs, tol=expS, x0=guess, maxiter=maxIter) except (ArpackError, ArpackNoConvergence): print "calcF: gmres failed, taking lame solution\n" F = F if info > 0 else guess #print "F\n", F.reshape(chi, chi) return F.reshape(chi, chi)
def lgmres_test(): A = rand(30, 30) b = rand(30) lgmres_cp = GPRpy.scipy.lgmres_wrapper(A, b) lgmres_py = lgmres(A, b)[0] print("LGMRES", check(lgmres_cp, lgmres_py)) return lgmres_cp, lgmres_py
def LGMRES_solver(mps, direction, left_dominant, right_dominant, inhom, x0, precision=1e-10, nmax=2000, **kwargs): #mps.D[0] has to be mps.D[-1], so no distincion between direction='l' or direction='r' has to be made here if not tf.equal(mps.D[0], mps.D[-1]): raise ValueError( 'in LGMRES_solver: mps.D[0]!=mps.D[-1], can only handle intinite MPS!' ) inhom_numpy = tf.reshape(inhom, [mps.D[0] * mps.D[0]]).numpy() x0_numpy = tf.reshape(x0, [mps.D[0] * mps.D[0]]).numpy() mv = fct.partial(one_minus_pseudo_unitcell_transfer_op, *[direction, mps, left_dominant, right_dominant]) LOP = LinearOperator((int(mps.D[0])**2, int(mps.D[-1])**2), matvec=mv, dtype=mps.dtype.as_numpy_dtype) out, info = lgmres( A=LOP, b=inhom_numpy, x0=x0_numpy, tol=precision, maxiter=nmax, **kwargs) return tf.reshape(tf.convert_to_tensor(out), [mps.D[0], mps.D[0]]), info
def calcF(Q_, R_, way, rho_, muL_, guess): chi, chi = Q_.shape rhs = - getQrhsQ(Q_, R_, way, rho_, muL_) if(guess == None): guess = np.random.rand(chi * chi) - .5 guess = guess.reshape(chi * chi) linOpWrap = functools.partial(linOpForF, Q_, R_, way, rho_) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec = linOpWrap, dtype = 'float64') try: F, info = spspla.lgmres(linOpForSol, rhs, tol = expS, x0 = guess, maxiter = maxIter, outer_k = 6) except (ArpackError, ArpackNoConvergence): print "calcF: bicgstab failed, trying gmres\n" guess = F if info > 0 else guess try: F, info = spspla.bicgstab(linOpForSol, rhs, tol = expS, x0 = guess, maxiter = maxIter) except (ArpackError, ArpackNoConvergence): print "calcF: gmres failed, taking lame solution\n" F = F if info > 0 else guess #print "F\n", F.reshape(chi, chi) return F.reshape(chi, chi)
def gw_comp_veff(self, vext, comega=1j * 0.0): """ This computes an effective field (scalar potential) given the external scalar potential as follows: (1-v\chi_{0})V_{eff} = V_{ext} = X_{a}^{n}V_{\mu}^{ab}X_{b}^{m} * v\chi_{0}v * X_{a}^{n}V_{nu}^{ab}X_{b}^{m} returns V_{eff} as list for all n states(self.nn[s]). """ from scipy.sparse.linalg import LinearOperator self.comega_current = comega veff_op = LinearOperator((self.nprod, self.nprod), matvec=self.gw_vext2veffmatvec, dtype=self.dtypeComplex) from scipy.sparse.linalg import lgmres resgm, info = lgmres(veff_op, np.require(vext, dtype=self.dtypeComplex, requirements='C'), atol=self.gw_iter_tol, maxiter=self.maxiter) if info != 0: print("LGMRES has not achieved convergence: exitCode = {}".format( info)) return resgm
def gw_corr_res_iter(self, sn2w): """ This computes a residue part of the GW correction at energies in iterative procedure """ from scipy.sparse.linalg import lgmres, LinearOperator v_pab = self.pb.get_ac_vertex_array() sn2res = [np.zeros_like(n2w, dtype=self.dtype) for n2w in sn2w ] k_c_opt = LinearOperator((self.nprod,self.nprod), matvec=self.gw_vext2veffmatvec, dtype=self.dtypeComplex) for s,ww in enumerate(sn2w): x = self.mo_coeff[0,s,:,:,0] for nl,(n,w) in enumerate(zip(self.nn[s],ww)): lsos = self.lsofs_inside_contour(self.ksn2e[0,s,:],w,self.dw_excl) zww = array([pole[0] for pole in lsos]) xv = np.dot(v_pab,x[n]) for pole, z_real in zip(lsos, zww): self.comega_current = z_real xvx = np.dot(xv, x[pole[1]]) a = np.dot(self.kernel_sq, xvx) b = self.gw_chi0_mv(a, self.comega_current) a = np.dot(self.kernel_sq, b) si_xvx, exitCode = lgmres(k_c_opt, a, atol=self.gw_iter_tol, maxiter=self.maxiter) if exitCode != 0: print("LGMRES has not achieved convergence: exitCode = {}".format(exitCode)) contr = np.dot(xvx, si_xvx) sn2res[s][nl] += pole[2]*contr.real return sn2res
def comp_veff(self, vext, comega=1j * 0.0, x0=None): """ This computes an effective field (scalar potential) given the external scalar potential """ from scipy.sparse.linalg import LinearOperator, lgmres nsp = self.nspin * self.nprod assert len(vext) == nsp, "{} {}".format(len(vext), nsp) self.comega_current = comega veff_op = LinearOperator((nsp, nsp), matvec=self.vext2veff_matvec, dtype=self.dtypeComplex) if self.res_method == "absolute": tol = 0.0 atol = self.tddft_iter_tol elif self.res_method == "relative": tol = self.tddft_iter_tol atol = 0.0 elif self.res_method == "both": tol = self.tddft_iter_tol atol = self.tddft_iter_tol else: raise ValueError("Unknow res_method") resgm, info = lgmres(veff_op, np.require(vext, dtype=self.dtypeComplex, requirements='C'), x0=x0, tol=tol, atol=atol, maxiter=self.maxiter) if info != 0: print("LGMRES Warning: info = {0}".format(info)) return resgm
def solve(A, b, method, tol=1e-3): """ General sparse solver interface. method can be one of - spsolve_umfpack_mmd_ata - spsolve_umfpack_colamd - spsolve_superlu_mmd_ata - spsolve_superlu_colamd - bicg - bicgstab - cg - cgs - gmres - lgmres - minres - qmr - lsqr - lsmr """ if method == 'spsolve_umfpack_mmd_ata': return spla.spsolve(A, b, use_umfpack=True, permc_spec='MMD_ATA') elif method == 'spsolve_umfpack_colamd': return spla.spsolve(A, b, use_umfpack=True, permc_spec='COLAMD') elif method == 'spsolve_superlu_mmd_ata': return spla.spsolve(A, b, use_umfpack=False, permc_spec='MMD_ATA') elif method == 'spsolve_superlu_colamd': return spla.spsolve(A, b, use_umfpack=False, permc_spec='COLAMD') elif method == 'bicg': res = spla.bicg(A, b, tol=tol) return res[0] elif method == 'bicgstab': res = spla.bicgstab(A, b, tol=tol) return res[0] elif method == 'cg': res = spla.cg(A, b, tol=tol) return res[0] elif method == 'cgs': res = spla.cgs(A, b, tol=tol) return res[0] elif method == 'gmres': res = spla.gmres(A, b, tol=tol) return res[0] elif method == 'lgmres': res = spla.lgmres(A, b, tol=tol) return res[0] elif method == 'minres': res = spla.minres(A, b, tol=tol) return res[0] elif method == 'qmr': res = spla.qmr(A, b, tol=tol) return res[0] elif method == 'lsqr': res = spla.lsqr(A, b, atol=tol, btol=tol) return res[0] elif method == 'lsmr': res = spla.lsmr(A, b, atol=tol, btol=tol) return res[0] else: raise Exception('UnknownSolverType')
def start_solve(self): B = np.zeros_like(self._Mesh.X_flatten) for i in range(len(self._Mesh.X_flatten)): if self._BCtype[i] == NodeType.DIRICHLET and self._Mesh.Y_flatten[ i] == 1: B[i] = 1 elif self._BCtype[ i] == NodeType.DIRICHLET and self._Mesh.X_flatten[i] == 1: B[i] = 0 self._Phi = lgmres(self._SystemMatrix, B)[0] fig = plt.figure() ax = fig.add_subplot(111, projection='3d') my_cm = plt.cm.get_cmap('rainbow') pnt3d = ax.scatter(self._Mesh.X_flatten, self._Mesh.Y_flatten, self._Phi, c=self._Phi, cmap=my_cm) cbar = plt.colorbar(pnt3d) plt.show() self.printDate(self._dir_name) print('Calculation Completed!!!')
def _step(self, dt): if dt != self.dt: self.LHS = self.M + dt/2*self.L self.RHS_matrix = self.M - dt/2*self.L #self.LU = spla.splu(LHS.tocsc(), permc_spec='NATURAL') self.dt = dt if (self.axis == 'full'): np.copyto(self.data, self.X.data) data_shape = self.data.shape flattened_data = self.data.reshape(np.prod(data_shape)) self.RHS = self.RHS.reshape(flattened_data.shape) apply_matrix(self.RHS_matrix, flattened_data, 0, out=self.RHS) #self.data = self.LU.solve(self.RHS).reshape(data_shape) self.data,exitCode = lgmres(self.LHS,self.RHS) self.data=self.data.reshape(data_shape) np.copyto(self.X.data, self.data) else: self._transpose_pre() # change view self.RHS = self.RHS.reshape(self.data.shape) apply_matrix(self.RHS_matrix, self.data, 0, out=self.RHS) self.data = self.LU.solve(self.RHS) self._transpose_post()
def LGMRES_solver(mps, direction, left_dominant, right_dominant, inhom, x0, precision=1e-10, nmax=2000, **kwargs): #mps.D[0] has to be mps.D[-1], so no distincion between direction='l' or direction='r' has to be made here if not tf.equal(mps.D[0], mps.D[-1]): raise ValueError( 'in LGMRES_solver: mps.D[0]!=mps.D[-1], can only handle intinite MPS!' ) inhom_numpy = tf.reshape(inhom, [mps.D[0] * mps.D[0]]).numpy() x0_numpy = tf.reshape(x0, [mps.D[0] * mps.D[0]]).numpy() mv = fct.partial(one_minus_pseudo_unitcell_transfer_op, *[direction, mps, left_dominant, right_dominant]) LOP = LinearOperator((int(mps.D[0])**2, int(mps.D[-1])**2), matvec=mv, dtype=mps.dtype.as_numpy_dtype) out, info = lgmres(A=LOP, b=inhom_numpy, x0=x0_numpy, tol=precision, maxiter=nmax, **kwargs) return tf.reshape(tf.convert_to_tensor(out), [mps.D[0], mps.D[0]]), info
def si_c2(self, ww): """ This computes the correlation part of the screened interaction using LinearOpt and lgmres lgmres method is much slower than np.linalg.solve !! """ import numpy as np from scipy.sparse.linalg import lgmres from scipy.sparse.linalg import LinearOperator rf0 = si0 = self.rf0(ww) for iw, w in enumerate(ww): k_c = np.dot(self.kernel_sq, rf0[iw, :, :]) b = np.dot(k_c, self.kernel_sq) self.comega_current = w k_c_opt = LinearOperator((self.nprod, self.nprod), matvec=self.gw_vext2veffmatvec, dtype=self.dtypeComplex) for m in range(self.nprod): si0[iw, m, :], exitCode = lgmres(k_c_opt, b[m, :], atol=self.gw_iter_tol, maxiter=self.maxiter) if exitCode != 0: print("LGMRES has not achieved convergence: exitCode = {}". format(exitCode)) #np.allclose(np.dot(k_c, si0), b, atol=1e-05) == True #Test return si0
def disk_conformal_mapping(mesh, lap_type='conformal', boundary=None, boundary_coords=None): """ compute comformal mapping of a mesh to a disk ADD ref :param mesh: a trimesh object :param lap_type: type of mesh Laplacian to be used, see the function differential_geometry/compute_mesh_weights for more informations :param boundary: boundary of the mesh, resulting from the function topology/mesh_boundary :param boundary_coords: coordindates of the boundary vertices on the output disk, if None then uniform sampling :return: a trimesh object, planar disk representation of the input mesh """ if boundary is None: boundary_t = stop.mesh_boundary(mesh) boundary = boundary_t[0] boundary = np.array(boundary) if boundary_coords is None: p = boundary.size t = np.arange(0, 2 * np.math.pi, (2 * np.math.pi / p)) boundary_coords = np.array([np.cos(t), np.sin(t)]) L, LB = sdg.compute_mesh_laplacian(mesh, lap_type=lap_type) Nv = len(mesh.vertices) # np.array(mesh.vertex()).shape[0] print('Boundary Size:', boundary.shape) print('Laplacian Size:', L.shape) for i in boundary: L[i, :] = 0 L[i, i] = 1 L = L.tocsr() Rx = np.zeros(Nv) Ry = np.zeros(Nv) Rx[boundary] = boundary_coords[0, :] Ry[boundary] = boundary_coords[1, :] x, info = lgmres(L, Rx, tol=solver_tolerance) y, info = lgmres(L, Ry, tol=solver_tolerance) z = np.zeros(Nv) return trimesh.Trimesh(faces=mesh.faces, vertices=np.array([x, y, z]).T, metadata=mesh.metadata, process=False)
def get_snmw2sf_iter(self, optimize="greedy"): """ This computes a matrix elements of W_c: <\Psi(r)\Psi(r) | W_c(r,r',\omega) |\Psi(r')\Psi(r')>. sf[spin,n,m,w] = X^n V_mu X^m W_mu_nu X^n V_nu X^m, where n runs from s...f, m runs from 0...norbs, w runs from 0...nff_ia, spin=0...1 or 2. 1- XVX is calculated using dominant product in COO format: gw_xvx('dp_coo') 2- I_nm = W XVX = (1-v\chi_0)^{-1}v\chi_0v 3- S_nm = XVX W XVX = XVX * I_nm """ from scipy.sparse.linalg import LinearOperator, lgmres ww = 1j * self.ww_ia xvx = self.gw_xvx('blas') snm2i = [] #convert k_c as full matrix into Operator k_c_opt = LinearOperator((self.nprod, self.nprod), matvec=self.gw_vext2veffmatvec, dtype=self.dtypeComplex) for s in range(self.nspin): sf_aux = np.zeros((len(self.nn[s]), self.norbs, self.nprod), dtype=self.dtypeComplex) inm = np.zeros((len(self.nn[s]), self.norbs, len(ww)), dtype=self.dtypeComplex) # w is complex plane for iw, w in enumerate(ww): self.comega_current = w #print('k_c_opt',k_c_opt.shape) for n in range(len(self.nn[s])): for m in range(self.norbs): # v XVX a = np.dot(self.kernel_sq, xvx[s][n, m, :]) # \chi_{0}v XVX by using matrix vector b = self.gw_chi0_mv(a, self.comega_current) # v\chi_{0}v XVX, this should be equals to bxvx in last approach a = np.dot(self.kernel_sq, b) sf_aux[n, m, :], exitCode = lgmres(k_c_opt, a, atol=self.gw_iter_tol, maxiter=self.maxiter) if exitCode != 0: print( "LGMRES has not achieved convergence: exitCode = {}" .format(exitCode)) # I= XVX I_aux inm[:, :, iw] = np.einsum('nmp,nmp->nm', xvx[s], sf_aux, optimize=optimize) snm2i.append(np.real(inm)) if (self.write_w == True): from pyscf.nao.m_restart import write_rst_h5py print(write_rst_h5py(data=snm2i, filename='SCREENED_COULOMB.hdf5')) return snm2i
def sort_capacitance(coords, mat, left_lead, right_lead, **kwargs): """Sorting procedure that uses a potential function defined over atomic coordinates as the sorting keys. Parameters ---------- coords : array list of atomic coordinates mat : 2D array adjacency matrix of the tight-binding model left_lead : array list of the atom indices contacting the left lead right_lead : array list of the atom indices contacting the right lead **kwargs : Returns ------- """ charge = np.zeros(coords.shape[0], dtype=np.complex) charge[left_lead] = 1e3 charge[right_lead] = -1e3 x = coords[:, 1].T y = coords[:, 0].T mat = (mat != 0.0).astype(np.float) mat = 10 * (mat - np.diag(np.diag(mat))) mat = mat - np.diag(np.sum(mat, axis=1)) + 0.001 * np.identity(mat.shape[0]) col, info = lgmres(mat, charge.T, x0=1.0 / np.diag(mat), tol=1e-5, maxiter=15) col = col / np.max(col) indices = np.argsort(col, kind='heapsort') mat = mat[indices, :] mat = mat[:, indices] plt.scatter(x, y, c=col, cmap=plt.cm.get_cmap('seismic'), s=50, marker="o", edgecolors="k") plt.colorbar() plt.axis('off') plt.show() return indices
def pseudoinverse(L, Q, y): '''Effective calculation of pseudoinverse without need for explicit calculation of pseudoinverse of L which would be dense. L is time-local generator of open system dynamics Q is operator projecting onto space orthogonal to steady state y is vector or matrix being operated on by pseudoinverse''' result = spla.lgmres(L, Q.dot(y), tol=1.e-5, maxiter=10000) return result[0] # spla.lgmres(L, Q.dot(y), tol=1.e-12)[0]
def solve(self, system: AlgebraicSystem): if (system.numberOfEquations() != system.numberOfVariables()): self.log( f"Number of Equations: {system.numberOfEquations()} Number of Variables: {system.numberOfVariables()}" ) raise RuntimeError("Can only solve square systems") system.createIndex() system.createSparsityPattern() delta = np.zeros(system.numberOfVariables()) b = np.zeros(system.numberOfEquations()) n = 1e12 e = 1e12 if (self.iterCallback): self.iterCallback(-1, n, e) labels = ["Iter", "Norm", "Residual", "Flags", "Comment"] comment = '' self.log( f"{labels[0]:<4} {'': <10s} {labels[1]:<12} {'': <10s} {labels[2]:<12} {'': <10s} {labels[3]:<6} {'': <10s} {labels[4]:<12}" ) for i in range(self.maximumIterations): A, b = fillJacobian(system, b) delta = sparseLinearSolve(A, -b) comment = '' n = norm(delta) e = np.amax(b) flags = ["-", "-", "-", "-"] if (np.isnan(n)): delta, _ = lgmres(A, -b) flags[0] = 'I' comment = 'Singular Matrix. Trying lgmres' n = norm(delta) for index, variable in enumerate(system.variables): variable.addDelta(self.factor * delta[index]) self.log( f"{i:4} {'': <10s} {('{0:2E}'.format(n)):>12} {'': <10s} {('{0:2E}'.format(e)):>12} {'': <10s} {''.join(flags):<6} {'': <10s} {comment}" ) if (self.iterCallback): self.iterCallback(i, n, e) if (norm(delta) < self.tolerance): if (e < self.tolerance): self.log("Solve succeeded.") else: self.log( "Norm is less than tolerance but residuals are not converged." ) return True self.log("Maximum number of iterations exceeded!") return False
def solve(self, tol=1e-12): A = self.A F = self.F counter = IterationCounter() x, info = lgmres(A, F, tol=1e-12, callback=counter) print("Convergence info:", info) print("Number of iteration of gmres:", counter.niter) return x
def gij(m, i=0, delta=0.01, e=0.0): """Calculate a single row of the Green function""" v0 = np.zeros(m.shape[0]) v0[i] = 1. iden = eye(v0.shape[0]) # identity matrix g = iden * (e + 1j * delta) - csc_matrix(m) # matrix to invert # print(type(g)) ; exit() (b, info) = slg.lgmres(g, v0) # solve the equation go = (b * np.conjugate(b)).real return go
def gij(m,i=0,delta=0.01,e=0.0): """Calculate a single row of the Green function""" v0 = np.zeros(m.shape[0]) v0[i] = 1. iden = eye(v0.shape[0]) # identity matrix g = iden*(e+1j*delta) - csc_matrix(m) # matrix to invert # print(type(g)) ; exit() (b,info) = slg.lgmres(g,v0) # solve the equation go = (b*np.conjugate(b)).real return go
def solve_linear(model): logger.info('solving problem with %d DOFs...' % model.DOF) K_, f_ = model.K_, model.f_ # M_x = lambda x: sl.spsolve(P, x) # M = sl.LinearOperator((n, n), M_x) #print(sl.spsolve(K_,f_)) delta, info = sl.lgmres(K_, f_.toarray()) model.is_solved = True logger.info('Done!') model.d_ = delta.reshape((model.node_count * 6, 1)) model.r_ = model.K * model.d_
def dyncorr(a, b, e0, v0, h, omega=0.0, eta=0.01): """Calculates a dynamical correlator. This funcion impements <0|A(E+omega+ieta - H)^(-1)B|0> """ bv = b * v0 # right term iden = tensorial.identity(len(v0)) # identity matrix g = iden * (omega + e0 + 1j * eta) - h # matrix to invert g = tensorial.slo2lo(g) # print(type(g)) ; exit() (gbv, info) = slg.lgmres(g, bv) # solve the equation cf = np.conjugate(v0).dot(a * gbv) # correlation function return cf.imag # return the expectation value
def compute_certificate(self): """ Function to compute the certificate based either current value or dual variables loaded from dual folder """ lambda_neg_val = self.sess.run(self.lambda_neg) lambda_lu_val = self.sess.run(self.lambda_lu) input_vector_h = tf.placeholder(tf.float32, shape=(self.matrix_m_dimension - 1, 1)) output_vector_h = self.get_h_product(input_vector_h) def np_vector_prod_fn_h(np_vector): np_vector = np.reshape(np_vector, [-1, 1]) output_np_vector = self.sess.run(output_vector_h, feed_dict={input_vector_h:np_vector}) return output_np_vector linear_operator_h = LinearOperator((self.matrix_m_dimension - 1, self.matrix_m_dimension - 1), matvec=np_vector_prod_fn_h) # Performing shift invert scipy operation when eig val estimate is available min_eig_val_h, _ = eigs(linear_operator_h, k=1, which='SR', tol=TOL) # It's likely that the approximation is off by the tolerance value, # so we shift it back min_eig_val_h = np.real(min_eig_val_h) - TOL dual_feed_dict = {} new_lambda_lu_val = [np.copy(x) for x in lambda_lu_val] new_lambda_neg_val = [np.copy(x) for x in lambda_neg_val] for i in range(self.nn_params.num_hidden_layers + 1): # Making H PSD new_lambda_lu_val[i] = lambda_lu_val[i] + 0.5*np.maximum(-min_eig_val_h, 0) + TOL # Adjusting the value of \lambda_neg to make change in g small new_lambda_neg_val[i] = lambda_neg_val[i] + np.multiply((self.lower[i] + self.upper[i]), (lambda_lu_val[i] - new_lambda_lu_val[i])) new_lambda_neg_val[i] = (np.multiply(self.negative_indices[i], new_lambda_neg_val[i]) + np.multiply(self.switch_indices[i], np.maximum(new_lambda_neg_val[i], 0))) dual_feed_dict.update(zip(self.lambda_lu, new_lambda_lu_val)) dual_feed_dict.update(zip(self.lambda_neg, new_lambda_neg_val)) scalar_f = self.sess.run(self.scalar_f, feed_dict=dual_feed_dict) vector_g = self.sess.run(self.vector_g, feed_dict=dual_feed_dict) x, _ = lgmres(linear_operator_h, vector_g) x = x.reshape((x.shape[0], 1)) second_term = np.matmul(np.transpose(vector_g), x) + 0.05 computed_certificate = scalar_f + 0.5*second_term return computed_certificate
def solveLinSys(Q_, R_, way, myGuess, method = None): chi, chi = Q_.shape linOpWrap = functools.partial(linOpForT, Q_, R_, way) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec = linOpWrap, dtype = 'float64') if(method == 'bicgstab'): S, info = spspla.lgmres(linOpForSol, np.zeros(chi * chi), tol = expS, x0 = myGuess, maxiter = maxIter, outer_k = 6) else:#if(method == 'gmres'): S, info = spspla.gmres(linOpForSol, np.zeros(chi * chi), tol = expS, x0 = myGuess, maxiter = maxIter) return info, S.reshape(chi, chi)
def iterative_solver_list(self, which, rhs, *args): """Solves the linear problem Ab = x using the sparse matrix Parameters ---------- rhs : ndarray the right hand side which : string choose which solver is used bicg(A, b[, x0, tol, maxiter, xtype, M, ...]) Use BIConjugate Gradient iteration to solve A x = b bicgstab(A, b[, x0, tol, maxiter, xtype, M, ...]) Use BIConjugate Gradient STABilized iteration to solve A x = b cg(A, b[, x0, tol, maxiter, xtype, M, callback]) Use Conjugate Gradient iteration to solve A x = b cgs(A, b[, x0, tol, maxiter, xtype, M, callback]) Use Conjugate Gradient Squared iteration to solve A x = b gmres(A, b[, x0, tol, restart, maxiter, ...]) Use Generalized Minimal RESidual iteration to solve A x = b. lgmres(A, b[, x0, tol, maxiter, M, ...]) Solve a matrix equation using the LGMRES algorithm. minres(A, b[, x0, shift, tol, maxiter, ...]) Use MINimum RESidual iteration to solve Ax=b qmr(A, b[, x0, tol, maxiter, xtype, M1, M2, ...]) Use Quasi-Minimal Residual iteration to solve A x = b """ if which == 'bicg': return spla.bicg(self.sp_matrix, rhs, args) elif which == "cg": return spla.cg(self.sp_matrix, rhs, args) elif which == "bicgstab": return spla.bicgstab(self.sp_matrix, rhs, args) elif which == "cgs": return spla.cgs(self.sp_matrix, rhs, args) elif which == "gmres": return spla.gmres(self.sp_matrix, rhs, args) elif which == "lgmres": return spla.lgmres(self.sp_matrix, rhs, args) elif which == "qmr": return spla.qmr(self.sp_matrix, rhs, args) else: raise NotImplementedError("this solver is unknown")
def diffuse(self): """Diffuses information from input nodes across the graph.""" lpp = sparse.csgraph.laplacian(self.network.network) alpha = 1 / float(np.max(np.sum(np.abs(lpp), axis=0))) ident = sparse.csc_matrix(np.eye(self.network.network.shape[0])) ps = ident + alpha * lpp initial_state = np.zeros(self.network.network.shape[0]) input_indices = self.get_node_indices(self.input_nodes) initial_state[input_indices] = 1 diff_out = lgmres(ps, initial_state, maxiter=1000, atol=1e-12) final_state = diff_out[0] result = DiffusionResult(final_state, initial_state, self.network.proteins) return result
def call_solver(op, hI, params, x0): """ Code used by both solve_for_RH and solve_for_LH to call the sparse solver. """ if x0 is not None: x0 = x0.flatten() x, info = lgmres(op, hI.flatten(), tol=params["env_tol"], maxiter=params["env_maxiter"], inner_m=params["inner_m_lgmres"], outer_k=params["outer_k_lgmres"], x0=x0) new_hI = x.reshape(hI.shape) return (new_hI, info)
def solveForMu(Q_, R_, way, myGuess, method, X): chi, chi = Q_.shape inhom = supOp(R_, R_, way, X).reshape(chi * chi) #print "solveForMu:", way linOpWrap = functools.partial(linOpForExp, Q_, R_, way) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec = linOpWrap, dtype = 'float64') if(method == 'bicgstab'): S, info = spspla.lgmres(linOpForSol, inhom, tol = expS, x0 = myGuess, maxiter = maxIter, outer_k = 6) else:#if(method == 'gmres'): S, info = spspla.gmres(linOpForSol, inhom, tol = expS, x0 = myGuess, maxiter = maxIter) return info, S.reshape(chi, chi)
def test_scipy_gmres_linop_parameter(self): """ This is a test on gmres method with a parameter-dependent linear operator """ for omega in np.linspace(-10.0, 10.0, 10): for eps in np.linspace(-10.0, 10.0, 10): linop_param = linalg.aslinearoperator(vext2veff_c(omega, eps, n)) Aparam = np.zeros((n,n), np.complex64) for i in range(n): uv = np.zeros(n, np.complex64); uv[i] = 1.0 Aparam[:,i] = linop_param.matvec(uv) x_ref = np.dot(inv(Aparam), b) x_itr,info = linalg.lgmres(linop_param, b) derr = abs(x_ref-x_itr).sum()/x_ref.size self.assertLess(derr, 1e-6)
def LinSolve(A,b,x0,method): if method=='bicg': x,info = bicg(A,b,x0) if method=='cgs': x,info = cgs(A,b,x0) if method=='bicgstab': x,info = bicgstab(A,b,x0) if (info): print 'INFO=',info if method=='superLU': x = linsolve.spsolve(A,b,use_umfpack=False) if method=='umfpack': x = linsolve.spsolve(A,b,use_umfpack=True) if method=='gmres': x,info = gmres(A,b,x0) if method=='lgmres': x,info = lgmres(A,b,x0) return x
def _apply_inverse(matrix, V, options=None): """Solve linear equation system. Applies the inverse of `matrix` to the row vectors in `V`. See :func:`dense_options` for documentation of all possible options for sparse matrices. See :func:`sparse_options` for documentation of all possible options for sparse matrices. This method is called by :meth:`pymor.core.NumpyMatrixOperator.apply_inverse` and usually should not be used directly. Parameters ---------- matrix The |NumPy| matrix to invert. V 2-dimensional |NumPy array| containing as row vectors the right-hand sides of the linear equation systems to solve. options The solver options to use. (See :func:`_options`.) Returns ------- |NumPy array| of the solution vectors. """ default_options = _options(matrix) if options is None: options = default_options.values()[0] elif isinstance(options, str): if options == "least_squares": for k, v in default_options.iteritems(): if k.startswith("least_squares"): options = v break assert not isinstance(options, str) else: options = default_options[options] else: assert ( "type" in options and options["type"] in default_options and options.viewkeys() <= default_options[options["type"]].viewkeys() ) user_options = options options = default_options[user_options["type"]] options.update(user_options) R = np.empty((len(V), matrix.shape[1]), dtype=np.promote_types(matrix.dtype, V.dtype)) if options["type"] == "solve": for i, VV in enumerate(V): try: R[i] = np.linalg.solve(matrix, VV) except np.linalg.LinAlgError as e: raise InversionError("{}: {}".format(str(type(e)), str(e))) elif options["type"] == "least_squares_lstsq": for i, VV in enumerate(V): try: R[i], _, _, _ = np.linalg.lstsq(matrix, VV, rcond=options["rcond"]) except np.linalg.LinAlgError as e: raise InversionError("{}: {}".format(str(type(e)), str(e))) elif options["type"] == "bicgstab": for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options["tol"], maxiter=options["maxiter"]) if info != 0: if info > 0: raise InversionError("bicgstab failed to converge after {} iterations".format(info)) else: raise InversionError("bicgstab failed with error code {} (illegal input or breakdown)".format(info)) elif options["type"] == "bicgstab_spilu": ilu = spilu( matrix, drop_tol=options["spilu_drop_tol"], fill_factor=options["spilu_fill_factor"], drop_rule=options["spilu_drop_rule"], permc_spec=options["spilu_permc_spec"], ) precond = LinearOperator(matrix.shape, ilu.solve) for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options["tol"], maxiter=options["maxiter"], M=precond) if info != 0: if info > 0: raise InversionError("bicgstab failed to converge after {} iterations".format(info)) else: raise InversionError("bicgstab failed with error code {} (illegal input or breakdown)".format(info)) elif options["type"] == "spsolve": try: if scipy.version.version >= "0.14": if hasattr(matrix, "factorization"): R = matrix.factorization.solve(V.T).T elif options["keep_factorization"]: matrix.factorization = splu(matrix, permc_spec=options["permc_spec"]) R = matrix.factorization.solve(V.T).T else: R = spsolve(matrix, V.T, permc_spec=options["permc_spec"]).T else: if hasattr(matrix, "factorization"): for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV) elif options["keep_factorization"]: matrix.factorization = splu(matrix, permc_spec=options["permc_spec"]) for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV) elif len(V) > 1: factorization = splu(matrix, permc_spec=options["permc_spec"]) for i, VV in enumerate(V): R[i] = factorization.solve(VV) else: R = spsolve(matrix, V.T, permc_spec=options["permc_spec"]).reshape((1, -1)) except RuntimeError as e: raise InversionError(e) elif options["type"] == "lgmres": for i, VV in enumerate(V): R[i], info = lgmres( matrix, VV.copy(i), tol=options["tol"], maxiter=options["maxiter"], inner_m=options["inner_m"], outer_k=options["outer_k"], ) if info > 0: raise InversionError("lgmres failed to converge after {} iterations".format(info)) assert info == 0 elif options["type"] == "least_squares_lsmr": for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _ = lsmr( matrix, VV.copy(i), damp=options["damp"], atol=options["atol"], btol=options["btol"], conlim=options["conlim"], maxiter=options["maxiter"], show=options["show"], ) assert 0 <= info <= 7 if info == 7: raise InversionError("lsmr failed to converge after {} iterations".format(itn)) elif options["type"] == "least_squares_lsqr": for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _, _, _ = lsqr( matrix, VV.copy(i), damp=options["damp"], atol=options["atol"], btol=options["btol"], conlim=options["conlim"], iter_lim=options["iter_lim"], show=options["show"], ) assert 0 <= info <= 7 if info == 7: raise InversionError("lsmr failed to converge after {} iterations".format(itn)) elif options["type"] == "pyamg": if len(V) > 0: V_iter = iter(enumerate(V)) R[0], ml = pyamg.solve( matrix, next(V_iter)[1], tol=options["tol"], maxiter=options["maxiter"], return_solver=True ) for i, VV in V_iter: R[i] = pyamg.solve(matrix, VV, tol=options["tol"], maxiter=options["maxiter"], existing_solver=ml) elif options["type"] == "pyamg-rs": ml = pyamg.ruge_stuben_solver( matrix, strength=options["strength"], CF=options["CF"], presmoother=options["presmoother"], postsmoother=options["postsmoother"], max_levels=options["max_levels"], max_coarse=options["max_coarse"], coarse_solver=options["coarse_solver"], ) for i, VV in enumerate(V): R[i] = ml.solve( VV, tol=options["tol"], maxiter=options["maxiter"], cycle=options["cycle"], accel=options["accel"] ) elif options["type"] == "pyamg-sa": ml = pyamg.smoothed_aggregation_solver( matrix, symmetry=options["symmetry"], strength=options["strength"], aggregate=options["aggregate"], smooth=options["smooth"], presmoother=options["presmoother"], postsmoother=options["postsmoother"], improve_candidates=options["improve_candidates"], max_levels=options["max_levels"], max_coarse=options["max_coarse"], diagonal_dominance=options["diagonal_dominance"], ) for i, VV in enumerate(V): R[i] = ml.solve( VV, tol=options["tol"], maxiter=options["maxiter"], cycle=options["cycle"], accel=options["accel"] ) elif options["type"].startswith("generic") or options["type"].startswith("least_squares_generic"): logger = getLogger("pymor.operators.numpy._apply_inverse") logger.warn("You have selected a (potentially slow) generic solver for a NumPy matrix operator!") from pymor.operators.numpy import NumpyMatrixOperator from pymor.vectorarrays.numpy import NumpyVectorArray return genericsolvers.apply_inverse( NumpyMatrixOperator(matrix), NumpyVectorArray(V, copy=False), options=options ).data else: raise ValueError("Unknown solver type") return R
def main(): """ STARTED 18/02/2015 PURPOSE Numerically integrate the coloured-noise FPE in 1. B+W and @. HO potentials. EXECUTION python FPE_NumericalIntegrate.py <IC> ipython FPE_NumericalIntegrate.py --matplotlib BUGS / NOTES / TODO -- Space is offset by one. Affects J and p. -- estep unstable if y-drift expanded -- abrupt F -> instability """ plt.ion() t0 = time.time(); tevo=0 IM = 0 ## Integration method; 0=RK2, 1=CN PS = 1 ## Potential setup; 0=harmonic, 1=bulk+walls, 2=diffusion try: IC = int(argv[1]) except: IC = 3 ## System / evolution parameters N = 100 global dx; dx = 1. global dy; dy = 1. dt = 1.0/(N*N) nsteps = int(1/dt) if IM == 1: dt*=10; #nsteps*=2 ## Space J = -np.arange(-N/2+1,N/2+1,1)[:,np.newaxis] X = np.arange(-N/2,N/2+2,1) ## Force f = 1. F = -f*X if PS == 1: i_w = N/10; x_w = i_w*dx F = np.zeros(N+2);F[:i_w+2]=f;F[-(i_w+2):]=-f; #Problem with index? elif PS == 2: f=0.0 ## Output framerate = 200#min([nsteps/50,200]) outfile = "./img_FPE_SS/FPE_PS"+str(PS)+"_f"+str(f)+"_n"+str(nsteps)+"_IM"+str(IM) ##--------------------------------------------------- ## Construct CN matrix if IM == 1: CN,CNp = make_CN_sp(N,dt,dx,dy,f,F,J,PS) CN = splinalg.aslinearoperator(CN) ##--------------------------------------------------- ## Initial condition sig = 0.05*N; tD0 = 0.5*sig*sig if IC == 3: ## 2D Gaussian p0 = pGaussD(0,tD0,X[1:-1],J,N) p=copy.copy(p0) ##--------------------------------------------------- ## Set up plots vmin,vmax = (np.min(p0),np.max(p0)) fig, (ax1,ax2) = plt.subplots(1,2, facecolor='white') im1 = ax1.imshow(p0, vmin=vmin,vmax=vmax, interpolation="nearest") ## Comparison if PS==2: ## Diffusion im2 = ax2.imshow(pGaussD(0,tD0,X[1:-1],J,N), vmin=vmin,vmax=vmax, interpolation="nearest") subtit = ["Numerical","Diffusion, exact"] else: ## HO SS ## Covariance matrix C = np.sqrt(8.)*(f**2) * np.array([[(f+1)**2.,+0.5*(f+1)**(3./2.)],[+0.5*(f+1)**(3./2.),(f+1)]]) im2 = ax2.imshow(Gauss2D(X[1:-1],J,C), vmin=vmin,vmax=vmax, interpolation="nearest") subtit = ["Numerical","HO SS"] if PS==1: pass [[ax.set_title(tit),ax.set_xlabel("$x$"),ax.set_ylabel("$\eta$")] for ax,tit in zip((ax1,ax2),subtit)] fig.colorbar(im1, ax=[ax1,ax2], orientation='horizontal') frame=0 ##--------------------------------------------------- ## Evolution for n in range(nsteps): t=n*dt t1=time.time() ## BCs p = apply_BCs(p,"outflow") ## Choose method: if IM==1: ## CN # test: cgs, gmres, lgmres p, info = splinalg.lgmres(CNp, CN.matvec(p.flatten()))#, p.flatten() p = p.reshape([N,N]) else: ## RK2 kp1 = dt*estep_unexp(p,J,F,PS) kp2 = dt*estep_unexp(p+0.5*kp1,J,F,PS) p += kp2 tevo+=time.time()-t1 ## Plot if n%(framerate)==0: plt.pause(1e-6) im1.set_data(p); im1.set_clim([p.min(),p.max()]) if PS==2: ## Diffusion res = p-pGaussD(t,tD0,X[1:-1],J,N) im2.set_data(res); im2.set_clim([p.min(),p.max()]) plt.draw() frame+=1 print "Step",n,"Time",round(n*dt,2),"\t Normalisation",intarr(p,dx) ##--------------------------------------------------- plt.savefig(outfile+".png") ## Outinfo print "Evolution",round(tevo/nsteps,3),"seconds per timestep." return
def test_scipy_gmres_linop(self): """ This is a test on gmres method with linear operators in scipy """ linop = linalg.LinearOperator((n,n), matvec=mvop, dtype=np.complex64) x_itr,info = linalg.lgmres(linop, b) derr = abs(x_ref-x_itr).sum()/x_ref.size self.assertLess(derr, 1e-6)
def test_scipy_gmres_den(self): """ This is a test on gmres method with dense matrix in scipy """ x_itr,info = linalg.lgmres(A, b) derr = abs(x_ref-x_itr).sum()/x_ref.size self.assertLess(derr, 1e-6)
def _steadystate_iterative(L, ss_args): """ Iterative steady state solver using the GMRES, LGMRES, or BICGSTAB algorithm and a sparse incomplete LU preconditioner. """ ss_iters = {'iter': 0} def _iter_count(r): ss_iters['iter'] += 1 return if settings.debug: print('Starting '+ss_args['method']+' solver...') dims = L.dims[0] n = prod(L.dims[0][0]) b = np.zeros(n ** 2) b[0] = ss_args['weight'] L, perm, perm2, rev_perm, ss_args = _steadystate_LU_liouvillian(L, ss_args) if np.any(perm): b = b[np.ix_(perm,)] if np.any(perm2): b = b[np.ix_(perm2,)] use_solver(assumeSortedIndices=True, useUmfpack=ss_args['use_umfpack']) if ss_args['M'] is None and ss_args['use_precond']: ss_args['M'], ss_args = _iterative_precondition(L, n, ss_args) if ss_args['M'] is None: warnings.warn("Preconditioning failed. Continuing without.", UserWarning) # Select iterative solver type _iter_start = time.time() if ss_args['method'] == 'iterative-gmres': v, check = gmres(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'iterative-lgmres': v, check = lgmres(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'iterative-bicgstab': v, check = bicgstab(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) else: raise Exception("Invalid iterative solver method.") _iter_end = time.time() ss_args['info']['iter_time'] = _iter_end - _iter_start if 'precond_time' in ss_args['info'].keys(): ss_args['info']['solution_time'] = (ss_args['info']['iter_time'] + ss_args['info']['precond_time']) ss_args['info']['iterations'] = ss_iters['iter'] ss_args['info']['residual_norm'] = la.norm(b - L*v, np.inf) if settings.debug: print('Number of Iterations:', ss_iters['iter']) print('Iteration. time:', _iter_end - _iter_start) if check > 0: raise Exception("Steadystate error: Did not reach tolerance after " + str(ss_args['maxiter']) + " steps." + "\nResidual norm: " + str(ss_args['info']['residual_norm'])) elif check < 0: raise Exception( "Steadystate error: Failed with fatal error: " + str(check) + ".") if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) if ss_args['return_info']: return Qobj(data, dims=dims, isherm=True), ss_args['info'] else: return Qobj(data, dims=dims, isherm=True)
# Set to CSR-format: C.tocsr() t2 = time.time() print "Time to impose BC: ", t2-t1 ######################### ## SOLVE: ######################### # We try to use a iterative solver: t1 = time.time() # NOTE: spla.minres, although fast, is as of yet # not properly tested by SciPy. # Seems like lgmres is a viable option concerning # speed for now. Another advantage here is that symmetry # is not assumed. X, info = spla.lgmres(C,F) t2 = time.time() print "Time to solve: ", t2-t1 if not info: print "Iterative solver exited successfully." else: print "Iterative solver had an issue. Exit status: ", info # Split solutions: sigma = X[:assembly.dofs_sig] u = X[assembly.dofs_sig:] ######################## ## POST-PROCESSING: ######################## points = np.array(mesh.points)
def _steadystate_iterative(L, ss_args): """ Iterative steady state solver using the GMRES, LGMRES, or BICGSTAB algorithm and a sparse incomplete LU preconditioner. """ ss_iters = {'iter': 0} def _iter_count(r): ss_iters['iter'] += 1 return if settings.debug: logger.debug('Starting %s solver.' % ss_args['method']) dims = L.dims[0] n = int(np.sqrt(L.shape[0])) b = np.zeros(n ** 2) b[0] = ss_args['weight'] L, perm, perm2, rev_perm, ss_args = _steadystate_LU_liouvillian(L, ss_args) if np.any(perm): b = b[np.ix_(perm,)] if np.any(perm2): b = b[np.ix_(perm2,)] use_solver(assumeSortedIndices=True) if ss_args['M'] is None and ss_args['use_precond']: ss_args['M'], ss_args = _iterative_precondition(L, n, ss_args) if ss_args['M'] is None: warnings.warn("Preconditioning failed. Continuing without.", UserWarning) # Select iterative solver type _iter_start = time.time() # FIXME: These atol keyword except checks can be removed once scipy 1.1 # is a minimum requirement if ss_args['method'] == 'iterative-gmres': try: v, check = gmres(L, b, tol=ss_args['tol'], atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = gmres(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'iterative-lgmres': try: v, check = lgmres(L, b, tol=ss_args['tol'], atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = lgmres(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'iterative-bicgstab': try: v, check = bicgstab(L, b, tol=ss_args['tol'], atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = bicgstab(L, b, tol=ss_args['tol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) else: raise Exception("Invalid iterative solver method.") _iter_end = time.time() ss_args['info']['iter_time'] = _iter_end - _iter_start if 'precond_time' in ss_args['info'].keys(): ss_args['info']['solution_time'] = (ss_args['info']['iter_time'] + ss_args['info']['precond_time']) else: ss_args['info']['solution_time'] = ss_args['info']['iter_time'] ss_args['info']['iterations'] = ss_iters['iter'] if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(b - L*v, np.inf) if settings.debug: logger.debug('Number of Iterations: %i' % ss_iters['iter']) logger.debug('Iteration. time: %f' % (_iter_end - _iter_start)) if check > 0: raise Exception("Steadystate error: Did not reach tolerance after " + str(ss_args['maxiter']) + " steps." + "\nResidual norm: " + str(ss_args['info']['residual_norm'])) elif check < 0: raise Exception( "Steadystate error: Failed with fatal error: " + str(check) + ".") if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] data = vec2mat(v) data = 0.5 * (data + data.conj().T) if ss_args['return_info']: return Qobj(data, dims=dims, isherm=True), ss_args['info'] else: return Qobj(data, dims=dims, isherm=True)
M = 100 print("MatrixMarket problem %s" % problem) print("Invert %d x %d matrix; nnz = %d" % (Am.shape[0], Am.shape[1], Am.nnz)) count[0] = 0 x0, info = la.gmres(A, b, restrt=M, tol=1e-14) count_0 = count[0] err0 = np.linalg.norm(Am*x0 - b) / np.linalg.norm(b) print("GMRES(%d):" % M, count_0, "matvecs, residual", err0) if info != 0: print("Didn't converge") count[0] = 0 x1, info = la.lgmres(A, b, inner_m=M-6*2, outer_k=6, tol=1e-14) count_1 = count[0] err1 = np.linalg.norm(Am*x1 - b) / np.linalg.norm(b) print("LGMRES(%d,6) [same memory req.]:" % (M-2*6), count_1, \ "matvecs, residual:", err1) if info != 0: print("Didn't converge") count[0] = 0 x2, info = la.lgmres(A, b, inner_m=M-6, outer_k=6, tol=1e-14) count_2 = count[0] err2 = np.linalg.norm(Am*x2 - b) / np.linalg.norm(b) print("LGMRES(%d,6) [same subspace size]:" % (M-6), count_2, \ "matvecs, residual:", err2) if info != 0: print("Didn't converge")
def apply_inverse(matrix, U, options=None): """Solve linear equation system. Applies the inverse of `matrix` to the row vectors in `U`. See :func:`sparse_options` for documentation of all possible options for sparse matrices. Parameters ---------- matrix The |NumPy| matrix to invert. U 2-dimensional |NumPy array| containing as row vectors the right-hand sides of the linear equation systems to solve. options |invert_options| to use. (See :func:`invert_options`.) Returns ------- |NumPy array| of the solution vectors. """ default_options = invert_options(matrix) if options is None: options = default_options.values()[0] elif isinstance(options, str): if options == 'least_squares': for k, v in default_options.iteritems(): if k.startswith('least_squares'): options = v break assert not isinstance(options, str) else: options = default_options[options] else: assert 'type' in options and options['type'] in default_options \ and options.viewkeys() <= default_options[options['type']].viewkeys() user_options = options options = default_options[user_options['type']] options.update(user_options) R = np.empty((len(U), matrix.shape[1])) if options['type'] == 'solve': for i, UU in enumerate(U): try: R[i] = np.linalg.solve(matrix, UU) except np.linalg.LinAlgError as e: raise InversionError('{}: {}'.format(str(type(e)), str(e))) elif options['type'] == 'least_squares_lstsq': for i, UU in enumerate(U): try: R[i], _, _, _ = np.linalg.lstsq(matrix, UU, rcond=options['rcond']) except np.linalg.LinAlgError as e: raise InversionError('{}: {}'.format(str(type(e)), str(e))) elif options['type'] == 'bicgstab': for i, UU in enumerate(U): R[i], info = bicgstab(matrix, UU, tol=options['tol'], maxiter=options['maxiter']) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'bicgstab_spilu': ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'], drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec']) precond = LinearOperator(matrix.shape, ilu.solve) for i, UU in enumerate(U): R[i], info = bicgstab(matrix, UU, tol=options['tol'], maxiter=options['maxiter'], M=precond) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'spsolve': for i, UU in enumerate(U): R[i] = spsolve(matrix, UU, permc_spec=options['permc_spec']) elif options['type'] == 'lgmres': for i, UU in enumerate(U): R[i], info = lgmres(matrix, UU.copy(i), tol=options['tol'], maxiter=options['maxiter'], inner_m=options['inner_m'], outer_k=options['outer_k']) if info > 0: raise InversionError('lgmres failed to converge after {} iterations'.format(info)) assert info == 0 elif options['type'] == 'least_squares_lsmr': for i, UU in enumerate(U): R[i], info, itn, _, _, _, _, _ = lsmr(matrix, UU.copy(i), damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], maxiter=options['maxiter'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) elif options['type'] == 'least_squares_lsqr': for i, UU in enumerate(U): R[i], info, itn, _, _, _, _, _, _, _ = lsqr(matrix, UU.copy(i), damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], iter_lim=options['iter_lim'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) elif options['type'] == 'pyamg': if len(U) > 0: U_iter = iter(enumerate(U)) R[0], ml = pyamg.solve(matrix, next(U_iter)[1], tol=options['tol'], maxiter=options['maxiter'], return_solver=True) for i, UU in U_iter: R[i] = pyamg.solve(matrix, UU, tol=options['tol'], maxiter=options['maxiter'], existing_solver=ml) elif options['type'] == 'pyamg-rs': ml = pyamg.ruge_stuben_solver(matrix, strength=options['strength'], CF=options['CF'], presmoother=options['presmoother'], postsmoother=options['postsmoother'], max_levels=options['max_levels'], max_coarse=options['max_coarse'], coarse_solver=options['coarse_solver']) for i, UU in enumerate(U): R[i] = ml.solve(UU, tol=options['tol'], maxiter=options['maxiter'], cycle=options['cycle'], accel=options['accel']) elif options['type'] == 'pyamg-sa': ml = pyamg.smoothed_aggregation_solver(matrix, symmetry=options['symmetry'], strength=options['strength'], aggregate=options['aggregate'], smooth=options['smooth'], presmoother=options['presmoother'], postsmoother=options['postsmoother'], improve_candidates=options['improve_candidates'], max_levels=options['max_levels'], max_coarse=options['max_coarse'], diagonal_dominance=options['diagonal_dominance']) for i, UU in enumerate(U): R[i] = ml.solve(UU, tol=options['tol'], maxiter=options['maxiter'], cycle=options['cycle'], accel=options['accel']) elif options['type'].startswith('generic') or options['type'].startswith('least_squares_generic'): logger = getLogger('pymor.la.numpysolvers.apply_inverse') logger.warn('You have selected a (potentially slow) generic solver for a NumPy matrix operator!') from pymor.operators.basic import NumpyMatrixOperator from pymor.la import NumpyVectorArray return genericsolvers.apply_inverse(NumpyMatrixOperator(matrix), NumpyVectorArray(U, copy=False), options=options).data else: raise ValueError('Unknown solver type') return R
def apply_inverse(op, V, options=None, least_squares=False, check_finite=True, default_solver='scipy_spsolve', default_least_squares_solver='scipy_least_squares_lsmr'): """Solve linear equation system. Applies the inverse of `op` to the vectors in `rhs` using PyAMG. Parameters ---------- op The linear, non-parametric |Operator| to invert. rhs |VectorArray| of right-hand sides for the equation system. options The |solver_options| to use (see :func:`solver_options`). check_finite Test if solution only containes finite values. default_solver Default solver to use (scipy_spsolve, scipy_bicgstab, scipy_bicgstab_spilu, scipy_lgmres, scipy_least_squares_lsmr, scipy_least_squares_lsqr). default_least_squares_solver Default solver to use for least squares problems (scipy_least_squares_lsmr, scipy_least_squares_lsqr). Returns ------- |VectorArray| of the solution vectors. """ assert V in op.range if isinstance(op, NumpyMatrixOperator): matrix = op._matrix else: from pymor.algorithms.to_matrix import to_matrix matrix = to_matrix(op) options = _parse_options(options, solver_options(), default_solver, default_least_squares_solver, least_squares) V = V.data promoted_type = np.promote_types(matrix.dtype, V.dtype) R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type) if options['type'] == 'scipy_bicgstab': for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter']) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'scipy_bicgstab_spilu': if Version(scipy.version.version) >= Version('0.19'): ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'], drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec']) else: if options['spilu_drop_rule']: logger = getLogger('pymor.operators.numpy._apply_inverse') logger.error("ignoring drop_rule in ilu factorization due to old SciPy") ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'], permc_spec=options['spilu_permc_spec']) precond = LinearOperator(matrix.shape, ilu.solve) for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter'], M=precond) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'scipy_spsolve': try: # maybe remove unusable factorization: if hasattr(matrix, 'factorization'): fdtype = matrix.factorizationdtype if not np.can_cast(V.dtype, fdtype, casting='safe'): del matrix.factorization if Version(scipy.version.version) >= Version('0.14'): if hasattr(matrix, 'factorization'): # we may use a complex factorization of a real matrix to # apply it to a real vector. In that case, we downcast # the result here, removing the imaginary part, # which should be zero. R = matrix.factorization.solve(V.T).T.astype(promoted_type, copy=False) elif options['keep_factorization']: # the matrix is always converted to the promoted type. # if matrix.dtype == promoted_type, this is a no_op matrix.factorization = splu(matrix_astype_nocopy(matrix.tocsc(), promoted_type), permc_spec=options['permc_spec']) matrix.factorizationdtype = promoted_type R = matrix.factorization.solve(V.T).T else: # the matrix is always converted to the promoted type. # if matrix.dtype == promoted_type, this is a no_op R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).T else: # see if-part for documentation if hasattr(matrix, 'factorization'): for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV).astype(promoted_type, copy=False) elif options['keep_factorization']: matrix.factorization = splu(matrix_astype_nocopy(matrix.tocsc(), promoted_type), permc_spec=options['permc_spec']) matrix.factorizationdtype = promoted_type for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV) elif len(V) > 1: factorization = splu(matrix_astype_nocopy(matrix.tocsc(), promoted_type), permc_spec=options['permc_spec']) for i, VV in enumerate(V): R[i] = factorization.solve(VV) else: R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).reshape((1, -1)) except RuntimeError as e: raise InversionError(e) elif options['type'] == 'scipy_lgmres': for i, VV in enumerate(V): R[i], info = lgmres(matrix, VV, tol=options['tol'], maxiter=options['maxiter'], inner_m=options['inner_m'], outer_k=options['outer_k']) if info > 0: raise InversionError('lgmres failed to converge after {} iterations'.format(info)) assert info == 0 elif options['type'] == 'scipy_least_squares_lsmr': from scipy.sparse.linalg import lsmr for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _ = lsmr(matrix, VV, damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], maxiter=options['maxiter'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) elif options['type'] == 'scipy_least_squares_lsqr': for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _, _, _ = lsqr(matrix, VV, damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], iter_lim=options['iter_lim'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) else: raise ValueError('Unknown solver type') if check_finite: if not np.isfinite(np.sum(R)): raise InversionError('Result contains non-finite values') return op.source.from_data(R)
def _steadystate_power(L, ss_args): """ Inverse power method for steady state solving. """ ss_args['info'].pop('weight', None) if settings.debug: logger.debug('Starting iterative inverse-power method solver.') tol = ss_args['tol'] maxiter = ss_args['maxiter'] use_solver(assumeSortedIndices=True) rhoss = Qobj() sflag = issuper(L) if sflag: rhoss.dims = L.dims[0] else: rhoss.dims = [L.dims[0], 1] n = L.shape[0] # Build Liouvillian if settings.has_mkl and ss_args['method'] == 'power': has_mkl = 1 else: has_mkl = 0 L, perm, perm2, rev_perm, ss_args = _steadystate_power_liouvillian(L, ss_args, has_mkl) orig_nnz = L.nnz # start with all ones as RHS v = np.ones(n, dtype=complex) if ss_args['use_rcm']: v = v[np.ix_(perm2,)] # Do preconditioning if ss_args['M'] is None and ss_args['use_precond'] and \ ss_args['method'] in ['power-gmres', 'power-lgmres', 'power-bicgstab']: ss_args['M'], ss_args = _iterative_precondition(L, int(np.sqrt(n)), ss_args) if ss_args['M'] is None: warnings.warn("Preconditioning failed. Continuing without.", UserWarning) ss_iters = {'iter': 0} def _iter_count(r): ss_iters['iter'] += 1 return _power_start = time.time() # Get LU factors if ss_args['method'] == 'power': if settings.has_mkl: lu = mkl_splu(L) else: lu = splu(L, permc_spec=ss_args['permc_spec'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) if settings.debug and _scipy_check: L_nnz = lu.L.nnz U_nnz = lu.U.nnz logger.debug('L NNZ: %i ; U NNZ: %i' % (L_nnz, U_nnz)) logger.debug('Fill factor: %f' % ((L_nnz+U_nnz)/orig_nnz)) it = 0 _tol = max(ss_args['tol']/10, 1e-15) # Should make this user accessible while (la.norm(L * v, np.inf) > tol) and (it < maxiter): if ss_args['method'] == 'power': v = lu.solve(v) elif ss_args['method'] == 'power-gmres': v, check = gmres(L, v, tol=_tol, M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'power-lgmres': v, check = lgmres(L, v, tol=_tol, M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'power-bicgstab': v, check = bicgstab(L, v, tol=_tol, M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) else: raise Exception("Invalid iterative solver method.") v = v / la.norm(v, np.inf) it += 1 if ss_args['method'] == 'power' and settings.has_mkl: lu.delete() if it >= maxiter: raise Exception('Failed to find steady state after ' + str(maxiter) + ' iterations') _power_end = time.time() ss_args['info']['solution_time'] = _power_end-_power_start ss_args['info']['iterations'] = it if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(L*v) if settings.debug: logger.debug('Number of iterations: %i' % it) if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] # normalise according to type of problem if sflag: trow = sp.eye(rhoss.shape[0], rhoss.shape[0], format='coo') trow = sp_reshape(trow, (1, n)) data = v / sum(trow.dot(v)) else: data = data / la.norm(v) data = sp.csr_matrix(vec2mat(data)) rhoss.data = 0.5 * (data + data.conj().T) rhoss.isherm = True if ss_args['return_info']: return rhoss, ss_args['info'] else: return rhoss
def time_inner(self, n, m): lgmres(self.A, self.b, inner_m=m, maxiter=1)
def lgmres_solve(A,b): """Solve Ax = b w/ lgmres""" x, info = lgmres(A,b,maxiter=10000) if info != 0: raise Exception("lgmres failed on A=%s,b=%s, info:%s" % (A,b,info)) return x
def _steadystate_power(L, ss_args): """ Inverse power method for steady state solving. """ ss_args['info'].pop('weight', None) if settings.debug: logger.debug('Starting iterative inverse-power method solver.') tol = ss_args['tol'] mtol = ss_args['mtol'] if mtol is None: mtol = max(0.1*tol, 1e-15) maxiter = ss_args['maxiter'] use_solver(assumeSortedIndices=True) rhoss = Qobj() sflag = issuper(L) if sflag: rhoss.dims = L.dims[0] else: rhoss.dims = [L.dims[0], 1] n = L.shape[0] # Build Liouvillian if ss_args['solver'] == 'mkl' and ss_args['method'] == 'power': has_mkl = 1 else: has_mkl = 0 L, perm, perm2, rev_perm, ss_args = _steadystate_power_liouvillian(L, ss_args, has_mkl) orig_nnz = L.nnz # start with all ones as RHS v = np.ones(n, dtype=complex) if ss_args['use_rcm']: v = v[np.ix_(perm2,)] # Do preconditioning if ss_args['solver'] == 'scipy': if ss_args['M'] is None and ss_args['use_precond'] and \ ss_args['method'] in ['power-gmres', 'power-lgmres', 'power-bicgstab']: ss_args['M'], ss_args = _iterative_precondition(L, int(np.sqrt(n)), ss_args) if ss_args['M'] is None: warnings.warn("Preconditioning failed. Continuing without.", UserWarning) ss_iters = {'iter': 0} def _iter_count(r): ss_iters['iter'] += 1 return _power_start = time.time() # Get LU factors if ss_args['method'] == 'power': if ss_args['solver'] == 'mkl': lu = mkl_splu(L, max_iter_refine=ss_args['max_iter_refine'], scaling_vectors=ss_args['scaling_vectors'], weighted_matching=ss_args['weighted_matching']) else: lu = splu(L, permc_spec=ss_args['permc_spec'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) if settings.debug and _scipy_check: L_nnz = lu.L.nnz U_nnz = lu.U.nnz logger.debug('L NNZ: %i ; U NNZ: %i' % (L_nnz, U_nnz)) logger.debug('Fill factor: %f' % ((L_nnz+U_nnz)/orig_nnz)) it = 0 # FIXME: These atol keyword except checks can be removed once scipy 1.1 # is a minimum requirement while (la.norm(L * v, np.inf) > tol) and (it < maxiter): check = 0 if ss_args['method'] == 'power': v = lu.solve(v) elif ss_args['method'] == 'power-gmres': try: v, check = gmres(L, v, tol=mtol, atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = gmres(L, v, tol=mtol, M=ss_args['M'], x0=ss_args['x0'], restart=ss_args['restart'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'power-lgmres': try: v, check = lgmres(L, v, tol=mtol, atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = lgmres(L, v, tol=mtol, M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) elif ss_args['method'] == 'power-bicgstab': try: v, check = bicgstab(L, v, tol=mtol, atol=ss_args['matol'], M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) except TypeError as e: if "unexpected keyword argument 'atol'" in str(e): v, check = bicgstab(L, v, tol=mtol, M=ss_args['M'], x0=ss_args['x0'], maxiter=ss_args['maxiter'], callback=_iter_count) else: raise Exception("Invalid iterative solver method.") if check > 0: raise Exception("{} failed to find solution in " "{} iterations.".format(ss_args['method'], check)) if check < 0: raise Exception("Breakdown in {}".format(ss_args['method'])) v = v / la.norm(v, np.inf) it += 1 if ss_args['method'] == 'power' and ss_args['solver'] == 'mkl': lu.delete() if ss_args['return_info']: ss_args['info']['max_iter_refine'] = ss_args['max_iter_refine'] ss_args['info']['scaling_vectors'] = ss_args['scaling_vectors'] ss_args['info']['weighted_matching'] = ss_args['weighted_matching'] if it >= maxiter: raise Exception('Failed to find steady state after ' + str(maxiter) + ' iterations') _power_end = time.time() ss_args['info']['solution_time'] = _power_end-_power_start ss_args['info']['iterations'] = it if ss_args['return_info']: ss_args['info']['residual_norm'] = la.norm(L*v, np.inf) if settings.debug: logger.debug('Number of iterations: %i' % it) if ss_args['use_rcm']: v = v[np.ix_(rev_perm,)] # normalise according to type of problem if sflag: trow = v[::rhoss.shape[0]+1] data = v / np.sum(trow) else: data = data / la.norm(v) data = dense2D_to_fastcsr_fmode(vec2mat(data), rhoss.shape[0], rhoss.shape[0]) rhoss.data = 0.5 * (data + data.H) rhoss.isherm = True if ss_args['return_info']: return rhoss, ss_args['info'] else: return rhoss
def _apply_inverse(matrix, V, options=None): """Solve linear equation system. Applies the inverse of `matrix` to the row vectors in `V`. See :func:`dense_options` for documentation of all possible options for sparse matrices. See :func:`sparse_options` for documentation of all possible options for sparse matrices. This method is called by :meth:`pymor.core.NumpyMatrixOperator.apply_inverse` and usually should not be used directly. Parameters ---------- matrix The |NumPy| matrix to invert. V 2-dimensional |NumPy array| containing as row vectors the right-hand sides of the linear equation systems to solve. options The solver options to use. (See :func:`_options`.) Returns ------- |NumPy array| of the solution vectors. """ default_options = _options(matrix) if options is None: options = default_options.values()[0] elif isinstance(options, str): if options == 'least_squares': for k, v in default_options.iteritems(): if k.startswith('least_squares'): options = v break assert not isinstance(options, str) else: options = default_options[options] else: assert 'type' in options and options['type'] in default_options \ and options.viewkeys() <= default_options[options['type']].viewkeys() user_options = options options = default_options[user_options['type']] options.update(user_options) promoted_type = np.promote_types(matrix.dtype, V.dtype) R = np.empty((len(V), matrix.shape[1]), dtype=promoted_type) if options['type'] == 'solve': for i, VV in enumerate(V): try: R[i] = np.linalg.solve(matrix, VV) except np.linalg.LinAlgError as e: raise InversionError('{}: {}'.format(str(type(e)), str(e))) elif options['type'] == 'least_squares_lstsq': for i, VV in enumerate(V): try: R[i], _, _, _ = np.linalg.lstsq(matrix, VV, rcond=options['rcond']) except np.linalg.LinAlgError as e: raise InversionError('{}: {}'.format(str(type(e)), str(e))) elif options['type'] == 'bicgstab': for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter']) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'bicgstab_spilu': ilu = spilu(matrix, drop_tol=options['spilu_drop_tol'], fill_factor=options['spilu_fill_factor'], drop_rule=options['spilu_drop_rule'], permc_spec=options['spilu_permc_spec']) precond = LinearOperator(matrix.shape, ilu.solve) for i, VV in enumerate(V): R[i], info = bicgstab(matrix, VV, tol=options['tol'], maxiter=options['maxiter'], M=precond) if info != 0: if info > 0: raise InversionError('bicgstab failed to converge after {} iterations'.format(info)) else: raise InversionError('bicgstab failed with error code {} (illegal input or breakdown)'. format(info)) elif options['type'] == 'spsolve': try: # maybe remove unusable factorization: if hasattr(matrix, 'factorization'): fdtype = matrix.factorizationdtype if not np.can_cast(V.dtype, fdtype, casting='safe'): del matrix.factorization if map(int, scipy.version.version.split('.')) >= [0, 14, 0]: if hasattr(matrix, 'factorization'): # we may use a complex factorization of a real matrix to # apply it to a real vector. In that case, we downcast # the result here, removing the imaginary part, # which should be zero. R = matrix.factorization.solve(V.T).T.astype(promoted_type, copy=False) elif options['keep_factorization']: # the matrix is always converted to the promoted type. # if matrix.dtype == promoted_type, this is a no_op matrix.factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec']) matrix.factorizationdtype = promoted_type R = matrix.factorization.solve(V.T).T else: # the matrix is always converted to the promoted type. # if matrix.dtype == promoted_type, this is a no_op R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).T else: # see if-part for documentation if hasattr(matrix, 'factorization'): for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV).astype(promoted_type, copy=False) elif options['keep_factorization']: matrix.factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec']) matrix.factorizationdtype = promoted_type for i, VV in enumerate(V): R[i] = matrix.factorization.solve(VV) elif len(V) > 1: factorization = splu(matrix_astype_nocopy(matrix, promoted_type), permc_spec=options['permc_spec']) for i, VV in enumerate(V): R[i] = factorization.solve(VV) else: R = spsolve(matrix_astype_nocopy(matrix, promoted_type), V.T, permc_spec=options['permc_spec']).reshape((1, -1)) except RuntimeError as e: raise InversionError(e) elif options['type'] == 'lgmres': for i, VV in enumerate(V): R[i], info = lgmres(matrix, VV.copy(i), tol=options['tol'], maxiter=options['maxiter'], inner_m=options['inner_m'], outer_k=options['outer_k']) if info > 0: raise InversionError('lgmres failed to converge after {} iterations'.format(info)) assert info == 0 elif options['type'] == 'least_squares_lsmr': for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _ = lsmr(matrix, VV.copy(i), damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], maxiter=options['maxiter'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) elif options['type'] == 'least_squares_lsqr': for i, VV in enumerate(V): R[i], info, itn, _, _, _, _, _, _, _ = lsqr(matrix, VV.copy(i), damp=options['damp'], atol=options['atol'], btol=options['btol'], conlim=options['conlim'], iter_lim=options['iter_lim'], show=options['show']) assert 0 <= info <= 7 if info == 7: raise InversionError('lsmr failed to converge after {} iterations'.format(itn)) elif options['type'] == 'pyamg': if len(V) > 0: V_iter = iter(enumerate(V)) R[0], ml = pyamg.solve(matrix, next(V_iter)[1], tol=options['tol'], maxiter=options['maxiter'], return_solver=True) for i, VV in V_iter: R[i] = pyamg.solve(matrix, VV, tol=options['tol'], maxiter=options['maxiter'], existing_solver=ml) elif options['type'] == 'pyamg-rs': ml = pyamg.ruge_stuben_solver(matrix, strength=options['strength'], CF=options['CF'], presmoother=options['presmoother'], postsmoother=options['postsmoother'], max_levels=options['max_levels'], max_coarse=options['max_coarse'], coarse_solver=options['coarse_solver']) for i, VV in enumerate(V): R[i] = ml.solve(VV, tol=options['tol'], maxiter=options['maxiter'], cycle=options['cycle'], accel=options['accel']) elif options['type'] == 'pyamg-sa': ml = pyamg.smoothed_aggregation_solver(matrix, symmetry=options['symmetry'], strength=options['strength'], aggregate=options['aggregate'], smooth=options['smooth'], presmoother=options['presmoother'], postsmoother=options['postsmoother'], improve_candidates=options['improve_candidates'], max_levels=options['max_levels'], max_coarse=options['max_coarse'], diagonal_dominance=options['diagonal_dominance']) for i, VV in enumerate(V): R[i] = ml.solve(VV, tol=options['tol'], maxiter=options['maxiter'], cycle=options['cycle'], accel=options['accel']) elif options['type'].startswith('generic') or options['type'].startswith('least_squares_generic'): logger = getLogger('pymor.operators.numpy._apply_inverse') logger.warn('You have selected a (potentially slow) generic solver for a NumPy matrix operator!') from pymor.operators.numpy import NumpyMatrixOperator from pymor.vectorarrays.numpy import NumpyVectorArray return genericsolvers.apply_inverse(NumpyMatrixOperator(matrix), NumpyVectorArray(V, copy=False), options=options).data else: raise ValueError('Unknown solver type') return R
A = mmread(args.A) f = mmread(args.f).flatten() if args.f else np.ones(A.shape[0]) else: with timeit('Generate problem'): A,f = make_poisson_3d(args.n) # Parse parameters prm = {p[0]: p[1] for p in map(lambda s: s.split('='), args.p)} # Create preconditioner with timeit('Setup solver'): P = amg.amgcl(A, prm) print(P) iters = [0] def count_iters(x): iters[0] += 1 # Solve the system for the RHS with timeit('Solve the problem'): x,info = lgmres(A, f, M=P, maxiter=100, tol=1e-8, atol=1e-8, callback=count_iters) print('{0}: {1:.6e}'.format(iters[0], np.linalg.norm(f - A * x) / np.linalg.norm(f))) # Save the solution if args.x: with timeit('Save the result'): mmwrite(args.x, x.reshape((-1,1))) timeit.report()
def _action(self, act=1): if QSMODE == MODE_MPMATH: args = {} if act==0: self.typeStr = "mpmath_qr_solve_dps"+getArgDesc(mpmath.qr_solve, args)+" DPS"+str(DPS) self.matrixType = 1 self.indexType = 1 else: self.coeffVec = mpmath.qr_solve(self.sysMat, self.resVec, **args) self.printCalStr() else: if PYTYPE_COEFF_SOLVE_METHOD == "numpy_solve": args = {} if act==0: self.typeStr = "numpy_solve"+getArgDesc(np.linalg.solve, args) self.matrixType = 0 self.indexType = 0 else: self.coeffVec = np.linalg.solve(self.sysMat, self.resVec, **args) self.printCalStr() elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_lstsq": args = {} if act==0: self.typeStr = "numpy_lstsq"+getArgDesc(np.linalg.lstsq, args) self.matrixType = 0 self.indexType = 0 else: self.coeffVec = np.linalg.lstsq(self.sysMat, self.resVec, **args)[0] self.printCalStr() elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_bicg": args = {} if act==0: self.typeStr = "numpy_sparse_bicg"+getArgDesc(sp_sparse_linalg.bicg, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.bicg(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_bicgstab": args = {} if act==0: self.typeStr = "numpy_sparse_bicgstab"+getArgDesc(sp_sparse_linalg.bicgstab, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.bicgstab(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_lgmres": args = {} if act==0: self.typeStr = "numpy_sparse_lgmres"+getArgDesc(sp_sparse_linalg.lgmres, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.lgmres(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=1000 elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_minres": args = {} if act==0: self.typeStr = "numpy_sparse_minres"+getArgDesc(sp_sparse_linalg.minres, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.minres(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=5*self.sysMat.shape[0] elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_qmr": args = {} if act==0: self.typeStr = "numpy_sparse_qmr"+getArgDesc(sp_sparse_linalg.qmr, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.qmr(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_qr": args_qr = {} args_s = {} if act==0: self.typeStr = "numpy_qr"+getArgDesc(np.linalg.qr, args_qr)+",numpy_solve"+getArgDesc(np.linalg.solve, args_s) self.matrixType = 0 self.indexType = 0 else: Q,R = np.linalg.qr(self.sysMat, **args_qr) y = np.dot(Q.T,self.resVec) self.coeffVec = np.linalg.solve(R,y, **args_s) self.printCalStr()