test_eigen.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. from sympy.core.evalf import N
  2. from sympy.core.numbers import (Float, I, Rational)
  3. from sympy.core.symbol import (Symbol, symbols)
  4. from sympy.functions.elementary.complexes import Abs
  5. from sympy.functions.elementary.exponential import exp
  6. from sympy.functions.elementary.miscellaneous import sqrt
  7. from sympy.functions.elementary.trigonometric import (cos, sin)
  8. from sympy.matrices import eye, Matrix
  9. from sympy.core.singleton import S
  10. from sympy.testing.pytest import raises, XFAIL
  11. from sympy.matrices.matrices import NonSquareMatrixError, MatrixError
  12. from sympy.matrices.expressions.fourier import DFT
  13. from sympy.simplify.simplify import simplify
  14. from sympy.matrices.immutable import ImmutableMatrix
  15. from sympy.testing.pytest import slow
  16. from sympy.testing.matrices import allclose
  17. def test_eigen():
  18. R = Rational
  19. M = Matrix.eye(3)
  20. assert M.eigenvals(multiple=False) == {S.One: 3}
  21. assert M.eigenvals(multiple=True) == [1, 1, 1]
  22. assert M.eigenvects() == (
  23. [(1, 3, [Matrix([1, 0, 0]),
  24. Matrix([0, 1, 0]),
  25. Matrix([0, 0, 1])])])
  26. assert M.left_eigenvects() == (
  27. [(1, 3, [Matrix([[1, 0, 0]]),
  28. Matrix([[0, 1, 0]]),
  29. Matrix([[0, 0, 1]])])])
  30. M = Matrix([[0, 1, 1],
  31. [1, 0, 0],
  32. [1, 1, 1]])
  33. assert M.eigenvals() == {2*S.One: 1, -S.One: 1, S.Zero: 1}
  34. assert M.eigenvects() == (
  35. [
  36. (-1, 1, [Matrix([-1, 1, 0])]),
  37. ( 0, 1, [Matrix([0, -1, 1])]),
  38. ( 2, 1, [Matrix([R(2, 3), R(1, 3), 1])])
  39. ])
  40. assert M.left_eigenvects() == (
  41. [
  42. (-1, 1, [Matrix([[-2, 1, 1]])]),
  43. (0, 1, [Matrix([[-1, -1, 1]])]),
  44. (2, 1, [Matrix([[1, 1, 1]])])
  45. ])
  46. a = Symbol('a')
  47. M = Matrix([[a, 0],
  48. [0, 1]])
  49. assert M.eigenvals() == {a: 1, S.One: 1}
  50. M = Matrix([[1, -1],
  51. [1, 3]])
  52. assert M.eigenvects() == ([(2, 2, [Matrix(2, 1, [-1, 1])])])
  53. assert M.left_eigenvects() == ([(2, 2, [Matrix([[1, 1]])])])
  54. M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  55. a = R(15, 2)
  56. b = 3*33**R(1, 2)
  57. c = R(13, 2)
  58. d = (R(33, 8) + 3*b/8)
  59. e = (R(33, 8) - 3*b/8)
  60. def NS(e, n):
  61. return str(N(e, n))
  62. r = [
  63. (a - b/2, 1, [Matrix([(12 + 24/(c - b/2))/((c - b/2)*e) + 3/(c - b/2),
  64. (6 + 12/(c - b/2))/e, 1])]),
  65. ( 0, 1, [Matrix([1, -2, 1])]),
  66. (a + b/2, 1, [Matrix([(12 + 24/(c + b/2))/((c + b/2)*d) + 3/(c + b/2),
  67. (6 + 12/(c + b/2))/d, 1])]),
  68. ]
  69. r1 = [(NS(r[i][0], 2), NS(r[i][1], 2),
  70. [NS(j, 2) for j in r[i][2][0]]) for i in range(len(r))]
  71. r = M.eigenvects()
  72. r2 = [(NS(r[i][0], 2), NS(r[i][1], 2),
  73. [NS(j, 2) for j in r[i][2][0]]) for i in range(len(r))]
  74. assert sorted(r1) == sorted(r2)
  75. eps = Symbol('eps', real=True)
  76. M = Matrix([[abs(eps), I*eps ],
  77. [-I*eps, abs(eps) ]])
  78. assert M.eigenvects() == (
  79. [
  80. ( 0, 1, [Matrix([[-I*eps/abs(eps)], [1]])]),
  81. ( 2*abs(eps), 1, [ Matrix([[I*eps/abs(eps)], [1]]) ] ),
  82. ])
  83. assert M.left_eigenvects() == (
  84. [
  85. (0, 1, [Matrix([[I*eps/Abs(eps), 1]])]),
  86. (2*Abs(eps), 1, [Matrix([[-I*eps/Abs(eps), 1]])])
  87. ])
  88. M = Matrix(3, 3, [1, 2, 0, 0, 3, 0, 2, -4, 2])
  89. M._eigenvects = M.eigenvects(simplify=False)
  90. assert max(i.q for i in M._eigenvects[0][2][0]) > 1
  91. M._eigenvects = M.eigenvects(simplify=True)
  92. assert max(i.q for i in M._eigenvects[0][2][0]) == 1
  93. M = Matrix([[Rational(1, 4), 1], [1, 1]])
  94. assert M.eigenvects() == [
  95. (Rational(5, 8) - sqrt(73)/8, 1, [Matrix([[-sqrt(73)/8 - Rational(3, 8)], [1]])]),
  96. (Rational(5, 8) + sqrt(73)/8, 1, [Matrix([[Rational(-3, 8) + sqrt(73)/8], [1]])])]
  97. # issue 10719
  98. assert Matrix([]).eigenvals() == {}
  99. assert Matrix([]).eigenvals(multiple=True) == []
  100. assert Matrix([]).eigenvects() == []
  101. # issue 15119
  102. raises(NonSquareMatrixError,
  103. lambda: Matrix([[1, 2], [0, 4], [0, 0]]).eigenvals())
  104. raises(NonSquareMatrixError,
  105. lambda: Matrix([[1, 0], [3, 4], [5, 6]]).eigenvals())
  106. raises(NonSquareMatrixError,
  107. lambda: Matrix([[1, 2, 3], [0, 5, 6]]).eigenvals())
  108. raises(NonSquareMatrixError,
  109. lambda: Matrix([[1, 0, 0], [4, 5, 0]]).eigenvals())
  110. raises(NonSquareMatrixError,
  111. lambda: Matrix([[1, 2, 3], [0, 5, 6]]).eigenvals(
  112. error_when_incomplete = False))
  113. raises(NonSquareMatrixError,
  114. lambda: Matrix([[1, 0, 0], [4, 5, 0]]).eigenvals(
  115. error_when_incomplete = False))
  116. m = Matrix([[1, 2], [3, 4]])
  117. assert isinstance(m.eigenvals(simplify=True, multiple=False), dict)
  118. assert isinstance(m.eigenvals(simplify=True, multiple=True), list)
  119. assert isinstance(m.eigenvals(simplify=lambda x: x, multiple=False), dict)
  120. assert isinstance(m.eigenvals(simplify=lambda x: x, multiple=True), list)
  121. @slow
  122. def test_eigen_slow():
  123. # issue 15125
  124. from sympy.core.function import count_ops
  125. q = Symbol("q", positive = True)
  126. m = Matrix([[-2, exp(-q), 1], [exp(q), -2, 1], [1, 1, -2]])
  127. assert count_ops(m.eigenvals(simplify=False)) > \
  128. count_ops(m.eigenvals(simplify=True))
  129. assert count_ops(m.eigenvals(simplify=lambda x: x)) > \
  130. count_ops(m.eigenvals(simplify=True))
  131. def test_float_eigenvals():
  132. m = Matrix([[1, .6, .6], [.6, .9, .9], [.9, .6, .6]])
  133. evals = [
  134. Rational(5, 4) - sqrt(385)/20,
  135. sqrt(385)/20 + Rational(5, 4),
  136. S.Zero]
  137. n_evals = m.eigenvals(rational=True, multiple=True)
  138. n_evals = sorted(n_evals)
  139. s_evals = [x.evalf() for x in evals]
  140. s_evals = sorted(s_evals)
  141. for x, y in zip(n_evals, s_evals):
  142. assert abs(x-y) < 10**-9
  143. @XFAIL
  144. def test_eigen_vects():
  145. m = Matrix(2, 2, [1, 0, 0, I])
  146. raises(NotImplementedError, lambda: m.is_diagonalizable(True))
  147. # !!! bug because of eigenvects() or roots(x**2 + (-1 - I)*x + I, x)
  148. # see issue 5292
  149. assert not m.is_diagonalizable(True)
  150. raises(MatrixError, lambda: m.diagonalize(True))
  151. (P, D) = m.diagonalize(True)
  152. def test_issue_8240():
  153. # Eigenvalues of large triangular matrices
  154. x, y = symbols('x y')
  155. n = 200
  156. diagonal_variables = [Symbol('x%s' % i) for i in range(n)]
  157. M = [[0 for i in range(n)] for j in range(n)]
  158. for i in range(n):
  159. M[i][i] = diagonal_variables[i]
  160. M = Matrix(M)
  161. eigenvals = M.eigenvals()
  162. assert len(eigenvals) == n
  163. for i in range(n):
  164. assert eigenvals[diagonal_variables[i]] == 1
  165. eigenvals = M.eigenvals(multiple=True)
  166. assert set(eigenvals) == set(diagonal_variables)
  167. # with multiplicity
  168. M = Matrix([[x, 0, 0], [1, y, 0], [2, 3, x]])
  169. eigenvals = M.eigenvals()
  170. assert eigenvals == {x: 2, y: 1}
  171. eigenvals = M.eigenvals(multiple=True)
  172. assert len(eigenvals) == 3
  173. assert eigenvals.count(x) == 2
  174. assert eigenvals.count(y) == 1
  175. def test_eigenvals():
  176. M = Matrix([[0, 1, 1],
  177. [1, 0, 0],
  178. [1, 1, 1]])
  179. assert M.eigenvals() == {2*S.One: 1, -S.One: 1, S.Zero: 1}
  180. m = Matrix([
  181. [3, 0, 0, 0, -3],
  182. [0, -3, -3, 0, 3],
  183. [0, 3, 0, 3, 0],
  184. [0, 0, 3, 0, 3],
  185. [3, 0, 0, 3, 0]])
  186. # XXX Used dry-run test because arbitrary symbol that appears in
  187. # CRootOf may not be unique.
  188. assert m.eigenvals()
  189. def test_eigenvects():
  190. M = Matrix([[0, 1, 1],
  191. [1, 0, 0],
  192. [1, 1, 1]])
  193. vecs = M.eigenvects()
  194. for val, mult, vec_list in vecs:
  195. assert len(vec_list) == 1
  196. assert M*vec_list[0] == val*vec_list[0]
  197. def test_left_eigenvects():
  198. M = Matrix([[0, 1, 1],
  199. [1, 0, 0],
  200. [1, 1, 1]])
  201. vecs = M.left_eigenvects()
  202. for val, mult, vec_list in vecs:
  203. assert len(vec_list) == 1
  204. assert vec_list[0]*M == val*vec_list[0]
  205. @slow
  206. def test_bidiagonalize():
  207. M = Matrix([[1, 0, 0],
  208. [0, 1, 0],
  209. [0, 0, 1]])
  210. assert M.bidiagonalize() == M
  211. assert M.bidiagonalize(upper=False) == M
  212. assert M.bidiagonalize() == M
  213. assert M.bidiagonal_decomposition() == (M, M, M)
  214. assert M.bidiagonal_decomposition(upper=False) == (M, M, M)
  215. assert M.bidiagonalize() == M
  216. import random
  217. #Real Tests
  218. for real_test in range(2):
  219. test_values = []
  220. row = 2
  221. col = 2
  222. for _ in range(row * col):
  223. value = random.randint(-1000000000, 1000000000)
  224. test_values = test_values + [value]
  225. # L -> Lower Bidiagonalization
  226. # M -> Mutable Matrix
  227. # N -> Immutable Matrix
  228. # 0 -> Bidiagonalized form
  229. # 1,2,3 -> Bidiagonal_decomposition matrices
  230. # 4 -> Product of 1 2 3
  231. M = Matrix(row, col, test_values)
  232. N = ImmutableMatrix(M)
  233. N1, N2, N3 = N.bidiagonal_decomposition()
  234. M1, M2, M3 = M.bidiagonal_decomposition()
  235. M0 = M.bidiagonalize()
  236. N0 = N.bidiagonalize()
  237. N4 = N1 * N2 * N3
  238. M4 = M1 * M2 * M3
  239. N2.simplify()
  240. N4.simplify()
  241. N0.simplify()
  242. M0.simplify()
  243. M2.simplify()
  244. M4.simplify()
  245. LM0 = M.bidiagonalize(upper=False)
  246. LM1, LM2, LM3 = M.bidiagonal_decomposition(upper=False)
  247. LN0 = N.bidiagonalize(upper=False)
  248. LN1, LN2, LN3 = N.bidiagonal_decomposition(upper=False)
  249. LN4 = LN1 * LN2 * LN3
  250. LM4 = LM1 * LM2 * LM3
  251. LN2.simplify()
  252. LN4.simplify()
  253. LN0.simplify()
  254. LM0.simplify()
  255. LM2.simplify()
  256. LM4.simplify()
  257. assert M == M4
  258. assert M2 == M0
  259. assert N == N4
  260. assert N2 == N0
  261. assert M == LM4
  262. assert LM2 == LM0
  263. assert N == LN4
  264. assert LN2 == LN0
  265. #Complex Tests
  266. for complex_test in range(2):
  267. test_values = []
  268. size = 2
  269. for _ in range(size * size):
  270. real = random.randint(-1000000000, 1000000000)
  271. comp = random.randint(-1000000000, 1000000000)
  272. value = real + comp * I
  273. test_values = test_values + [value]
  274. M = Matrix(size, size, test_values)
  275. N = ImmutableMatrix(M)
  276. # L -> Lower Bidiagonalization
  277. # M -> Mutable Matrix
  278. # N -> Immutable Matrix
  279. # 0 -> Bidiagonalized form
  280. # 1,2,3 -> Bidiagonal_decomposition matrices
  281. # 4 -> Product of 1 2 3
  282. N1, N2, N3 = N.bidiagonal_decomposition()
  283. M1, M2, M3 = M.bidiagonal_decomposition()
  284. M0 = M.bidiagonalize()
  285. N0 = N.bidiagonalize()
  286. N4 = N1 * N2 * N3
  287. M4 = M1 * M2 * M3
  288. N2.simplify()
  289. N4.simplify()
  290. N0.simplify()
  291. M0.simplify()
  292. M2.simplify()
  293. M4.simplify()
  294. LM0 = M.bidiagonalize(upper=False)
  295. LM1, LM2, LM3 = M.bidiagonal_decomposition(upper=False)
  296. LN0 = N.bidiagonalize(upper=False)
  297. LN1, LN2, LN3 = N.bidiagonal_decomposition(upper=False)
  298. LN4 = LN1 * LN2 * LN3
  299. LM4 = LM1 * LM2 * LM3
  300. LN2.simplify()
  301. LN4.simplify()
  302. LN0.simplify()
  303. LM0.simplify()
  304. LM2.simplify()
  305. LM4.simplify()
  306. assert M == M4
  307. assert M2 == M0
  308. assert N == N4
  309. assert N2 == N0
  310. assert M == LM4
  311. assert LM2 == LM0
  312. assert N == LN4
  313. assert LN2 == LN0
  314. M = Matrix(18, 8, range(1, 145))
  315. M = M.applyfunc(lambda i: Float(i))
  316. assert M.bidiagonal_decomposition()[1] == M.bidiagonalize()
  317. assert M.bidiagonal_decomposition(upper=False)[1] == M.bidiagonalize(upper=False)
  318. a, b, c = M.bidiagonal_decomposition()
  319. diff = a * b * c - M
  320. assert abs(max(diff)) < 10**-12
  321. def test_diagonalize():
  322. m = Matrix(2, 2, [0, -1, 1, 0])
  323. raises(MatrixError, lambda: m.diagonalize(reals_only=True))
  324. P, D = m.diagonalize()
  325. assert D.is_diagonal()
  326. assert D == Matrix([
  327. [-I, 0],
  328. [ 0, I]])
  329. # make sure we use floats out if floats are passed in
  330. m = Matrix(2, 2, [0, .5, .5, 0])
  331. P, D = m.diagonalize()
  332. assert all(isinstance(e, Float) for e in D.values())
  333. assert all(isinstance(e, Float) for e in P.values())
  334. _, D2 = m.diagonalize(reals_only=True)
  335. assert D == D2
  336. m = Matrix(
  337. [[0, 1, 0, 0], [1, 0, 0, 0.002], [0.002, 0, 0, 1], [0, 0, 1, 0]])
  338. P, D = m.diagonalize()
  339. assert allclose(P*D, m*P)
  340. def test_is_diagonalizable():
  341. a, b, c = symbols('a b c')
  342. m = Matrix(2, 2, [a, c, c, b])
  343. assert m.is_symmetric()
  344. assert m.is_diagonalizable()
  345. assert not Matrix(2, 2, [1, 1, 0, 1]).is_diagonalizable()
  346. m = Matrix(2, 2, [0, -1, 1, 0])
  347. assert m.is_diagonalizable()
  348. assert not m.is_diagonalizable(reals_only=True)
  349. def test_jordan_form():
  350. m = Matrix(3, 2, [-3, 1, -3, 20, 3, 10])
  351. raises(NonSquareMatrixError, lambda: m.jordan_form())
  352. # the next two tests test the cases where the old
  353. # algorithm failed due to the fact that the block structure can
  354. # *NOT* be determined from algebraic and geometric multiplicity alone
  355. # This can be seen most easily when one lets compute the J.c.f. of a matrix that
  356. # is in J.c.f already.
  357. m = Matrix(4, 4, [2, 1, 0, 0,
  358. 0, 2, 1, 0,
  359. 0, 0, 2, 0,
  360. 0, 0, 0, 2
  361. ])
  362. P, J = m.jordan_form()
  363. assert m == J
  364. m = Matrix(4, 4, [2, 1, 0, 0,
  365. 0, 2, 0, 0,
  366. 0, 0, 2, 1,
  367. 0, 0, 0, 2
  368. ])
  369. P, J = m.jordan_form()
  370. assert m == J
  371. A = Matrix([[ 2, 4, 1, 0],
  372. [-4, 2, 0, 1],
  373. [ 0, 0, 2, 4],
  374. [ 0, 0, -4, 2]])
  375. P, J = A.jordan_form()
  376. assert simplify(P*J*P.inv()) == A
  377. assert Matrix(1, 1, [1]).jordan_form() == (Matrix([1]), Matrix([1]))
  378. assert Matrix(1, 1, [1]).jordan_form(calc_transform=False) == Matrix([1])
  379. # If we have eigenvalues in CRootOf form, raise errors
  380. m = Matrix([[3, 0, 0, 0, -3], [0, -3, -3, 0, 3], [0, 3, 0, 3, 0], [0, 0, 3, 0, 3], [3, 0, 0, 3, 0]])
  381. raises(MatrixError, lambda: m.jordan_form())
  382. # make sure that if the input has floats, the output does too
  383. m = Matrix([
  384. [ 0.6875, 0.125 + 0.1875*sqrt(3)],
  385. [0.125 + 0.1875*sqrt(3), 0.3125]])
  386. P, J = m.jordan_form()
  387. assert all(isinstance(x, Float) or x == 0 for x in P)
  388. assert all(isinstance(x, Float) or x == 0 for x in J)
  389. def test_singular_values():
  390. x = Symbol('x', real=True)
  391. A = Matrix([[0, 1*I], [2, 0]])
  392. # if singular values can be sorted, they should be in decreasing order
  393. assert A.singular_values() == [2, 1]
  394. A = eye(3)
  395. A[1, 1] = x
  396. A[2, 2] = 5
  397. vals = A.singular_values()
  398. # since Abs(x) cannot be sorted, test set equality
  399. assert set(vals) == {5, 1, Abs(x)}
  400. A = Matrix([[sin(x), cos(x)], [-cos(x), sin(x)]])
  401. vals = [sv.trigsimp() for sv in A.singular_values()]
  402. assert vals == [S.One, S.One]
  403. A = Matrix([
  404. [2, 4],
  405. [1, 3],
  406. [0, 0],
  407. [0, 0]
  408. ])
  409. assert A.singular_values() == \
  410. [sqrt(sqrt(221) + 15), sqrt(15 - sqrt(221))]
  411. assert A.T.singular_values() == \
  412. [sqrt(sqrt(221) + 15), sqrt(15 - sqrt(221)), 0, 0]
  413. def test___eq__():
  414. assert (Matrix(
  415. [[0, 1, 1],
  416. [1, 0, 0],
  417. [1, 1, 1]]) == {}) is False
  418. def test_definite():
  419. # Examples from Gilbert Strang, "Introduction to Linear Algebra"
  420. # Positive definite matrices
  421. m = Matrix([[2, -1, 0], [-1, 2, -1], [0, -1, 2]])
  422. assert m.is_positive_definite == True
  423. assert m.is_positive_semidefinite == True
  424. assert m.is_negative_definite == False
  425. assert m.is_negative_semidefinite == False
  426. assert m.is_indefinite == False
  427. m = Matrix([[5, 4], [4, 5]])
  428. assert m.is_positive_definite == True
  429. assert m.is_positive_semidefinite == True
  430. assert m.is_negative_definite == False
  431. assert m.is_negative_semidefinite == False
  432. assert m.is_indefinite == False
  433. # Positive semidefinite matrices
  434. m = Matrix([[2, -1, -1], [-1, 2, -1], [-1, -1, 2]])
  435. assert m.is_positive_definite == False
  436. assert m.is_positive_semidefinite == True
  437. assert m.is_negative_definite == False
  438. assert m.is_negative_semidefinite == False
  439. assert m.is_indefinite == False
  440. m = Matrix([[1, 2], [2, 4]])
  441. assert m.is_positive_definite == False
  442. assert m.is_positive_semidefinite == True
  443. assert m.is_negative_definite == False
  444. assert m.is_negative_semidefinite == False
  445. assert m.is_indefinite == False
  446. # Examples from Mathematica documentation
  447. # Non-hermitian positive definite matrices
  448. m = Matrix([[2, 3], [4, 8]])
  449. assert m.is_positive_definite == True
  450. assert m.is_positive_semidefinite == True
  451. assert m.is_negative_definite == False
  452. assert m.is_negative_semidefinite == False
  453. assert m.is_indefinite == False
  454. # Hermetian matrices
  455. m = Matrix([[1, 2*I], [-I, 4]])
  456. assert m.is_positive_definite == True
  457. assert m.is_positive_semidefinite == True
  458. assert m.is_negative_definite == False
  459. assert m.is_negative_semidefinite == False
  460. assert m.is_indefinite == False
  461. # Symbolic matrices examples
  462. a = Symbol('a', positive=True)
  463. b = Symbol('b', negative=True)
  464. m = Matrix([[a, 0, 0], [0, a, 0], [0, 0, a]])
  465. assert m.is_positive_definite == True
  466. assert m.is_positive_semidefinite == True
  467. assert m.is_negative_definite == False
  468. assert m.is_negative_semidefinite == False
  469. assert m.is_indefinite == False
  470. m = Matrix([[b, 0, 0], [0, b, 0], [0, 0, b]])
  471. assert m.is_positive_definite == False
  472. assert m.is_positive_semidefinite == False
  473. assert m.is_negative_definite == True
  474. assert m.is_negative_semidefinite == True
  475. assert m.is_indefinite == False
  476. m = Matrix([[a, 0], [0, b]])
  477. assert m.is_positive_definite == False
  478. assert m.is_positive_semidefinite == False
  479. assert m.is_negative_definite == False
  480. assert m.is_negative_semidefinite == False
  481. assert m.is_indefinite == True
  482. m = Matrix([
  483. [0.0228202735623867, 0.00518748979085398,
  484. -0.0743036351048907, -0.00709135324903921],
  485. [0.00518748979085398, 0.0349045359786350,
  486. 0.0830317991056637, 0.00233147902806909],
  487. [-0.0743036351048907, 0.0830317991056637,
  488. 1.15859676366277, 0.340359081555988],
  489. [-0.00709135324903921, 0.00233147902806909,
  490. 0.340359081555988, 0.928147644848199]
  491. ])
  492. assert m.is_positive_definite == True
  493. assert m.is_positive_semidefinite == True
  494. assert m.is_indefinite == False
  495. # test for issue 19547: https://github.com/sympy/sympy/issues/19547
  496. m = Matrix([
  497. [0, 0, 0],
  498. [0, 1, 2],
  499. [0, 2, 1]
  500. ])
  501. assert not m.is_positive_definite
  502. assert not m.is_positive_semidefinite
  503. def test_positive_semidefinite_cholesky():
  504. from sympy.matrices.eigen import _is_positive_semidefinite_cholesky
  505. m = Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
  506. assert _is_positive_semidefinite_cholesky(m) == True
  507. m = Matrix([[0, 0, 0], [0, 5, -10*I], [0, 10*I, 5]])
  508. assert _is_positive_semidefinite_cholesky(m) == False
  509. m = Matrix([[1, 0, 0], [0, 0, 0], [0, 0, -1]])
  510. assert _is_positive_semidefinite_cholesky(m) == False
  511. m = Matrix([[0, 1], [1, 0]])
  512. assert _is_positive_semidefinite_cholesky(m) == False
  513. # https://www.value-at-risk.net/cholesky-factorization/
  514. m = Matrix([[4, -2, -6], [-2, 10, 9], [-6, 9, 14]])
  515. assert _is_positive_semidefinite_cholesky(m) == True
  516. m = Matrix([[9, -3, 3], [-3, 2, 1], [3, 1, 6]])
  517. assert _is_positive_semidefinite_cholesky(m) == True
  518. m = Matrix([[4, -2, 2], [-2, 1, -1], [2, -1, 5]])
  519. assert _is_positive_semidefinite_cholesky(m) == True
  520. m = Matrix([[1, 2, -1], [2, 5, 1], [-1, 1, 9]])
  521. assert _is_positive_semidefinite_cholesky(m) == False
  522. def test_issue_20582():
  523. A = Matrix([
  524. [5, -5, -3, 2, -7],
  525. [-2, -5, 0, 2, 1],
  526. [-2, -7, -5, -2, -6],
  527. [7, 10, 3, 9, -2],
  528. [4, -10, 3, -8, -4]
  529. ])
  530. # XXX Used dry-run test because arbitrary symbol that appears in
  531. # CRootOf may not be unique.
  532. assert A.eigenvects()
  533. def test_issue_19210():
  534. t = Symbol('t')
  535. H = Matrix([[3, 0, 0, 0], [0, 1 , 2, 0], [0, 2, 2, 0], [0, 0, 0, 4]])
  536. A = (-I * H * t).jordan_form()
  537. assert A == (Matrix([
  538. [0, 1, 0, 0],
  539. [0, 0, -4/(-1 + sqrt(17)), 4/(1 + sqrt(17))],
  540. [0, 0, 1, 1],
  541. [1, 0, 0, 0]]), Matrix([
  542. [-4*I*t, 0, 0, 0],
  543. [ 0, -3*I*t, 0, 0],
  544. [ 0, 0, t*(-3*I/2 + sqrt(17)*I/2), 0],
  545. [ 0, 0, 0, t*(-sqrt(17)*I/2 - 3*I/2)]]))
  546. def test_issue_20275():
  547. # XXX We use complex expansions because complex exponentials are not
  548. # recognized by polys.domains
  549. A = DFT(3).as_explicit().expand(complex=True)
  550. eigenvects = A.eigenvects()
  551. assert eigenvects[0] == (
  552. -1, 1,
  553. [Matrix([[1 - sqrt(3)], [1], [1]])]
  554. )
  555. assert eigenvects[1] == (
  556. 1, 1,
  557. [Matrix([[1 + sqrt(3)], [1], [1]])]
  558. )
  559. assert eigenvects[2] == (
  560. -I, 1,
  561. [Matrix([[0], [-1], [1]])]
  562. )
  563. A = DFT(4).as_explicit().expand(complex=True)
  564. eigenvects = A.eigenvects()
  565. assert eigenvects[0] == (
  566. -1, 1,
  567. [Matrix([[-1], [1], [1], [1]])]
  568. )
  569. assert eigenvects[1] == (
  570. 1, 2,
  571. [Matrix([[1], [0], [1], [0]]), Matrix([[2], [1], [0], [1]])]
  572. )
  573. assert eigenvects[2] == (
  574. -I, 1,
  575. [Matrix([[0], [-1], [0], [1]])]
  576. )
  577. # XXX We skip test for some parts of eigenvectors which are very
  578. # complicated and fragile under expression tree changes
  579. A = DFT(5).as_explicit().expand(complex=True)
  580. eigenvects = A.eigenvects()
  581. assert eigenvects[0] == (
  582. -1, 1,
  583. [Matrix([[1 - sqrt(5)], [1], [1], [1], [1]])]
  584. )
  585. assert eigenvects[1] == (
  586. 1, 2,
  587. [Matrix([[S(1)/2 + sqrt(5)/2], [0], [1], [1], [0]]),
  588. Matrix([[S(1)/2 + sqrt(5)/2], [1], [0], [0], [1]])]
  589. )
  590. def test_issue_20752():
  591. b = symbols('b', nonzero=True)
  592. m = Matrix([[0, 0, 0], [0, b, 0], [0, 0, b]])
  593. assert m.is_positive_semidefinite is None