123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- from sympy.core.function import expand_mul
- from sympy.core.numbers import I, Rational
- from sympy.core.singleton import S
- from sympy.core.symbol import Symbol
- from sympy.functions.elementary.miscellaneous import sqrt
- from sympy.functions.elementary.complexes import Abs
- from sympy.simplify.simplify import simplify
- from sympy.matrices.matrices import NonSquareMatrixError
- from sympy.matrices import Matrix, zeros, eye, SparseMatrix
- from sympy.abc import x, y, z
- from sympy.testing.pytest import raises, slow
- from sympy.testing.matrices import allclose
- def test_LUdecomp():
- testmat = Matrix([[0, 2, 5, 3],
- [3, 3, 7, 4],
- [8, 4, 0, 2],
- [-2, 6, 3, 4]])
- L, U, p = testmat.LUdecomposition()
- assert L.is_lower
- assert U.is_upper
- assert (L*U).permute_rows(p, 'backward') - testmat == zeros(4)
- testmat = Matrix([[6, -2, 7, 4],
- [0, 3, 6, 7],
- [1, -2, 7, 4],
- [-9, 2, 6, 3]])
- L, U, p = testmat.LUdecomposition()
- assert L.is_lower
- assert U.is_upper
- assert (L*U).permute_rows(p, 'backward') - testmat == zeros(4)
- # non-square
- testmat = Matrix([[1, 2, 3],
- [4, 5, 6],
- [7, 8, 9],
- [10, 11, 12]])
- L, U, p = testmat.LUdecomposition(rankcheck=False)
- assert L.is_lower
- assert U.is_upper
- assert (L*U).permute_rows(p, 'backward') - testmat == zeros(4, 3)
- # square and singular
- testmat = Matrix([[1, 2, 3],
- [2, 4, 6],
- [4, 5, 6]])
- L, U, p = testmat.LUdecomposition(rankcheck=False)
- assert L.is_lower
- assert U.is_upper
- assert (L*U).permute_rows(p, 'backward') - testmat == zeros(3)
- M = Matrix(((1, x, 1), (2, y, 0), (y, 0, z)))
- L, U, p = M.LUdecomposition()
- assert L.is_lower
- assert U.is_upper
- assert (L*U).permute_rows(p, 'backward') - M == zeros(3)
- mL = Matrix((
- (1, 0, 0),
- (2, 3, 0),
- ))
- assert mL.is_lower is True
- assert mL.is_upper is False
- mU = Matrix((
- (1, 2, 3),
- (0, 4, 5),
- ))
- assert mU.is_lower is False
- assert mU.is_upper is True
- # test FF LUdecomp
- M = Matrix([[1, 3, 3],
- [3, 2, 6],
- [3, 2, 2]])
- P, L, Dee, U = M.LUdecompositionFF()
- assert P*M == L*Dee.inv()*U
- M = Matrix([[1, 2, 3, 4],
- [3, -1, 2, 3],
- [3, 1, 3, -2],
- [6, -1, 0, 2]])
- P, L, Dee, U = M.LUdecompositionFF()
- assert P*M == L*Dee.inv()*U
- M = Matrix([[0, 0, 1],
- [2, 3, 0],
- [3, 1, 4]])
- P, L, Dee, U = M.LUdecompositionFF()
- assert P*M == L*Dee.inv()*U
- # issue 15794
- M = Matrix(
- [[1, 2, 3],
- [4, 5, 6],
- [7, 8, 9]]
- )
- raises(ValueError, lambda : M.LUdecomposition_Simple(rankcheck=True))
- def test_singular_value_decompositionD():
- A = Matrix([[1, 2], [2, 1]])
- U, S, V = A.singular_value_decomposition()
- assert U * S * V.T == A
- assert U.T * U == eye(U.cols)
- assert V.T * V == eye(V.cols)
- B = Matrix([[1, 2]])
- U, S, V = B.singular_value_decomposition()
- assert U * S * V.T == B
- assert U.T * U == eye(U.cols)
- assert V.T * V == eye(V.cols)
- C = Matrix([
- [1, 0, 0, 0, 2],
- [0, 0, 3, 0, 0],
- [0, 0, 0, 0, 0],
- [0, 2, 0, 0, 0],
- ])
- U, S, V = C.singular_value_decomposition()
- assert U * S * V.T == C
- assert U.T * U == eye(U.cols)
- assert V.T * V == eye(V.cols)
- D = Matrix([[Rational(1, 3), sqrt(2)], [0, Rational(1, 4)]])
- U, S, V = D.singular_value_decomposition()
- assert simplify(U.T * U) == eye(U.cols)
- assert simplify(V.T * V) == eye(V.cols)
- assert simplify(U * S * V.T) == D
- def test_QR():
- A = Matrix([[1, 2], [2, 3]])
- Q, S = A.QRdecomposition()
- R = Rational
- assert Q == Matrix([
- [ 5**R(-1, 2), (R(2)/5)*(R(1)/5)**R(-1, 2)],
- [2*5**R(-1, 2), (-R(1)/5)*(R(1)/5)**R(-1, 2)]])
- assert S == Matrix([[5**R(1, 2), 8*5**R(-1, 2)], [0, (R(1)/5)**R(1, 2)]])
- assert Q*S == A
- assert Q.T * Q == eye(2)
- A = Matrix([[1, 1, 1], [1, 1, 3], [2, 3, 4]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[12, 0, -51], [6, 0, 167], [-4, 0, 24]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- x = Symbol('x')
- A = Matrix([x])
- Q, R = A.QRdecomposition()
- assert Q == Matrix([x / Abs(x)])
- assert R == Matrix([Abs(x)])
- A = Matrix([[x, 0], [0, x]])
- Q, R = A.QRdecomposition()
- assert Q == x / Abs(x) * Matrix([[1, 0], [0, 1]])
- assert R == Abs(x) * Matrix([[1, 0], [0, 1]])
- def test_QR_non_square():
- # Narrow (cols < rows) matrices
- A = Matrix([[9, 0, 26], [12, 0, -7], [0, 4, 4], [0, -3, -3]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[1, -1, 4], [1, 4, -2], [1, 4, 2], [1, -1, 0]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix(2, 1, [1, 2])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- # Wide (cols > rows) matrices
- A = Matrix([[1, 2, 3], [4, 5, 6]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[1, 2, 3, 4], [1, 4, 9, 16], [1, 8, 27, 64]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix(1, 2, [1, 2])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- def test_QR_trivial():
- # Rank deficient matrices
- A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- # Zero rank matrices
- A = Matrix([[0, 0, 0]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0], [0, 0, 0]])
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0], [0, 0, 0]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- # Rank deficient matrices with zero norm from beginning columns
- A = Matrix([[0, 0, 0], [1, 2, 3]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0, 0], [1, 2, 3, 4], [0, 0, 0, 0]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0, 0], [1, 2, 3, 4], [0, 0, 0, 0], [2, 4, 6, 8]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- A = Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0], [1, 2, 3]]).T
- Q, R = A.QRdecomposition()
- assert Q.T * Q == eye(Q.cols)
- assert R.is_upper
- assert A == Q*R
- def test_QR_float():
- A = Matrix([[1, 1], [1, 1.01]])
- Q, R = A.QRdecomposition()
- assert allclose(Q * R, A)
- assert allclose(Q * Q.T, Matrix.eye(2))
- assert allclose(Q.T * Q, Matrix.eye(2))
- A = Matrix([[1, 1], [1, 1.001]])
- Q, R = A.QRdecomposition()
- assert allclose(Q * R, A)
- assert allclose(Q * Q.T, Matrix.eye(2))
- assert allclose(Q.T * Q, Matrix.eye(2))
- def test_LUdecomposition_Simple_iszerofunc():
- # Test if callable passed to matrices.LUdecomposition_Simple() as iszerofunc keyword argument is used inside
- # matrices.LUdecomposition_Simple()
- magic_string = "I got passed in!"
- def goofyiszero(value):
- raise ValueError(magic_string)
- try:
- lu, p = Matrix([[1, 0], [0, 1]]).LUdecomposition_Simple(iszerofunc=goofyiszero)
- except ValueError as err:
- assert magic_string == err.args[0]
- return
- assert False
- def test_LUdecomposition_iszerofunc():
- # Test if callable passed to matrices.LUdecomposition() as iszerofunc keyword argument is used inside
- # matrices.LUdecomposition_Simple()
- magic_string = "I got passed in!"
- def goofyiszero(value):
- raise ValueError(magic_string)
- try:
- l, u, p = Matrix([[1, 0], [0, 1]]).LUdecomposition(iszerofunc=goofyiszero)
- except ValueError as err:
- assert magic_string == err.args[0]
- return
- assert False
- def test_LDLdecomposition():
- raises(NonSquareMatrixError, lambda: Matrix((1, 2)).LDLdecomposition())
- raises(ValueError, lambda: Matrix(((1, 2), (3, 4))).LDLdecomposition())
- raises(ValueError, lambda: Matrix(((5 + I, 0), (0, 1))).LDLdecomposition())
- raises(ValueError, lambda: Matrix(((1, 5), (5, 1))).LDLdecomposition())
- raises(ValueError, lambda: Matrix(((1, 2), (3, 4))).LDLdecomposition(hermitian=False))
- A = Matrix(((1, 5), (5, 1)))
- L, D = A.LDLdecomposition(hermitian=False)
- assert L * D * L.T == A
- A = Matrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
- L, D = A.LDLdecomposition()
- assert L * D * L.T == A
- assert L.is_lower
- assert L == Matrix([[1, 0, 0], [ Rational(3, 5), 1, 0], [Rational(-1, 5), Rational(1, 3), 1]])
- assert D.is_diagonal()
- assert D == Matrix([[25, 0, 0], [0, 9, 0], [0, 0, 9]])
- A = Matrix(((4, -2*I, 2 + 2*I), (2*I, 2, -1 + I), (2 - 2*I, -1 - I, 11)))
- L, D = A.LDLdecomposition()
- assert expand_mul(L * D * L.H) == A
- assert L.expand() == Matrix([[1, 0, 0], [I/2, 1, 0], [S.Half - I/2, 0, 1]])
- assert D.expand() == Matrix(((4, 0, 0), (0, 1, 0), (0, 0, 9)))
- raises(NonSquareMatrixError, lambda: SparseMatrix((1, 2)).LDLdecomposition())
- raises(ValueError, lambda: SparseMatrix(((1, 2), (3, 4))).LDLdecomposition())
- raises(ValueError, lambda: SparseMatrix(((5 + I, 0), (0, 1))).LDLdecomposition())
- raises(ValueError, lambda: SparseMatrix(((1, 5), (5, 1))).LDLdecomposition())
- raises(ValueError, lambda: SparseMatrix(((1, 2), (3, 4))).LDLdecomposition(hermitian=False))
- A = SparseMatrix(((1, 5), (5, 1)))
- L, D = A.LDLdecomposition(hermitian=False)
- assert L * D * L.T == A
- A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
- L, D = A.LDLdecomposition()
- assert L * D * L.T == A
- assert L.is_lower
- assert L == Matrix([[1, 0, 0], [ Rational(3, 5), 1, 0], [Rational(-1, 5), Rational(1, 3), 1]])
- assert D.is_diagonal()
- assert D == Matrix([[25, 0, 0], [0, 9, 0], [0, 0, 9]])
- A = SparseMatrix(((4, -2*I, 2 + 2*I), (2*I, 2, -1 + I), (2 - 2*I, -1 - I, 11)))
- L, D = A.LDLdecomposition()
- assert expand_mul(L * D * L.H) == A
- assert L == Matrix(((1, 0, 0), (I/2, 1, 0), (S.Half - I/2, 0, 1)))
- assert D == Matrix(((4, 0, 0), (0, 1, 0), (0, 0, 9)))
- def test_pinv_succeeds_with_rank_decomposition_method():
- # Test rank decomposition method of pseudoinverse succeeding
- As = [Matrix([
- [61, 89, 55, 20, 71, 0],
- [62, 96, 85, 85, 16, 0],
- [69, 56, 17, 4, 54, 0],
- [10, 54, 91, 41, 71, 0],
- [ 7, 30, 10, 48, 90, 0],
- [0,0,0,0,0,0]])]
- for A in As:
- A_pinv = A.pinv(method="RD")
- AAp = A * A_pinv
- ApA = A_pinv * A
- assert simplify(AAp * A) == A
- assert simplify(ApA * A_pinv) == A_pinv
- assert AAp.H == AAp
- assert ApA.H == ApA
- def test_rank_decomposition():
- a = Matrix(0, 0, [])
- c, f = a.rank_decomposition()
- assert f.is_echelon
- assert c.cols == f.rows == a.rank()
- assert c * f == a
- a = Matrix(1, 1, [5])
- c, f = a.rank_decomposition()
- assert f.is_echelon
- assert c.cols == f.rows == a.rank()
- assert c * f == a
- a = Matrix(3, 3, [1, 2, 3, 1, 2, 3, 1, 2, 3])
- c, f = a.rank_decomposition()
- assert f.is_echelon
- assert c.cols == f.rows == a.rank()
- assert c * f == a
- a = Matrix([
- [0, 0, 1, 2, 2, -5, 3],
- [-1, 5, 2, 2, 1, -7, 5],
- [0, 0, -2, -3, -3, 8, -5],
- [-1, 5, 0, -1, -2, 1, 0]])
- c, f = a.rank_decomposition()
- assert f.is_echelon
- assert c.cols == f.rows == a.rank()
- assert c * f == a
- @slow
- def test_upper_hessenberg_decomposition():
- A = Matrix([
- [1, 0, sqrt(3)],
- [sqrt(2), Rational(1, 2), 2],
- [1, Rational(1, 4), 3],
- ])
- H, P = A.upper_hessenberg_decomposition()
- assert simplify(P * P.H) == eye(P.cols)
- assert simplify(P.H * P) == eye(P.cols)
- assert H.is_upper_hessenberg
- assert (simplify(P * H * P.H)) == A
- B = Matrix([
- [1, 2, 10],
- [8, 2, 5],
- [3, 12, 34],
- ])
- H, P = B.upper_hessenberg_decomposition()
- assert simplify(P * P.H) == eye(P.cols)
- assert simplify(P.H * P) == eye(P.cols)
- assert H.is_upper_hessenberg
- assert simplify(P * H * P.H) == B
- C = Matrix([
- [1, sqrt(2), 2, 3],
- [0, 5, 3, 4],
- [1, 1, 4, sqrt(5)],
- [0, 2, 2, 3]
- ])
- H, P = C.upper_hessenberg_decomposition()
- assert simplify(P * P.H) == eye(P.cols)
- assert simplify(P.H * P) == eye(P.cols)
- assert H.is_upper_hessenberg
- assert simplify(P * H * P.H) == C
- D = Matrix([
- [1, 2, 3],
- [-3, 5, 6],
- [4, -8, 9],
- ])
- H, P = D.upper_hessenberg_decomposition()
- assert simplify(P * P.H) == eye(P.cols)
- assert simplify(P.H * P) == eye(P.cols)
- assert H.is_upper_hessenberg
- assert simplify(P * H * P.H) == D
- E = Matrix([
- [1, 0, 0, 0],
- [0, 1, 0, 0],
- [1, 1, 0, 1],
- [1, 1, 1, 0]
- ])
- H, P = E.upper_hessenberg_decomposition()
- assert simplify(P * P.H) == eye(P.cols)
- assert simplify(P.H * P) == eye(P.cols)
- assert H.is_upper_hessenberg
- assert simplify(P * H * P.H) == E
|