from sympy.core.basic import Basic from sympy.core.expr import Expr from sympy.core.singleton import S from sympy.core.sympify import sympify from sympy.matrices.exceptions import NonSquareMatrixError from sympy.matrices.matrixbase import MatrixBase class Determinant(Expr): """Matrix Determinant Represents the determinant of a matrix expression. Examples ======== >>> from sympy import MatrixSymbol, Determinant, eye >>> A = MatrixSymbol('A', 3, 3) >>> Determinant(A) Determinant(A) >>> Determinant(eye(3)).doit() 1 """ is_commutative = True def __new__(cls, mat): mat = sympify(mat) if not mat.is_Matrix: raise TypeError("Input to Determinant, %s, not a matrix" % str(mat)) if mat.is_square is False: raise NonSquareMatrixError("Det of a non-square matrix") return Basic.__new__(cls, mat) @property def arg(self): return self.args[0] @property def kind(self): return self.arg.kind.element_kind def doit(self, **hints): arg = self.arg if hints.get('deep', True): arg = arg.doit(**hints) result = arg._eval_determinant() if result is not None: return result return self def det(matexpr): """ Matrix Determinant Examples ======== >>> from sympy import MatrixSymbol, det, eye >>> A = MatrixSymbol('A', 3, 3) >>> det(A) Determinant(A) >>> det(eye(3)) 1 """ return Determinant(matexpr).doit() class Permanent(Expr): """Matrix Permanent Represents the permanent of a matrix expression. Examples ======== >>> from sympy import MatrixSymbol, Permanent, ones >>> A = MatrixSymbol('A', 3, 3) >>> Permanent(A) Permanent(A) >>> Permanent(ones(3, 3)).doit() 6 """ def __new__(cls, mat): mat = sympify(mat) if not mat.is_Matrix: raise TypeError("Input to Permanent, %s, not a matrix" % str(mat)) return Basic.__new__(cls, mat) @property def arg(self): return self.args[0] def doit(self, expand=False, **hints): if isinstance(self.arg, MatrixBase): return self.arg.per() else: return self def per(matexpr): """ Matrix Permanent Examples ======== >>> from sympy import MatrixSymbol, Matrix, per, ones >>> A = MatrixSymbol('A', 3, 3) >>> per(A) Permanent(A) >>> per(ones(5, 5)) 120 >>> M = Matrix([1, 2, 5]) >>> per(M) 8 """ return Permanent(matexpr).doit() from sympy.assumptions.ask import ask, Q from sympy.assumptions.refine import handlers_dict def refine_Determinant(expr, assumptions): """ >>> from sympy import MatrixSymbol, Q, assuming, refine, det >>> X = MatrixSymbol('X', 2, 2) >>> det(X) Determinant(X) >>> with assuming(Q.orthogonal(X)): ... print(refine(det(X))) 1 """ if ask(Q.orthogonal(expr.arg), assumptions): return S.One elif ask(Q.singular(expr.arg), assumptions): return S.Zero elif ask(Q.unit_triangular(expr.arg), assumptions): return S.One return expr handlers_dict['Determinant'] = refine_Determinant