determinant.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. from sympy.core.basic import Basic
  2. from sympy.core.expr import Expr
  3. from sympy.core.singleton import S
  4. from sympy.core.sympify import sympify
  5. from sympy.matrices.exceptions import NonSquareMatrixError
  6. from sympy.matrices.matrixbase import MatrixBase
  7. class Determinant(Expr):
  8. """Matrix Determinant
  9. Represents the determinant of a matrix expression.
  10. Examples
  11. ========
  12. >>> from sympy import MatrixSymbol, Determinant, eye
  13. >>> A = MatrixSymbol('A', 3, 3)
  14. >>> Determinant(A)
  15. Determinant(A)
  16. >>> Determinant(eye(3)).doit()
  17. 1
  18. """
  19. is_commutative = True
  20. def __new__(cls, mat):
  21. mat = sympify(mat)
  22. if not mat.is_Matrix:
  23. raise TypeError("Input to Determinant, %s, not a matrix" % str(mat))
  24. if mat.is_square is False:
  25. raise NonSquareMatrixError("Det of a non-square matrix")
  26. return Basic.__new__(cls, mat)
  27. @property
  28. def arg(self):
  29. return self.args[0]
  30. @property
  31. def kind(self):
  32. return self.arg.kind.element_kind
  33. def doit(self, **hints):
  34. arg = self.arg
  35. if hints.get('deep', True):
  36. arg = arg.doit(**hints)
  37. result = arg._eval_determinant()
  38. if result is not None:
  39. return result
  40. return self
  41. def det(matexpr):
  42. """ Matrix Determinant
  43. Examples
  44. ========
  45. >>> from sympy import MatrixSymbol, det, eye
  46. >>> A = MatrixSymbol('A', 3, 3)
  47. >>> det(A)
  48. Determinant(A)
  49. >>> det(eye(3))
  50. 1
  51. """
  52. return Determinant(matexpr).doit()
  53. class Permanent(Expr):
  54. """Matrix Permanent
  55. Represents the permanent of a matrix expression.
  56. Examples
  57. ========
  58. >>> from sympy import MatrixSymbol, Permanent, ones
  59. >>> A = MatrixSymbol('A', 3, 3)
  60. >>> Permanent(A)
  61. Permanent(A)
  62. >>> Permanent(ones(3, 3)).doit()
  63. 6
  64. """
  65. def __new__(cls, mat):
  66. mat = sympify(mat)
  67. if not mat.is_Matrix:
  68. raise TypeError("Input to Permanent, %s, not a matrix" % str(mat))
  69. return Basic.__new__(cls, mat)
  70. @property
  71. def arg(self):
  72. return self.args[0]
  73. def doit(self, expand=False, **hints):
  74. if isinstance(self.arg, MatrixBase):
  75. return self.arg.per()
  76. else:
  77. return self
  78. def per(matexpr):
  79. """ Matrix Permanent
  80. Examples
  81. ========
  82. >>> from sympy import MatrixSymbol, Matrix, per, ones
  83. >>> A = MatrixSymbol('A', 3, 3)
  84. >>> per(A)
  85. Permanent(A)
  86. >>> per(ones(5, 5))
  87. 120
  88. >>> M = Matrix([1, 2, 5])
  89. >>> per(M)
  90. 8
  91. """
  92. return Permanent(matexpr).doit()
  93. from sympy.assumptions.ask import ask, Q
  94. from sympy.assumptions.refine import handlers_dict
  95. def refine_Determinant(expr, assumptions):
  96. """
  97. >>> from sympy import MatrixSymbol, Q, assuming, refine, det
  98. >>> X = MatrixSymbol('X', 2, 2)
  99. >>> det(X)
  100. Determinant(X)
  101. >>> with assuming(Q.orthogonal(X)):
  102. ... print(refine(det(X)))
  103. 1
  104. """
  105. if ask(Q.orthogonal(expr.arg), assumptions):
  106. return S.One
  107. elif ask(Q.singular(expr.arg), assumptions):
  108. return S.Zero
  109. elif ask(Q.unit_triangular(expr.arg), assumptions):
  110. return S.One
  111. return expr
  112. handlers_dict['Determinant'] = refine_Determinant