kind.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # sympy.matrices.kind
  2. from sympy.core.kind import Kind, _NumberKind, NumberKind
  3. from sympy.core.mul import Mul
  4. class MatrixKind(Kind):
  5. """
  6. Kind for all matrices in SymPy.
  7. Basic class for this kind is ``MatrixBase`` and ``MatrixExpr``,
  8. but any expression representing the matrix can have this.
  9. Parameters
  10. ==========
  11. element_kind : Kind
  12. Kind of the element. Default is
  13. :class:`sympy.core.kind.NumberKind`,
  14. which means that the matrix contains only numbers.
  15. Examples
  16. ========
  17. Any instance of matrix class has kind ``MatrixKind``:
  18. >>> from sympy import MatrixSymbol
  19. >>> A = MatrixSymbol('A', 2, 2)
  20. >>> A.kind
  21. MatrixKind(NumberKind)
  22. An expression representing a matrix may not be an instance of
  23. the Matrix class, but it will have kind ``MatrixKind``:
  24. >>> from sympy import MatrixExpr, Integral
  25. >>> from sympy.abc import x
  26. >>> intM = Integral(A, x)
  27. >>> isinstance(intM, MatrixExpr)
  28. False
  29. >>> intM.kind
  30. MatrixKind(NumberKind)
  31. Use ``isinstance()`` to check for ``MatrixKind`` without specifying the
  32. element kind. Use ``is`` to check the kind including the element kind:
  33. >>> from sympy import Matrix
  34. >>> from sympy.core import NumberKind
  35. >>> from sympy.matrices import MatrixKind
  36. >>> M = Matrix([1, 2])
  37. >>> isinstance(M.kind, MatrixKind)
  38. True
  39. >>> M.kind is MatrixKind(NumberKind)
  40. True
  41. See Also
  42. ========
  43. sympy.core.kind.NumberKind
  44. sympy.core.kind.UndefinedKind
  45. sympy.core.containers.TupleKind
  46. sympy.sets.sets.SetKind
  47. """
  48. def __new__(cls, element_kind=NumberKind):
  49. obj = super().__new__(cls, element_kind)
  50. obj.element_kind = element_kind
  51. return obj
  52. def __repr__(self):
  53. return "MatrixKind(%s)" % self.element_kind
  54. @Mul._kind_dispatcher.register(_NumberKind, MatrixKind)
  55. def num_mat_mul(k1, k2):
  56. """
  57. Return MatrixKind. The element kind is selected by recursive dispatching.
  58. Do not need to dispatch in reversed order because KindDispatcher
  59. searches for this automatically.
  60. """
  61. # Deal with Mul._kind_dispatcher's commutativity
  62. # XXX: this function is called with either k1 or k2 as MatrixKind because
  63. # the Mul kind dispatcher is commutative. Maybe it shouldn't be. Need to
  64. # swap the args here because NumberKind does not have an element_kind
  65. # attribute.
  66. if not isinstance(k2, MatrixKind):
  67. k1, k2 = k2, k1
  68. elemk = Mul._kind_dispatcher(k1, k2.element_kind)
  69. return MatrixKind(elemk)
  70. @Mul._kind_dispatcher.register(MatrixKind, MatrixKind)
  71. def mat_mat_mul(k1, k2):
  72. """
  73. Return MatrixKind. The element kind is selected by recursive dispatching.
  74. """
  75. elemk = Mul._kind_dispatcher(k1.element_kind, k2.element_kind)
  76. return MatrixKind(elemk)