def test_issymmetric(self): net = op.network.Cubic(shape=[5, 5, 5]) am = net.create_adjacency_matrix(triu=False) assert topotools.issymmetric(am) am = net.create_adjacency_matrix(triu=True) assert not topotools.issymmetric(am) am = am.T assert not topotools.issymmetric(am) # Now test non-coo AM's am = net.create_adjacency_matrix(triu=False, fmt="lil") assert topotools.issymmetric(am) am = net.create_adjacency_matrix(triu=True, fmt="lil") assert not topotools.issymmetric(am) am = am.T assert not topotools.issymmetric(am) # Now test non-triangular AM im = net.create_incidence_matrix() assert not topotools.issymmetric(im)
def _solve(self, A=None, b=None): r""" Sends the A and b matrices to the specified solver, and solves for *x* given the boundary conditions, and source terms based on the present value of *x*. This method does NOT iterate to solve for non-linear source terms or march time steps. Parameters ---------- A : sparse matrix The coefficient matrix in sparse format. If not specified, then it uses the ``A`` matrix attached to the object. b : ND-array The RHS matrix in any format. If not specified, then it uses the ``b`` matrix attached to the object. Notes ----- The solver used here is specified in the ``settings`` attribute of the algorithm. """ if A is None: A = self.A if A is None: raise Exception('The A matrix has not been built yet') if b is None: b = self.b if b is None: raise Exception('The b matrix has not been built yet') if self.settings['solver'] == 'petsc': # Check if petsc is available petsc = importlib.util.find_spec('petsc4py') if not petsc: raise Exception('petsc is not installed') if not self.settings['petsc_solver']: self.settings['petsc_solver'] = 'cg' if not self.settings['petsc_precondioner']: self.settings['petsc_precondioner'] = 'jacobi' if not self.settings['petsc_atol']: self.settings['petsc_atol'] = 1e-06 if not self.settings['petsc_rtol']: self.settings['petsc_rtol'] = 1e-06 if not self.settings['petsc_max_it']: self.settings['petsc_max_it'] = 1000 # Define the petsc linear system converting the scipy objects ls = sls(A=A.tocsr(), b=b) ls.settings.update({ 'solver': self.settings['petsc_solver'], 'preconditioner': self.settings['petsc_precondioner'], 'atol': self.settings['petsc_atol'], 'rtol': self.settings['petsc_rtol'], 'max_it': self.settings['petsc_max_it'] }) x = sls.solve(ls) del (ls) # Clean else: A = A.tocsr() A.indices = A.indices.astype(np.int64) A.indptr = A.indptr.astype(np.int64) solver = getattr(sprs.linalg, self.settings['solver']) if 'tol' in inspect.getfullargspec(solver)[0]: # If an iterative solver is used, set tol norm_A = sprs.linalg.norm(self._A) norm_b = np.linalg.norm(self._b) tol = min(norm_A, norm_b) * 1e-06 x = solver(A=A, b=b, tol=tol) else: sym = issymmetric(A) if (sym and self.settings['solver'] == 'spsolve_triangular'): solver = getattr(sprs.linalg, self.settings['solver']) x = solver(A=sprs.tril(A), b=b) else: x = solver(A=A, b=b) if type(x) == tuple: x = x[0] return x