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

26 statements  

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

1from sympy.core.relational import Eq 

2from sympy.core.expr import Expr 

3from sympy.core.numbers import Integer 

4from sympy.logic.boolalg import Boolean, And 

5from sympy.matrices.expressions.matexpr import MatrixExpr 

6from sympy.matrices.common import ShapeError 

7from typing import Union 

8 

9 

10def is_matadd_valid(*args: MatrixExpr) -> Boolean: 

11 """Return the symbolic condition how ``MatAdd``, ``HadamardProduct`` 

12 makes sense. 

13 

14 Parameters 

15 ========== 

16 

17 args 

18 The list of arguments of matrices to be tested for. 

19 

20 Examples 

21 ======== 

22 

23 >>> from sympy import MatrixSymbol, symbols 

24 >>> from sympy.matrices.expressions._shape import is_matadd_valid 

25 

26 >>> m, n, p, q = symbols('m n p q') 

27 >>> A = MatrixSymbol('A', m, n) 

28 >>> B = MatrixSymbol('B', p, q) 

29 >>> is_matadd_valid(A, B) 

30 Eq(m, p) & Eq(n, q) 

31 """ 

32 rows, cols = zip(*(arg.shape for arg in args)) 

33 return And( 

34 *(Eq(i, j) for i, j in zip(rows[:-1], rows[1:])), 

35 *(Eq(i, j) for i, j in zip(cols[:-1], cols[1:])), 

36 ) 

37 

38 

39def is_matmul_valid(*args: Union[MatrixExpr, Expr]) -> Boolean: 

40 """Return the symbolic condition how ``MatMul`` makes sense 

41 

42 Parameters 

43 ========== 

44 

45 args 

46 The list of arguments of matrices and scalar expressions to be tested 

47 for. 

48 

49 Examples 

50 ======== 

51 

52 >>> from sympy import MatrixSymbol, symbols 

53 >>> from sympy.matrices.expressions._shape import is_matmul_valid 

54 

55 >>> m, n, p, q = symbols('m n p q') 

56 >>> A = MatrixSymbol('A', m, n) 

57 >>> B = MatrixSymbol('B', p, q) 

58 >>> is_matmul_valid(A, B) 

59 Eq(n, p) 

60 """ 

61 rows, cols = zip(*(arg.shape for arg in args if isinstance(arg, MatrixExpr))) 

62 return And(*(Eq(i, j) for i, j in zip(cols[:-1], rows[1:]))) 

63 

64 

65def is_square(arg: MatrixExpr, /) -> Boolean: 

66 """Return the symbolic condition how the matrix is assumed to be square 

67 

68 Parameters 

69 ========== 

70 

71 arg 

72 The matrix to be tested for. 

73 

74 Examples 

75 ======== 

76 

77 >>> from sympy import MatrixSymbol, symbols 

78 >>> from sympy.matrices.expressions._shape import is_square 

79 

80 >>> m, n = symbols('m n') 

81 >>> A = MatrixSymbol('A', m, n) 

82 >>> is_square(A) 

83 Eq(m, n) 

84 """ 

85 return Eq(arg.rows, arg.cols) 

86 

87 

88def validate_matadd_integer(*args: MatrixExpr) -> None: 

89 """Validate matrix shape for addition only for integer values""" 

90 rows, cols = zip(*(x.shape for x in args)) 

91 if len(set(filter(lambda x: isinstance(x, (int, Integer)), rows))) > 1: 

92 raise ShapeError(f"Matrices have mismatching shape: {rows}") 

93 if len(set(filter(lambda x: isinstance(x, (int, Integer)), cols))) > 1: 

94 raise ShapeError(f"Matrices have mismatching shape: {cols}") 

95 

96 

97def validate_matmul_integer(*args: MatrixExpr) -> None: 

98 """Validate matrix shape for multiplication only for integer values""" 

99 for A, B in zip(args[:-1], args[1:]): 

100 i, j = A.cols, B.rows 

101 if isinstance(i, (int, Integer)) and isinstance(j, (int, Integer)) and i != j: 

102 raise ShapeError("Matrices are not aligned", i, j)