Spaces:
Sleeping
Sleeping
File size: 2,963 Bytes
6a86ad5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
from sympy.core.sympify import _sympify
from sympy.core import S, Basic
from sympy.matrices.exceptions import NonSquareMatrixError
from sympy.matrices.expressions.matpow import MatPow
class Inverse(MatPow):
"""
The multiplicative inverse of a matrix expression
This is a symbolic object that simply stores its argument without
evaluating it. To actually compute the inverse, use the ``.inverse()``
method of matrices.
Examples
========
>>> from sympy import MatrixSymbol, Inverse
>>> A = MatrixSymbol('A', 3, 3)
>>> B = MatrixSymbol('B', 3, 3)
>>> Inverse(A)
A**(-1)
>>> A.inverse() == Inverse(A)
True
>>> (A*B).inverse()
B**(-1)*A**(-1)
>>> Inverse(A*B)
(A*B)**(-1)
"""
is_Inverse = True
exp = S.NegativeOne
def __new__(cls, mat, exp=S.NegativeOne):
# exp is there to make it consistent with
# inverse.func(*inverse.args) == inverse
mat = _sympify(mat)
exp = _sympify(exp)
if not mat.is_Matrix:
raise TypeError("mat should be a matrix")
if mat.is_square is False:
raise NonSquareMatrixError("Inverse of non-square matrix %s" % mat)
return Basic.__new__(cls, mat, exp)
@property
def arg(self):
return self.args[0]
@property
def shape(self):
return self.arg.shape
def _eval_inverse(self):
return self.arg
def _eval_transpose(self):
return Inverse(self.arg.transpose())
def _eval_adjoint(self):
return Inverse(self.arg.adjoint())
def _eval_conjugate(self):
return Inverse(self.arg.conjugate())
def _eval_determinant(self):
from sympy.matrices.expressions.determinant import det
return 1/det(self.arg)
def doit(self, **hints):
if 'inv_expand' in hints and hints['inv_expand'] == False:
return self
arg = self.arg
if hints.get('deep', True):
arg = arg.doit(**hints)
return arg.inverse()
def _eval_derivative_matrix_lines(self, x):
arg = self.args[0]
lines = arg._eval_derivative_matrix_lines(x)
for line in lines:
line.first_pointer *= -self.T
line.second_pointer *= self
return lines
from sympy.assumptions.ask import ask, Q
from sympy.assumptions.refine import handlers_dict
def refine_Inverse(expr, assumptions):
"""
>>> from sympy import MatrixSymbol, Q, assuming, refine
>>> X = MatrixSymbol('X', 2, 2)
>>> X.I
X**(-1)
>>> with assuming(Q.orthogonal(X)):
... print(refine(X.I))
X.T
"""
if ask(Q.orthogonal(expr), assumptions):
return expr.arg.T
elif ask(Q.unitary(expr), assumptions):
return expr.arg.conjugate()
elif ask(Q.singular(expr), assumptions):
raise ValueError("Inverse of singular matrix %s" % expr.arg)
return expr
handlers_dict['Inverse'] = refine_Inverse
|