def preprocess(self, filepath): """Remember: row-first ordered csv file only!""" self.pp("reading") self.node2index, H = read_matrix(filepath, d=-self.d, add_identity=True) self.n, _ = H.shape if self.t is None: self.t = np.power(self.n, -0.5) elif self.t == 0: self.exact = True if self.k is None: self.k = max(1, int(0.001 * self.n)) self.pp("running slashburn") self.perm_H, wing = slashburn(H, self.k, self.greedy) self.body = self.n - wing self.pp("sorting H") H = reorder_matrix(H, self.perm_H) self.pp("partitioning H") H11, H12, H21, H22 = matrix_partition(H, self.body) del H H11 = H11.tocsc() self.pp("computing LU decomposition on H11") if self.exact: self.LU1 = splu(H11) else: self.LU1 = spilu(H11, drop_tol=self.t) del H11 self.pp("computing LU1 solve") S = H22 - H21 @ self.LU1.solve(H12.toarray()) S = coo_matrix(S) self.pp("sorting S") self.perm_S = degree_reverse_rank_perm(S) S = reorder_matrix(S, self.perm_S) self.H12 = reorder_matrix(H12, self.perm_S, fix_row=True) self.H21 = reorder_matrix(H21, self.perm_S, fix_col=True) S = S.tocsc() del H12, H21, H22 self.pp("computing LU decomposition on S") if self.exact: self.LU2 = splu(S) else: self.LU2 = spilu(S, drop_tol=self.t) # issue: this approximation drops accuracy way too much! why? """ if not self.exact: H12 = drop_tolerance(self.H12, self.t) del self.H12 self.H12 = H12 H21 = drop_tolerance(self.H21, self.t) del self.H21 self.H21 = H21 """ del S
def finalize(self): if not self.finalized: # extract diagonal terms for i in xrange(self.rows_l): self.diags[i] = self.data[i, self.row_offset + i] # convert data into sparse format if self.sparse: self.data = self.data.tocsr() else: self.data = sp.csr_matrix(self.data) # if serial, use ILU if self.comm_size == 1: self.ilu_fwd = la.spilu(self.data.tocsc()) self.ilu_rev = la.spilu(self.data.T.tocsc()) self.finalized = True
def prac(): A = np.array([[1, 2], [1, 1]]) b = np.array([1, 2]) LU = linalg.spilu(scipy.sparse.csr_matrix(A)) x = LU.solve(b) print(x)
def __init__(self, A, drop_tol=0.005, fill_factor=2.0, normalize_inplace=False): # the spilu and gmres functions are most efficient with csc sparse. If the # matrix is already csc then this will do nothing A = sp.csc_matrix(A) n = row_norms(A) if normalize_inplace: divide_rows(A, n, inplace=True) else: A = divide_rows(A, n, inplace=False).tocsc() LOGGER.debug( 'computing the ILU decomposition of a %s by %s sparse matrix with %s ' 'nonzeros ' % (A.shape + (A.nnz, ))) ilu = spla.spilu(A, drop_rule='basic', drop_tol=drop_tol, fill_factor=fill_factor) LOGGER.debug('done') M = spla.LinearOperator(A.shape, ilu.solve) self.A = A self.M = M self.n = n
def build_pc_ilu(A: spmatrix, drop_tol: Optional[float] = 1e-4, fill_factor: Optional[float] = 20) -> spl.LinearOperator: """Incomplete LU preconditioner.""" P = spl.spilu(A.tocsc(), drop_tol=drop_tol, fill_factor=fill_factor) M = spl.LinearOperator(A.shape, matvec=P.solve) return M
def __init__(self, A, drop_tol=0.001, fill_factor=15): '''Constructor.''' super().__init__() # Construct the ILU approximate factorization using SuperLU accessed # through the scipy.sparse.linalg interface. Super LU needs # to use CSC format, so do the conversion here. # To adapt SuperLU to incomplete Cholesky, we need to disable # column permutation and row pivoting. We then scale U by sqrt(D^-1) # get the Cholesky factor L^T. ILU = spla.spilu(A.tocsc(), drop_tol=drop_tol, fill_factor=fill_factor, diag_pivot_thresh=0.0, options={'ColPerm': 'NATURAL'}) n = A.shape[0] diagScale = np.reciprocal(np.sqrt(ILU.U.diagonal())) DInv = sp.dia_matrix((diagScale, [0]), shape=(n, n)) self._Lt = DInv * ILU.U del ILU # delete this now to save memory self._L = self._Lt.transpose() self._Lt = self._Lt.tocsr() self._L = self._L.tocsr()
def init_solver(self, L): global linalg from scipy.sparse import linalg ilu = linalg.spilu(self.L1.tocsc()) n = self.n - 1 self.M = linalg.LinearOperator(shape=(n, n), matvec=ilu.solve)
def get_preconditioner(): """Compute the preconditioner M""" diags_x = zeros((3, nx)) diags_x[0, :] = 1 / hx / hx diags_x[1, :] = -2 / hx / hx diags_x[2, :] = 1 / hx / hx Lx = spdiags(diags_x, [-1, 0, 1], nx, nx) diags_y = zeros((3, ny)) diags_y[0, :] = 1 / hy / hy diags_y[1, :] = -2 / hy / hy diags_y[2, :] = 1 / hy / hy Ly = spdiags(diags_y, [-1, 0, 1], ny, ny) J1 = spkron(Lx, eye(ny)) + spkron(eye(nx), Ly) # Now we have the matrix `J_1`. We need to find its inverse `M` -- # however, since an approximate inverse is enough, we can use # the *incomplete LU* decomposition J1_ilu = spilu(J1) # This returns an object with a method .solve() that evaluates # the corresponding matrix-vector product. We need to wrap it into # a LinearOperator before it can be passed to the Krylov methods: M = LinearOperator(shape=(nx * ny, nx * ny), matvec=J1_ilu.solve) return M
def rbf_fd(inner_nodes, boundary_nodes, l, pdim, rbf_tag='r^3', boundary=boundary): n = len(inner_nodes) n_b = len(boundary_nodes) C, b_vec = gen_system(inner_nodes, boundary_nodes, l, pdim, rbf_tag=rbf_tag, boundary=boundary) A_mat = C[:, :n] rhs = C[:, n:] @ b_vec tol = 1e-14 if n <= 400: u = spsolve(A_mat, rhs) else: ilu_A = spilu(A_mat) M = LinearOperator((n, n), lambda x: ilu_A.solve(x)) u, info = gmres(A_mat, rhs, M=M, tol=tol) if info != 0: print('gmres failed') print('n: %d\tinfo: %d' % (n, info)) u = spsolve(A_mat, rhs) u = np.concatenate((u.ravel(), -b_vec.ravel()), axis=0) return u, C, b_vec
def solver_pminres_ilu(A): """ Return a function for solving a sparse linear system using MINRES with ILU. Parameters ---------- A : (N, N) array_like Input. Returns ------- solve : callable To solve the linear system of equations given in `A`, the `solve` callable should be passed an ndarray of shape (N,). """ from scipy.sparse.linalg import minres, spilu, LinearOperator M = LinearOperator(A.shape, matvec=spilu(A.solve)) def solver(b, x0=None): x, info = minres(A.T, b, x0=x0, M=M) if info != 0: raise ValueError(f'MINRES failed: info={info}') return x return solver,
def precond_solve(self): k_mtrx = spilu(self.matrix) r0 = self.b - self.matrix @ self.x0 x0 = self.x0 r2 = r0 p = r0 while True: if r0 @ r2 == 0: exit() pp = k_mtrx.solve(p) tmp = self.matrix @ pp alpha = (r0 @ r2) / (tmp @ r2) s = r0 - alpha * tmp if norm(s) < self.eps: self.k += 1 x = x0 + alpha * pp break z = k_mtrx.solve(s) tmp2 = self.matrix @ z omega = (tmp2 @ s) / (tmp2 @ tmp2) x = x0 + alpha * pp + omega * z r = s - omega * tmp2 beta = (r @ r2) / (r0 @ r2) * (alpha / omega) p = r + beta * (p - omega * tmp) self.k += 1 if norm(r) < self.eps: break x0 = x r0 = r return x
def cgs_solver(self, K, f_ext): """sadasdsa expects K in lil_matrix format """ # convert stiffness matrix to csc format K_csc = sp.csc_matrix(K) if self.settings["precond"]: # perform ILU decomposition stiffness matrix pre_cond = linalg.LinearOperator(K.get_shape(), linalg.spilu(K_csc).solve) else: pre_cond = None (u, exit) = linalg.cgs(K_csc, f_ext, tol=self.settings["tol"], maxiter=self.settings["maxiter"], M=pre_cond) if (exit != 0): raise FEASolverError("CGS solver did not converge.") return u
def preCondition (A): from scipy.sparse.linalg import spilu Ainv=spilu(A,drop_tol= 1e-9) # Using invere.solve to define the mv of preconditioner preconditioner=scipy.sparse.linalg.LinearOperator(Ainv.shape,matvec=Ainv.solve) return preconditioner
def InitializeSolver(self): nodes = self.mesh.nodes elements = self.mesh.elementNodeIds nNodes = nodes.shape[0] nElms = elements.shape[0] nElmNodes = elements.shape[1] w = self.w lN = self.lN lDN = self.lDN # --- Initial assemble: DNs and LHS self.DNs = np.empty((nElms, vDof, nElmNodes), dtype=float) self.volumes = np.zeros(nElms, dtype=float) self.LHS = np.zeros((dof*nNodes, dof*nNodes), dtype=float) lMs = np.zeros((nElms, vDof*nElmNodes, vDof*nElmNodes), dtype=float) self.invLMs = np.zeros_like(lMs) OptimizedExplicitVMSInitialAssemble(nodes, elements, w, lN, lDN, self.DNs, self.volumes, self.LHS, lMs) # Sparse matrix self.spLHS = csc_matrix(self.LHS) myPreconditioner = spilu(self.spLHS) M_x = lambda x: myPreconditioner.solve(x) self.M = LinearOperator((dof*nNodes, dof*nNodes), M_x) # Lumped mass self.lumpLHS = np.sum(self.LHS, axis=1) # Calculate inverse of local mass matrix for subscales calculation for iElm in range(nElms): self.invLMs[iElm,:,:] = np.linalg.inv(lMs[iElm])
def steady_state_numerical( Q, g_BP1, g_BP2, tol=1e-9, drop_tol=1e-3, fill_factor=10, method='ILU-LGMRes'): """Determine the limit expectation of a given gamble by solving a sparse system of equations. Parameters ---------- Q: ndarray The transition rate matrix. g_BP1: ndarray A first gamble of which to compute the limit lower (or upper) expectation. g_BP2: ndarray A second gamble of which to compute the limit lower (or upper) expectation. tol: float, optional Parameter of the `scipy.sparse.linalg` methods. The default is `1e-9`. drop_tol: float, optional Parameter of the `scipy.sparse.linalg.spilu()` method. The default is `1e-3`. fill_factor: float, optional Parameter of the `scipy.sparse.linalg.spilu()` method. The default is `10`. method: str, optional The method to be used, either 'GMRES', 'LGMRES' or 'BiCGStab', corresponding to the respective methods in `scipy.sparse.linalg`. If the prefix 'ILU-' is added, the ILU preconditioner is used. The default is 'ILU-LGMRES'. Returns ------- float The estimate of the limit expectation of `g_BP1`. float The estimate of the limit expectation of `g_BP2`. timedelta The duration of the set up. timedelta The duration of the computations excluding the set up time. """ dur_su = perf_counter() n = Q.shape[0] A = sparse.csc_matrix(Q.transpose(), copy=True) A[n-1, :] = np.ones(n) b = np.zeros(n) b[n-1] = 1 if method.startswith('ILU-'): Mb = spla.spilu(A, drop_tol=drop_tol, fill_factor=fill_factor).solve else: Mb = lambda x: spla.spsolve(A, x) M = spla.LinearOperator((n, n), Mb) dur_su = timedelta(seconds=perf_counter() - dur_su) dur_c = perf_counter() if method.endswith('-GMRes') or ?? method == 'GMRES' ??: piEst, info = spla.gmres(A, b, tol=tol, M=M)
def ilu_linsolver(A, b): """ ILU wrapper function for linear system solve A x = b :param A: System matrix :param b: right hand side :return: solution """ return spilu(A).solve(b)
def _smooth_ilu(self, matrix, grid, fill_factor=1, omega=0.1): d = omega * self.rhomat # d = 10*self.rhomat*h # d = 1100*self.rhomat*h*h # print(f"h = {h} d={d}") ilu = splinalg.spilu( (matrix + d * sp.sparse.identity(matrix.shape[0])).tocsc(), fill_factor=fill_factor) return splinalg.LinearOperator(matrix.shape, ilu.solve)
def test_spilu(): X = scipy.sparse.csc_array([ [1, 0, 0, 0], [2, 1, 0, 0], [3, 2, 1, 0], [4, 3, 2, 1], ]) LU = spla.spilu(X) npt.assert_allclose(LU.solve(np.array([1, 2, 3, 4])), [1, 0, 0, 0])
def ilu_smoother(A, b, x_0, N): global fill_factor B = csc_matrix(A) inv_B_approx = spilu(B, fill_factor=fill_factor) x = np.copy(x_0) for _ in range(N): r = b - A @ x x = x + inv_B_approx.solve(r) return x
def solve(self, series, use_gmres=False, remove0=False, remove_vec=None, preconditioner=None, quiet=False, **kwargs): if not self.position == series.position or \ not self.index_set == series.index_set: raise ValueError("Invalid argument: \ position and index set must coincide!") if remove0 or remove_vec is not None: vstack, hstack = (np.vstack, np.hstack) if not self.is_sparse \ else (ss.vstack, ss.hstack) if remove0: [e], [s] = self.eigs(k=1, which='SM') if not quiet: print("Removing eigenspace with eigenvalue {}.".format(abs(e))) remove_vec = s else: remove_vec = remove_vec / np.sqrt(float(remove_vec*remove_vec)) e = float(remove_vec*self(remove_vec)) if not quiet: print("Removing vector with value {}.".format(abs(e))) if abs(e) > 0.01: print("[Hermipy:varf:solve warning] Value of e: {}".format(e)) matrix = vstack((self.matrix, remove_vec.coeffs)) matrix = hstack((matrix, np.array([[*remove_vec.coeffs, 0]]).T)) vector = np.array([*series.coeffs, 0]) if self.is_sparse: matrix = matrix.tocsr() else: matrix = self.matrix vector = series.coeffs if use_gmres: # Extend hash function to ignore callback from scipy.sparse.linalg import gmres cachefun = cache.cache(quiet=True, hash_extend=lambda arg: '0') if preconditioner == 'ilu': ilu, n = spla.spilu(matrix), matrix.shape[0] M = spla.LinearOperator((n, n), ilu.solve) solution = cachefun(gmres)(matrix, vector, M=M, **kwargs)[0] else: solve = cache.cache(quiet=True)(spla.spsolve if self.is_sparse else la.solve) solution = solve(matrix, vector, **kwargs) if remove0 or remove_vec: solution = np.array(solution[0:-1]) return hs.Series(solution, position=self.position, factor=self.factor, index_set=self.index_set)
def get_preconditioner(self, **kwargs): ''' Create an ilu preconditioner using spilu. Return the preconditioner as a LinearOperator object. These are described at: http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.spilu.html#scipy.sparse.linalg.spilu http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.LinearOperator.html#scipy.sparse.linalg.LinearOperator The idea for this approach was based on information found at: http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html ''' drop_tol = None fill_factor = None drop_rule = None permc_spec = None diag_pivot_thresh = None relax = None panel_size = None options = None if kwargs.has_key('drop_tol'): drop_tol = kwargs['drop_tol'] if kwargs.has_key('fill_factor'): fill_factor = kwargs['fill_factor'] if kwargs.has_key('drop_rule'): drop_rule = kwargs['drop_rule'] if kwargs.has_key('permc_spec'): permc_spec = kwargs['permc_spec'] if kwargs.has_key('diag_pivot_thresh'): diag_pivot_thresh = kwargs['diag_pivot_thresh'] if kwargs.has_key('relax'): relax = kwargs['relax'] if kwargs.has_key('panel_size'): panel_size = kwargs['panel_size'] if kwargs.has_key('options'): options = kwargs['options'] #if VERBOSE: # print 'drop_tol: ', drop_tol # print 'fill_factor: ', fill_factor # print 'drop_rule: ', drop_rule # print 'permc_spec: ', permc_spec # print 'diag_pivot_thresh: ', diag_pivot_thresh # print 'relax: ', relax # print 'panel_size: ', panel_size # print 'options: ', options from scipy.sparse.linalg import spilu, LinearOperator A_ilu = spilu(self.acsr, drop_tol=drop_tol, fill_factor=fill_factor, drop_rule=drop_rule, permc_spec=permc_spec, diag_pivot_thresh=diag_pivot_thresh, relax=relax, panel_size=panel_size, options=options ) M_x = lambda x: A_ilu.solve(x) M = LinearOperator(shape=(self.neq, self.neq), matvec=M_x) #M = LinearOperator(shape=(self.nodes, self.nodes), matvec=A_ilu.solve) return M
def get_preconditioner(self, **kwargs): ''' Create an ilu preconditioner using spilu. Return the preconditioner as a LinearOperator object. These are described at: http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.spilu.html#scipy.sparse.linalg.spilu http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.linalg.LinearOperator.html#scipy.sparse.linalg.LinearOperator The idea for this approach was based on information found at: http://docs.scipy.org/doc/scipy/reference/tutorial/optimize.html ''' drop_tol = None fill_factor = None drop_rule = None permc_spec = None diag_pivot_thresh = None relax = None panel_size = None options = None if kwargs.has_key('drop_tol'): drop_tol = kwargs['drop_tol'] if kwargs.has_key('fill_factor'): fill_factor = kwargs['fill_factor'] if kwargs.has_key('drop_rule'): drop_rule = kwargs['drop_rule'] if kwargs.has_key('permc_spec'): permc_spec = kwargs['permc_spec'] if kwargs.has_key('diag_pivot_thresh'): diag_pivot_thresh = kwargs['diag_pivot_thresh'] if kwargs.has_key('relax'): relax = kwargs['relax'] if kwargs.has_key('panel_size'): panel_size = kwargs['panel_size'] if kwargs.has_key('options'): options = kwargs['options'] #if VERBOSE: # print 'drop_tol: ', drop_tol # print 'fill_factor: ', fill_factor # print 'drop_rule: ', drop_rule # print 'permc_spec: ', permc_spec # print 'diag_pivot_thresh: ', diag_pivot_thresh # print 'relax: ', relax # print 'panel_size: ', panel_size # print 'options: ', options from scipy.sparse.linalg import spilu, LinearOperator A_ilu = spilu(self.acsr, drop_tol=drop_tol, fill_factor=fill_factor, drop_rule=drop_rule, permc_spec=permc_spec, diag_pivot_thresh=diag_pivot_thresh, relax=relax, panel_size=panel_size, options=options) M_x = lambda x: A_ilu.solve(x) M = LinearOperator(shape=(self.neq, self.neq), matvec=M_x) #M = LinearOperator(shape=(self.nodes, self.nodes), matvec=A_ilu.solve) return M
def __init__(self, K, C, M, tau, eta, fill_factor=10.0, timing=False): P = K + 1j * tau * C - tau**2 * M #P = K-tau*M t0 = time.time() self.P = spla.spilu(P.tocsc(), fill_factor=fill_factor) self.IE = sparse.identity(len(eta)) - sparse.diags(eta, 0) te = time.time() if timing: print('iLU({}) decomposition:'.format(fill_factor) + str(te - t0))
def solve(self): print(type(self.KF)) print(type(self.KF)) print(type(self.FF)) self.KF = csc_matrix(self.KF) self.FF = csc_matrix(self.FF) luKF = spilu(self.KF) self.UF = luKF.solve(self.FF.toarray())
def solve_system(A, method): """ Solve linear system Ax = b with A matrix in filename and b = (0, 1, 2, 3, ...) using the specified method """ # find b vector such that Ax = b # with x = [0 1 2 ... size(m)] size = A.shape true_x = list(xrange(0, size[1])) b = A.dot(true_x) # solve Ax = b and check solution error # diretti if method in [sla.spsolve, direttolu]: x = method(A, b) print("\t" + method.func_name + " solved " + str(size)) return x, sol_error(x, true_x) # iterativi else: # per accellerare la convergenza dei metodi iterativi # dobbiamo passare un precondizionatore (una matrice M, # che approssima l'inversa di A) # http://osdir.com/ml/python-scientific-user/2011-06/msg00249.html try: P = sla.spilu(A, drop_tol=1e-5) except Exception as err: print("\t", err) print("\tPorta le tue sporche matrici singolari altrove...") return None, "nan" M = sla.LinearOperator(size, P.solve) global current_x current_x = None try: x, status = method(A, b, tol=1e-16, M=M, maxiter=500, callback=callback_func) except Exception: print("\t" + method.func_name + " converged on " + str(size)) return current_x, sol_error(current_x, true_x) if status != 0: print("\t" + method.func_name + " DIDN'T converge on " + str(size) + " in less than 500 iterations") return current_x, sol_error(x, true_x) else: print("\t" + method.func_name + " converged on " + str(size)) return current_x, sol_error(x, true_x)
def test(model, writer, device): """Test loop for whole test data set.""" model.eval() _, _, test_loader = init_loaders() data = np.zeros((len(test_loader), 5, 4)) for idx, (features, coors, shape, l_matrix) in enumerate(test_loader): print('Evaluating ' + str(idx) + ' out of ' + str(len(test_loader))) l_matrix = csr_matrix(l_matrix[0].to_dense().numpy(), dtype=np.float32) rhs = np.random.randn(shape[0]) # Vanilla conjugate gradients without preconditioner as baseline. data[idx, 0] = evaluate('vanilla', l_matrix, rhs, eye(shape[0])) # Jacobi preconditioner. data[idx, 1] = evaluate('jacobi', l_matrix, rhs, diags(1. / l_matrix.diagonal())) # Incomplete Cholesky preconditioner. lu = sla.spilu(l_matrix.tocsc(), fill_factor=1., drop_tol=0.) L = lu.L D = diags(lu.U.diagonal()) # https://is.gd/5PJcTp Pr = np.zeros(l_matrix.shape) Pc = np.zeros(l_matrix.shape) Pr[lu.perm_r, np.arange(l_matrix.shape[0])] = 1 Pc[np.arange(l_matrix.shape[0]), lu.perm_c] = 1 Pr = lil_matrix(Pr) Pc = lil_matrix(Pc) preconditioner = sla.inv((Pr.T * (L * D * L.T) * Pc.T).tocsc()) data[idx, 2] = evaluate('ic(0)', l_matrix, rhs, preconditioner) # Algebraic MultiGrid preconditioner. preconditioner = smoothed_aggregation_solver( l_matrix).aspreconditioner(cycle='V') preconditioner = csr_matrix( preconditioner.matmat(np.eye(shape[0], dtype=np.float32))) data[idx, 3] = evaluate('amg', l_matrix, rhs, preconditioner) # Learned preconditioner. sp_tensor = SparseConvTensor(features.T.to(device), coors.int().squeeze(), shape, 1) preconditioner = csr_matrix(model(sp_tensor).detach().cpu().numpy()) data[idx, 4] = evaluate('learned', l_matrix, rhs, preconditioner) np.savetxt('./tmp/time.csv', data[:, :, 0], fmt='%.4f') np.savetxt('./tmp/iterations.csv', data[:, :, 1], fmt='%.4f') np.savetxt('./tmp/condition.csv', data[:, :, 2], fmt='%.4f') for m in range(1, 5): # Compare time/iterations/condition to baseline CG. writer.add_histogram('test/time', data[:, 0, 0] / data[:, m, 0], m) writer.add_histogram('test/iterations', data[:, 0, 1] / data[:, m, 1], m) writer.add_histogram('test/condition', data[:, 0, 2] / data[:, m, 2], m) writer.add_histogram('test/density', data[:, m, 3], m)
def _computePreconditioner(self, system_matrix): ''' Create a preconditioner base on an incomplete LU decomposition ''' # convert to compressed column storage format (efficiency) sm_csc = system_matrix.tocsc() lu = sparse_solvers.spilu(sm_csc) m_operator = lambda x: lu.solve(x) shape = (self.nx * self.ny, self.nx * self.ny) self.preconditioner = sparse_solvers.LinearOperator(shape, m_operator)
def _computePreconditioner(self, system_matrix): ''' Create a preconditioner base on an incomplete LU decomposition ''' # convert to compressed column storage format (efficiency) sm_csc = system_matrix.tocsc() lu = sparse_solvers.spilu(sm_csc) m_operator = lambda x: lu.solve(x) shape = (self.nx*self.ny, self.nx*self.ny) self.preconditioner = sparse_solvers.LinearOperator(shape, m_operator)
def test_spilu(matrices): A_dense, A_sparse, b = matrices sparse_cls = type(A_sparse) lu = splin.spilu(A_sparse) assert isinstance(lu.L, sparse_cls) assert isinstance(lu.U, sparse_cls) z = lu.solve(A_sparse.todense()) assert_allclose(z, np.eye(len(b)), atol=1e-3)
def build(self, A=None, preconditioner = 'spilu',**kwargs): super().build(A,**kwargs) A = self._A if preconditioner == 'spilu': M = spla.spilu(A) M = spla.LinearOperator(A.shape,M.solve) self.__solve = lambda b: spla.bicg(A,b,**kwargs) else: self.__solve = lambda b: spla.bicg(A,b,**kwargs) self.built = True return self
def preconditionate(self,Keff): """Preconditionate the matrix using SuperLU :param Keff: The matrix do be preconditionated :type Keff: CSC Matrix :return: Linear operator of the preconditionated matrix :rtype: CSC Matrix """ ilu = sla.spilu(Keff) Mx = lambda x: ilu.solve(x) K_prec = sla.LinearOperator(Keff.shape, Mx) return K_prec
def __init__(self, sess, n, filename, jump_prob=0.05, drop_tol=1e-8, verbose=False): """ Computes PPR using LU decomposition. Args: sess (Session): tensorflow session. n (int): Number of nodes. filename (str): A csv file denoting the graph. jump_prob (float): Jumping probability of PPR. drop_tol (float): Drops entries with absolute value lower than this value when computing inverse of LU. verbose (bool): Prints step messages if True. """ self.alias = 'ludc' self.verbose = verbose self.pp("initializing") self.sess = sess self.n = n self.c = jump_prob d = 1 - self.c t = drop_tol exact = False if t is None: t = np.power(n, -0.5) elif t == 0: exact = True self.pp("reading") self.node2index, H = read_matrix(filename, d=-d, add_identity=True) self.pp("sorting H") self.perm = degree_reverse_rank_perm(H) H = reorder_matrix(H, self.perm).tocsc() self.pp("computing LU decomposition") if exact: self.LU = splu(H) else: self.LU = spilu(H, drop_tol=t) Linv = inv(self.LU.L).tocoo() Uinv = inv(self.LU.U).tocoo() self.pp("tf init") with tf.variable_scope('ppr_lu_decomposition_tf'): t_Linv = tf.SparseTensorValue(list(zip(Linv.row, Linv.col)), Linv.data, dense_shape=self.LU.L.shape) t_Uinv = tf.SparseTensorValue(list(zip(Uinv.row, Uinv.col)), Uinv.data, dense_shape=self.LU.U.shape) self.t_q = tf.placeholder(tf.float64, shape=[self.n, 1]) self.t_r = _sdmm(t_Uinv, _sdmm(t_Linv, self.c * self.t_q))
def preconditioner(self, x): """Compute the preconditioner M""" h = x[1:] - x[:-1] n = len(h)-1 diags = zeros((3, n)) diags[0] = 2/(h[:-1]*(h[:-1]+h[1:])) diags[1] = -(2/h[:-1]+2/h[1:])/(h[:-1]+h[1:]) diags[2] = 2/(h[1:]*(h[:-1]+h[1:])) J = spdiags(diags, [-1,0,1], n, n) J_ilu = spilu(J) M = LinearOperator(shape=(n,n), matvec=J_ilu.solve) return M
def compute_preconditioner(L): print("running spilu") start_process_time = time.process_time() start_wall_time = time.time() M = sp.eye(L.shape[0]) + L ilu = spilu(M) process_time = time.process_time() - start_process_time wall_time = time.time() - start_wall_time print("finished in %0.3f sec, %0.3f process time" % (process_time, wall_time)) Mx = lambda x: ilu.solve(x) Milu = LinearOperator(L.shape, Mx) return Milu
def __init__(self, vs): self._matrix = self._assemble_poisson_matrix(vs) jacobi_precon = self._jacobi_preconditioner(vs, self._matrix) self._matrix = jacobi_precon * self._matrix self._rhs_scale = jacobi_precon.diagonal() self._extra_args = {} logger.info('Computing ILU preconditioner...') ilu_preconditioner = spalg.spilu(self._matrix.tocsc(), drop_tol=1e-6, fill_factor=100) self._extra_args['M'] = spalg.LinearOperator(self._matrix.shape, ilu_preconditioner.solve)
def _iterative_precondition(A, n, ss_args): """ Internal function for preconditioning the steadystate problem for use with iterative solvers. """ if settings.debug: logger.debug('Starting preconditioner.') _precond_start = time.time() try: P = spilu(A, permc_spec=ss_args['permc_spec'], drop_tol=ss_args['drop_tol'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], fill_factor=ss_args['fill_factor'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) P_x = lambda x: P.solve(x) M = LinearOperator((n ** 2, n ** 2), matvec=P_x) _precond_end = time.time() ss_args['info']['permc_spec'] = ss_args['permc_spec'] ss_args['info']['drop_tol'] = ss_args['drop_tol'] ss_args['info']['diag_pivot_thresh'] = ss_args['diag_pivot_thresh'] ss_args['info']['fill_factor'] = ss_args['fill_factor'] ss_args['info']['ILU_MILU'] = ss_args['ILU_MILU'] ss_args['info']['precond_time'] = _precond_end-_precond_start if settings.debug or ss_args['return_info']: if settings.debug: logger.debug('Preconditioning succeeded.') logger.debug('Precond. time: %f' % (_precond_end - _precond_start)) if _scipy_check: L_nnz = P.L.nnz U_nnz = P.U.nnz ss_args['info']['l_nnz'] = L_nnz ss_args['info']['u_nnz'] = U_nnz ss_args['info']['ilu_fill_factor'] = (L_nnz+U_nnz)/A.nnz e = np.ones(n ** 2, dtype=int) condest = la.norm(M*e, np.inf) ss_args['info']['ilu_condest'] = condest if settings.debug: logger.debug('L NNZ: %i ; U NNZ: %i' % (L_nnz, U_nnz)) logger.debug('Fill factor: %f' % ((L_nnz+U_nnz)/A.nnz)) logger.debug('iLU condest: %f' % condest) except: raise Exception("Failed to build preconditioner. Try increasing " + "fill_factor and/or drop_tol.") return M, ss_args
def keo_ilu(self, psi, droptol): if self._modeleval._keo is None: self._modeleval._assemble_kinetic_energy_operator() if self._keo_ilu is None \ or self._keo_ilu_droptol is None \ or droptol != self._keo_ilu_droptol: self._keo_ilu = spilu(self._modeleval._keo, drop_tol=droptol, fill_factor=10, drop_rule=None, relax=None, panel_size=None ) self._keo_ilu_droptol = droptol return self._keo_ilu.solve(psi)
def main(): A = csc_matrix(mmread('./matrici/mtx_files/non-simmetrica-46902.mtx')) start = time.clock() P = sla.spilu(A, drop_tol=1e-5) M = sla.LinearOperator(A.shape, P.solve) sol, err = solve_system(A, sla.bicgstab) end = time.clock() true_x = list(xrange(0, 46902)) print(">> Soluzione (reale):", true_x[0], true_x[1], "...", true_x[-2], true_x[-1]) print(">> Soluzione (approx): ", sol[0], sol[1], "...", sol[-2], sol[-1]) print(">> Errore: ", err) print(">> Tempo:", end - start, " secondi")
def _iterative_precondition(A, n, ss_args): """ Internal function for preconditioning the steadystate problem for use with iterative solvers. """ if settings.debug: print('Starting preconditioner...',) _precond_start = time.time() try: P = spilu(A, permc_spec=ss_args['permc_spec'], drop_tol=ss_args['drop_tol'], diag_pivot_thresh=ss_args['diag_pivot_thresh'], fill_factor=ss_args['fill_factor'], options=dict(ILU_MILU=ss_args['ILU_MILU'])) P_x = lambda x: P.solve(x) M = LinearOperator((n ** 2, n ** 2), matvec=P_x) _precond_end = time.time() ss_args['info']['permc_spec'] = ss_args['permc_spec'] ss_args['info']['drop_tol'] = ss_args['drop_tol'] ss_args['info']['diag_pivot_thresh'] = ss_args['diag_pivot_thresh'] ss_args['info']['fill_factor'] = ss_args['fill_factor'] ss_args['info']['ILU_MILU'] = ss_args['ILU_MILU'] ss_args['info']['precond_time'] = _precond_end-_precond_start if settings.debug or ss_args['return_info']: if settings.debug: print('Preconditioning succeeded.') print('Precond. time:', _precond_end-_precond_start) if _scipy_check: L_nnz = P.L.nnz U_nnz = P.U.nnz ss_args['info']['l_nnz'] = L_nnz ss_args['info']['u_nnz'] = U_nnz ss_args['info']['ilu_fill_factor'] = (L_nnz+U_nnz)/A.nnz e = np.ones(n ** 2, dtype=int) condest = la.norm(M*e, np.inf) ss_args['info']['ilu_condest'] = condest if settings.debug: print('L NNZ:', L_nnz, ';', 'U NNZ:', U_nnz) print('Fill factor:', (L_nnz+U_nnz)/A.nnz) print('iLU condest:', condest) except: M = None return M, ss_args
def compute_fundamental_matrix(P, fast=True, drop_tol=1e-5, fill_factor=1000): """Computes the fundamental matrix for an absorbing random walk. Parameters ---------- P : scipy.sparse matrix The transition probability matrix of the absorbing random walk. To construct this matrix, you start from the original transition matrix and delete the rows that correspond to the absorbing nodes. fast : bool, optional If True (default), use the iterative SuperLU solver from scipy.sparse.linalg. drop_tol : float, optional If `fast` is True, the `drop_tol` parameter of the SuperLU solver is set to this value (default is 1e-5). fill_factor: int, optional If `If `fast` is True, the `fill_factor` parameter of the SuperLU solver is set to this value (default is 1000). Returns ------- F : scipy.sparse matrix The fundamental matrix of the random walk. Element (i,j) holds the expected number of times the random walk will be in state j before absorption, when it starts from state i. For more information, check [1]_. References ---------- .. [1] Doyle, Peter G., and J. Laurie Snell. Random walks and electric networks. Carus mathematical monographs 22 (2000). https://math.dartmouth.edu/~doyle/docs/walks/walks.pdf """ n = P.shape[0] F_inv = speye(n, format='csc') - P.tocsc() if fast: solver = spilu(F_inv, drop_tol=drop_tol, fill_factor=fill_factor) F = matrix(solver.solve(eye(n))) else: F = spinv(F_inv).todense() return F
def get_ilu(A, fill_factor=1): # setup preconditioner from scipy.sparse.linalg import spilu B_ilu = spilu(A, fill_factor=fill_factor, permc_spec='MMD_AT_PLUS_A') def _apply_ilu(x): ret = numpy.zeros(x.shape, dtype=x.dtype) for i in range(x.shape[1]): if numpy.iscomplexobj(x): ret[:, i] = (B_ilu.solve(numpy.real(x[:, i])) + 1j*B_ilu.solve(numpy.imag(x[:, i]))) else: ret[:, i] = B_ilu.solve(x[:, i]) return ret B = krypy.utils.LinearOperator(A.shape, dtype=A.dtype, dot=_apply_ilu) return B, B_ilu
def keo_symmetric_ilu(self, psi, droptol): if self._modeleval._keo is None: self._modeleval._assemble_kinetic_energy_operator() if self._keo_symmetric_ilu is None \ or self._keo_symmetric_ilu_droptol is None \ or droptol != self._keo_symmetric_ilu_droptol: self._keo_symmetric_ilu = spilu(self._modeleval._keo, drop_tol=droptol, fill_factor=10, drop_rule=None, # see remark above for splu options={'SymmetricMode': True}, permc_spec='MMD_AT_PLUS_A', diag_pivot_thresh=0.0, relax=None, panel_size=None ) self._keo_symmetric_ilu_droptol = droptol return self._keo_symmetric_ilu.solve(psi)
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 pop_K(self): start = time.time() self.K = np.zeros((self.m, self.m)) if Fourier_Feature: z_cache = np.zeros((self.m,D)) w = random.normal(0, 1.0/sigma, size=(self.m*D,len(self.x_data[0]))) b = random.uniform(0,2*np.pi,size=self.m*D) for i in range(self.m): z_cache[i]=self.z(self.x_data[i],w[i:i+D,:],b[i:i+D]) end = time.time() if end - start > timer_thresh: print 'z_cache:',end - start,'sec' for i in range(self.m): # for j in range(self.m): self.K[i,:] = np.dot(z_cache,z_cache[i]) # self.z(self.x_data[i]),self.z(self.x_data[j])) else: for i in range(self.m): self.K[i, :] = kernel_vect(self.x_data, self.x_data[i]) if Fourier_Feature: K_test=np.zeros((self.m,self.m)) for i in range(self.m): K_test[i,:] = kernel_vect(self.x_data,self.x_data[i]) print 'Fourier norm diff', norm(K_test-self.K) self.K_K = np.dot(self.K, self.K) self.H = self.get_H('b') if is_approx: # incomplete_cholesky, P, k = incomplete_cholesky_decomp4(self.H.copy()) start1 = time.time() self.incomplete_cholesky = spilu(self.H.copy(),drop_tol=drop_tol)#,fill_factor=10000,) end1 = time.time() self.spilu_time = end1 - start1 print 'self.spilu_time',self.spilu_time # assert np.isfinite(incomplete_cholesky.L.A).all() # assert np.isfinite(incomplete_cholesky.U.A).all() # print 'k', k # print 'P', P # print 'incomplete_cholesky',incomplete_cholesky # print 'np.dot(incomplete_cholesky, incomplete_cholesky.T',\ # np.dot(incomplete_cholesky, incomplete_cholesky.T.conj()) # print 'np.dot(P,np.dot(self.H,P.T))',self.H #np.dot(P,np.dot(self.H,P.T)) # print 'subtract',np.dot(incomplete_cholesky, incomplete_cholesky.T.conj()) - \ # np.dot(P,np.dot(self.H,P.T)) # print 'norm',norm(np.dot(incomplete_cholesky, # incomplete_cholesky.T.conj()), # np.dot(P,np.dot(self.H,P.T))) # print norm(np.dot(incomplete_cholesky.L.A, # incomplete_cholesky.U.A) - \ # self.H) # assert norm(np.dot(incomplete_cholesky.L.A, # incomplete_cholesky.U.A) - \ # self.H) < .00000001 #np.dot(P,np.dot(self.H,P.T))) < .00000001 # assert np.allclose(np.dot(incomplete_cholesky.L.A, incomplete_cholesky.U.A),self.H) #, atol=.001, rtol=.001) # np.dot(P,np.dot(self.H,P.T)), atol=.001, rtol=.001) # self.incomplete_cholesky_inv = incomplete_cholesky.solve(np.eye(self.H.shape[0])) # solve_triangular( # incomplete_cholesky, # np.identity(incomplete_cholesky.shape[0])) # self.incomplete_cholesky_T_inv = solve_triangular( # incomplete_cholesky.T, # np.identity(incomplete_cholesky.shape[0])) else: if Use_Cholesky: self.L = cholesky(self.H) self.L_inv = inv(self.L) self.L_T_inv = inv(self.L.T) else: self.H_inv = inv(self.H) end = time.time() if end - start > timer_thresh: print 'pop_K:', end - start, 'sec'
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 apply_inverse(self, U, ind=None, mu=None, options=None): default_options = self.invert_options if options is None: options = default_options.values()[0] elif isinstance(options, str): 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) assert isinstance(U, NumpyVectorArray) assert self.dim_range == U.dim U = U._array[:U._len] if ind is None else U._array[ind] if U.shape[1] == 0: return NumpyVectorArray(U) R = np.empty((len(U), self.dim_source)) if self.sparse: if options['type'] == 'bicgstab': for i, UU in enumerate(U): R[i], info = bicgstab(self._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(self._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(self._matrix.shape, ilu.solve) for i, UU in enumerate(U): R[i], info = bicgstab(self._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(self._matrix, UU, permc_spec=options['permc_spec']) elif options['type'] == 'pyamg': if len(U) > 0: U_iter = iter(enumerate(U)) R[0], ml = pyamg.solve(self._matrix, next(U_iter)[1], tol=options['tol'], maxiter=options['maxiter'], return_solver=True) for i, UU in U_iter: R[i] = pyamg.solve(self._matrix, UU, tol=options['tol'], maxiter=options['maxiter'], existing_solver=ml) elif options['type'] == 'pyamg-rs': ml = pyamg.ruge_stuben_solver(self._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(self._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']) else: raise ValueError('Unknown solver type') else: for i, UU in enumerate(U): try: R[i] = np.linalg.solve(self._matrix, UU) except np.linalg.LinAlgError as e: raise InversionError('{}: {}'.format(str(type(e)), str(e))) return NumpyVectorArray(R)
def precond(self, input, algorithm_parameters, experiment_parameters, save_data=True, display=False): # todo: check parameters A = input["A"] n = A.shape[0] b = input["b"] x0 = input["x0"] parameters = algorithm_parameters.copy() parameters.update(experiment_parameters) m = parameters.get("m", n) tol = parameters.get("tol", 1.e-12) max_iter = parameters.get("iterMax", m) dtype = parameters.get("type", 'd') vulnerable = parameters.get("vulnerable", True) orthogonalization = parameters.get("orthMethod", classical_gramschmidt) save_data = parameters.get("save_data", None) full = parameters.get("full", False) faulty = Fault(Parameters(parameters.get("fault_parameters", {"max_fault_count":1}))) normb = np.linalg.norm(b, ord=2) x = np.zeros((n, 1), dtype=dtype) x[:, 0] = x0[:, 0] r = b - A.dot(x) beta = np.linalg.norm(r) M = spilu(A) sum_A = A.sum(axis=0) if (normb == 0.0): normb = 1. resid = np.linalg.norm(r) / normb if save_data: if "iteration_count" in save_data: self.data["iteration_count"] = 0 if "residual" in save_data: self.data["residual"] = resid if "residuals" in save_data: self.data["residuals"] = [resid] if "true_residual" in save_data: self.data["true_residual"] = resid if "true_residuals" in save_data: self.data["true_residuals"] = [resid] if "H_rank" in save_data: self.data["H_rank"] = [0] if "orthogonality" in save_data: self.data["orthogonality"] = [0.] if "arnoldi" in save_data: self.data["arnoldi"] = [0.] if "y" in save_data: self.data["y"] = [] if "checksum" in save_data: self.data["checksum"] = [] if "criteria" in save_data: self.data["criteria"] = [] if "threshold" in save_data: self.data["threshold"] = [] if "delta" in save_data: self.data["delta"] = [0.] if "breakdown" in save_data: self.data["breakdown"] = False if (resid <= tol): return x # V : Krylov basis V = np.zeros((n, m+1), dtype=dtype) # H : upper Hessenberg H = np.zeros((m+1, m), dtype=dtype) j = 0 while (j < max_iter): V[:, 0:1] = r * (1.0 / beta) s = np.zeros((m+1, 1), dtype=dtype) s[0, 0] = beta cs, sn = [], [] i = 0 while (i < m and j < max_iter): z = M.solve(V[:, i]) if vulnerable: w = faulty.product(A, z) else: w = A.dot(z) if "checksum" in save_data: checksum_Av = w.sum(axis = 0) checksum_A = np.dot(sum_A, z) if np.isscalar(np.dot(sum_A, z)) else np.dot(sum_A, z)[0, 0] checksum = abs(checksum_Av - checksum_A) orthogonalization(w, V, H, i) # Happy breakdown if (H[i+1, i] < 1.e-20): try: if i > 0: y = solve_triangular(H[:i, :i], s[:i]) xc = x + M.solve(np.dot(V[:, :i], y)) return xc else: return x except: if "breakdown" in save_data: self.data["breakdown"] = True if i > 0: y = solve_triangular(H[:i, :i], s[:i]) xc = x + M.solve(np.dot(V[:, :i], y)) return xc else: return x V[:, i+1] = w * (1.0 / H[i+1, i]) # Previous plane rotations for k, (cs_k, sn_k) in enumerate(zip(cs, sn)): ApplyGivens(H, k, i, cs_k, sn_k) # Current plane rotation mu = np.sqrt(H[i, i]**2 + H[i+1, i]**2) try: cs_i = H[i, i] / mu sn_i = -H[i+1, i] / mu cs.append(cs_i) sn.append(sn_i) except: if "breakdown" in save_data: self.data["breakdown"] = True if i > 0: return x + xc # a verifier else: return x # rotation on H H[i , i] = cs_i * H[i, i] - sn_i * H[i+1, i] H[i+1, i] = 0. # rotation on right hand side ApplyGivens(s, i, 0, cs_i, sn_i) resid = abs(s[i+1, 0]) / normb if save_data: if "iteration_count" in save_data: self.data["iteration_count"] = j+1 if "residual" in save_data: self.data["residual"] = resid if "residuals" in save_data: self.data["residuals"] += [resid] if ("true_residual" in save_data or "true_residuals" in save_data or "y" in save_data): try: y = solve_triangular(H[:i+1, :i+1], s[:i+1]) xc = x + M.solve(np.dot(V[:, :i+1], y)) except: if "breakdown" in save_data: self.data["breakdown"] = True vulnerable = False return #y = Solve_y(i, H, s) #y = solve_triangular(H[:i+1, :i+1], s[:i+1]) #xc = x + Update(i, H, s, V) #xc = x + solve_triangular(A, np.dot(V[:, :i+1], y), lower=True, check_finite=True) #xc = x + np.dot(V[:, :i+1], y) xc = x + M.solve(np.dot(V[:, :i+1], y)) # M xc = V[:,:i+1] * y #xc = x + spsolve(M, np.dot(V[:, :i+1], y)) true_resid = np.linalg.norm(b - A.dot(xc)) true_resid_ = true_resid / normb if "y" in save_data: self.data["y"] += [y] if "true_residual" in save_data: self.data["true_residual"] = true_resid_ if "true_residuals" in save_data: self.data["true_residuals"] += [true_resid_] if "faults" in save_data: self.data["faults"] = faulty.faults if "H" in save_data: self.data["H"] = H if "V" in save_data: self.data["V"] = V if "H_rank" in save_data: self.data["H_rank"] += [np.linalg.matrix_rank(H[:i+1, :i+1])-(i+1)] if "orthogonality" in save_data: self.data["orthogonality"] += [np.linalg.norm(np.dot(V[:, :i+2].T, V[:,:i+2]) - np.eye(i+2),ord='fro')/np.linalg.norm(np.eye(i+2))] if "arnoldi" in save_data: self.data["arnoldi"] += [np.linalg.norm(np.dot(A, V[:,:i+1]) - np.dot(V[:,:i+2], H[:i+2, :i+1]),ord='fro') / np.linalg.norm(np.dot(V[:,:i+2], H[:i+2, :i+1]), ord='fro')] if "delta" in save_data: if len(self.data["faults"]) > 0: Ekvk = abs(self.data["faults"][0]["value_after"] - self.data["faults"][0]["value_before"]) k = self.data["faults"][0]["timer"] self.data["delta"] += [(abs(y[k]) * Ekvk) / normb] else: self.data["delta"] += [0] if "checksum" in save_data: self.data["checksum"] += [checksum] if "threshold" in save_data: self.data["threshold"] += [(tol * normb)/abs(y[i])] if "criteria" in save_data: #TODO: bug if y not in save_data self.data["criteria"] += [(tol * normb)/abs(y[i])] if (true_resid_ < tol): if not full: return xc if (not save_data or not "true_residual" in save_data or not "true_residual" in save_data): if resid < tol: if not full: return x + Update(i, H, s, V) #if (resid < tol): # if save_data: # return xc # else: # return x + Update(i, H, s, V) i += 1 j += 1 xc = x + Update(i - 1, H, s, V) r = b - A.dot(xc) beta = np.linalg.norm(r) resid = beta / normb #if save_data: # self.data["iteration_count"] = j # self.data["residual"] = resid # self.data["residuals"] += [self.data["residual"]] # self.data["true_residual"] = resid # self.data["true_residuals"] += [self.data["true_residual"]] if (resid < tol): return xc tol = resid return x
if not r == rows-1: S.append(1) I.append(r*cols+c) J.append(r*cols+c+cols) gradient += (foreImg[r+1, c, i] + backImg[r+1, c, i]) else: S.append(1) I.append(r*cols+c) J.append(r*cols+c) B[r*cols+c] = gradient if mask[r, c, i] else backImg[r, c, i] A = coo_matrix((S, (I, J)), shape=(alls, alls)) B = np.array(B).transpose() # solve Ax=B with least square #X[i] = linalg.lsqr(A, B, iter_lim=1000)[0] M0 = linalg.LinearOperator(A.shape, linalg.spilu(csc_matrix(A)).solve) X[i], code = linalg.cg(A, B, maxiter=1000, M=M0) # in some cases, cg solver may not come to a convergence, even become divergent # e.g. when the foregound in mask is not completely surrounded by the background # make R an image & output P = zip(X[0], X[1], X[2]) R = np.array([[P[c+r*cols] for c in range(cols)] for r in range(rows)]) #R = np.reshape(R, (rows, cols)) if channels == 1 else np.reshape(R, (rows, cols, channels)) print "Time spent: %.2fs" % (time.time()-start_time) cv2.imshow('output', R) cv2.waitKey(0) cv2.imwrite(outputName, R * 255)
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 _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
def init_solver(self,L): global linalg from scipy.sparse import linalg ilu= linalg.spilu(self.L1.tocsc()) n=self.n-1 self.M = linalg.LinearOperator(shape=(n,n), matvec=ilu.solve)