test_commonmatrix.py 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. #
  2. # Code for testing deprecated matrix classes. New test code should not be added
  3. # here. Instead, add it to test_matrixbase.py.
  4. #
  5. # This entire test module and the corresponding sympy/matrices/common.py
  6. # module will be removed in a future release.
  7. #
  8. from sympy.testing.pytest import raises, XFAIL, warns_deprecated_sympy
  9. from sympy.assumptions import Q
  10. from sympy.core.expr import Expr
  11. from sympy.core.add import Add
  12. from sympy.core.function import Function
  13. from sympy.core.kind import NumberKind, UndefinedKind
  14. from sympy.core.numbers import I, Integer, oo, pi, Rational
  15. from sympy.core.singleton import S
  16. from sympy.core.symbol import Symbol, symbols
  17. from sympy.functions.elementary.complexes import Abs
  18. from sympy.functions.elementary.exponential import exp
  19. from sympy.functions.elementary.miscellaneous import sqrt
  20. from sympy.functions.elementary.trigonometric import cos, sin
  21. from sympy.matrices.exceptions import ShapeError, NonSquareMatrixError
  22. from sympy.matrices.kind import MatrixKind
  23. from sympy.matrices.common import (
  24. _MinimalMatrix, _CastableMatrix, MatrixShaping, MatrixProperties,
  25. MatrixOperations, MatrixArithmetic, MatrixSpecial)
  26. from sympy.matrices.matrices import MatrixCalculus
  27. from sympy.matrices import (Matrix, diag, eye,
  28. matrix_multiply_elementwise, ones, zeros, SparseMatrix, banded,
  29. MutableDenseMatrix, MutableSparseMatrix, ImmutableDenseMatrix,
  30. ImmutableSparseMatrix)
  31. from sympy.polys.polytools import Poly
  32. from sympy.utilities.iterables import flatten
  33. from sympy.tensor.array.dense_ndim_array import ImmutableDenseNDimArray as Array
  34. from sympy.abc import x, y, z
  35. def test_matrix_deprecated_isinstance():
  36. # Test that e.g. isinstance(M, MatrixCommon) still gives True when M is a
  37. # Matrix for each of the deprecated matrix classes.
  38. from sympy.matrices.common import (
  39. MatrixRequired,
  40. MatrixShaping,
  41. MatrixSpecial,
  42. MatrixProperties,
  43. MatrixOperations,
  44. MatrixArithmetic,
  45. MatrixCommon
  46. )
  47. from sympy.matrices.matrices import (
  48. MatrixDeterminant,
  49. MatrixReductions,
  50. MatrixSubspaces,
  51. MatrixEigen,
  52. MatrixCalculus,
  53. MatrixDeprecated
  54. )
  55. from sympy import (
  56. Matrix,
  57. ImmutableMatrix,
  58. SparseMatrix,
  59. ImmutableSparseMatrix
  60. )
  61. all_mixins = (
  62. MatrixRequired,
  63. MatrixShaping,
  64. MatrixSpecial,
  65. MatrixProperties,
  66. MatrixOperations,
  67. MatrixArithmetic,
  68. MatrixCommon,
  69. MatrixDeterminant,
  70. MatrixReductions,
  71. MatrixSubspaces,
  72. MatrixEigen,
  73. MatrixCalculus,
  74. MatrixDeprecated
  75. )
  76. all_matrices = (
  77. Matrix,
  78. ImmutableMatrix,
  79. SparseMatrix,
  80. ImmutableSparseMatrix
  81. )
  82. Ms = [M([[1, 2], [3, 4]]) for M in all_matrices]
  83. t = ()
  84. for mixin in all_mixins:
  85. for M in Ms:
  86. with warns_deprecated_sympy():
  87. assert isinstance(M, mixin) is True
  88. with warns_deprecated_sympy():
  89. assert isinstance(t, mixin) is False
  90. # classes to test the deprecated matrix classes. We use warns_deprecated_sympy
  91. # to suppress the deprecation warnings because subclassing the deprecated
  92. # classes causes a warning to be raised.
  93. with warns_deprecated_sympy():
  94. class ShapingOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixShaping):
  95. pass
  96. def eye_Shaping(n):
  97. return ShapingOnlyMatrix(n, n, lambda i, j: int(i == j))
  98. def zeros_Shaping(n):
  99. return ShapingOnlyMatrix(n, n, lambda i, j: 0)
  100. with warns_deprecated_sympy():
  101. class PropertiesOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixProperties):
  102. pass
  103. def eye_Properties(n):
  104. return PropertiesOnlyMatrix(n, n, lambda i, j: int(i == j))
  105. def zeros_Properties(n):
  106. return PropertiesOnlyMatrix(n, n, lambda i, j: 0)
  107. with warns_deprecated_sympy():
  108. class OperationsOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixOperations):
  109. pass
  110. def eye_Operations(n):
  111. return OperationsOnlyMatrix(n, n, lambda i, j: int(i == j))
  112. def zeros_Operations(n):
  113. return OperationsOnlyMatrix(n, n, lambda i, j: 0)
  114. with warns_deprecated_sympy():
  115. class ArithmeticOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixArithmetic):
  116. pass
  117. def eye_Arithmetic(n):
  118. return ArithmeticOnlyMatrix(n, n, lambda i, j: int(i == j))
  119. def zeros_Arithmetic(n):
  120. return ArithmeticOnlyMatrix(n, n, lambda i, j: 0)
  121. with warns_deprecated_sympy():
  122. class SpecialOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixSpecial):
  123. pass
  124. with warns_deprecated_sympy():
  125. class CalculusOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixCalculus):
  126. pass
  127. def test__MinimalMatrix():
  128. x = _MinimalMatrix(2, 3, [1, 2, 3, 4, 5, 6])
  129. assert x.rows == 2
  130. assert x.cols == 3
  131. assert x[2] == 3
  132. assert x[1, 1] == 5
  133. assert list(x) == [1, 2, 3, 4, 5, 6]
  134. assert list(x[1, :]) == [4, 5, 6]
  135. assert list(x[:, 1]) == [2, 5]
  136. assert list(x[:, :]) == list(x)
  137. assert x[:, :] == x
  138. assert _MinimalMatrix(x) == x
  139. assert _MinimalMatrix([[1, 2, 3], [4, 5, 6]]) == x
  140. assert _MinimalMatrix(([1, 2, 3], [4, 5, 6])) == x
  141. assert _MinimalMatrix([(1, 2, 3), (4, 5, 6)]) == x
  142. assert _MinimalMatrix(((1, 2, 3), (4, 5, 6))) == x
  143. assert not (_MinimalMatrix([[1, 2], [3, 4], [5, 6]]) == x)
  144. def test_kind():
  145. assert Matrix([[1, 2], [3, 4]]).kind == MatrixKind(NumberKind)
  146. assert Matrix([[0, 0], [0, 0]]).kind == MatrixKind(NumberKind)
  147. assert Matrix(0, 0, []).kind == MatrixKind(NumberKind)
  148. assert Matrix([[x]]).kind == MatrixKind(NumberKind)
  149. assert Matrix([[1, Matrix([[1]])]]).kind == MatrixKind(UndefinedKind)
  150. assert SparseMatrix([[1]]).kind == MatrixKind(NumberKind)
  151. assert SparseMatrix([[1, Matrix([[1]])]]).kind == MatrixKind(UndefinedKind)
  152. # ShapingOnlyMatrix tests
  153. def test_vec():
  154. m = ShapingOnlyMatrix(2, 2, [1, 3, 2, 4])
  155. m_vec = m.vec()
  156. assert m_vec.cols == 1
  157. for i in range(4):
  158. assert m_vec[i] == i + 1
  159. def test_todok():
  160. a, b, c, d = symbols('a:d')
  161. m1 = MutableDenseMatrix([[a, b], [c, d]])
  162. m2 = ImmutableDenseMatrix([[a, b], [c, d]])
  163. m3 = MutableSparseMatrix([[a, b], [c, d]])
  164. m4 = ImmutableSparseMatrix([[a, b], [c, d]])
  165. assert m1.todok() == m2.todok() == m3.todok() == m4.todok() == \
  166. {(0, 0): a, (0, 1): b, (1, 0): c, (1, 1): d}
  167. def test_tolist():
  168. lst = [[S.One, S.Half, x*y, S.Zero], [x, y, z, x**2], [y, -S.One, z*x, 3]]
  169. flat_lst = [S.One, S.Half, x*y, S.Zero, x, y, z, x**2, y, -S.One, z*x, 3]
  170. m = ShapingOnlyMatrix(3, 4, flat_lst)
  171. assert m.tolist() == lst
  172. def test_todod():
  173. m = ShapingOnlyMatrix(3, 2, [[S.One, 0], [0, S.Half], [x, 0]])
  174. dict = {0: {0: S.One}, 1: {1: S.Half}, 2: {0: x}}
  175. assert m.todod() == dict
  176. def test_row_col_del():
  177. e = ShapingOnlyMatrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
  178. raises(IndexError, lambda: e.row_del(5))
  179. raises(IndexError, lambda: e.row_del(-5))
  180. raises(IndexError, lambda: e.col_del(5))
  181. raises(IndexError, lambda: e.col_del(-5))
  182. assert e.row_del(2) == e.row_del(-1) == Matrix([[1, 2, 3], [4, 5, 6]])
  183. assert e.col_del(2) == e.col_del(-1) == Matrix([[1, 2], [4, 5], [7, 8]])
  184. assert e.row_del(1) == e.row_del(-2) == Matrix([[1, 2, 3], [7, 8, 9]])
  185. assert e.col_del(1) == e.col_del(-2) == Matrix([[1, 3], [4, 6], [7, 9]])
  186. def test_get_diag_blocks1():
  187. a = Matrix([[1, 2], [2, 3]])
  188. b = Matrix([[3, x], [y, 3]])
  189. c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
  190. assert a.get_diag_blocks() == [a]
  191. assert b.get_diag_blocks() == [b]
  192. assert c.get_diag_blocks() == [c]
  193. def test_get_diag_blocks2():
  194. a = Matrix([[1, 2], [2, 3]])
  195. b = Matrix([[3, x], [y, 3]])
  196. c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
  197. A, B, C, D = diag(a, b, b), diag(a, b, c), diag(a, c, b), diag(c, c, b)
  198. A = ShapingOnlyMatrix(A.rows, A.cols, A)
  199. B = ShapingOnlyMatrix(B.rows, B.cols, B)
  200. C = ShapingOnlyMatrix(C.rows, C.cols, C)
  201. D = ShapingOnlyMatrix(D.rows, D.cols, D)
  202. assert A.get_diag_blocks() == [a, b, b]
  203. assert B.get_diag_blocks() == [a, b, c]
  204. assert C.get_diag_blocks() == [a, c, b]
  205. assert D.get_diag_blocks() == [c, c, b]
  206. def test_shape():
  207. m = ShapingOnlyMatrix(1, 2, [0, 0])
  208. assert m.shape == (1, 2)
  209. def test_reshape():
  210. m0 = eye_Shaping(3)
  211. assert m0.reshape(1, 9) == Matrix(1, 9, (1, 0, 0, 0, 1, 0, 0, 0, 1))
  212. m1 = ShapingOnlyMatrix(3, 4, lambda i, j: i + j)
  213. assert m1.reshape(
  214. 4, 3) == Matrix(((0, 1, 2), (3, 1, 2), (3, 4, 2), (3, 4, 5)))
  215. assert m1.reshape(2, 6) == Matrix(((0, 1, 2, 3, 1, 2), (3, 4, 2, 3, 4, 5)))
  216. def test_row_col():
  217. m = ShapingOnlyMatrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
  218. assert m.row(0) == Matrix(1, 3, [1, 2, 3])
  219. assert m.col(0) == Matrix(3, 1, [1, 4, 7])
  220. def test_row_join():
  221. assert eye_Shaping(3).row_join(Matrix([7, 7, 7])) == \
  222. Matrix([[1, 0, 0, 7],
  223. [0, 1, 0, 7],
  224. [0, 0, 1, 7]])
  225. def test_col_join():
  226. assert eye_Shaping(3).col_join(Matrix([[7, 7, 7]])) == \
  227. Matrix([[1, 0, 0],
  228. [0, 1, 0],
  229. [0, 0, 1],
  230. [7, 7, 7]])
  231. def test_row_insert():
  232. r4 = Matrix([[4, 4, 4]])
  233. for i in range(-4, 5):
  234. l = [1, 0, 0]
  235. l.insert(i, 4)
  236. assert flatten(eye_Shaping(3).row_insert(i, r4).col(0).tolist()) == l
  237. def test_col_insert():
  238. c4 = Matrix([4, 4, 4])
  239. for i in range(-4, 5):
  240. l = [0, 0, 0]
  241. l.insert(i, 4)
  242. assert flatten(zeros_Shaping(3).col_insert(i, c4).row(0).tolist()) == l
  243. # issue 13643
  244. assert eye_Shaping(6).col_insert(3, Matrix([[2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]])) == \
  245. Matrix([[1, 0, 0, 2, 2, 0, 0, 0],
  246. [0, 1, 0, 2, 2, 0, 0, 0],
  247. [0, 0, 1, 2, 2, 0, 0, 0],
  248. [0, 0, 0, 2, 2, 1, 0, 0],
  249. [0, 0, 0, 2, 2, 0, 1, 0],
  250. [0, 0, 0, 2, 2, 0, 0, 1]])
  251. def test_extract():
  252. m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
  253. assert m.extract([0, 1, 3], [0, 1]) == Matrix(3, 2, [0, 1, 3, 4, 9, 10])
  254. assert m.extract([0, 3], [0, 0, 2]) == Matrix(2, 3, [0, 0, 2, 9, 9, 11])
  255. assert m.extract(range(4), range(3)) == m
  256. raises(IndexError, lambda: m.extract([4], [0]))
  257. raises(IndexError, lambda: m.extract([0], [3]))
  258. def test_hstack():
  259. m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
  260. m2 = ShapingOnlyMatrix(3, 4, lambda i, j: i*3 + j)
  261. assert m == m.hstack(m)
  262. assert m.hstack(m, m, m) == ShapingOnlyMatrix.hstack(m, m, m) == Matrix([
  263. [0, 1, 2, 0, 1, 2, 0, 1, 2],
  264. [3, 4, 5, 3, 4, 5, 3, 4, 5],
  265. [6, 7, 8, 6, 7, 8, 6, 7, 8],
  266. [9, 10, 11, 9, 10, 11, 9, 10, 11]])
  267. raises(ShapeError, lambda: m.hstack(m, m2))
  268. assert Matrix.hstack() == Matrix()
  269. # test regression #12938
  270. M1 = Matrix.zeros(0, 0)
  271. M2 = Matrix.zeros(0, 1)
  272. M3 = Matrix.zeros(0, 2)
  273. M4 = Matrix.zeros(0, 3)
  274. m = ShapingOnlyMatrix.hstack(M1, M2, M3, M4)
  275. assert m.rows == 0 and m.cols == 6
  276. def test_vstack():
  277. m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
  278. m2 = ShapingOnlyMatrix(3, 4, lambda i, j: i*3 + j)
  279. assert m == m.vstack(m)
  280. assert m.vstack(m, m, m) == ShapingOnlyMatrix.vstack(m, m, m) == Matrix([
  281. [0, 1, 2],
  282. [3, 4, 5],
  283. [6, 7, 8],
  284. [9, 10, 11],
  285. [0, 1, 2],
  286. [3, 4, 5],
  287. [6, 7, 8],
  288. [9, 10, 11],
  289. [0, 1, 2],
  290. [3, 4, 5],
  291. [6, 7, 8],
  292. [9, 10, 11]])
  293. raises(ShapeError, lambda: m.vstack(m, m2))
  294. assert Matrix.vstack() == Matrix()
  295. # PropertiesOnlyMatrix tests
  296. def test_atoms():
  297. m = PropertiesOnlyMatrix(2, 2, [1, 2, x, 1 - 1/x])
  298. assert m.atoms() == {S.One, S(2), S.NegativeOne, x}
  299. assert m.atoms(Symbol) == {x}
  300. def test_free_symbols():
  301. assert PropertiesOnlyMatrix([[x], [0]]).free_symbols == {x}
  302. def test_has():
  303. A = PropertiesOnlyMatrix(((x, y), (2, 3)))
  304. assert A.has(x)
  305. assert not A.has(z)
  306. assert A.has(Symbol)
  307. A = PropertiesOnlyMatrix(((2, y), (2, 3)))
  308. assert not A.has(x)
  309. def test_is_anti_symmetric():
  310. x = symbols('x')
  311. assert PropertiesOnlyMatrix(2, 1, [1, 2]).is_anti_symmetric() is False
  312. m = PropertiesOnlyMatrix(3, 3, [0, x**2 + 2*x + 1, y, -(x + 1)**2, 0, x*y, -y, -x*y, 0])
  313. assert m.is_anti_symmetric() is True
  314. assert m.is_anti_symmetric(simplify=False) is False
  315. assert m.is_anti_symmetric(simplify=lambda x: x) is False
  316. m = PropertiesOnlyMatrix(3, 3, [x.expand() for x in m])
  317. assert m.is_anti_symmetric(simplify=False) is True
  318. m = PropertiesOnlyMatrix(3, 3, [x.expand() for x in [S.One] + list(m)[1:]])
  319. assert m.is_anti_symmetric() is False
  320. def test_diagonal_symmetrical():
  321. m = PropertiesOnlyMatrix(2, 2, [0, 1, 1, 0])
  322. assert not m.is_diagonal()
  323. assert m.is_symmetric()
  324. assert m.is_symmetric(simplify=False)
  325. m = PropertiesOnlyMatrix(2, 2, [1, 0, 0, 1])
  326. assert m.is_diagonal()
  327. m = PropertiesOnlyMatrix(3, 3, diag(1, 2, 3))
  328. assert m.is_diagonal()
  329. assert m.is_symmetric()
  330. m = PropertiesOnlyMatrix(3, 3, [1, 0, 0, 0, 2, 0, 0, 0, 3])
  331. assert m == diag(1, 2, 3)
  332. m = PropertiesOnlyMatrix(2, 3, zeros(2, 3))
  333. assert not m.is_symmetric()
  334. assert m.is_diagonal()
  335. m = PropertiesOnlyMatrix(((5, 0), (0, 6), (0, 0)))
  336. assert m.is_diagonal()
  337. m = PropertiesOnlyMatrix(((5, 0, 0), (0, 6, 0)))
  338. assert m.is_diagonal()
  339. m = Matrix(3, 3, [1, x**2 + 2*x + 1, y, (x + 1)**2, 2, 0, y, 0, 3])
  340. assert m.is_symmetric()
  341. assert not m.is_symmetric(simplify=False)
  342. assert m.expand().is_symmetric(simplify=False)
  343. def test_is_hermitian():
  344. a = PropertiesOnlyMatrix([[1, I], [-I, 1]])
  345. assert a.is_hermitian
  346. a = PropertiesOnlyMatrix([[2*I, I], [-I, 1]])
  347. assert a.is_hermitian is False
  348. a = PropertiesOnlyMatrix([[x, I], [-I, 1]])
  349. assert a.is_hermitian is None
  350. a = PropertiesOnlyMatrix([[x, 1], [-I, 1]])
  351. assert a.is_hermitian is False
  352. def test_is_Identity():
  353. assert eye_Properties(3).is_Identity
  354. assert not PropertiesOnlyMatrix(zeros(3)).is_Identity
  355. assert not PropertiesOnlyMatrix(ones(3)).is_Identity
  356. # issue 6242
  357. assert not PropertiesOnlyMatrix([[1, 0, 0]]).is_Identity
  358. def test_is_symbolic():
  359. a = PropertiesOnlyMatrix([[x, x], [x, x]])
  360. assert a.is_symbolic() is True
  361. a = PropertiesOnlyMatrix([[1, 2, 3, 4], [5, 6, 7, 8]])
  362. assert a.is_symbolic() is False
  363. a = PropertiesOnlyMatrix([[1, 2, 3, 4], [5, 6, x, 8]])
  364. assert a.is_symbolic() is True
  365. a = PropertiesOnlyMatrix([[1, x, 3]])
  366. assert a.is_symbolic() is True
  367. a = PropertiesOnlyMatrix([[1, 2, 3]])
  368. assert a.is_symbolic() is False
  369. a = PropertiesOnlyMatrix([[1], [x], [3]])
  370. assert a.is_symbolic() is True
  371. a = PropertiesOnlyMatrix([[1], [2], [3]])
  372. assert a.is_symbolic() is False
  373. def test_is_upper():
  374. a = PropertiesOnlyMatrix([[1, 2, 3]])
  375. assert a.is_upper is True
  376. a = PropertiesOnlyMatrix([[1], [2], [3]])
  377. assert a.is_upper is False
  378. def test_is_lower():
  379. a = PropertiesOnlyMatrix([[1, 2, 3]])
  380. assert a.is_lower is False
  381. a = PropertiesOnlyMatrix([[1], [2], [3]])
  382. assert a.is_lower is True
  383. def test_is_square():
  384. m = PropertiesOnlyMatrix([[1], [1]])
  385. m2 = PropertiesOnlyMatrix([[2, 2], [2, 2]])
  386. assert not m.is_square
  387. assert m2.is_square
  388. def test_is_symmetric():
  389. m = PropertiesOnlyMatrix(2, 2, [0, 1, 1, 0])
  390. assert m.is_symmetric()
  391. m = PropertiesOnlyMatrix(2, 2, [0, 1, 0, 1])
  392. assert not m.is_symmetric()
  393. def test_is_hessenberg():
  394. A = PropertiesOnlyMatrix([[3, 4, 1], [2, 4, 5], [0, 1, 2]])
  395. assert A.is_upper_hessenberg
  396. A = PropertiesOnlyMatrix(3, 3, [3, 2, 0, 4, 4, 1, 1, 5, 2])
  397. assert A.is_lower_hessenberg
  398. A = PropertiesOnlyMatrix(3, 3, [3, 2, -1, 4, 4, 1, 1, 5, 2])
  399. assert A.is_lower_hessenberg is False
  400. assert A.is_upper_hessenberg is False
  401. A = PropertiesOnlyMatrix([[3, 4, 1], [2, 4, 5], [3, 1, 2]])
  402. assert not A.is_upper_hessenberg
  403. def test_is_zero():
  404. assert PropertiesOnlyMatrix(0, 0, []).is_zero_matrix
  405. assert PropertiesOnlyMatrix([[0, 0], [0, 0]]).is_zero_matrix
  406. assert PropertiesOnlyMatrix(zeros(3, 4)).is_zero_matrix
  407. assert not PropertiesOnlyMatrix(eye(3)).is_zero_matrix
  408. assert PropertiesOnlyMatrix([[x, 0], [0, 0]]).is_zero_matrix == None
  409. assert PropertiesOnlyMatrix([[x, 1], [0, 0]]).is_zero_matrix == False
  410. a = Symbol('a', nonzero=True)
  411. assert PropertiesOnlyMatrix([[a, 0], [0, 0]]).is_zero_matrix == False
  412. def test_values():
  413. assert set(PropertiesOnlyMatrix(2, 2, [0, 1, 2, 3]
  414. ).values()) == {1, 2, 3}
  415. x = Symbol('x', real=True)
  416. assert set(PropertiesOnlyMatrix(2, 2, [x, 0, 0, 1]
  417. ).values()) == {x, 1}
  418. # OperationsOnlyMatrix tests
  419. def test_applyfunc():
  420. m0 = OperationsOnlyMatrix(eye(3))
  421. assert m0.applyfunc(lambda x: 2*x) == eye(3)*2
  422. assert m0.applyfunc(lambda x: 0) == zeros(3)
  423. assert m0.applyfunc(lambda x: 1) == ones(3)
  424. def test_adjoint():
  425. dat = [[0, I], [1, 0]]
  426. ans = OperationsOnlyMatrix([[0, 1], [-I, 0]])
  427. assert ans.adjoint() == Matrix(dat)
  428. def test_as_real_imag():
  429. m1 = OperationsOnlyMatrix(2, 2, [1, 2, 3, 4])
  430. m3 = OperationsOnlyMatrix(2, 2,
  431. [1 + S.ImaginaryUnit, 2 + 2*S.ImaginaryUnit,
  432. 3 + 3*S.ImaginaryUnit, 4 + 4*S.ImaginaryUnit])
  433. a, b = m3.as_real_imag()
  434. assert a == m1
  435. assert b == m1
  436. def test_conjugate():
  437. M = OperationsOnlyMatrix([[0, I, 5],
  438. [1, 2, 0]])
  439. assert M.T == Matrix([[0, 1],
  440. [I, 2],
  441. [5, 0]])
  442. assert M.C == Matrix([[0, -I, 5],
  443. [1, 2, 0]])
  444. assert M.C == M.conjugate()
  445. assert M.H == M.T.C
  446. assert M.H == Matrix([[ 0, 1],
  447. [-I, 2],
  448. [ 5, 0]])
  449. def test_doit():
  450. a = OperationsOnlyMatrix([[Add(x, x, evaluate=False)]])
  451. assert a[0] != 2*x
  452. assert a.doit() == Matrix([[2*x]])
  453. def test_evalf():
  454. a = OperationsOnlyMatrix(2, 1, [sqrt(5), 6])
  455. assert all(a.evalf()[i] == a[i].evalf() for i in range(2))
  456. assert all(a.evalf(2)[i] == a[i].evalf(2) for i in range(2))
  457. assert all(a.n(2)[i] == a[i].n(2) for i in range(2))
  458. def test_expand():
  459. m0 = OperationsOnlyMatrix([[x*(x + y), 2], [((x + y)*y)*x, x*(y + x*(x + y))]])
  460. # Test if expand() returns a matrix
  461. m1 = m0.expand()
  462. assert m1 == Matrix(
  463. [[x*y + x**2, 2], [x*y**2 + y*x**2, x*y + y*x**2 + x**3]])
  464. a = Symbol('a', real=True)
  465. assert OperationsOnlyMatrix(1, 1, [exp(I*a)]).expand(complex=True) == \
  466. Matrix([cos(a) + I*sin(a)])
  467. def test_refine():
  468. m0 = OperationsOnlyMatrix([[Abs(x)**2, sqrt(x**2)],
  469. [sqrt(x**2)*Abs(y)**2, sqrt(y**2)*Abs(x)**2]])
  470. m1 = m0.refine(Q.real(x) & Q.real(y))
  471. assert m1 == Matrix([[x**2, Abs(x)], [y**2*Abs(x), x**2*Abs(y)]])
  472. m1 = m0.refine(Q.positive(x) & Q.positive(y))
  473. assert m1 == Matrix([[x**2, x], [x*y**2, x**2*y]])
  474. m1 = m0.refine(Q.negative(x) & Q.negative(y))
  475. assert m1 == Matrix([[x**2, -x], [-x*y**2, -x**2*y]])
  476. def test_replace():
  477. F, G = symbols('F, G', cls=Function)
  478. K = OperationsOnlyMatrix(2, 2, lambda i, j: G(i+j))
  479. M = OperationsOnlyMatrix(2, 2, lambda i, j: F(i+j))
  480. N = M.replace(F, G)
  481. assert N == K
  482. def test_replace_map():
  483. F, G = symbols('F, G', cls=Function)
  484. K = OperationsOnlyMatrix(2, 2, [(G(0), {F(0): G(0)}), (G(1), {F(1): G(1)}), (G(1), {F(1) \
  485. : G(1)}), (G(2), {F(2): G(2)})])
  486. M = OperationsOnlyMatrix(2, 2, lambda i, j: F(i+j))
  487. N = M.replace(F, G, True)
  488. assert N == K
  489. def test_rot90():
  490. A = Matrix([[1, 2], [3, 4]])
  491. assert A == A.rot90(0) == A.rot90(4)
  492. assert A.rot90(2) == A.rot90(-2) == A.rot90(6) == Matrix(((4, 3), (2, 1)))
  493. assert A.rot90(3) == A.rot90(-1) == A.rot90(7) == Matrix(((2, 4), (1, 3)))
  494. assert A.rot90() == A.rot90(-7) == A.rot90(-3) == Matrix(((3, 1), (4, 2)))
  495. def test_simplify():
  496. n = Symbol('n')
  497. f = Function('f')
  498. M = OperationsOnlyMatrix([[ 1/x + 1/y, (x + x*y) / x ],
  499. [ (f(x) + y*f(x))/f(x), 2 * (1/n - cos(n * pi)/n) / pi ]])
  500. assert M.simplify() == Matrix([[ (x + y)/(x * y), 1 + y ],
  501. [ 1 + y, 2*((1 - 1*cos(pi*n))/(pi*n)) ]])
  502. eq = (1 + x)**2
  503. M = OperationsOnlyMatrix([[eq]])
  504. assert M.simplify() == Matrix([[eq]])
  505. assert M.simplify(ratio=oo) == Matrix([[eq.simplify(ratio=oo)]])
  506. # https://github.com/sympy/sympy/issues/19353
  507. m = Matrix([[30, 2], [3, 4]])
  508. assert (1/(m.trace())).simplify() == Rational(1, 34)
  509. def test_subs():
  510. assert OperationsOnlyMatrix([[1, x], [x, 4]]).subs(x, 5) == Matrix([[1, 5], [5, 4]])
  511. assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs([[x, -1], [y, -2]]) == \
  512. Matrix([[-1, 2], [-3, 4]])
  513. assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs([(x, -1), (y, -2)]) == \
  514. Matrix([[-1, 2], [-3, 4]])
  515. assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs({x: -1, y: -2}) == \
  516. Matrix([[-1, 2], [-3, 4]])
  517. assert OperationsOnlyMatrix([[x*y]]).subs({x: y - 1, y: x - 1}, simultaneous=True) == \
  518. Matrix([[(x - 1)*(y - 1)]])
  519. def test_trace():
  520. M = OperationsOnlyMatrix([[1, 0, 0],
  521. [0, 5, 0],
  522. [0, 0, 8]])
  523. assert M.trace() == 14
  524. def test_xreplace():
  525. assert OperationsOnlyMatrix([[1, x], [x, 4]]).xreplace({x: 5}) == \
  526. Matrix([[1, 5], [5, 4]])
  527. assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).xreplace({x: -1, y: -2}) == \
  528. Matrix([[-1, 2], [-3, 4]])
  529. def test_permute():
  530. a = OperationsOnlyMatrix(3, 4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
  531. raises(IndexError, lambda: a.permute([[0, 5]]))
  532. raises(ValueError, lambda: a.permute(Symbol('x')))
  533. b = a.permute_rows([[0, 2], [0, 1]])
  534. assert a.permute([[0, 2], [0, 1]]) == b == Matrix([
  535. [5, 6, 7, 8],
  536. [9, 10, 11, 12],
  537. [1, 2, 3, 4]])
  538. b = a.permute_cols([[0, 2], [0, 1]])
  539. assert a.permute([[0, 2], [0, 1]], orientation='cols') == b ==\
  540. Matrix([
  541. [ 2, 3, 1, 4],
  542. [ 6, 7, 5, 8],
  543. [10, 11, 9, 12]])
  544. b = a.permute_cols([[0, 2], [0, 1]], direction='backward')
  545. assert a.permute([[0, 2], [0, 1]], orientation='cols', direction='backward') == b ==\
  546. Matrix([
  547. [ 3, 1, 2, 4],
  548. [ 7, 5, 6, 8],
  549. [11, 9, 10, 12]])
  550. assert a.permute([1, 2, 0, 3]) == Matrix([
  551. [5, 6, 7, 8],
  552. [9, 10, 11, 12],
  553. [1, 2, 3, 4]])
  554. from sympy.combinatorics import Permutation
  555. assert a.permute(Permutation([1, 2, 0, 3])) == Matrix([
  556. [5, 6, 7, 8],
  557. [9, 10, 11, 12],
  558. [1, 2, 3, 4]])
  559. def test_upper_triangular():
  560. A = OperationsOnlyMatrix([
  561. [1, 1, 1, 1],
  562. [1, 1, 1, 1],
  563. [1, 1, 1, 1],
  564. [1, 1, 1, 1]
  565. ])
  566. R = A.upper_triangular(2)
  567. assert R == OperationsOnlyMatrix([
  568. [0, 0, 1, 1],
  569. [0, 0, 0, 1],
  570. [0, 0, 0, 0],
  571. [0, 0, 0, 0]
  572. ])
  573. R = A.upper_triangular(-2)
  574. assert R == OperationsOnlyMatrix([
  575. [1, 1, 1, 1],
  576. [1, 1, 1, 1],
  577. [1, 1, 1, 1],
  578. [0, 1, 1, 1]
  579. ])
  580. R = A.upper_triangular()
  581. assert R == OperationsOnlyMatrix([
  582. [1, 1, 1, 1],
  583. [0, 1, 1, 1],
  584. [0, 0, 1, 1],
  585. [0, 0, 0, 1]
  586. ])
  587. def test_lower_triangular():
  588. A = OperationsOnlyMatrix([
  589. [1, 1, 1, 1],
  590. [1, 1, 1, 1],
  591. [1, 1, 1, 1],
  592. [1, 1, 1, 1]
  593. ])
  594. L = A.lower_triangular()
  595. assert L == ArithmeticOnlyMatrix([
  596. [1, 0, 0, 0],
  597. [1, 1, 0, 0],
  598. [1, 1, 1, 0],
  599. [1, 1, 1, 1]])
  600. L = A.lower_triangular(2)
  601. assert L == ArithmeticOnlyMatrix([
  602. [1, 1, 1, 0],
  603. [1, 1, 1, 1],
  604. [1, 1, 1, 1],
  605. [1, 1, 1, 1]
  606. ])
  607. L = A.lower_triangular(-2)
  608. assert L == ArithmeticOnlyMatrix([
  609. [0, 0, 0, 0],
  610. [0, 0, 0, 0],
  611. [1, 0, 0, 0],
  612. [1, 1, 0, 0]
  613. ])
  614. # ArithmeticOnlyMatrix tests
  615. def test_abs():
  616. m = ArithmeticOnlyMatrix([[1, -2], [x, y]])
  617. assert abs(m) == ArithmeticOnlyMatrix([[1, 2], [Abs(x), Abs(y)]])
  618. def test_add():
  619. m = ArithmeticOnlyMatrix([[1, 2, 3], [x, y, x], [2*y, -50, z*x]])
  620. assert m + m == ArithmeticOnlyMatrix([[2, 4, 6], [2*x, 2*y, 2*x], [4*y, -100, 2*z*x]])
  621. n = ArithmeticOnlyMatrix(1, 2, [1, 2])
  622. raises(ShapeError, lambda: m + n)
  623. def test_multiplication():
  624. a = ArithmeticOnlyMatrix((
  625. (1, 2),
  626. (3, 1),
  627. (0, 6),
  628. ))
  629. b = ArithmeticOnlyMatrix((
  630. (1, 2),
  631. (3, 0),
  632. ))
  633. raises(ShapeError, lambda: b*a)
  634. raises(TypeError, lambda: a*{})
  635. c = a*b
  636. assert c[0, 0] == 7
  637. assert c[0, 1] == 2
  638. assert c[1, 0] == 6
  639. assert c[1, 1] == 6
  640. assert c[2, 0] == 18
  641. assert c[2, 1] == 0
  642. try:
  643. eval('c = a @ b')
  644. except SyntaxError:
  645. pass
  646. else:
  647. assert c[0, 0] == 7
  648. assert c[0, 1] == 2
  649. assert c[1, 0] == 6
  650. assert c[1, 1] == 6
  651. assert c[2, 0] == 18
  652. assert c[2, 1] == 0
  653. h = a.multiply_elementwise(c)
  654. assert h == matrix_multiply_elementwise(a, c)
  655. assert h[0, 0] == 7
  656. assert h[0, 1] == 4
  657. assert h[1, 0] == 18
  658. assert h[1, 1] == 6
  659. assert h[2, 0] == 0
  660. assert h[2, 1] == 0
  661. raises(ShapeError, lambda: a.multiply_elementwise(b))
  662. c = b * Symbol("x")
  663. assert isinstance(c, ArithmeticOnlyMatrix)
  664. assert c[0, 0] == x
  665. assert c[0, 1] == 2*x
  666. assert c[1, 0] == 3*x
  667. assert c[1, 1] == 0
  668. c2 = x * b
  669. assert c == c2
  670. c = 5 * b
  671. assert isinstance(c, ArithmeticOnlyMatrix)
  672. assert c[0, 0] == 5
  673. assert c[0, 1] == 2*5
  674. assert c[1, 0] == 3*5
  675. assert c[1, 1] == 0
  676. try:
  677. eval('c = 5 @ b')
  678. except SyntaxError:
  679. pass
  680. else:
  681. assert isinstance(c, ArithmeticOnlyMatrix)
  682. assert c[0, 0] == 5
  683. assert c[0, 1] == 2*5
  684. assert c[1, 0] == 3*5
  685. assert c[1, 1] == 0
  686. # https://github.com/sympy/sympy/issues/22353
  687. A = Matrix(ones(3, 1))
  688. _h = -Rational(1, 2)
  689. B = Matrix([_h, _h, _h])
  690. assert A.multiply_elementwise(B) == Matrix([
  691. [_h],
  692. [_h],
  693. [_h]])
  694. def test_matmul():
  695. a = Matrix([[1, 2], [3, 4]])
  696. assert a.__matmul__(2) == NotImplemented
  697. assert a.__rmatmul__(2) == NotImplemented
  698. #This is done this way because @ is only supported in Python 3.5+
  699. #To check 2@a case
  700. try:
  701. eval('2 @ a')
  702. except SyntaxError:
  703. pass
  704. except TypeError: #TypeError is raised in case of NotImplemented is returned
  705. pass
  706. #Check a@2 case
  707. try:
  708. eval('a @ 2')
  709. except SyntaxError:
  710. pass
  711. except TypeError: #TypeError is raised in case of NotImplemented is returned
  712. pass
  713. def test_non_matmul():
  714. """
  715. Test that if explicitly specified as non-matrix, mul reverts
  716. to scalar multiplication.
  717. """
  718. class foo(Expr):
  719. is_Matrix=False
  720. is_MatrixLike=False
  721. shape = (1, 1)
  722. A = Matrix([[1, 2], [3, 4]])
  723. b = foo()
  724. assert b*A == Matrix([[b, 2*b], [3*b, 4*b]])
  725. assert A*b == Matrix([[b, 2*b], [3*b, 4*b]])
  726. def test_power():
  727. raises(NonSquareMatrixError, lambda: Matrix((1, 2))**2)
  728. A = ArithmeticOnlyMatrix([[2, 3], [4, 5]])
  729. assert (A**5)[:] == (6140, 8097, 10796, 14237)
  730. A = ArithmeticOnlyMatrix([[2, 1, 3], [4, 2, 4], [6, 12, 1]])
  731. assert (A**3)[:] == (290, 262, 251, 448, 440, 368, 702, 954, 433)
  732. assert A**0 == eye(3)
  733. assert A**1 == A
  734. assert (ArithmeticOnlyMatrix([[2]]) ** 100)[0, 0] == 2**100
  735. assert ArithmeticOnlyMatrix([[1, 2], [3, 4]])**Integer(2) == ArithmeticOnlyMatrix([[7, 10], [15, 22]])
  736. A = Matrix([[1,2],[4,5]])
  737. assert A.pow(20, method='cayley') == A.pow(20, method='multiply')
  738. def test_neg():
  739. n = ArithmeticOnlyMatrix(1, 2, [1, 2])
  740. assert -n == ArithmeticOnlyMatrix(1, 2, [-1, -2])
  741. def test_sub():
  742. n = ArithmeticOnlyMatrix(1, 2, [1, 2])
  743. assert n - n == ArithmeticOnlyMatrix(1, 2, [0, 0])
  744. def test_div():
  745. n = ArithmeticOnlyMatrix(1, 2, [1, 2])
  746. assert n/2 == ArithmeticOnlyMatrix(1, 2, [S.Half, S(2)/2])
  747. # SpecialOnlyMatrix tests
  748. def test_eye():
  749. assert list(SpecialOnlyMatrix.eye(2, 2)) == [1, 0, 0, 1]
  750. assert list(SpecialOnlyMatrix.eye(2)) == [1, 0, 0, 1]
  751. assert type(SpecialOnlyMatrix.eye(2)) == SpecialOnlyMatrix
  752. assert type(SpecialOnlyMatrix.eye(2, cls=Matrix)) == Matrix
  753. def test_ones():
  754. assert list(SpecialOnlyMatrix.ones(2, 2)) == [1, 1, 1, 1]
  755. assert list(SpecialOnlyMatrix.ones(2)) == [1, 1, 1, 1]
  756. assert SpecialOnlyMatrix.ones(2, 3) == Matrix([[1, 1, 1], [1, 1, 1]])
  757. assert type(SpecialOnlyMatrix.ones(2)) == SpecialOnlyMatrix
  758. assert type(SpecialOnlyMatrix.ones(2, cls=Matrix)) == Matrix
  759. def test_zeros():
  760. assert list(SpecialOnlyMatrix.zeros(2, 2)) == [0, 0, 0, 0]
  761. assert list(SpecialOnlyMatrix.zeros(2)) == [0, 0, 0, 0]
  762. assert SpecialOnlyMatrix.zeros(2, 3) == Matrix([[0, 0, 0], [0, 0, 0]])
  763. assert type(SpecialOnlyMatrix.zeros(2)) == SpecialOnlyMatrix
  764. assert type(SpecialOnlyMatrix.zeros(2, cls=Matrix)) == Matrix
  765. def test_diag_make():
  766. diag = SpecialOnlyMatrix.diag
  767. a = Matrix([[1, 2], [2, 3]])
  768. b = Matrix([[3, x], [y, 3]])
  769. c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
  770. assert diag(a, b, b) == Matrix([
  771. [1, 2, 0, 0, 0, 0],
  772. [2, 3, 0, 0, 0, 0],
  773. [0, 0, 3, x, 0, 0],
  774. [0, 0, y, 3, 0, 0],
  775. [0, 0, 0, 0, 3, x],
  776. [0, 0, 0, 0, y, 3],
  777. ])
  778. assert diag(a, b, c) == Matrix([
  779. [1, 2, 0, 0, 0, 0, 0],
  780. [2, 3, 0, 0, 0, 0, 0],
  781. [0, 0, 3, x, 0, 0, 0],
  782. [0, 0, y, 3, 0, 0, 0],
  783. [0, 0, 0, 0, 3, x, 3],
  784. [0, 0, 0, 0, y, 3, z],
  785. [0, 0, 0, 0, x, y, z],
  786. ])
  787. assert diag(a, c, b) == Matrix([
  788. [1, 2, 0, 0, 0, 0, 0],
  789. [2, 3, 0, 0, 0, 0, 0],
  790. [0, 0, 3, x, 3, 0, 0],
  791. [0, 0, y, 3, z, 0, 0],
  792. [0, 0, x, y, z, 0, 0],
  793. [0, 0, 0, 0, 0, 3, x],
  794. [0, 0, 0, 0, 0, y, 3],
  795. ])
  796. a = Matrix([x, y, z])
  797. b = Matrix([[1, 2], [3, 4]])
  798. c = Matrix([[5, 6]])
  799. # this "wandering diagonal" is what makes this
  800. # a block diagonal where each block is independent
  801. # of the others
  802. assert diag(a, 7, b, c) == Matrix([
  803. [x, 0, 0, 0, 0, 0],
  804. [y, 0, 0, 0, 0, 0],
  805. [z, 0, 0, 0, 0, 0],
  806. [0, 7, 0, 0, 0, 0],
  807. [0, 0, 1, 2, 0, 0],
  808. [0, 0, 3, 4, 0, 0],
  809. [0, 0, 0, 0, 5, 6]])
  810. raises(ValueError, lambda: diag(a, 7, b, c, rows=5))
  811. assert diag(1) == Matrix([[1]])
  812. assert diag(1, rows=2) == Matrix([[1, 0], [0, 0]])
  813. assert diag(1, cols=2) == Matrix([[1, 0], [0, 0]])
  814. assert diag(1, rows=3, cols=2) == Matrix([[1, 0], [0, 0], [0, 0]])
  815. assert diag(*[2, 3]) == Matrix([
  816. [2, 0],
  817. [0, 3]])
  818. assert diag(Matrix([2, 3])) == Matrix([
  819. [2],
  820. [3]])
  821. assert diag([1, [2, 3], 4], unpack=False) == \
  822. diag([[1], [2, 3], [4]], unpack=False) == Matrix([
  823. [1, 0],
  824. [2, 3],
  825. [4, 0]])
  826. assert type(diag(1)) == SpecialOnlyMatrix
  827. assert type(diag(1, cls=Matrix)) == Matrix
  828. assert Matrix.diag([1, 2, 3]) == Matrix.diag(1, 2, 3)
  829. assert Matrix.diag([1, 2, 3], unpack=False).shape == (3, 1)
  830. assert Matrix.diag([[1, 2, 3]]).shape == (3, 1)
  831. assert Matrix.diag([[1, 2, 3]], unpack=False).shape == (1, 3)
  832. assert Matrix.diag([[[1, 2, 3]]]).shape == (1, 3)
  833. # kerning can be used to move the starting point
  834. assert Matrix.diag(ones(0, 2), 1, 2) == Matrix([
  835. [0, 0, 1, 0],
  836. [0, 0, 0, 2]])
  837. assert Matrix.diag(ones(2, 0), 1, 2) == Matrix([
  838. [0, 0],
  839. [0, 0],
  840. [1, 0],
  841. [0, 2]])
  842. def test_diagonal():
  843. m = Matrix(3, 3, range(9))
  844. d = m.diagonal()
  845. assert d == m.diagonal(0)
  846. assert tuple(d) == (0, 4, 8)
  847. assert tuple(m.diagonal(1)) == (1, 5)
  848. assert tuple(m.diagonal(-1)) == (3, 7)
  849. assert tuple(m.diagonal(2)) == (2,)
  850. assert type(m.diagonal()) == type(m)
  851. s = SparseMatrix(3, 3, {(1, 1): 1})
  852. assert type(s.diagonal()) == type(s)
  853. assert type(m) != type(s)
  854. raises(ValueError, lambda: m.diagonal(3))
  855. raises(ValueError, lambda: m.diagonal(-3))
  856. raises(ValueError, lambda: m.diagonal(pi))
  857. M = ones(2, 3)
  858. assert banded({i: list(M.diagonal(i))
  859. for i in range(1-M.rows, M.cols)}) == M
  860. def test_jordan_block():
  861. assert SpecialOnlyMatrix.jordan_block(3, 2) == SpecialOnlyMatrix.jordan_block(3, eigenvalue=2) \
  862. == SpecialOnlyMatrix.jordan_block(size=3, eigenvalue=2) \
  863. == SpecialOnlyMatrix.jordan_block(3, 2, band='upper') \
  864. == SpecialOnlyMatrix.jordan_block(
  865. size=3, eigenval=2, eigenvalue=2) \
  866. == Matrix([
  867. [2, 1, 0],
  868. [0, 2, 1],
  869. [0, 0, 2]])
  870. assert SpecialOnlyMatrix.jordan_block(3, 2, band='lower') == Matrix([
  871. [2, 0, 0],
  872. [1, 2, 0],
  873. [0, 1, 2]])
  874. # missing eigenvalue
  875. raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(2))
  876. # non-integral size
  877. raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(3.5, 2))
  878. # size not specified
  879. raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(eigenvalue=2))
  880. # inconsistent eigenvalue
  881. raises(ValueError,
  882. lambda: SpecialOnlyMatrix.jordan_block(
  883. eigenvalue=2, eigenval=4))
  884. # Using alias keyword
  885. assert SpecialOnlyMatrix.jordan_block(size=3, eigenvalue=2) == \
  886. SpecialOnlyMatrix.jordan_block(size=3, eigenval=2)
  887. def test_orthogonalize():
  888. m = Matrix([[1, 2], [3, 4]])
  889. assert m.orthogonalize(Matrix([[2], [1]])) == [Matrix([[2], [1]])]
  890. assert m.orthogonalize(Matrix([[2], [1]]), normalize=True) == \
  891. [Matrix([[2*sqrt(5)/5], [sqrt(5)/5]])]
  892. assert m.orthogonalize(Matrix([[1], [2]]), Matrix([[-1], [4]])) == \
  893. [Matrix([[1], [2]]), Matrix([[Rational(-12, 5)], [Rational(6, 5)]])]
  894. assert m.orthogonalize(Matrix([[0], [0]]), Matrix([[-1], [4]])) == \
  895. [Matrix([[-1], [4]])]
  896. assert m.orthogonalize(Matrix([[0], [0]])) == []
  897. n = Matrix([[9, 1, 9], [3, 6, 10], [8, 5, 2]])
  898. vecs = [Matrix([[-5], [1]]), Matrix([[-5], [2]]), Matrix([[-5], [-2]])]
  899. assert n.orthogonalize(*vecs) == \
  900. [Matrix([[-5], [1]]), Matrix([[Rational(5, 26)], [Rational(25, 26)]])]
  901. vecs = [Matrix([0, 0, 0]), Matrix([1, 2, 3]), Matrix([1, 4, 5])]
  902. raises(ValueError, lambda: Matrix.orthogonalize(*vecs, rankcheck=True))
  903. vecs = [Matrix([1, 2, 3]), Matrix([4, 5, 6]), Matrix([7, 8, 9])]
  904. raises(ValueError, lambda: Matrix.orthogonalize(*vecs, rankcheck=True))
  905. def test_wilkinson():
  906. wminus, wplus = Matrix.wilkinson(1)
  907. assert wminus == Matrix([
  908. [-1, 1, 0],
  909. [1, 0, 1],
  910. [0, 1, 1]])
  911. assert wplus == Matrix([
  912. [1, 1, 0],
  913. [1, 0, 1],
  914. [0, 1, 1]])
  915. wminus, wplus = Matrix.wilkinson(3)
  916. assert wminus == Matrix([
  917. [-3, 1, 0, 0, 0, 0, 0],
  918. [1, -2, 1, 0, 0, 0, 0],
  919. [0, 1, -1, 1, 0, 0, 0],
  920. [0, 0, 1, 0, 1, 0, 0],
  921. [0, 0, 0, 1, 1, 1, 0],
  922. [0, 0, 0, 0, 1, 2, 1],
  923. [0, 0, 0, 0, 0, 1, 3]])
  924. assert wplus == Matrix([
  925. [3, 1, 0, 0, 0, 0, 0],
  926. [1, 2, 1, 0, 0, 0, 0],
  927. [0, 1, 1, 1, 0, 0, 0],
  928. [0, 0, 1, 0, 1, 0, 0],
  929. [0, 0, 0, 1, 1, 1, 0],
  930. [0, 0, 0, 0, 1, 2, 1],
  931. [0, 0, 0, 0, 0, 1, 3]])
  932. # CalculusOnlyMatrix tests
  933. @XFAIL
  934. def test_diff():
  935. x, y = symbols('x y')
  936. m = CalculusOnlyMatrix(2, 1, [x, y])
  937. # TODO: currently not working as ``_MinimalMatrix`` cannot be sympified:
  938. assert m.diff(x) == Matrix(2, 1, [1, 0])
  939. def test_integrate():
  940. x, y = symbols('x y')
  941. m = CalculusOnlyMatrix(2, 1, [x, y])
  942. assert m.integrate(x) == Matrix(2, 1, [x**2/2, y*x])
  943. def test_jacobian2():
  944. rho, phi = symbols("rho,phi")
  945. X = CalculusOnlyMatrix(3, 1, [rho*cos(phi), rho*sin(phi), rho**2])
  946. Y = CalculusOnlyMatrix(2, 1, [rho, phi])
  947. J = Matrix([
  948. [cos(phi), -rho*sin(phi)],
  949. [sin(phi), rho*cos(phi)],
  950. [ 2*rho, 0],
  951. ])
  952. assert X.jacobian(Y) == J
  953. m = CalculusOnlyMatrix(2, 2, [1, 2, 3, 4])
  954. m2 = CalculusOnlyMatrix(4, 1, [1, 2, 3, 4])
  955. raises(TypeError, lambda: m.jacobian(Matrix([1, 2])))
  956. raises(TypeError, lambda: m2.jacobian(m))
  957. def test_limit():
  958. x, y = symbols('x y')
  959. m = CalculusOnlyMatrix(2, 1, [1/x, y])
  960. assert m.limit(x, 5) == Matrix(2, 1, [Rational(1, 5), y])
  961. def test_issue_13774():
  962. M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  963. v = [1, 1, 1]
  964. raises(TypeError, lambda: M*v)
  965. raises(TypeError, lambda: v*M)
  966. def test_companion():
  967. x = Symbol('x')
  968. y = Symbol('y')
  969. raises(ValueError, lambda: Matrix.companion(1))
  970. raises(ValueError, lambda: Matrix.companion(Poly([1], x)))
  971. raises(ValueError, lambda: Matrix.companion(Poly([2, 1], x)))
  972. raises(ValueError, lambda: Matrix.companion(Poly(x*y, [x, y])))
  973. c0, c1, c2 = symbols('c0:3')
  974. assert Matrix.companion(Poly([1, c0], x)) == Matrix([-c0])
  975. assert Matrix.companion(Poly([1, c1, c0], x)) == \
  976. Matrix([[0, -c0], [1, -c1]])
  977. assert Matrix.companion(Poly([1, c2, c1, c0], x)) == \
  978. Matrix([[0, 0, -c0], [1, 0, -c1], [0, 1, -c2]])
  979. def test_issue_10589():
  980. x, y, z = symbols("x, y z")
  981. M1 = Matrix([x, y, z])
  982. M1 = M1.subs(zip([x, y, z], [1, 2, 3]))
  983. assert M1 == Matrix([[1], [2], [3]])
  984. M2 = Matrix([[x, x, x, x, x], [x, x, x, x, x], [x, x, x, x, x]])
  985. M2 = M2.subs(zip([x], [1]))
  986. assert M2 == Matrix([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]])
  987. def test_rmul_pr19860():
  988. class Foo(ImmutableDenseMatrix):
  989. _op_priority = MutableDenseMatrix._op_priority + 0.01
  990. a = Matrix(2, 2, [1, 2, 3, 4])
  991. b = Foo(2, 2, [1, 2, 3, 4])
  992. # This would throw a RecursionError: maximum recursion depth
  993. # since b always has higher priority even after a.as_mutable()
  994. c = a*b
  995. assert isinstance(c, Foo)
  996. assert c == Matrix([[7, 10], [15, 22]])
  997. def test_issue_18956():
  998. A = Array([[1, 2], [3, 4]])
  999. B = Matrix([[1,2],[3,4]])
  1000. raises(TypeError, lambda: B + A)
  1001. raises(TypeError, lambda: A + B)
  1002. def test__eq__():
  1003. class My(object):
  1004. def __iter__(self):
  1005. yield 1
  1006. yield 2
  1007. return
  1008. def __getitem__(self, i):
  1009. return list(self)[i]
  1010. a = Matrix(2, 1, [1, 2])
  1011. assert a != My()
  1012. class My_sympy(My):
  1013. def _sympy_(self):
  1014. return Matrix(self)
  1015. assert a == My_sympy()