m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2304 lines
76 KiB

6 months ago
  1. import mpmath as mp
  2. from collections.abc import Callable
  3. from sympy.core.add import Add
  4. from sympy.core.basic import Basic
  5. from sympy.core.function import diff
  6. from sympy.core.expr import Expr
  7. from sympy.core.kind import _NumberKind, UndefinedKind
  8. from sympy.core.mul import Mul
  9. from sympy.core.power import Pow
  10. from sympy.core.singleton import S
  11. from sympy.core.symbol import Dummy, Symbol, uniquely_named_symbol
  12. from sympy.core.sympify import sympify
  13. from sympy.core.sympify import _sympify
  14. from sympy.functions import factorial
  15. from sympy.functions.elementary.complexes import re
  16. from sympy.functions.elementary.exponential import exp, log
  17. from sympy.functions.elementary.miscellaneous import Max, Min, sqrt
  18. from sympy.functions.special.tensor_functions import KroneckerDelta
  19. from sympy.polys import cancel
  20. from sympy.printing import sstr
  21. from sympy.printing.defaults import Printable
  22. from sympy.simplify import simplify as _simplify
  23. from sympy.utilities.decorator import deprecated
  24. from sympy.utilities.exceptions import sympy_deprecation_warning
  25. from sympy.utilities.iterables import flatten, NotIterable, is_sequence, reshape
  26. from sympy.utilities.misc import as_int, filldedent
  27. from .common import (
  28. MatrixCommon, MatrixError, NonSquareMatrixError, NonInvertibleMatrixError,
  29. ShapeError, MatrixKind)
  30. from .utilities import _iszero, _is_zero_after_expand_mul
  31. from .determinant import (
  32. _find_reasonable_pivot, _find_reasonable_pivot_naive,
  33. _adjugate, _charpoly, _cofactor, _cofactor_matrix, _per,
  34. _det, _det_bareiss, _det_berkowitz, _det_LU, _minor, _minor_submatrix)
  35. from .reductions import _is_echelon, _echelon_form, _rank, _rref
  36. from .subspaces import _columnspace, _nullspace, _rowspace, _orthogonalize
  37. from .eigen import (
  38. _eigenvals, _eigenvects,
  39. _bidiagonalize, _bidiagonal_decomposition,
  40. _is_diagonalizable, _diagonalize,
  41. _is_positive_definite, _is_positive_semidefinite,
  42. _is_negative_definite, _is_negative_semidefinite, _is_indefinite,
  43. _jordan_form, _left_eigenvects, _singular_values)
  44. from .decompositions import (
  45. _rank_decomposition, _cholesky, _LDLdecomposition,
  46. _LUdecomposition, _LUdecomposition_Simple, _LUdecompositionFF,
  47. _singular_value_decomposition, _QRdecomposition, _upper_hessenberg_decomposition)
  48. from .graph import (
  49. _connected_components, _connected_components_decomposition,
  50. _strongly_connected_components, _strongly_connected_components_decomposition)
  51. from .solvers import (
  52. _diagonal_solve, _lower_triangular_solve, _upper_triangular_solve,
  53. _cholesky_solve, _LDLsolve, _LUsolve, _QRsolve, _gauss_jordan_solve,
  54. _pinv_solve, _solve, _solve_least_squares)
  55. from .inverse import (
  56. _pinv, _inv_mod, _inv_ADJ, _inv_GE, _inv_LU, _inv_CH, _inv_LDL, _inv_QR,
  57. _inv, _inv_block)
  58. class DeferredVector(Symbol, NotIterable):
  59. """A vector whose components are deferred (e.g. for use with lambdify)
  60. Examples
  61. ========
  62. >>> from sympy import DeferredVector, lambdify
  63. >>> X = DeferredVector( 'X' )
  64. >>> X
  65. X
  66. >>> expr = (X[0] + 2, X[2] + 3)
  67. >>> func = lambdify( X, expr)
  68. >>> func( [1, 2, 3] )
  69. (3, 6)
  70. """
  71. def __getitem__(self, i):
  72. if i == -0:
  73. i = 0
  74. if i < 0:
  75. raise IndexError('DeferredVector index out of range')
  76. component_name = '%s[%d]' % (self.name, i)
  77. return Symbol(component_name)
  78. def __str__(self):
  79. return sstr(self)
  80. def __repr__(self):
  81. return "DeferredVector('%s')" % self.name
  82. class MatrixDeterminant(MatrixCommon):
  83. """Provides basic matrix determinant operations. Should not be instantiated
  84. directly. See ``determinant.py`` for their implementations."""
  85. def _eval_det_bareiss(self, iszerofunc=_is_zero_after_expand_mul):
  86. return _det_bareiss(self, iszerofunc=iszerofunc)
  87. def _eval_det_berkowitz(self):
  88. return _det_berkowitz(self)
  89. def _eval_det_lu(self, iszerofunc=_iszero, simpfunc=None):
  90. return _det_LU(self, iszerofunc=iszerofunc, simpfunc=simpfunc)
  91. def _eval_determinant(self): # for expressions.determinant.Determinant
  92. return _det(self)
  93. def adjugate(self, method="berkowitz"):
  94. return _adjugate(self, method=method)
  95. def charpoly(self, x='lambda', simplify=_simplify):
  96. return _charpoly(self, x=x, simplify=simplify)
  97. def cofactor(self, i, j, method="berkowitz"):
  98. return _cofactor(self, i, j, method=method)
  99. def cofactor_matrix(self, method="berkowitz"):
  100. return _cofactor_matrix(self, method=method)
  101. def det(self, method="bareiss", iszerofunc=None):
  102. return _det(self, method=method, iszerofunc=iszerofunc)
  103. def per(self):
  104. return _per(self)
  105. def minor(self, i, j, method="berkowitz"):
  106. return _minor(self, i, j, method=method)
  107. def minor_submatrix(self, i, j):
  108. return _minor_submatrix(self, i, j)
  109. _find_reasonable_pivot.__doc__ = _find_reasonable_pivot.__doc__
  110. _find_reasonable_pivot_naive.__doc__ = _find_reasonable_pivot_naive.__doc__
  111. _eval_det_bareiss.__doc__ = _det_bareiss.__doc__
  112. _eval_det_berkowitz.__doc__ = _det_berkowitz.__doc__
  113. _eval_det_lu.__doc__ = _det_LU.__doc__
  114. _eval_determinant.__doc__ = _det.__doc__
  115. adjugate.__doc__ = _adjugate.__doc__
  116. charpoly.__doc__ = _charpoly.__doc__
  117. cofactor.__doc__ = _cofactor.__doc__
  118. cofactor_matrix.__doc__ = _cofactor_matrix.__doc__
  119. det.__doc__ = _det.__doc__
  120. per.__doc__ = _per.__doc__
  121. minor.__doc__ = _minor.__doc__
  122. minor_submatrix.__doc__ = _minor_submatrix.__doc__
  123. class MatrixReductions(MatrixDeterminant):
  124. """Provides basic matrix row/column operations. Should not be instantiated
  125. directly. See ``reductions.py`` for some of their implementations."""
  126. def echelon_form(self, iszerofunc=_iszero, simplify=False, with_pivots=False):
  127. return _echelon_form(self, iszerofunc=iszerofunc, simplify=simplify,
  128. with_pivots=with_pivots)
  129. @property
  130. def is_echelon(self):
  131. return _is_echelon(self)
  132. def rank(self, iszerofunc=_iszero, simplify=False):
  133. return _rank(self, iszerofunc=iszerofunc, simplify=simplify)
  134. def rref(self, iszerofunc=_iszero, simplify=False, pivots=True,
  135. normalize_last=True):
  136. return _rref(self, iszerofunc=iszerofunc, simplify=simplify,
  137. pivots=pivots, normalize_last=normalize_last)
  138. echelon_form.__doc__ = _echelon_form.__doc__
  139. is_echelon.__doc__ = _is_echelon.__doc__
  140. rank.__doc__ = _rank.__doc__
  141. rref.__doc__ = _rref.__doc__
  142. def _normalize_op_args(self, op, col, k, col1, col2, error_str="col"):
  143. """Validate the arguments for a row/column operation. ``error_str``
  144. can be one of "row" or "col" depending on the arguments being parsed."""
  145. if op not in ["n->kn", "n<->m", "n->n+km"]:
  146. raise ValueError("Unknown {} operation '{}'. Valid col operations "
  147. "are 'n->kn', 'n<->m', 'n->n+km'".format(error_str, op))
  148. # define self_col according to error_str
  149. self_cols = self.cols if error_str == 'col' else self.rows
  150. # normalize and validate the arguments
  151. if op == "n->kn":
  152. col = col if col is not None else col1
  153. if col is None or k is None:
  154. raise ValueError("For a {0} operation 'n->kn' you must provide the "
  155. "kwargs `{0}` and `k`".format(error_str))
  156. if not 0 <= col < self_cols:
  157. raise ValueError("This matrix doesn't have a {} '{}'".format(error_str, col))
  158. elif op == "n<->m":
  159. # we need two cols to swap. It doesn't matter
  160. # how they were specified, so gather them together and
  161. # remove `None`
  162. cols = {col, k, col1, col2}.difference([None])
  163. if len(cols) > 2:
  164. # maybe the user left `k` by mistake?
  165. cols = {col, col1, col2}.difference([None])
  166. if len(cols) != 2:
  167. raise ValueError("For a {0} operation 'n<->m' you must provide the "
  168. "kwargs `{0}1` and `{0}2`".format(error_str))
  169. col1, col2 = cols
  170. if not 0 <= col1 < self_cols:
  171. raise ValueError("This matrix doesn't have a {} '{}'".format(error_str, col1))
  172. if not 0 <= col2 < self_cols:
  173. raise ValueError("This matrix doesn't have a {} '{}'".format(error_str, col2))
  174. elif op == "n->n+km":
  175. col = col1 if col is None else col
  176. col2 = col1 if col2 is None else col2
  177. if col is None or col2 is None or k is None:
  178. raise ValueError("For a {0} operation 'n->n+km' you must provide the "
  179. "kwargs `{0}`, `k`, and `{0}2`".format(error_str))
  180. if col == col2:
  181. raise ValueError("For a {0} operation 'n->n+km' `{0}` and `{0}2` must "
  182. "be different.".format(error_str))
  183. if not 0 <= col < self_cols:
  184. raise ValueError("This matrix doesn't have a {} '{}'".format(error_str, col))
  185. if not 0 <= col2 < self_cols:
  186. raise ValueError("This matrix doesn't have a {} '{}'".format(error_str, col2))
  187. else:
  188. raise ValueError('invalid operation %s' % repr(op))
  189. return op, col, k, col1, col2
  190. def _eval_col_op_multiply_col_by_const(self, col, k):
  191. def entry(i, j):
  192. if j == col:
  193. return k * self[i, j]
  194. return self[i, j]
  195. return self._new(self.rows, self.cols, entry)
  196. def _eval_col_op_swap(self, col1, col2):
  197. def entry(i, j):
  198. if j == col1:
  199. return self[i, col2]
  200. elif j == col2:
  201. return self[i, col1]
  202. return self[i, j]
  203. return self._new(self.rows, self.cols, entry)
  204. def _eval_col_op_add_multiple_to_other_col(self, col, k, col2):
  205. def entry(i, j):
  206. if j == col:
  207. return self[i, j] + k * self[i, col2]
  208. return self[i, j]
  209. return self._new(self.rows, self.cols, entry)
  210. def _eval_row_op_swap(self, row1, row2):
  211. def entry(i, j):
  212. if i == row1:
  213. return self[row2, j]
  214. elif i == row2:
  215. return self[row1, j]
  216. return self[i, j]
  217. return self._new(self.rows, self.cols, entry)
  218. def _eval_row_op_multiply_row_by_const(self, row, k):
  219. def entry(i, j):
  220. if i == row:
  221. return k * self[i, j]
  222. return self[i, j]
  223. return self._new(self.rows, self.cols, entry)
  224. def _eval_row_op_add_multiple_to_other_row(self, row, k, row2):
  225. def entry(i, j):
  226. if i == row:
  227. return self[i, j] + k * self[row2, j]
  228. return self[i, j]
  229. return self._new(self.rows, self.cols, entry)
  230. def elementary_col_op(self, op="n->kn", col=None, k=None, col1=None, col2=None):
  231. """Performs the elementary column operation `op`.
  232. `op` may be one of
  233. * ``"n->kn"`` (column n goes to k*n)
  234. * ``"n<->m"`` (swap column n and column m)
  235. * ``"n->n+km"`` (column n goes to column n + k*column m)
  236. Parameters
  237. ==========
  238. op : string; the elementary row operation
  239. col : the column to apply the column operation
  240. k : the multiple to apply in the column operation
  241. col1 : one column of a column swap
  242. col2 : second column of a column swap or column "m" in the column operation
  243. "n->n+km"
  244. """
  245. op, col, k, col1, col2 = self._normalize_op_args(op, col, k, col1, col2, "col")
  246. # now that we've validated, we're all good to dispatch
  247. if op == "n->kn":
  248. return self._eval_col_op_multiply_col_by_const(col, k)
  249. if op == "n<->m":
  250. return self._eval_col_op_swap(col1, col2)
  251. if op == "n->n+km":
  252. return self._eval_col_op_add_multiple_to_other_col(col, k, col2)
  253. def elementary_row_op(self, op="n->kn", row=None, k=None, row1=None, row2=None):
  254. """Performs the elementary row operation `op`.
  255. `op` may be one of
  256. * ``"n->kn"`` (row n goes to k*n)
  257. * ``"n<->m"`` (swap row n and row m)
  258. * ``"n->n+km"`` (row n goes to row n + k*row m)
  259. Parameters
  260. ==========
  261. op : string; the elementary row operation
  262. row : the row to apply the row operation
  263. k : the multiple to apply in the row operation
  264. row1 : one row of a row swap
  265. row2 : second row of a row swap or row "m" in the row operation
  266. "n->n+km"
  267. """
  268. op, row, k, row1, row2 = self._normalize_op_args(op, row, k, row1, row2, "row")
  269. # now that we've validated, we're all good to dispatch
  270. if op == "n->kn":
  271. return self._eval_row_op_multiply_row_by_const(row, k)
  272. if op == "n<->m":
  273. return self._eval_row_op_swap(row1, row2)
  274. if op == "n->n+km":
  275. return self._eval_row_op_add_multiple_to_other_row(row, k, row2)
  276. class MatrixSubspaces(MatrixReductions):
  277. """Provides methods relating to the fundamental subspaces of a matrix.
  278. Should not be instantiated directly. See ``subspaces.py`` for their
  279. implementations."""
  280. def columnspace(self, simplify=False):
  281. return _columnspace(self, simplify=simplify)
  282. def nullspace(self, simplify=False, iszerofunc=_iszero):
  283. return _nullspace(self, simplify=simplify, iszerofunc=iszerofunc)
  284. def rowspace(self, simplify=False):
  285. return _rowspace(self, simplify=simplify)
  286. # This is a classmethod but is converted to such later in order to allow
  287. # assignment of __doc__ since that does not work for already wrapped
  288. # classmethods in Python 3.6.
  289. def orthogonalize(cls, *vecs, **kwargs):
  290. return _orthogonalize(cls, *vecs, **kwargs)
  291. columnspace.__doc__ = _columnspace.__doc__
  292. nullspace.__doc__ = _nullspace.__doc__
  293. rowspace.__doc__ = _rowspace.__doc__
  294. orthogonalize.__doc__ = _orthogonalize.__doc__
  295. orthogonalize = classmethod(orthogonalize) # type:ignore
  296. class MatrixEigen(MatrixSubspaces):
  297. """Provides basic matrix eigenvalue/vector operations.
  298. Should not be instantiated directly. See ``eigen.py`` for their
  299. implementations."""
  300. def eigenvals(self, error_when_incomplete=True, **flags):
  301. return _eigenvals(self, error_when_incomplete=error_when_incomplete, **flags)
  302. def eigenvects(self, error_when_incomplete=True, iszerofunc=_iszero, **flags):
  303. return _eigenvects(self, error_when_incomplete=error_when_incomplete,
  304. iszerofunc=iszerofunc, **flags)
  305. def is_diagonalizable(self, reals_only=False, **kwargs):
  306. return _is_diagonalizable(self, reals_only=reals_only, **kwargs)
  307. def diagonalize(self, reals_only=False, sort=False, normalize=False):
  308. return _diagonalize(self, reals_only=reals_only, sort=sort,
  309. normalize=normalize)
  310. def bidiagonalize(self, upper=True):
  311. return _bidiagonalize(self, upper=upper)
  312. def bidiagonal_decomposition(self, upper=True):
  313. return _bidiagonal_decomposition(self, upper=upper)
  314. @property
  315. def is_positive_definite(self):
  316. return _is_positive_definite(self)
  317. @property
  318. def is_positive_semidefinite(self):
  319. return _is_positive_semidefinite(self)
  320. @property
  321. def is_negative_definite(self):
  322. return _is_negative_definite(self)
  323. @property
  324. def is_negative_semidefinite(self):
  325. return _is_negative_semidefinite(self)
  326. @property
  327. def is_indefinite(self):
  328. return _is_indefinite(self)
  329. def jordan_form(self, calc_transform=True, **kwargs):
  330. return _jordan_form(self, calc_transform=calc_transform, **kwargs)
  331. def left_eigenvects(self, **flags):
  332. return _left_eigenvects(self, **flags)
  333. def singular_values(self):
  334. return _singular_values(self)
  335. eigenvals.__doc__ = _eigenvals.__doc__
  336. eigenvects.__doc__ = _eigenvects.__doc__
  337. is_diagonalizable.__doc__ = _is_diagonalizable.__doc__
  338. diagonalize.__doc__ = _diagonalize.__doc__
  339. is_positive_definite.__doc__ = _is_positive_definite.__doc__
  340. is_positive_semidefinite.__doc__ = _is_positive_semidefinite.__doc__
  341. is_negative_definite.__doc__ = _is_negative_definite.__doc__
  342. is_negative_semidefinite.__doc__ = _is_negative_semidefinite.__doc__
  343. is_indefinite.__doc__ = _is_indefinite.__doc__
  344. jordan_form.__doc__ = _jordan_form.__doc__
  345. left_eigenvects.__doc__ = _left_eigenvects.__doc__
  346. singular_values.__doc__ = _singular_values.__doc__
  347. bidiagonalize.__doc__ = _bidiagonalize.__doc__
  348. bidiagonal_decomposition.__doc__ = _bidiagonal_decomposition.__doc__
  349. class MatrixCalculus(MatrixCommon):
  350. """Provides calculus-related matrix operations."""
  351. def diff(self, *args, **kwargs):
  352. """Calculate the derivative of each element in the matrix.
  353. ``args`` will be passed to the ``integrate`` function.
  354. Examples
  355. ========
  356. >>> from sympy import Matrix
  357. >>> from sympy.abc import x, y
  358. >>> M = Matrix([[x, y], [1, 0]])
  359. >>> M.diff(x)
  360. Matrix([
  361. [1, 0],
  362. [0, 0]])
  363. See Also
  364. ========
  365. integrate
  366. limit
  367. """
  368. # XXX this should be handled here rather than in Derivative
  369. from sympy.tensor.array.array_derivatives import ArrayDerivative
  370. kwargs.setdefault('evaluate', True)
  371. deriv = ArrayDerivative(self, *args, evaluate=True)
  372. if not isinstance(self, Basic):
  373. return deriv.as_mutable()
  374. else:
  375. return deriv
  376. def _eval_derivative(self, arg):
  377. return self.applyfunc(lambda x: x.diff(arg))
  378. def integrate(self, *args, **kwargs):
  379. """Integrate each element of the matrix. ``args`` will
  380. be passed to the ``integrate`` function.
  381. Examples
  382. ========
  383. >>> from sympy import Matrix
  384. >>> from sympy.abc import x, y
  385. >>> M = Matrix([[x, y], [1, 0]])
  386. >>> M.integrate((x, ))
  387. Matrix([
  388. [x**2/2, x*y],
  389. [ x, 0]])
  390. >>> M.integrate((x, 0, 2))
  391. Matrix([
  392. [2, 2*y],
  393. [2, 0]])
  394. See Also
  395. ========
  396. limit
  397. diff
  398. """
  399. return self.applyfunc(lambda x: x.integrate(*args, **kwargs))
  400. def jacobian(self, X):
  401. """Calculates the Jacobian matrix (derivative of a vector-valued function).
  402. Parameters
  403. ==========
  404. ``self`` : vector of expressions representing functions f_i(x_1, ..., x_n).
  405. X : set of x_i's in order, it can be a list or a Matrix
  406. Both ``self`` and X can be a row or a column matrix in any order
  407. (i.e., jacobian() should always work).
  408. Examples
  409. ========
  410. >>> from sympy import sin, cos, Matrix
  411. >>> from sympy.abc import rho, phi
  412. >>> X = Matrix([rho*cos(phi), rho*sin(phi), rho**2])
  413. >>> Y = Matrix([rho, phi])
  414. >>> X.jacobian(Y)
  415. Matrix([
  416. [cos(phi), -rho*sin(phi)],
  417. [sin(phi), rho*cos(phi)],
  418. [ 2*rho, 0]])
  419. >>> X = Matrix([rho*cos(phi), rho*sin(phi)])
  420. >>> X.jacobian(Y)
  421. Matrix([
  422. [cos(phi), -rho*sin(phi)],
  423. [sin(phi), rho*cos(phi)]])
  424. See Also
  425. ========
  426. hessian
  427. wronskian
  428. """
  429. if not isinstance(X, MatrixBase):
  430. X = self._new(X)
  431. # Both X and ``self`` can be a row or a column matrix, so we need to make
  432. # sure all valid combinations work, but everything else fails:
  433. if self.shape[0] == 1:
  434. m = self.shape[1]
  435. elif self.shape[1] == 1:
  436. m = self.shape[0]
  437. else:
  438. raise TypeError("``self`` must be a row or a column matrix")
  439. if X.shape[0] == 1:
  440. n = X.shape[1]
  441. elif X.shape[1] == 1:
  442. n = X.shape[0]
  443. else:
  444. raise TypeError("X must be a row or a column matrix")
  445. # m is the number of functions and n is the number of variables
  446. # computing the Jacobian is now easy:
  447. return self._new(m, n, lambda j, i: self[j].diff(X[i]))
  448. def limit(self, *args):
  449. """Calculate the limit of each element in the matrix.
  450. ``args`` will be passed to the ``limit`` function.
  451. Examples
  452. ========
  453. >>> from sympy import Matrix
  454. >>> from sympy.abc import x, y
  455. >>> M = Matrix([[x, y], [1, 0]])
  456. >>> M.limit(x, 2)
  457. Matrix([
  458. [2, y],
  459. [1, 0]])
  460. See Also
  461. ========
  462. integrate
  463. diff
  464. """
  465. return self.applyfunc(lambda x: x.limit(*args))
  466. # https://github.com/sympy/sympy/pull/12854
  467. class MatrixDeprecated(MatrixCommon):
  468. """A class to house deprecated matrix methods."""
  469. def _legacy_array_dot(self, b):
  470. """Compatibility function for deprecated behavior of ``matrix.dot(vector)``
  471. """
  472. from .dense import Matrix
  473. if not isinstance(b, MatrixBase):
  474. if is_sequence(b):
  475. if len(b) != self.cols and len(b) != self.rows:
  476. raise ShapeError(
  477. "Dimensions incorrect for dot product: %s, %s" % (
  478. self.shape, len(b)))
  479. return self.dot(Matrix(b))
  480. else:
  481. raise TypeError(
  482. "`b` must be an ordered iterable or Matrix, not %s." %
  483. type(b))
  484. mat = self
  485. if mat.cols == b.rows:
  486. if b.cols != 1:
  487. mat = mat.T
  488. b = b.T
  489. prod = flatten((mat * b).tolist())
  490. return prod
  491. if mat.cols == b.cols:
  492. return mat.dot(b.T)
  493. elif mat.rows == b.rows:
  494. return mat.T.dot(b)
  495. else:
  496. raise ShapeError("Dimensions incorrect for dot product: %s, %s" % (
  497. self.shape, b.shape))
  498. def berkowitz_charpoly(self, x=Dummy('lambda'), simplify=_simplify):
  499. return self.charpoly(x=x)
  500. def berkowitz_det(self):
  501. """Computes determinant using Berkowitz method.
  502. See Also
  503. ========
  504. det
  505. berkowitz
  506. """
  507. return self.det(method='berkowitz')
  508. def berkowitz_eigenvals(self, **flags):
  509. """Computes eigenvalues of a Matrix using Berkowitz method.
  510. See Also
  511. ========
  512. berkowitz
  513. """
  514. return self.eigenvals(**flags)
  515. def berkowitz_minors(self):
  516. """Computes principal minors using Berkowitz method.
  517. See Also
  518. ========
  519. berkowitz
  520. """
  521. sign, minors = self.one, []
  522. for poly in self.berkowitz():
  523. minors.append(sign * poly[-1])
  524. sign = -sign
  525. return tuple(minors)
  526. def berkowitz(self):
  527. from sympy.matrices import zeros
  528. berk = ((1,),)
  529. if not self:
  530. return berk
  531. if not self.is_square:
  532. raise NonSquareMatrixError()
  533. A, N = self, self.rows
  534. transforms = [0] * (N - 1)
  535. for n in range(N, 1, -1):
  536. T, k = zeros(n + 1, n), n - 1
  537. R, C = -A[k, :k], A[:k, k]
  538. A, a = A[:k, :k], -A[k, k]
  539. items = [C]
  540. for i in range(0, n - 2):
  541. items.append(A * items[i])
  542. for i, B in enumerate(items):
  543. items[i] = (R * B)[0, 0]
  544. items = [self.one, a] + items
  545. for i in range(n):
  546. T[i:, i] = items[:n - i + 1]
  547. transforms[k - 1] = T
  548. polys = [self._new([self.one, -A[0, 0]])]
  549. for i, T in enumerate(transforms):
  550. polys.append(T * polys[i])
  551. return berk + tuple(map(tuple, polys))
  552. def cofactorMatrix(self, method="berkowitz"):
  553. return self.cofactor_matrix(method=method)
  554. def det_bareis(self):
  555. return _det_bareiss(self)
  556. def det_LU_decomposition(self):
  557. """Compute matrix determinant using LU decomposition
  558. Note that this method fails if the LU decomposition itself
  559. fails. In particular, if the matrix has no inverse this method
  560. will fail.
  561. TODO: Implement algorithm for sparse matrices (SFF),
  562. http://www.eecis.udel.edu/~saunders/papers/sffge/it5.ps.
  563. See Also
  564. ========
  565. det
  566. det_bareiss
  567. berkowitz_det
  568. """
  569. return self.det(method='lu')
  570. def jordan_cell(self, eigenval, n):
  571. return self.jordan_block(size=n, eigenvalue=eigenval)
  572. def jordan_cells(self, calc_transformation=True):
  573. P, J = self.jordan_form()
  574. return P, J.get_diag_blocks()
  575. def minorEntry(self, i, j, method="berkowitz"):
  576. return self.minor(i, j, method=method)
  577. def minorMatrix(self, i, j):
  578. return self.minor_submatrix(i, j)
  579. def permuteBkwd(self, perm):
  580. """Permute the rows of the matrix with the given permutation in reverse."""
  581. return self.permute_rows(perm, direction='backward')
  582. def permuteFwd(self, perm):
  583. """Permute the rows of the matrix with the given permutation."""
  584. return self.permute_rows(perm, direction='forward')
  585. @Mul._kind_dispatcher.register(_NumberKind, MatrixKind)
  586. def num_mat_mul(k1, k2):
  587. """
  588. Return MatrixKind. The element kind is selected by recursive dispatching.
  589. Do not need to dispatch in reversed order because KindDispatcher
  590. searches for this automatically.
  591. """
  592. # Deal with Mul._kind_dispatcher's commutativity
  593. # XXX: this function is called with either k1 or k2 as MatrixKind because
  594. # the Mul kind dispatcher is commutative. Maybe it shouldn't be. Need to
  595. # swap the args here because NumberKind doesn't have an element_kind
  596. # attribute.
  597. if not isinstance(k2, MatrixKind):
  598. k1, k2 = k2, k1
  599. elemk = Mul._kind_dispatcher(k1, k2.element_kind)
  600. return MatrixKind(elemk)
  601. @Mul._kind_dispatcher.register(MatrixKind, MatrixKind)
  602. def mat_mat_mul(k1, k2):
  603. """
  604. Return MatrixKind. The element kind is selected by recursive dispatching.
  605. """
  606. elemk = Mul._kind_dispatcher(k1.element_kind, k2.element_kind)
  607. return MatrixKind(elemk)
  608. class MatrixBase(MatrixDeprecated,
  609. MatrixCalculus,
  610. MatrixEigen,
  611. MatrixCommon,
  612. Printable):
  613. """Base class for matrix objects."""
  614. # Added just for numpy compatibility
  615. __array_priority__ = 11
  616. is_Matrix = True
  617. _class_priority = 3
  618. _sympify = staticmethod(sympify)
  619. zero = S.Zero
  620. one = S.One
  621. @property
  622. def kind(self) -> MatrixKind:
  623. elem_kinds = set(e.kind for e in self.flat())
  624. if len(elem_kinds) == 1:
  625. elemkind, = elem_kinds
  626. else:
  627. elemkind = UndefinedKind
  628. return MatrixKind(elemkind)
  629. def flat(self):
  630. return [self[i, j] for i in range(self.rows) for j in range(self.cols)]
  631. def __array__(self, dtype=object):
  632. from .dense import matrix2numpy
  633. return matrix2numpy(self, dtype=dtype)
  634. def __len__(self):
  635. """Return the number of elements of ``self``.
  636. Implemented mainly so bool(Matrix()) == False.
  637. """
  638. return self.rows * self.cols
  639. def _matrix_pow_by_jordan_blocks(self, num):
  640. from sympy.matrices import diag, MutableMatrix
  641. from sympy.functions.combinatorial.factorials import binomial
  642. def jordan_cell_power(jc, n):
  643. N = jc.shape[0]
  644. l = jc[0,0]
  645. if l.is_zero:
  646. if N == 1 and n.is_nonnegative:
  647. jc[0,0] = l**n
  648. elif not (n.is_integer and n.is_nonnegative):
  649. raise NonInvertibleMatrixError("Non-invertible matrix can only be raised to a nonnegative integer")
  650. else:
  651. for i in range(N):
  652. jc[0,i] = KroneckerDelta(i, n)
  653. else:
  654. for i in range(N):
  655. bn = binomial(n, i)
  656. if isinstance(bn, binomial):
  657. bn = bn._eval_expand_func()
  658. jc[0,i] = l**(n-i)*bn
  659. for i in range(N):
  660. for j in range(1, N-i):
  661. jc[j,i+j] = jc [j-1,i+j-1]
  662. P, J = self.jordan_form()
  663. jordan_cells = J.get_diag_blocks()
  664. # Make sure jordan_cells matrices are mutable:
  665. jordan_cells = [MutableMatrix(j) for j in jordan_cells]
  666. for j in jordan_cells:
  667. jordan_cell_power(j, num)
  668. return self._new(P.multiply(diag(*jordan_cells))
  669. .multiply(P.inv()))
  670. def __str__(self):
  671. if S.Zero in self.shape:
  672. return 'Matrix(%s, %s, [])' % (self.rows, self.cols)
  673. return "Matrix(%s)" % str(self.tolist())
  674. def _format_str(self, printer=None):
  675. if not printer:
  676. from sympy.printing.str import StrPrinter
  677. printer = StrPrinter()
  678. # Handle zero dimensions:
  679. if S.Zero in self.shape:
  680. return 'Matrix(%s, %s, [])' % (self.rows, self.cols)
  681. if self.rows == 1:
  682. return "Matrix([%s])" % self.table(printer, rowsep=',\n')
  683. return "Matrix([\n%s])" % self.table(printer, rowsep=',\n')
  684. @classmethod
  685. def irregular(cls, ntop, *matrices, **kwargs):
  686. """Return a matrix filled by the given matrices which
  687. are listed in order of appearance from left to right, top to
  688. bottom as they first appear in the matrix. They must fill the
  689. matrix completely.
  690. Examples
  691. ========
  692. >>> from sympy import ones, Matrix
  693. >>> Matrix.irregular(3, ones(2,1), ones(3,3)*2, ones(2,2)*3,
  694. ... ones(1,1)*4, ones(2,2)*5, ones(1,2)*6, ones(1,2)*7)
  695. Matrix([
  696. [1, 2, 2, 2, 3, 3],
  697. [1, 2, 2, 2, 3, 3],
  698. [4, 2, 2, 2, 5, 5],
  699. [6, 6, 7, 7, 5, 5]])
  700. """
  701. ntop = as_int(ntop)
  702. # make sure we are working with explicit matrices
  703. b = [i.as_explicit() if hasattr(i, 'as_explicit') else i
  704. for i in matrices]
  705. q = list(range(len(b)))
  706. dat = [i.rows for i in b]
  707. active = [q.pop(0) for _ in range(ntop)]
  708. cols = sum([b[i].cols for i in active])
  709. rows = []
  710. while any(dat):
  711. r = []
  712. for a, j in enumerate(active):
  713. r.extend(b[j][-dat[j], :])
  714. dat[j] -= 1
  715. if dat[j] == 0 and q:
  716. active[a] = q.pop(0)
  717. if len(r) != cols:
  718. raise ValueError(filldedent('''
  719. Matrices provided do not appear to fill
  720. the space completely.'''))
  721. rows.append(r)
  722. return cls._new(rows)
  723. @classmethod
  724. def _handle_ndarray(cls, arg):
  725. # NumPy array or matrix or some other object that implements
  726. # __array__. So let's first use this method to get a
  727. # numpy.array() and then make a Python list out of it.
  728. arr = arg.__array__()
  729. if len(arr.shape) == 2:
  730. rows, cols = arr.shape[0], arr.shape[1]
  731. flat_list = [cls._sympify(i) for i in arr.ravel()]
  732. return rows, cols, flat_list
  733. elif len(arr.shape) == 1:
  734. flat_list = [cls._sympify(i) for i in arr]
  735. return arr.shape[0], 1, flat_list
  736. else:
  737. raise NotImplementedError(
  738. "SymPy supports just 1D and 2D matrices")
  739. @classmethod
  740. def _handle_creation_inputs(cls, *args, **kwargs):
  741. """Return the number of rows, cols and flat matrix elements.
  742. Examples
  743. ========
  744. >>> from sympy import Matrix, I
  745. Matrix can be constructed as follows:
  746. * from a nested list of iterables
  747. >>> Matrix( ((1, 2+I), (3, 4)) )
  748. Matrix([
  749. [1, 2 + I],
  750. [3, 4]])
  751. * from un-nested iterable (interpreted as a column)
  752. >>> Matrix( [1, 2] )
  753. Matrix([
  754. [1],
  755. [2]])
  756. * from un-nested iterable with dimensions
  757. >>> Matrix(1, 2, [1, 2] )
  758. Matrix([[1, 2]])
  759. * from no arguments (a 0 x 0 matrix)
  760. >>> Matrix()
  761. Matrix(0, 0, [])
  762. * from a rule
  763. >>> Matrix(2, 2, lambda i, j: i/(j + 1) )
  764. Matrix([
  765. [0, 0],
  766. [1, 1/2]])
  767. See Also
  768. ========
  769. irregular - filling a matrix with irregular blocks
  770. """
  771. from sympy.matrices import SparseMatrix
  772. from sympy.matrices.expressions.matexpr import MatrixSymbol
  773. from sympy.matrices.expressions.blockmatrix import BlockMatrix
  774. flat_list = None
  775. if len(args) == 1:
  776. # Matrix(SparseMatrix(...))
  777. if isinstance(args[0], SparseMatrix):
  778. return args[0].rows, args[0].cols, flatten(args[0].tolist())
  779. # Matrix(Matrix(...))
  780. elif isinstance(args[0], MatrixBase):
  781. return args[0].rows, args[0].cols, args[0].flat()
  782. # Matrix(MatrixSymbol('X', 2, 2))
  783. elif isinstance(args[0], Basic) and args[0].is_Matrix:
  784. return args[0].rows, args[0].cols, args[0].as_explicit().flat()
  785. elif isinstance(args[0], mp.matrix):
  786. M = args[0]
  787. flat_list = [cls._sympify(x) for x in M]
  788. return M.rows, M.cols, flat_list
  789. # Matrix(numpy.ones((2, 2)))
  790. elif hasattr(args[0], "__array__"):
  791. return cls._handle_ndarray(args[0])
  792. # Matrix([1, 2, 3]) or Matrix([[1, 2], [3, 4]])
  793. elif is_sequence(args[0]) \
  794. and not isinstance(args[0], DeferredVector):
  795. dat = list(args[0])
  796. ismat = lambda i: isinstance(i, MatrixBase) and (
  797. evaluate or
  798. isinstance(i, BlockMatrix) or
  799. isinstance(i, MatrixSymbol))
  800. raw = lambda i: is_sequence(i) and not ismat(i)
  801. evaluate = kwargs.get('evaluate', True)
  802. if evaluate:
  803. def make_explicit(x):
  804. """make Block and Symbol explicit"""
  805. if isinstance(x, BlockMatrix):
  806. return x.as_explicit()
  807. elif isinstance(x, MatrixSymbol) and all(_.is_Integer for _ in x.shape):
  808. return x.as_explicit()
  809. else:
  810. return x
  811. def make_explicit_row(row):
  812. # Could be list or could be list of lists
  813. if isinstance(row, (list, tuple)):
  814. return [make_explicit(x) for x in row]
  815. else:
  816. return make_explicit(row)
  817. if isinstance(dat, (list, tuple)):
  818. dat = [make_explicit_row(row) for row in dat]
  819. if dat in ([], [[]]):
  820. rows = cols = 0
  821. flat_list = []
  822. elif not any(raw(i) or ismat(i) for i in dat):
  823. # a column as a list of values
  824. flat_list = [cls._sympify(i) for i in dat]
  825. rows = len(flat_list)
  826. cols = 1 if rows else 0
  827. elif evaluate and all(ismat(i) for i in dat):
  828. # a column as a list of matrices
  829. ncol = {i.cols for i in dat if any(i.shape)}
  830. if ncol:
  831. if len(ncol) != 1:
  832. raise ValueError('mismatched dimensions')
  833. flat_list = [_ for i in dat for r in i.tolist() for _ in r]
  834. cols = ncol.pop()
  835. rows = len(flat_list)//cols
  836. else:
  837. rows = cols = 0
  838. flat_list = []
  839. elif evaluate and any(ismat(i) for i in dat):
  840. ncol = set()
  841. flat_list = []
  842. for i in dat:
  843. if ismat(i):
  844. flat_list.extend(
  845. [k for j in i.tolist() for k in j])
  846. if any(i.shape):
  847. ncol.add(i.cols)
  848. elif raw(i):
  849. if i:
  850. ncol.add(len(i))
  851. flat_list.extend([cls._sympify(ij) for ij in i])
  852. else:
  853. ncol.add(1)
  854. flat_list.append(i)
  855. if len(ncol) > 1:
  856. raise ValueError('mismatched dimensions')
  857. cols = ncol.pop()
  858. rows = len(flat_list)//cols
  859. else:
  860. # list of lists; each sublist is a logical row
  861. # which might consist of many rows if the values in
  862. # the row are matrices
  863. flat_list = []
  864. ncol = set()
  865. rows = cols = 0
  866. for row in dat:
  867. if not is_sequence(row) and \
  868. not getattr(row, 'is_Matrix', False):
  869. raise ValueError('expecting list of lists')
  870. if hasattr(row, '__array__'):
  871. if 0 in row.shape:
  872. continue
  873. elif not row:
  874. continue
  875. if evaluate and all(ismat(i) for i in row):
  876. r, c, flatT = cls._handle_creation_inputs(
  877. [i.T for i in row])
  878. T = reshape(flatT, [c])
  879. flat = \
  880. [T[i][j] for j in range(c) for i in range(r)]
  881. r, c = c, r
  882. else:
  883. r = 1
  884. if getattr(row, 'is_Matrix', False):
  885. c = 1
  886. flat = [row]
  887. else:
  888. c = len(row)
  889. flat = [cls._sympify(i) for i in row]
  890. ncol.add(c)
  891. if len(ncol) > 1:
  892. raise ValueError('mismatched dimensions')
  893. flat_list.extend(flat)
  894. rows += r
  895. cols = ncol.pop() if ncol else 0
  896. elif len(args) == 3:
  897. rows = as_int(args[0])
  898. cols = as_int(args[1])
  899. if rows < 0 or cols < 0:
  900. raise ValueError("Cannot create a {} x {} matrix. "
  901. "Both dimensions must be positive".format(rows, cols))
  902. # Matrix(2, 2, lambda i, j: i+j)
  903. if len(args) == 3 and isinstance(args[2], Callable):
  904. op = args[2]
  905. flat_list = []
  906. for i in range(rows):
  907. flat_list.extend(
  908. [cls._sympify(op(cls._sympify(i), cls._sympify(j)))
  909. for j in range(cols)])
  910. # Matrix(2, 2, [1, 2, 3, 4])
  911. elif len(args) == 3 and is_sequence(args[2]):
  912. flat_list = args[2]
  913. if len(flat_list) != rows * cols:
  914. raise ValueError(
  915. 'List length should be equal to rows*columns')
  916. flat_list = [cls._sympify(i) for i in flat_list]
  917. # Matrix()
  918. elif len(args) == 0:
  919. # Empty Matrix
  920. rows = cols = 0
  921. flat_list = []
  922. if flat_list is None:
  923. raise TypeError(filldedent('''
  924. Data type not understood; expecting list of lists
  925. or lists of values.'''))
  926. return rows, cols, flat_list
  927. def _setitem(self, key, value):
  928. """Helper to set value at location given by key.
  929. Examples
  930. ========
  931. >>> from sympy import Matrix, I, zeros, ones
  932. >>> m = Matrix(((1, 2+I), (3, 4)))
  933. >>> m
  934. Matrix([
  935. [1, 2 + I],
  936. [3, 4]])
  937. >>> m[1, 0] = 9
  938. >>> m
  939. Matrix([
  940. [1, 2 + I],
  941. [9, 4]])
  942. >>> m[1, 0] = [[0, 1]]
  943. To replace row r you assign to position r*m where m
  944. is the number of columns:
  945. >>> M = zeros(4)
  946. >>> m = M.cols
  947. >>> M[3*m] = ones(1, m)*2; M
  948. Matrix([
  949. [0, 0, 0, 0],
  950. [0, 0, 0, 0],
  951. [0, 0, 0, 0],
  952. [2, 2, 2, 2]])
  953. And to replace column c you can assign to position c:
  954. >>> M[2] = ones(m, 1)*4; M
  955. Matrix([
  956. [0, 0, 4, 0],
  957. [0, 0, 4, 0],
  958. [0, 0, 4, 0],
  959. [2, 2, 4, 2]])
  960. """
  961. from .dense import Matrix
  962. is_slice = isinstance(key, slice)
  963. i, j = key = self.key2ij(key)
  964. is_mat = isinstance(value, MatrixBase)
  965. if isinstance(i, slice) or isinstance(j, slice):
  966. if is_mat:
  967. self.copyin_matrix(key, value)
  968. return
  969. if not isinstance(value, Expr) and is_sequence(value):
  970. self.copyin_list(key, value)
  971. return
  972. raise ValueError('unexpected value: %s' % value)
  973. else:
  974. if (not is_mat and
  975. not isinstance(value, Basic) and is_sequence(value)):
  976. value = Matrix(value)
  977. is_mat = True
  978. if is_mat:
  979. if is_slice:
  980. key = (slice(*divmod(i, self.cols)),
  981. slice(*divmod(j, self.cols)))
  982. else:
  983. key = (slice(i, i + value.rows),
  984. slice(j, j + value.cols))
  985. self.copyin_matrix(key, value)
  986. else:
  987. return i, j, self._sympify(value)
  988. return
  989. def add(self, b):
  990. """Return self + b """
  991. return self + b
  992. def condition_number(self):
  993. """Returns the condition number of a matrix.
  994. This is the maximum singular value divided by the minimum singular value
  995. Examples
  996. ========
  997. >>> from sympy import Matrix, S
  998. >>> A = Matrix([[1, 0, 0], [0, 10, 0], [0, 0, S.One/10]])
  999. >>> A.condition_number()
  1000. 100
  1001. See Also
  1002. ========
  1003. singular_values
  1004. """
  1005. if not self:
  1006. return self.zero
  1007. singularvalues = self.singular_values()
  1008. return Max(*singularvalues) / Min(*singularvalues)
  1009. def copy(self):
  1010. """
  1011. Returns the copy of a matrix.
  1012. Examples
  1013. ========
  1014. >>> from sympy import Matrix
  1015. >>> A = Matrix(2, 2, [1, 2, 3, 4])
  1016. >>> A.copy()
  1017. Matrix([
  1018. [1, 2],
  1019. [3, 4]])
  1020. """
  1021. return self._new(self.rows, self.cols, self.flat())
  1022. def cross(self, b):
  1023. r"""
  1024. Return the cross product of ``self`` and ``b`` relaxing the condition
  1025. of compatible dimensions: if each has 3 elements, a matrix of the
  1026. same type and shape as ``self`` will be returned. If ``b`` has the same
  1027. shape as ``self`` then common identities for the cross product (like
  1028. `a \times b = - b \times a`) will hold.
  1029. Parameters
  1030. ==========
  1031. b : 3x1 or 1x3 Matrix
  1032. See Also
  1033. ========
  1034. dot
  1035. multiply
  1036. multiply_elementwise
  1037. """
  1038. from sympy.matrices.expressions.matexpr import MatrixExpr
  1039. if not isinstance(b, (MatrixBase, MatrixExpr)):
  1040. raise TypeError(
  1041. "{} must be a Matrix, not {}.".format(b, type(b)))
  1042. if not (self.rows * self.cols == b.rows * b.cols == 3):
  1043. raise ShapeError("Dimensions incorrect for cross product: %s x %s" %
  1044. ((self.rows, self.cols), (b.rows, b.cols)))
  1045. else:
  1046. return self._new(self.rows, self.cols, (
  1047. (self[1] * b[2] - self[2] * b[1]),
  1048. (self[2] * b[0] - self[0] * b[2]),
  1049. (self[0] * b[1] - self[1] * b[0])))
  1050. @property
  1051. def D(self):
  1052. """Return Dirac conjugate (if ``self.rows == 4``).
  1053. Examples
  1054. ========
  1055. >>> from sympy import Matrix, I, eye
  1056. >>> m = Matrix((0, 1 + I, 2, 3))
  1057. >>> m.D
  1058. Matrix([[0, 1 - I, -2, -3]])
  1059. >>> m = (eye(4) + I*eye(4))
  1060. >>> m[0, 3] = 2
  1061. >>> m.D
  1062. Matrix([
  1063. [1 - I, 0, 0, 0],
  1064. [ 0, 1 - I, 0, 0],
  1065. [ 0, 0, -1 + I, 0],
  1066. [ 2, 0, 0, -1 + I]])
  1067. If the matrix does not have 4 rows an AttributeError will be raised
  1068. because this property is only defined for matrices with 4 rows.
  1069. >>> Matrix(eye(2)).D
  1070. Traceback (most recent call last):
  1071. ...
  1072. AttributeError: Matrix has no attribute D.
  1073. See Also
  1074. ========
  1075. sympy.matrices.common.MatrixCommon.conjugate: By-element conjugation
  1076. sympy.matrices.common.MatrixCommon.H: Hermite conjugation
  1077. """
  1078. from sympy.physics.matrices import mgamma
  1079. if self.rows != 4:
  1080. # In Python 3.2, properties can only return an AttributeError
  1081. # so we can't raise a ShapeError -- see commit which added the
  1082. # first line of this inline comment. Also, there is no need
  1083. # for a message since MatrixBase will raise the AttributeError
  1084. raise AttributeError
  1085. return self.H * mgamma(0)
  1086. def dot(self, b, hermitian=None, conjugate_convention=None):
  1087. """Return the dot or inner product of two vectors of equal length.
  1088. Here ``self`` must be a ``Matrix`` of size 1 x n or n x 1, and ``b``
  1089. must be either a matrix of size 1 x n, n x 1, or a list/tuple of length n.
  1090. A scalar is returned.
  1091. By default, ``dot`` does not conjugate ``self`` or ``b``, even if there are
  1092. complex entries. Set ``hermitian=True`` (and optionally a ``conjugate_convention``)
  1093. to compute the hermitian inner product.
  1094. Possible kwargs are ``hermitian`` and ``conjugate_convention``.
  1095. If ``conjugate_convention`` is ``"left"``, ``"math"`` or ``"maths"``,
  1096. the conjugate of the first vector (``self``) is used. If ``"right"``
  1097. or ``"physics"`` is specified, the conjugate of the second vector ``b`` is used.
  1098. Examples
  1099. ========
  1100. >>> from sympy import Matrix
  1101. >>> M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  1102. >>> v = Matrix([1, 1, 1])
  1103. >>> M.row(0).dot(v)
  1104. 6
  1105. >>> M.col(0).dot(v)
  1106. 12
  1107. >>> v = [3, 2, 1]
  1108. >>> M.row(0).dot(v)
  1109. 10
  1110. >>> from sympy import I
  1111. >>> q = Matrix([1*I, 1*I, 1*I])
  1112. >>> q.dot(q, hermitian=False)
  1113. -3
  1114. >>> q.dot(q, hermitian=True)
  1115. 3
  1116. >>> q1 = Matrix([1, 1, 1*I])
  1117. >>> q.dot(q1, hermitian=True, conjugate_convention="maths")
  1118. 1 - 2*I
  1119. >>> q.dot(q1, hermitian=True, conjugate_convention="physics")
  1120. 1 + 2*I
  1121. See Also
  1122. ========
  1123. cross
  1124. multiply
  1125. multiply_elementwise
  1126. """
  1127. from .dense import Matrix
  1128. if not isinstance(b, MatrixBase):
  1129. if is_sequence(b):
  1130. if len(b) != self.cols and len(b) != self.rows:
  1131. raise ShapeError(
  1132. "Dimensions incorrect for dot product: %s, %s" % (
  1133. self.shape, len(b)))
  1134. return self.dot(Matrix(b))
  1135. else:
  1136. raise TypeError(
  1137. "`b` must be an ordered iterable or Matrix, not %s." %
  1138. type(b))
  1139. mat = self
  1140. if (1 not in mat.shape) or (1 not in b.shape) :
  1141. sympy_deprecation_warning(
  1142. """
  1143. Using the dot method to multiply non-row/column vectors is
  1144. deprecated. Use * or @ to perform matrix multiplication.
  1145. """,
  1146. deprecated_since_version="1.2",
  1147. active_deprecations_target="deprecated-matrix-dot-non-vector")
  1148. return mat._legacy_array_dot(b)
  1149. if len(mat) != len(b):
  1150. raise ShapeError("Dimensions incorrect for dot product: %s, %s" % (self.shape, b.shape))
  1151. n = len(mat)
  1152. if mat.shape != (1, n):
  1153. mat = mat.reshape(1, n)
  1154. if b.shape != (n, 1):
  1155. b = b.reshape(n, 1)
  1156. # Now ``mat`` is a row vector and ``b`` is a column vector.
  1157. # If it so happens that only conjugate_convention is passed
  1158. # then automatically set hermitian to True. If only hermitian
  1159. # is true but no conjugate_convention is not passed then
  1160. # automatically set it to ``"maths"``
  1161. if conjugate_convention is not None and hermitian is None:
  1162. hermitian = True
  1163. if hermitian and conjugate_convention is None:
  1164. conjugate_convention = "maths"
  1165. if hermitian == True:
  1166. if conjugate_convention in ("maths", "left", "math"):
  1167. mat = mat.conjugate()
  1168. elif conjugate_convention in ("physics", "right"):
  1169. b = b.conjugate()
  1170. else:
  1171. raise ValueError("Unknown conjugate_convention was entered."
  1172. " conjugate_convention must be one of the"
  1173. " following: math, maths, left, physics or right.")
  1174. return (mat * b)[0]
  1175. def dual(self):
  1176. """Returns the dual of a matrix, which is:
  1177. ``(1/2)*levicivita(i, j, k, l)*M(k, l)`` summed over indices `k` and `l`
  1178. Since the levicivita method is anti_symmetric for any pairwise
  1179. exchange of indices, the dual of a symmetric matrix is the zero
  1180. matrix. Strictly speaking the dual defined here assumes that the
  1181. 'matrix' `M` is a contravariant anti_symmetric second rank tensor,
  1182. so that the dual is a covariant second rank tensor.
  1183. """
  1184. from sympy.functions.special.tensor_functions import LeviCivita
  1185. from sympy.matrices import zeros
  1186. M, n = self[:, :], self.rows
  1187. work = zeros(n)
  1188. if self.is_symmetric():
  1189. return work
  1190. for i in range(1, n):
  1191. for j in range(1, n):
  1192. acum = 0
  1193. for k in range(1, n):
  1194. acum += LeviCivita(i, j, 0, k) * M[0, k]
  1195. work[i, j] = acum
  1196. work[j, i] = -acum
  1197. for l in range(1, n):
  1198. acum = 0
  1199. for a in range(1, n):
  1200. for b in range(1, n):
  1201. acum += LeviCivita(0, l, a, b) * M[a, b]
  1202. acum /= 2
  1203. work[0, l] = -acum
  1204. work[l, 0] = acum
  1205. return work
  1206. def _eval_matrix_exp_jblock(self):
  1207. """A helper function to compute an exponential of a Jordan block
  1208. matrix
  1209. Examples
  1210. ========
  1211. >>> from sympy import Symbol, Matrix
  1212. >>> l = Symbol('lamda')
  1213. A trivial example of 1*1 Jordan block:
  1214. >>> m = Matrix.jordan_block(1, l)
  1215. >>> m._eval_matrix_exp_jblock()
  1216. Matrix([[exp(lamda)]])
  1217. An example of 3*3 Jordan block:
  1218. >>> m = Matrix.jordan_block(3, l)
  1219. >>> m._eval_matrix_exp_jblock()
  1220. Matrix([
  1221. [exp(lamda), exp(lamda), exp(lamda)/2],
  1222. [ 0, exp(lamda), exp(lamda)],
  1223. [ 0, 0, exp(lamda)]])
  1224. References
  1225. ==========
  1226. .. [1] https://en.wikipedia.org/wiki/Matrix_function#Jordan_decomposition
  1227. """
  1228. size = self.rows
  1229. l = self[0, 0]
  1230. exp_l = exp(l)
  1231. bands = {i: exp_l / factorial(i) for i in range(size)}
  1232. from .sparsetools import banded
  1233. return self.__class__(banded(size, bands))
  1234. def analytic_func(self, f, x):
  1235. """
  1236. Computes f(A) where A is a Square Matrix
  1237. and f is an analytic function.
  1238. Examples
  1239. ========
  1240. >>> from sympy import Symbol, Matrix, S, log
  1241. >>> x = Symbol('x')
  1242. >>> m = Matrix([[S(5)/4, S(3)/4], [S(3)/4, S(5)/4]])
  1243. >>> f = log(x)
  1244. >>> m.analytic_func(f, x)
  1245. Matrix([
  1246. [ 0, log(2)],
  1247. [log(2), 0]])
  1248. Parameters
  1249. ==========
  1250. f : Expr
  1251. Analytic Function
  1252. x : Symbol
  1253. parameter of f
  1254. """
  1255. f, x = _sympify(f), _sympify(x)
  1256. if not self.is_square:
  1257. raise NonSquareMatrixError
  1258. if not x.is_symbol:
  1259. raise ValueError("{} must be a symbol.".format(x))
  1260. if x not in f.free_symbols:
  1261. raise ValueError(
  1262. "{} must be a parameter of {}.".format(x, f))
  1263. if x in self.free_symbols:
  1264. raise ValueError(
  1265. "{} must not be a parameter of {}.".format(x, self))
  1266. eigen = self.eigenvals()
  1267. max_mul = max(eigen.values())
  1268. derivative = {}
  1269. dd = f
  1270. for i in range(max_mul - 1):
  1271. dd = diff(dd, x)
  1272. derivative[i + 1] = dd
  1273. n = self.shape[0]
  1274. r = self.zeros(n)
  1275. f_val = self.zeros(n, 1)
  1276. row = 0
  1277. for i in eigen:
  1278. mul = eigen[i]
  1279. f_val[row] = f.subs(x, i)
  1280. if f_val[row].is_number and not f_val[row].is_complex:
  1281. raise ValueError(
  1282. "Cannot evaluate the function because the "
  1283. "function {} is not analytic at the given "
  1284. "eigenvalue {}".format(f, f_val[row]))
  1285. val = 1
  1286. for a in range(n):
  1287. r[row, a] = val
  1288. val *= i
  1289. if mul > 1:
  1290. coe = [1 for ii in range(n)]
  1291. deri = 1
  1292. while mul > 1:
  1293. row = row + 1
  1294. mul -= 1
  1295. d_i = derivative[deri].subs(x, i)
  1296. if d_i.is_number and not d_i.is_complex:
  1297. raise ValueError(
  1298. "Cannot evaluate the function because the "
  1299. "derivative {} is not analytic at the given "
  1300. "eigenvalue {}".format(derivative[deri], d_i))
  1301. f_val[row] = d_i
  1302. for a in range(n):
  1303. if a - deri + 1 <= 0:
  1304. r[row, a] = 0
  1305. coe[a] = 0
  1306. continue
  1307. coe[a] = coe[a]*(a - deri + 1)
  1308. r[row, a] = coe[a]*pow(i, a - deri)
  1309. deri += 1
  1310. row += 1
  1311. c = r.solve(f_val)
  1312. ans = self.zeros(n)
  1313. pre = self.eye(n)
  1314. for i in range(n):
  1315. ans = ans + c[i]*pre
  1316. pre *= self
  1317. return ans
  1318. def exp(self):
  1319. """Return the exponential of a square matrix
  1320. Examples
  1321. ========
  1322. >>> from sympy import Symbol, Matrix
  1323. >>> t = Symbol('t')
  1324. >>> m = Matrix([[0, 1], [-1, 0]]) * t
  1325. >>> m.exp()
  1326. Matrix([
  1327. [ exp(I*t)/2 + exp(-I*t)/2, -I*exp(I*t)/2 + I*exp(-I*t)/2],
  1328. [I*exp(I*t)/2 - I*exp(-I*t)/2, exp(I*t)/2 + exp(-I*t)/2]])
  1329. """
  1330. if not self.is_square:
  1331. raise NonSquareMatrixError(
  1332. "Exponentiation is valid only for square matrices")
  1333. try:
  1334. P, J = self.jordan_form()
  1335. cells = J.get_diag_blocks()
  1336. except MatrixError:
  1337. raise NotImplementedError(
  1338. "Exponentiation is implemented only for matrices for which the Jordan normal form can be computed")
  1339. blocks = [cell._eval_matrix_exp_jblock() for cell in cells]
  1340. from sympy.matrices import diag
  1341. eJ = diag(*blocks)
  1342. # n = self.rows
  1343. ret = P.multiply(eJ, dotprodsimp=None).multiply(P.inv(), dotprodsimp=None)
  1344. if all(value.is_real for value in self.values()):
  1345. return type(self)(re(ret))
  1346. else:
  1347. return type(self)(ret)
  1348. def _eval_matrix_log_jblock(self):
  1349. """Helper function to compute logarithm of a jordan block.
  1350. Examples
  1351. ========
  1352. >>> from sympy import Symbol, Matrix
  1353. >>> l = Symbol('lamda')
  1354. A trivial example of 1*1 Jordan block:
  1355. >>> m = Matrix.jordan_block(1, l)
  1356. >>> m._eval_matrix_log_jblock()
  1357. Matrix([[log(lamda)]])
  1358. An example of 3*3 Jordan block:
  1359. >>> m = Matrix.jordan_block(3, l)
  1360. >>> m._eval_matrix_log_jblock()
  1361. Matrix([
  1362. [log(lamda), 1/lamda, -1/(2*lamda**2)],
  1363. [ 0, log(lamda), 1/lamda],
  1364. [ 0, 0, log(lamda)]])
  1365. """
  1366. size = self.rows
  1367. l = self[0, 0]
  1368. if l.is_zero:
  1369. raise MatrixError(
  1370. 'Could not take logarithm or reciprocal for the given '
  1371. 'eigenvalue {}'.format(l))
  1372. bands = {0: log(l)}
  1373. for i in range(1, size):
  1374. bands[i] = -((-l) ** -i) / i
  1375. from .sparsetools import banded
  1376. return self.__class__(banded(size, bands))
  1377. def log(self, simplify=cancel):
  1378. """Return the logarithm of a square matrix
  1379. Parameters
  1380. ==========
  1381. simplify : function, bool
  1382. The function to simplify the result with.
  1383. Default is ``cancel``, which is effective to reduce the
  1384. expression growing for taking reciprocals and inverses for
  1385. symbolic matrices.
  1386. Examples
  1387. ========
  1388. >>> from sympy import S, Matrix
  1389. Examples for positive-definite matrices:
  1390. >>> m = Matrix([[1, 1], [0, 1]])
  1391. >>> m.log()
  1392. Matrix([
  1393. [0, 1],
  1394. [0, 0]])
  1395. >>> m = Matrix([[S(5)/4, S(3)/4], [S(3)/4, S(5)/4]])
  1396. >>> m.log()
  1397. Matrix([
  1398. [ 0, log(2)],
  1399. [log(2), 0]])
  1400. Examples for non positive-definite matrices:
  1401. >>> m = Matrix([[S(3)/4, S(5)/4], [S(5)/4, S(3)/4]])
  1402. >>> m.log()
  1403. Matrix([
  1404. [ I*pi/2, log(2) - I*pi/2],
  1405. [log(2) - I*pi/2, I*pi/2]])
  1406. >>> m = Matrix(
  1407. ... [[0, 0, 0, 1],
  1408. ... [0, 0, 1, 0],
  1409. ... [0, 1, 0, 0],
  1410. ... [1, 0, 0, 0]])
  1411. >>> m.log()
  1412. Matrix([
  1413. [ I*pi/2, 0, 0, -I*pi/2],
  1414. [ 0, I*pi/2, -I*pi/2, 0],
  1415. [ 0, -I*pi/2, I*pi/2, 0],
  1416. [-I*pi/2, 0, 0, I*pi/2]])
  1417. """
  1418. if not self.is_square:
  1419. raise NonSquareMatrixError(
  1420. "Logarithm is valid only for square matrices")
  1421. try:
  1422. if simplify:
  1423. P, J = simplify(self).jordan_form()
  1424. else:
  1425. P, J = self.jordan_form()
  1426. cells = J.get_diag_blocks()
  1427. except MatrixError:
  1428. raise NotImplementedError(
  1429. "Logarithm is implemented only for matrices for which "
  1430. "the Jordan normal form can be computed")
  1431. blocks = [
  1432. cell._eval_matrix_log_jblock()
  1433. for cell in cells]
  1434. from sympy.matrices import diag
  1435. eJ = diag(*blocks)
  1436. if simplify:
  1437. ret = simplify(P * eJ * simplify(P.inv()))
  1438. ret = self.__class__(ret)
  1439. else:
  1440. ret = P * eJ * P.inv()
  1441. return ret
  1442. def is_nilpotent(self):
  1443. """Checks if a matrix is nilpotent.
  1444. A matrix B is nilpotent if for some integer k, B**k is
  1445. a zero matrix.
  1446. Examples
  1447. ========
  1448. >>> from sympy import Matrix
  1449. >>> a = Matrix([[0, 0, 0], [1, 0, 0], [1, 1, 0]])
  1450. >>> a.is_nilpotent()
  1451. True
  1452. >>> a = Matrix([[1, 0, 1], [1, 0, 0], [1, 1, 0]])
  1453. >>> a.is_nilpotent()
  1454. False
  1455. """
  1456. if not self:
  1457. return True
  1458. if not self.is_square:
  1459. raise NonSquareMatrixError(
  1460. "Nilpotency is valid only for square matrices")
  1461. x = uniquely_named_symbol('x', self, modify=lambda s: '_' + s)
  1462. p = self.charpoly(x)
  1463. if p.args[0] == x ** self.rows:
  1464. return True
  1465. return False
  1466. def key2bounds(self, keys):
  1467. """Converts a key with potentially mixed types of keys (integer and slice)
  1468. into a tuple of ranges and raises an error if any index is out of ``self``'s
  1469. range.
  1470. See Also
  1471. ========
  1472. key2ij
  1473. """
  1474. from sympy.matrices.common import a2idx as a2idx_ # Remove this line after deprecation of a2idx from matrices.py
  1475. islice, jslice = [isinstance(k, slice) for k in keys]
  1476. if islice:
  1477. if not self.rows:
  1478. rlo = rhi = 0
  1479. else:
  1480. rlo, rhi = keys[0].indices(self.rows)[:2]
  1481. else:
  1482. rlo = a2idx_(keys[0], self.rows)
  1483. rhi = rlo + 1
  1484. if jslice:
  1485. if not self.cols:
  1486. clo = chi = 0
  1487. else:
  1488. clo, chi = keys[1].indices(self.cols)[:2]
  1489. else:
  1490. clo = a2idx_(keys[1], self.cols)
  1491. chi = clo + 1
  1492. return rlo, rhi, clo, chi
  1493. def key2ij(self, key):
  1494. """Converts key into canonical form, converting integers or indexable
  1495. items into valid integers for ``self``'s range or returning slices
  1496. unchanged.
  1497. See Also
  1498. ========
  1499. key2bounds
  1500. """
  1501. from sympy.matrices.common import a2idx as a2idx_ # Remove this line after deprecation of a2idx from matrices.py
  1502. if is_sequence(key):
  1503. if not len(key) == 2:
  1504. raise TypeError('key must be a sequence of length 2')
  1505. return [a2idx_(i, n) if not isinstance(i, slice) else i
  1506. for i, n in zip(key, self.shape)]
  1507. elif isinstance(key, slice):
  1508. return key.indices(len(self))[:2]
  1509. else:
  1510. return divmod(a2idx_(key, len(self)), self.cols)
  1511. def normalized(self, iszerofunc=_iszero):
  1512. """Return the normalized version of ``self``.
  1513. Parameters
  1514. ==========
  1515. iszerofunc : Function, optional
  1516. A function to determine whether ``self`` is a zero vector.
  1517. The default ``_iszero`` tests to see if each element is
  1518. exactly zero.
  1519. Returns
  1520. =======
  1521. Matrix
  1522. Normalized vector form of ``self``.
  1523. It has the same length as a unit vector. However, a zero vector
  1524. will be returned for a vector with norm 0.
  1525. Raises
  1526. ======
  1527. ShapeError
  1528. If the matrix is not in a vector form.
  1529. See Also
  1530. ========
  1531. norm
  1532. """
  1533. if self.rows != 1 and self.cols != 1:
  1534. raise ShapeError("A Matrix must be a vector to normalize.")
  1535. norm = self.norm()
  1536. if iszerofunc(norm):
  1537. out = self.zeros(self.rows, self.cols)
  1538. else:
  1539. out = self.applyfunc(lambda i: i / norm)
  1540. return out
  1541. def norm(self, ord=None):
  1542. """Return the Norm of a Matrix or Vector.
  1543. In the simplest case this is the geometric size of the vector
  1544. Other norms can be specified by the ord parameter
  1545. ===== ============================ ==========================
  1546. ord norm for matrices norm for vectors
  1547. ===== ============================ ==========================
  1548. None Frobenius norm 2-norm
  1549. 'fro' Frobenius norm - does not exist
  1550. inf maximum row sum max(abs(x))
  1551. -inf -- min(abs(x))
  1552. 1 maximum column sum as below
  1553. -1 -- as below
  1554. 2 2-norm (largest sing. value) as below
  1555. -2 smallest singular value as below
  1556. other - does not exist sum(abs(x)**ord)**(1./ord)
  1557. ===== ============================ ==========================
  1558. Examples
  1559. ========
  1560. >>> from sympy import Matrix, Symbol, trigsimp, cos, sin, oo
  1561. >>> x = Symbol('x', real=True)
  1562. >>> v = Matrix([cos(x), sin(x)])
  1563. >>> trigsimp( v.norm() )
  1564. 1
  1565. >>> v.norm(10)
  1566. (sin(x)**10 + cos(x)**10)**(1/10)
  1567. >>> A = Matrix([[1, 1], [1, 1]])
  1568. >>> A.norm(1) # maximum sum of absolute values of A is 2
  1569. 2
  1570. >>> A.norm(2) # Spectral norm (max of |Ax|/|x| under 2-vector-norm)
  1571. 2
  1572. >>> A.norm(-2) # Inverse spectral norm (smallest singular value)
  1573. 0
  1574. >>> A.norm() # Frobenius Norm
  1575. 2
  1576. >>> A.norm(oo) # Infinity Norm
  1577. 2
  1578. >>> Matrix([1, -2]).norm(oo)
  1579. 2
  1580. >>> Matrix([-1, 2]).norm(-oo)
  1581. 1
  1582. See Also
  1583. ========
  1584. normalized
  1585. """
  1586. # Row or Column Vector Norms
  1587. vals = list(self.values()) or [0]
  1588. if S.One in self.shape:
  1589. if ord in (2, None): # Common case sqrt(<x, x>)
  1590. return sqrt(Add(*(abs(i) ** 2 for i in vals)))
  1591. elif ord == 1: # sum(abs(x))
  1592. return Add(*(abs(i) for i in vals))
  1593. elif ord is S.Infinity: # max(abs(x))
  1594. return Max(*[abs(i) for i in vals])
  1595. elif ord is S.NegativeInfinity: # min(abs(x))
  1596. return Min(*[abs(i) for i in vals])
  1597. # Otherwise generalize the 2-norm, Sum(x_i**ord)**(1/ord)
  1598. # Note that while useful this is not mathematically a norm
  1599. try:
  1600. return Pow(Add(*(abs(i) ** ord for i in vals)), S.One / ord)
  1601. except (NotImplementedError, TypeError):
  1602. raise ValueError("Expected order to be Number, Symbol, oo")
  1603. # Matrix Norms
  1604. else:
  1605. if ord == 1: # Maximum column sum
  1606. m = self.applyfunc(abs)
  1607. return Max(*[sum(m.col(i)) for i in range(m.cols)])
  1608. elif ord == 2: # Spectral Norm
  1609. # Maximum singular value
  1610. return Max(*self.singular_values())
  1611. elif ord == -2:
  1612. # Minimum singular value
  1613. return Min(*self.singular_values())
  1614. elif ord is S.Infinity: # Infinity Norm - Maximum row sum
  1615. m = self.applyfunc(abs)
  1616. return Max(*[sum(m.row(i)) for i in range(m.rows)])
  1617. elif (ord is None or isinstance(ord,
  1618. str) and ord.lower() in
  1619. ['f', 'fro', 'frobenius', 'vector']):
  1620. # Reshape as vector and send back to norm function
  1621. return self.vec().norm(ord=2)
  1622. else:
  1623. raise NotImplementedError("Matrix Norms under development")
  1624. def print_nonzero(self, symb="X"):
  1625. """Shows location of non-zero entries for fast shape lookup.
  1626. Examples
  1627. ========
  1628. >>> from sympy import Matrix, eye
  1629. >>> m = Matrix(2, 3, lambda i, j: i*3+j)
  1630. >>> m
  1631. Matrix([
  1632. [0, 1, 2],
  1633. [3, 4, 5]])
  1634. >>> m.print_nonzero()
  1635. [ XX]
  1636. [XXX]
  1637. >>> m = eye(4)
  1638. >>> m.print_nonzero("x")
  1639. [x ]
  1640. [ x ]
  1641. [ x ]
  1642. [ x]
  1643. """
  1644. s = []
  1645. for i in range(self.rows):
  1646. line = []
  1647. for j in range(self.cols):
  1648. if self[i, j] == 0:
  1649. line.append(" ")
  1650. else:
  1651. line.append(str(symb))
  1652. s.append("[%s]" % ''.join(line))
  1653. print('\n'.join(s))
  1654. def project(self, v):
  1655. """Return the projection of ``self`` onto the line containing ``v``.
  1656. Examples
  1657. ========
  1658. >>> from sympy import Matrix, S, sqrt
  1659. >>> V = Matrix([sqrt(3)/2, S.Half])
  1660. >>> x = Matrix([[1, 0]])
  1661. >>> V.project(x)
  1662. Matrix([[sqrt(3)/2, 0]])
  1663. >>> V.project(-x)
  1664. Matrix([[sqrt(3)/2, 0]])
  1665. """
  1666. return v * (self.dot(v) / v.dot(v))
  1667. def table(self, printer, rowstart='[', rowend=']', rowsep='\n',
  1668. colsep=', ', align='right'):
  1669. r"""
  1670. String form of Matrix as a table.
  1671. ``printer`` is the printer to use for on the elements (generally
  1672. something like StrPrinter())
  1673. ``rowstart`` is the string used to start each row (by default '[').
  1674. ``rowend`` is the string used to end each row (by default ']').
  1675. ``rowsep`` is the string used to separate rows (by default a newline).
  1676. ``colsep`` is the string used to separate columns (by default ', ').
  1677. ``align`` defines how the elements are aligned. Must be one of 'left',
  1678. 'right', or 'center'. You can also use '<', '>', and '^' to mean the
  1679. same thing, respectively.
  1680. This is used by the string printer for Matrix.
  1681. Examples
  1682. ========
  1683. >>> from sympy import Matrix, StrPrinter
  1684. >>> M = Matrix([[1, 2], [-33, 4]])
  1685. >>> printer = StrPrinter()
  1686. >>> M.table(printer)
  1687. '[ 1, 2]\n[-33, 4]'
  1688. >>> print(M.table(printer))
  1689. [ 1, 2]
  1690. [-33, 4]
  1691. >>> print(M.table(printer, rowsep=',\n'))
  1692. [ 1, 2],
  1693. [-33, 4]
  1694. >>> print('[%s]' % M.table(printer, rowsep=',\n'))
  1695. [[ 1, 2],
  1696. [-33, 4]]
  1697. >>> print(M.table(printer, colsep=' '))
  1698. [ 1 2]
  1699. [-33 4]
  1700. >>> print(M.table(printer, align='center'))
  1701. [ 1 , 2]
  1702. [-33, 4]
  1703. >>> print(M.table(printer, rowstart='{', rowend='}'))
  1704. { 1, 2}
  1705. {-33, 4}
  1706. """
  1707. # Handle zero dimensions:
  1708. if S.Zero in self.shape:
  1709. return '[]'
  1710. # Build table of string representations of the elements
  1711. res = []
  1712. # Track per-column max lengths for pretty alignment
  1713. maxlen = [0] * self.cols
  1714. for i in range(self.rows):
  1715. res.append([])
  1716. for j in range(self.cols):
  1717. s = printer._print(self[i, j])
  1718. res[-1].append(s)
  1719. maxlen[j] = max(len(s), maxlen[j])
  1720. # Patch strings together
  1721. align = {
  1722. 'left': 'ljust',
  1723. 'right': 'rjust',
  1724. 'center': 'center',
  1725. '<': 'ljust',
  1726. '>': 'rjust',
  1727. '^': 'center',
  1728. }[align]
  1729. for i, row in enumerate(res):
  1730. for j, elem in enumerate(row):
  1731. row[j] = getattr(elem, align)(maxlen[j])
  1732. res[i] = rowstart + colsep.join(row) + rowend
  1733. return rowsep.join(res)
  1734. def rank_decomposition(self, iszerofunc=_iszero, simplify=False):
  1735. return _rank_decomposition(self, iszerofunc=iszerofunc,
  1736. simplify=simplify)
  1737. def cholesky(self, hermitian=True):
  1738. raise NotImplementedError('This function is implemented in DenseMatrix or SparseMatrix')
  1739. def LDLdecomposition(self, hermitian=True):
  1740. raise NotImplementedError('This function is implemented in DenseMatrix or SparseMatrix')
  1741. def LUdecomposition(self, iszerofunc=_iszero, simpfunc=None,
  1742. rankcheck=False):
  1743. return _LUdecomposition(self, iszerofunc=iszerofunc, simpfunc=simpfunc,
  1744. rankcheck=rankcheck)
  1745. def LUdecomposition_Simple(self, iszerofunc=_iszero, simpfunc=None,
  1746. rankcheck=False):
  1747. return _LUdecomposition_Simple(self, iszerofunc=iszerofunc,
  1748. simpfunc=simpfunc, rankcheck=rankcheck)
  1749. def LUdecompositionFF(self):
  1750. return _LUdecompositionFF(self)
  1751. def singular_value_decomposition(self):
  1752. return _singular_value_decomposition(self)
  1753. def QRdecomposition(self):
  1754. return _QRdecomposition(self)
  1755. def upper_hessenberg_decomposition(self):
  1756. return _upper_hessenberg_decomposition(self)
  1757. def diagonal_solve(self, rhs):
  1758. return _diagonal_solve(self, rhs)
  1759. def lower_triangular_solve(self, rhs):
  1760. raise NotImplementedError('This function is implemented in DenseMatrix or SparseMatrix')
  1761. def upper_triangular_solve(self, rhs):
  1762. raise NotImplementedError('This function is implemented in DenseMatrix or SparseMatrix')
  1763. def cholesky_solve(self, rhs):
  1764. return _cholesky_solve(self, rhs)
  1765. def LDLsolve(self, rhs):
  1766. return _LDLsolve(self, rhs)
  1767. def LUsolve(self, rhs, iszerofunc=_iszero):
  1768. return _LUsolve(self, rhs, iszerofunc=iszerofunc)
  1769. def QRsolve(self, b):
  1770. return _QRsolve(self, b)
  1771. def gauss_jordan_solve(self, B, freevar=False):
  1772. return _gauss_jordan_solve(self, B, freevar=freevar)
  1773. def pinv_solve(self, B, arbitrary_matrix=None):
  1774. return _pinv_solve(self, B, arbitrary_matrix=arbitrary_matrix)
  1775. def solve(self, rhs, method='GJ'):
  1776. return _solve(self, rhs, method=method)
  1777. def solve_least_squares(self, rhs, method='CH'):
  1778. return _solve_least_squares(self, rhs, method=method)
  1779. def pinv(self, method='RD'):
  1780. return _pinv(self, method=method)
  1781. def inv_mod(self, m):
  1782. return _inv_mod(self, m)
  1783. def inverse_ADJ(self, iszerofunc=_iszero):
  1784. return _inv_ADJ(self, iszerofunc=iszerofunc)
  1785. def inverse_BLOCK(self, iszerofunc=_iszero):
  1786. return _inv_block(self, iszerofunc=iszerofunc)
  1787. def inverse_GE(self, iszerofunc=_iszero):
  1788. return _inv_GE(self, iszerofunc=iszerofunc)
  1789. def inverse_LU(self, iszerofunc=_iszero):
  1790. return _inv_LU(self, iszerofunc=iszerofunc)
  1791. def inverse_CH(self, iszerofunc=_iszero):
  1792. return _inv_CH(self, iszerofunc=iszerofunc)
  1793. def inverse_LDL(self, iszerofunc=_iszero):
  1794. return _inv_LDL(self, iszerofunc=iszerofunc)
  1795. def inverse_QR(self, iszerofunc=_iszero):
  1796. return _inv_QR(self, iszerofunc=iszerofunc)
  1797. def inv(self, method=None, iszerofunc=_iszero, try_block_diag=False):
  1798. return _inv(self, method=method, iszerofunc=iszerofunc,
  1799. try_block_diag=try_block_diag)
  1800. def connected_components(self):
  1801. return _connected_components(self)
  1802. def connected_components_decomposition(self):
  1803. return _connected_components_decomposition(self)
  1804. def strongly_connected_components(self):
  1805. return _strongly_connected_components(self)
  1806. def strongly_connected_components_decomposition(self, lower=True):
  1807. return _strongly_connected_components_decomposition(self, lower=lower)
  1808. _sage_ = Basic._sage_
  1809. rank_decomposition.__doc__ = _rank_decomposition.__doc__
  1810. cholesky.__doc__ = _cholesky.__doc__
  1811. LDLdecomposition.__doc__ = _LDLdecomposition.__doc__
  1812. LUdecomposition.__doc__ = _LUdecomposition.__doc__
  1813. LUdecomposition_Simple.__doc__ = _LUdecomposition_Simple.__doc__
  1814. LUdecompositionFF.__doc__ = _LUdecompositionFF.__doc__
  1815. singular_value_decomposition.__doc__ = _singular_value_decomposition.__doc__
  1816. QRdecomposition.__doc__ = _QRdecomposition.__doc__
  1817. upper_hessenberg_decomposition.__doc__ = _upper_hessenberg_decomposition.__doc__
  1818. diagonal_solve.__doc__ = _diagonal_solve.__doc__
  1819. lower_triangular_solve.__doc__ = _lower_triangular_solve.__doc__
  1820. upper_triangular_solve.__doc__ = _upper_triangular_solve.__doc__
  1821. cholesky_solve.__doc__ = _cholesky_solve.__doc__
  1822. LDLsolve.__doc__ = _LDLsolve.__doc__
  1823. LUsolve.__doc__ = _LUsolve.__doc__
  1824. QRsolve.__doc__ = _QRsolve.__doc__
  1825. gauss_jordan_solve.__doc__ = _gauss_jordan_solve.__doc__
  1826. pinv_solve.__doc__ = _pinv_solve.__doc__
  1827. solve.__doc__ = _solve.__doc__
  1828. solve_least_squares.__doc__ = _solve_least_squares.__doc__
  1829. pinv.__doc__ = _pinv.__doc__
  1830. inv_mod.__doc__ = _inv_mod.__doc__
  1831. inverse_ADJ.__doc__ = _inv_ADJ.__doc__
  1832. inverse_GE.__doc__ = _inv_GE.__doc__
  1833. inverse_LU.__doc__ = _inv_LU.__doc__
  1834. inverse_CH.__doc__ = _inv_CH.__doc__
  1835. inverse_LDL.__doc__ = _inv_LDL.__doc__
  1836. inverse_QR.__doc__ = _inv_QR.__doc__
  1837. inverse_BLOCK.__doc__ = _inv_block.__doc__
  1838. inv.__doc__ = _inv.__doc__
  1839. connected_components.__doc__ = _connected_components.__doc__
  1840. connected_components_decomposition.__doc__ = \
  1841. _connected_components_decomposition.__doc__
  1842. strongly_connected_components.__doc__ = \
  1843. _strongly_connected_components.__doc__
  1844. strongly_connected_components_decomposition.__doc__ = \
  1845. _strongly_connected_components_decomposition.__doc__
  1846. @deprecated(
  1847. """
  1848. sympy.matrices.matrices.classof is deprecated. Use
  1849. sympy.matrices.common.classof instead.
  1850. """,
  1851. deprecated_since_version="1.3",
  1852. active_deprecations_target="deprecated-sympy-matrices-classof-a2idx",
  1853. )
  1854. def classof(A, B):
  1855. from sympy.matrices.common import classof as classof_
  1856. return classof_(A, B)
  1857. @deprecated(
  1858. """
  1859. sympy.matrices.matrices.a2idx is deprecated. Use
  1860. sympy.matrices.common.a2idx instead.
  1861. """,
  1862. deprecated_since_version="1.3",
  1863. active_deprecations_target="deprecated-sympy-matrices-classof-a2idx",
  1864. )
  1865. def a2idx(j, n=None):
  1866. from sympy.matrices.common import a2idx as a2idx_
  1867. return a2idx_(j, n)