Coverage for /usr/lib/python3/dist-packages/sympy/matrices/expressions/inverse.py: 39%

51 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1from sympy.core.sympify import _sympify 

2from sympy.core import S, Basic 

3 

4from sympy.matrices.common import NonSquareMatrixError 

5from sympy.matrices.expressions.matpow import MatPow 

6 

7 

8class Inverse(MatPow): 

9 """ 

10 The multiplicative inverse of a matrix expression 

11 

12 This is a symbolic object that simply stores its argument without 

13 evaluating it. To actually compute the inverse, use the ``.inverse()`` 

14 method of matrices. 

15 

16 Examples 

17 ======== 

18 

19 >>> from sympy import MatrixSymbol, Inverse 

20 >>> A = MatrixSymbol('A', 3, 3) 

21 >>> B = MatrixSymbol('B', 3, 3) 

22 >>> Inverse(A) 

23 A**(-1) 

24 >>> A.inverse() == Inverse(A) 

25 True 

26 >>> (A*B).inverse() 

27 B**(-1)*A**(-1) 

28 >>> Inverse(A*B) 

29 (A*B)**(-1) 

30 

31 """ 

32 is_Inverse = True 

33 exp = S.NegativeOne 

34 

35 def __new__(cls, mat, exp=S.NegativeOne): 

36 # exp is there to make it consistent with 

37 # inverse.func(*inverse.args) == inverse 

38 mat = _sympify(mat) 

39 exp = _sympify(exp) 

40 if not mat.is_Matrix: 

41 raise TypeError("mat should be a matrix") 

42 if mat.is_square is False: 

43 raise NonSquareMatrixError("Inverse of non-square matrix %s" % mat) 

44 return Basic.__new__(cls, mat, exp) 

45 

46 @property 

47 def arg(self): 

48 return self.args[0] 

49 

50 @property 

51 def shape(self): 

52 return self.arg.shape 

53 

54 def _eval_inverse(self): 

55 return self.arg 

56 

57 def _eval_determinant(self): 

58 from sympy.matrices.expressions.determinant import det 

59 return 1/det(self.arg) 

60 

61 def doit(self, **hints): 

62 if 'inv_expand' in hints and hints['inv_expand'] == False: 

63 return self 

64 

65 arg = self.arg 

66 if hints.get('deep', True): 

67 arg = arg.doit(**hints) 

68 

69 return arg.inverse() 

70 

71 def _eval_derivative_matrix_lines(self, x): 

72 arg = self.args[0] 

73 lines = arg._eval_derivative_matrix_lines(x) 

74 for line in lines: 

75 line.first_pointer *= -self.T 

76 line.second_pointer *= self 

77 return lines 

78 

79 

80from sympy.assumptions.ask import ask, Q 

81from sympy.assumptions.refine import handlers_dict 

82 

83 

84def refine_Inverse(expr, assumptions): 

85 """ 

86 >>> from sympy import MatrixSymbol, Q, assuming, refine 

87 >>> X = MatrixSymbol('X', 2, 2) 

88 >>> X.I 

89 X**(-1) 

90 >>> with assuming(Q.orthogonal(X)): 

91 ... print(refine(X.I)) 

92 X.T 

93 """ 

94 if ask(Q.orthogonal(expr), assumptions): 

95 return expr.arg.T 

96 elif ask(Q.unitary(expr), assumptions): 

97 return expr.arg.conjugate() 

98 elif ask(Q.singular(expr), assumptions): 

99 raise ValueError("Inverse of singular matrix %s" % expr.arg) 

100 

101 return expr 

102 

103handlers_dict['Inverse'] = refine_Inverse