def test_diagonal_symmetrical(): m = PropertiesOnlyMatrix(2, 2, [0, 1, 1, 0]) assert not m.is_diagonal() assert m.is_symmetric() assert m.is_symmetric(simplify=False) m = PropertiesOnlyMatrix(2, 2, [1, 0, 0, 1]) assert m.is_diagonal() m = PropertiesOnlyMatrix(3, 3, diag(1, 2, 3)) assert m.is_diagonal() assert m.is_symmetric() m = PropertiesOnlyMatrix(3, 3, [1, 0, 0, 0, 2, 0, 0, 0, 3]) assert m == diag(1, 2, 3) m = PropertiesOnlyMatrix(2, 3, zeros(2, 3)) assert not m.is_symmetric() assert m.is_diagonal() m = PropertiesOnlyMatrix(((5, 0), (0, 6), (0, 0))) assert m.is_diagonal() m = PropertiesOnlyMatrix(((5, 0, 0), (0, 6, 0))) assert m.is_diagonal() m = Matrix(3, 3, [1, x**2 + 2*x + 1, y, (x + 1)**2, 2, 0, y, 0, 3]) assert m.is_symmetric() assert not m.is_symmetric(simplify=False) assert m.expand().is_symmetric(simplify=False)
def test_diag_make(): diag = SpecialOnlyMatrix.diag a = Matrix([[1, 2], [2, 3]]) b = Matrix([[3, x], [y, 3]]) c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]]) assert diag(a, b, b) == Matrix([ [1, 2, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0], [0, 0, 3, x, 0, 0], [0, 0, y, 3, 0, 0], [0, 0, 0, 0, 3, x], [0, 0, 0, 0, y, 3], ]) assert diag(a, b, c) == Matrix([ [1, 2, 0, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0, 0], [0, 0, 3, x, 0, 0, 0], [0, 0, y, 3, 0, 0, 0], [0, 0, 0, 0, 3, x, 3], [0, 0, 0, 0, y, 3, z], [0, 0, 0, 0, x, y, z], ]) assert diag(a, c, b) == Matrix([ [1, 2, 0, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0, 0], [0, 0, 3, x, 3, 0, 0], [0, 0, y, 3, z, 0, 0], [0, 0, x, y, z, 0, 0], [0, 0, 0, 0, 0, 3, x], [0, 0, 0, 0, 0, y, 3], ]) a = Matrix([x, y, z]) b = Matrix([[1, 2], [3, 4]]) c = Matrix([[5, 6]]) assert diag(a, 7, b, c) == Matrix([ [x, 0, 0, 0, 0, 0], [y, 0, 0, 0, 0, 0], [z, 0, 0, 0, 0, 0], [0, 7, 0, 0, 0, 0], [0, 0, 1, 2, 0, 0], [0, 0, 3, 4, 0, 0], [0, 0, 0, 0, 5, 6], ]) assert SpecialOnlyMatrix.diag([2, 3]) == Matrix([ [2, 0], [0, 3]]) assert SpecialOnlyMatrix.diag(Matrix([2, 3])) == Matrix([ [2], [3]]) assert SpecialOnlyMatrix.diag(1, rows=3, cols=2) == Matrix([ [1, 0], [0, 0], [0, 0]]) assert type(SpecialOnlyMatrix.diag(1)) == SpecialOnlyMatrix assert type(SpecialOnlyMatrix.diag(1, cls=Matrix)) == Matrix
def test_get_diag_blocks2(): a = Matrix([[1, 2], [2, 3]]) b = Matrix([[3, x], [y, 3]]) c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]]) A, B, C, D = diag(a, b, b), diag(a, b, c), diag(a, c, b), diag(c, c, b) A = ShapingOnlyMatrix(A.rows, A.cols, A) B = ShapingOnlyMatrix(B.rows, B.cols, B) C = ShapingOnlyMatrix(C.rows, C.cols, C) D = ShapingOnlyMatrix(D.rows, D.cols, D) assert A.get_diag_blocks() == [a, b, b] assert B.get_diag_blocks() == [a, b, c] assert C.get_diag_blocks() == [a, c, b] assert D.get_diag_blocks() == [c, c, b]
def smith_normal_form(m, domain = None): ''' Return the Smith Normal Form of a matrix `m` over the ring `domain`. This will only work if the ring is a principal ideal domain. Examples ======== >>> from sympy.polys.solvers import RawMatrix as Matrix >>> from sympy.polys.domains import ZZ >>> from sympy.matrices.normalforms import smith_normal_form >>> m = Matrix([[12, 6, 4], [3, 9, 6], [2, 16, 14]]) >>> setattr(m, "ring", ZZ) >>> print(smith_normal_form(m)) Matrix([[1, 0, 0], [0, 10, 0], [0, 0, -30]]) ''' invs = invariant_factors(m, domain=domain) smf = diag(*invs) n = len(invs) if m.rows > n: smf = smf.row_insert(m.rows, zeros(m.rows-n, m.cols)) elif m.cols > n: smf = smf.col_insert(m.cols, zeros(m.rows, m.cols-n)) return smf
def _eval_inverse(self, **kwargs): """Return the matrix inverse using the method indicated (default is Gauss elimination). kwargs ====== method : ('GE', 'LU', or 'ADJ') iszerofunc try_block_diag Notes ===== According to the ``method`` keyword, it calls the appropriate method: GE .... inverse_GE(); default LU .... inverse_LU() ADJ ... inverse_ADJ() According to the ``try_block_diag`` keyword, it will try to form block diagonal matrices using the method get_diag_blocks(), invert these individually, and then reconstruct the full inverse matrix. Note, the GE and LU methods may require the matrix to be simplified before it is inverted in order to properly detect zeros during pivoting. In difficult cases a custom zero detection function can be provided by setting the ``iszerosfunc`` argument to a function that should return True if its argument is zero. The ADJ routine computes the determinant and uses that to detect singular matrices in addition to testing for zeros on the diagonal. See Also ======== inverse_LU inverse_GE inverse_ADJ """ from sympy.matrices import diag method = kwargs.get('method', 'GE') iszerofunc = kwargs.get('iszerofunc', _iszero) if kwargs.get('try_block_diag', False): blocks = self.get_diag_blocks() r = [] for block in blocks: r.append(block.inv(method=method, iszerofunc=iszerofunc)) return diag(*r) if method == "GE": return self.inverse_GE(iszerofunc=iszerofunc) elif method == "LU": return self.inverse_LU(iszerofunc=iszerofunc) elif method == "ADJ": return self.inverse_ADJ(iszerofunc=iszerofunc) else: # make sure to add an invertibility check (as in inverse_LU) # if a new method is added. raise ValueError("Inversion method unrecognized")
def scale_matrix(all_elements, mat, inds): """ Scales the k or l matrix. The procedure is the same for each matrix: (D^x)^(-1) * y * D^(x_i) Inverse diagonal The matrix to be The diagonal of of the x where scaled. i.e. the the independent x x is either the k or l matrix where x is the species or the species or the fluxes fluxes """ d_all_inv = diag(*all_elements).inv() d_inds = diag(*inds) scaled_matrix = d_all_inv * mat * d_inds return scaled_matrix
def rmat_k2d(d): d = normalize(d) if d == k: rot = eye(3) elif d == -k: rot = diag(1,-1,-1) else: rot = rquat2rmat(rquat(acos(dot(k, d)), cross(k, d))) return rot
def zfac2zmat(zfac): """ >>> from sympy import * >>> from symplus.strplus import init_mprinting >>> init_mprinting() >>> zfac2zmat([5,2,sqrt(3)]) <BLANKLINE> [5 0 0] [0 2 0] [0 0 sqrt(3)] """ return Mat(diag(*zfac))
def eye(n, cls=None): """Create square identity matrix n x n See Also ======== diag zeros ones """ n = as_int(n) return diag(*[S.One]*n, **dict(cls=cls))
def ALGO4(As,Bs,Cs,Ds,do_test): #-------------------STEP 1------------------------------ if not is_row_proper(As): Us,Ast=row_proper(As) else: Us,Ast=eye(As.rows),As Bst=Us*Bs Bst=expand(Bst) r=Ast.cols #-------------------STEP 2------------------------------ K=simplify(Ast.inv()*Bst) #very important Ys=zeros(K.shape) for i,j in product(range(K.rows),range(K.cols)): Ys[i,j],q=div(numer(K[i,j]),denom(K[i,j])) B_hat=Bst-Ast*Ys #-------------------END STEP 2------------------------------ #-------------------STEP 3------------------------------ Psi=diag(*[[s**( mc.row_degrees(Ast,s)[j] -i -1) for i in range( mc.row_degrees(Ast,s)[j])] for j in range(r)]).T S=diag(*[s**(rho) for rho in mc.row_degrees(Ast,s)]) Ahr=mc.highest_row_degree_matrix(Ast,s) Help=Ast-S*Ahr SOL={} numvar=Psi.rows*Psi.cols alr=symbols('a0:%d'%numvar) Alr=Matrix(Psi.cols,Psi.rows,alr) RHS=Psi*Alr for i,j in product(range(Help.rows),range(Help.cols)): #diagonal explain later SOL.update(solve_undetermined_coeffs(Eq(Help[i,j],RHS[i,j]),alr,s)) Alr=Alr.subs(SOL) #substitute(SOL) Aoc=Matrix(BlockDiagMatrix(*[Matrix(rho, rho, lambda i,j: KroneckerDelta(i+1,j))for rho in mc.row_degrees(Ast,s)])) Boc=eye(sum(mc.row_degrees(Ast,s))) Coc=Matrix(BlockDiagMatrix(*[SparseMatrix(1,rho,{(x,0):1 if x==0 else 0 for x in range(rho)}) for rho in mc.row_degrees(Ast,s)])) A0=Aoc-Alr*Ahr.inv()*Matrix(Coc) C0=Ahr.inv()*Coc SOL={} numvar=Psi.cols*Bst.cols b0=symbols('b0:%d'%numvar) B0=Matrix(Psi.cols,Bst.cols,b0) RHS=Psi*B0 for i,j in product(range(B_hat.rows),range(B_hat.cols)): #diagonal explain later SOL.update(solve_undetermined_coeffs(Eq(B_hat[i,j],RHS[i,j]),b0,s)) B0=B0.subs(SOL) #substitute(SOL) LHS_matrix=simplify(Cs*C0) #left hand side of the equation (1) sI_A=s*eye(A0.cols)- A0 max_degree=mc.find_degree(LHS_matrix,s) #get the degree of the matrix at the LHS #which is also the maximum degree for the coefficients of Λ(s) #---------------------------Creating Matrices Λ(s) and C ------------------------------------- Lamda=[] numvar=((max_degree))*A0.cols a=symbols('a0:%d'%numvar) for i in range(A0.cols): # paratirisi den douleuei to prin giat;i otra oxi diagonios p=sum(a[n +i*(max_degree)]*s**n for n in range(max_degree)) # we want variables one degree lower because we are multiplying by first order monomials Lamda.append(p) Lamda=Matrix(Cs.rows,A0.cols,Lamda) #convert the list to Matrix c=symbols('c0:%d'%(Lamda.rows*Lamda.cols)) C=Matrix(Lamda.rows,Lamda.cols,c) #----------------------------------------- RHS_matrix=Lamda*sI_A +C #right hand side of the equation (1) ''' -----------Converting equation (1) to a system of linear ----------- -----------equations, comparing the coefficients of the ----------- -----------polynomials in both sides of the equation (1) ----------- ''' EQ=[Eq(LHS_matrix[i,j],expand(RHS_matrix[i,j])) for i,j in product(range(LHS_matrix.rows),range(LHS_matrix.cols)) ]
from sympy import Symbol from sympy.matrices import Matrix, eye, zeros, ones, diag from sympy import pretty_print from SymbolicCollisions.core.DiscreteCMTransforms import get_DF from SymbolicCollisions.core.cm_symbols import Shift_ortho_Straka_d2q5 """ See 'New Cascaded Thermal Lattice Boltzmann Method for simulations for advection-diffusion and convective heat transfer' by K.V. Sharma, R. Straka, F.W. Tavares, 2017 """ # Smat = get_shift_matrix(K_ortho_Straka_d2q5, ex_Straka_d2_q5, ey_Straka_d2_q5) # pretty_print(Smat) Smat = Shift_ortho_Straka_d2q5 k = get_DF(q=4, print_symbol='k') Relax = diag(Symbol('w2'), Symbol('w3'), Symbol('w4'), Symbol('w5')) # cm_neq = get_DF(q=4, print_symbol='cm_neq') k = Smat.inv()*Relax*cm_neq pretty_print(k)
def _eval_inverse(self, **kwargs): """Return the matrix inverse using the method indicated (default is Gauss elimination). kwargs ====== method : ('GE', 'LU', or 'ADJ') iszerofunc try_block_diag Notes ===== According to the ``method`` keyword, it calls the appropriate method: GE .... inverse_GE(); default LU .... inverse_LU() ADJ ... inverse_ADJ() According to the ``try_block_diag`` keyword, it will try to form block diagonal matrices using the method get_diag_blocks(), invert these individually, and then reconstruct the full inverse matrix. Note, the GE and LU methods may require the matrix to be simplified before it is inverted in order to properly detect zeros during pivoting. In difficult cases a custom zero detection function can be provided by setting the ``iszerosfunc`` argument to a function that should return True if its argument is zero. The ADJ routine computes the determinant and uses that to detect singular matrices in addition to testing for zeros on the diagonal. See Also ======== inverse_LU inverse_GE inverse_ADJ """ from sympy.matrices import diag method = kwargs.get('method', 'GE') iszerofunc = kwargs.get('iszerofunc', _iszero) if kwargs.get('try_block_diag', False): blocks = self.get_diag_blocks() r = [] for block in blocks: r.append(block.inv(method=method, iszerofunc=iszerofunc)) return diag(*r) M = self.as_mutable() if method == "GE": rv = M.inverse_GE(iszerofunc=iszerofunc) elif method == "LU": rv = M.inverse_LU(iszerofunc=iszerofunc) elif method == "ADJ": rv = M.inverse_ADJ(iszerofunc=iszerofunc) else: # make sure to add an invertibility check (as in inverse_LU) # if a new method is added. raise ValueError("Inversion method unrecognized") return self._new(rv)
def test_diag_make(): diag = SpecialOnlyMatrix.diag a = Matrix([[1, 2], [2, 3]]) b = Matrix([[3, x], [y, 3]]) c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]]) assert diag(a, b, b) == Matrix([ [1, 2, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0], [0, 0, 3, x, 0, 0], [0, 0, y, 3, 0, 0], [0, 0, 0, 0, 3, x], [0, 0, 0, 0, y, 3], ]) assert diag(a, b, c) == Matrix([ [1, 2, 0, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0, 0], [0, 0, 3, x, 0, 0, 0], [0, 0, y, 3, 0, 0, 0], [0, 0, 0, 0, 3, x, 3], [0, 0, 0, 0, y, 3, z], [0, 0, 0, 0, x, y, z], ]) assert diag(a, c, b) == Matrix([ [1, 2, 0, 0, 0, 0, 0], [2, 3, 0, 0, 0, 0, 0], [0, 0, 3, x, 3, 0, 0], [0, 0, y, 3, z, 0, 0], [0, 0, x, y, z, 0, 0], [0, 0, 0, 0, 0, 3, x], [0, 0, 0, 0, 0, y, 3], ]) a = Matrix([x, y, z]) b = Matrix([[1, 2], [3, 4]]) c = Matrix([[5, 6]]) # this "wandering diagonal" is what makes this # a block diagonal where each block is independent # of the others assert diag(a, 7, b, c) == Matrix([[x, 0, 0, 0, 0, 0], [y, 0, 0, 0, 0, 0], [z, 0, 0, 0, 0, 0], [0, 7, 0, 0, 0, 0], [0, 0, 1, 2, 0, 0], [0, 0, 3, 4, 0, 0], [0, 0, 0, 0, 5, 6]]) raises(ValueError, lambda: diag(a, 7, b, c, rows=5)) assert diag(1) == Matrix([[1]]) assert diag(1, rows=2) == Matrix([[1, 0], [0, 0]]) assert diag(1, cols=2) == Matrix([[1, 0], [0, 0]]) assert diag(1, rows=3, cols=2) == Matrix([[1, 0], [0, 0], [0, 0]]) assert diag(*[2, 3]) == Matrix([[2, 0], [0, 3]]) assert diag(Matrix([2, 3])) == Matrix([[2], [3]]) assert diag([1, [2, 3], 4], unpack=False) == \ diag([[1], [2, 3], [4]], unpack=False) == Matrix([ [1, 0], [2, 3], [4, 0]]) assert type(diag(1)) == SpecialOnlyMatrix assert type(diag(1, cls=Matrix)) == Matrix assert Matrix.diag([1, 2, 3]) == Matrix.diag(1, 2, 3) assert Matrix.diag([1, 2, 3], unpack=False).shape == (3, 1) assert Matrix.diag([[1, 2, 3]]).shape == (3, 1) assert Matrix.diag([[1, 2, 3]], unpack=False).shape == (1, 3) assert Matrix.diag([[[1, 2, 3]]]).shape == (1, 3) # kerning can be used to move the starting point assert Matrix.diag(ones(0, 2), 1, 2) == Matrix([[0, 0, 1, 0], [0, 0, 0, 2]]) assert Matrix.diag(ones(2, 0), 1, 2) == Matrix([[0, 0], [0, 0], [1, 0], [0, 2]])
ex_D2Q9 = Matrix([0, 1, 0, -1, 0, 1, -1, -1, 1]) ey_D2Q9 = Matrix([0, 0, 1, 0, -1, 1, 1, -1, -1]) e_D2Q9 = ex_D2Q9.col_insert(1, ey_D2Q9) # D3Q7 notation from TCLB ex_D3Q7 = Matrix([0, 1, -1, 0, 0, 0, 0]) ey_D3Q7 = Matrix([0, 0, 0, 1, -1, 0, 0]) ez_D3Q7 = Matrix([0, 0, 0, 0, 0, 1, -1]) # D3Q15 - notation from 'LBM Principles and Practise' Book p. 89 ex_D3Q15 = Matrix([0, 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, -1, 1]) ey_D3Q15 = Matrix([0, 0, 0, 1, -1, 0, 0, 1, -1, 1, -1, -1, 1, 1, -1]) ez_D3Q15 = Matrix([0, 0, 0, 0, 0, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1]) S_relax_ADE_D3Q15 = diag(1, omega_ade, omega_ade, omega_ade, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) # D3Q19 - # as in TCLB or '3D CLBM: Improved implementation and consistent forcing scheme' by L. Fei and Q. li 2018 # (differs from 'LBM Principles and Practise' Book) ex_D3Q19 = Matrix([0, 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0]) ey_D3Q19 = Matrix([0, 0, 0, 1, -1, 0, 0, 1, 1, -1, -1, 0, 0, 0, 0, 1, -1, 1, -1]) ez_D3Q19 = Matrix([0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, 1, -1, -1, 1, 1, -1, -1]) S_relax_ADE_D3Q19 = diag(1, omega_ade, omega_ade, omega_ade, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) # FROM TCLB # d3q19 = matrix(c( # 0, 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0, # 0, 0, 0, 1, -1, 0, 0, 1, 1, -1, -1, 0, 0, 0, 0, 1, -1, 1, -1,
def _inv(M, method=None, iszerofunc=_iszero, try_block_diag=False): """ Return the inverse of a matrix using the method indicated. Default for dense matrices is is Gauss elimination, default for sparse matrices is LDL. Parameters ========== method : ('GE', 'LU', 'ADJ', 'CH', 'LDL') iszerofunc : function, optional Zero-testing function to use. try_block_diag : bool, optional If True then will try to form block diagonal matrices using the method get_diag_blocks(), invert these individually, and then reconstruct the full inverse matrix. Examples ======== >>> from sympy import SparseMatrix, Matrix >>> A = SparseMatrix([ ... [ 2, -1, 0], ... [-1, 2, -1], ... [ 0, 0, 2]]) >>> A.inv('CH') Matrix([ [2/3, 1/3, 1/6], [1/3, 2/3, 1/3], [ 0, 0, 1/2]]) >>> A.inv(method='LDL') # use of 'method=' is optional Matrix([ [2/3, 1/3, 1/6], [1/3, 2/3, 1/3], [ 0, 0, 1/2]]) >>> A * _ Matrix([ [1, 0, 0], [0, 1, 0], [0, 0, 1]]) >>> A = Matrix(A) >>> A.inv('CH') Matrix([ [2/3, 1/3, 1/6], [1/3, 2/3, 1/3], [ 0, 0, 1/2]]) >>> A.inv('ADJ') == A.inv('GE') == A.inv('LU') == A.inv('CH') == A.inv('LDL') == A.inv('QR') True Notes ===== According to the ``method`` keyword, it calls the appropriate method: GE .... inverse_GE(); default for dense matrices LU .... inverse_LU() ADJ ... inverse_ADJ() CH ... inverse_CH() LDL ... inverse_LDL(); default for sparse matrices QR ... inverse_QR() Note, the GE and LU methods may require the matrix to be simplified before it is inverted in order to properly detect zeros during pivoting. In difficult cases a custom zero detection function can be provided by setting the ``iszerofunc`` argument to a function that should return True if its argument is zero. The ADJ routine computes the determinant and uses that to detect singular matrices in addition to testing for zeros on the diagonal. See Also ======== inverse_ADJ inverse_GE inverse_LU inverse_CH inverse_LDL Raises ====== ValueError If the determinant of the matrix is zero. """ from sympy.matrices import diag, SparseMatrix if method is None: method = 'LDL' if isinstance(M, SparseMatrix) else 'GE' if try_block_diag: blocks = M.get_diag_blocks() r = [] for block in blocks: r.append(block.inv(method=method, iszerofunc=iszerofunc)) return diag(*r) if method == "GE": rv = M.inverse_GE(iszerofunc=iszerofunc) elif method == "LU": rv = M.inverse_LU(iszerofunc=iszerofunc) elif method == "ADJ": rv = M.inverse_ADJ(iszerofunc=iszerofunc) elif method == "CH": rv = M.inverse_CH(iszerofunc=iszerofunc) elif method == "LDL": rv = M.inverse_LDL(iszerofunc=iszerofunc) elif method == "QR": rv = M.inverse_QR(iszerofunc=iszerofunc) else: raise ValueError("Inversion method unrecognized") return M._new(rv)