AI Newsletter Digest improvements: fixed QP soft line break decoding, URL extraction, and content cleaning
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,474 @@
|
||||
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.exceptions 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
|
||||
@@ -0,0 +1,280 @@
|
||||
import random
|
||||
import pytest
|
||||
from sympy.core.numbers import I
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.matrices import Matrix, eye, ones
|
||||
from sympy.abc import x, y, z
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.matrices.exceptions import NonSquareMatrixError
|
||||
from sympy.functions.combinatorial.factorials import factorial, subfactorial
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
# Evaluating these directly because they are never reached via M.det()
|
||||
Matrix._eval_det_bareiss, Matrix._eval_det_berkowitz,
|
||||
Matrix._eval_det_bird, Matrix._eval_det_laplace, Matrix._eval_det_lu
|
||||
])
|
||||
@pytest.mark.parametrize("M, sol", [
|
||||
(Matrix(), 1),
|
||||
(Matrix([[0]]), 0),
|
||||
(Matrix([[5]]), 5),
|
||||
])
|
||||
def test_eval_determinant(method, M, sol):
|
||||
assert method(M) == sol
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
"domain-ge", "bareiss", "berkowitz", "bird", "laplace", "lu"])
|
||||
@pytest.mark.parametrize("M, sol", [
|
||||
(Matrix(( (-3, 2),
|
||||
( 8, -5) )), -1),
|
||||
(Matrix(( (x, 1),
|
||||
(y, 2*y) )), 2*x*y - y),
|
||||
(Matrix(( (1, 1, 1),
|
||||
(1, 2, 3),
|
||||
(1, 3, 6) )), 1),
|
||||
(Matrix(( ( 3, -2, 0, 5),
|
||||
(-2, 1, -2, 2),
|
||||
( 0, -2, 5, 0),
|
||||
( 5, 0, 3, 4) )), -289),
|
||||
(Matrix(( ( 1, 2, 3, 4),
|
||||
( 5, 6, 7, 8),
|
||||
( 9, 10, 11, 12),
|
||||
(13, 14, 15, 16) )), 0),
|
||||
(Matrix(( (3, 2, 0, 0, 0),
|
||||
(0, 3, 2, 0, 0),
|
||||
(0, 0, 3, 2, 0),
|
||||
(0, 0, 0, 3, 2),
|
||||
(2, 0, 0, 0, 3) )), 275),
|
||||
(Matrix(( ( 3, 0, 0, 0),
|
||||
(-2, 1, 0, 0),
|
||||
( 0, -2, 5, 0),
|
||||
( 5, 0, 3, 4) )), 60),
|
||||
(Matrix(( ( 1, 0, 0, 0),
|
||||
( 5, 0, 0, 0),
|
||||
( 9, 10, 11, 0),
|
||||
(13, 14, 15, 16) )), 0),
|
||||
(Matrix(( (3, 2, 0, 0, 0),
|
||||
(0, 3, 2, 0, 0),
|
||||
(0, 0, 3, 2, 0),
|
||||
(0, 0, 0, 3, 2),
|
||||
(0, 0, 0, 0, 3) )), 243),
|
||||
(Matrix(( (1, 0, 1, 2, 12),
|
||||
(2, 0, 1, 1, 4),
|
||||
(2, 1, 1, -1, 3),
|
||||
(3, 2, -1, 1, 8),
|
||||
(1, 1, 1, 0, 6) )), -55),
|
||||
(Matrix(( (-5, 2, 3, 4, 5),
|
||||
( 1, -4, 3, 4, 5),
|
||||
( 1, 2, -3, 4, 5),
|
||||
( 1, 2, 3, -2, 5),
|
||||
( 1, 2, 3, 4, -1) )), 11664),
|
||||
(Matrix(( ( 2, 7, -1, 3, 2),
|
||||
( 0, 0, 1, 0, 1),
|
||||
(-2, 0, 7, 0, 2),
|
||||
(-3, -2, 4, 5, 3),
|
||||
( 1, 0, 0, 0, 1) )), 123),
|
||||
(Matrix(( (x, y, z),
|
||||
(1, 0, 0),
|
||||
(y, z, x) )), z**2 - x*y),
|
||||
])
|
||||
def test_determinant(method, M, sol):
|
||||
assert M.det(method=method) == sol
|
||||
|
||||
|
||||
def test_issue_13835():
|
||||
a = symbols('a')
|
||||
M = lambda n: Matrix([[i + a*j for i in range(n)]
|
||||
for j in range(n)])
|
||||
assert M(5).det() == 0
|
||||
assert M(6).det() == 0
|
||||
assert M(7).det() == 0
|
||||
|
||||
|
||||
def test_issue_14517():
|
||||
M = Matrix([
|
||||
[ 0, 10*I, 10*I, 0],
|
||||
[10*I, 0, 0, 10*I],
|
||||
[10*I, 0, 5 + 2*I, 10*I],
|
||||
[ 0, 10*I, 10*I, 5 + 2*I]])
|
||||
ev = M.eigenvals()
|
||||
# test one random eigenvalue, the computation is a little slow
|
||||
test_ev = random.choice(list(ev.keys()))
|
||||
assert (M - test_ev*eye(4)).det() == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("method", [
|
||||
"bareis", "det_lu", "det_LU", "Bareis", "BAREISS", "BERKOWITZ", "LU"])
|
||||
@pytest.mark.parametrize("M, sol", [
|
||||
(Matrix(( ( 3, -2, 0, 5),
|
||||
(-2, 1, -2, 2),
|
||||
( 0, -2, 5, 0),
|
||||
( 5, 0, 3, 4) )), -289),
|
||||
(Matrix(( (-5, 2, 3, 4, 5),
|
||||
( 1, -4, 3, 4, 5),
|
||||
( 1, 2, -3, 4, 5),
|
||||
( 1, 2, 3, -2, 5),
|
||||
( 1, 2, 3, 4, -1) )), 11664),
|
||||
])
|
||||
def test_legacy_det(method, M, sol):
|
||||
# Minimal support for legacy keys for 'method' in det()
|
||||
# Partially copied from test_determinant()
|
||||
assert M.det(method=method) == sol
|
||||
|
||||
|
||||
def eye_Determinant(n):
|
||||
return Matrix(n, n, lambda i, j: int(i == j))
|
||||
|
||||
def zeros_Determinant(n):
|
||||
return Matrix(n, n, lambda i, j: 0)
|
||||
|
||||
def test_det():
|
||||
a = Matrix(2, 3, [1, 2, 3, 4, 5, 6])
|
||||
raises(NonSquareMatrixError, lambda: a.det())
|
||||
|
||||
z = zeros_Determinant(2)
|
||||
ey = eye_Determinant(2)
|
||||
assert z.det() == 0
|
||||
assert ey.det() == 1
|
||||
|
||||
x = Symbol('x')
|
||||
a = Matrix(0, 0, [])
|
||||
b = Matrix(1, 1, [5])
|
||||
c = Matrix(2, 2, [1, 2, 3, 4])
|
||||
d = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 8])
|
||||
e = Matrix(4, 4,
|
||||
[x, 1, 2, 3, 4, 5, 6, 7, 2, 9, 10, 11, 12, 13, 14, 14])
|
||||
from sympy.abc import i, j, k, l, m, n
|
||||
f = Matrix(3, 3, [i, l, m, 0, j, n, 0, 0, k])
|
||||
g = Matrix(3, 3, [i, 0, 0, l, j, 0, m, n, k])
|
||||
h = Matrix(3, 3, [x**3, 0, 0, i, x**-1, 0, j, k, x**-2])
|
||||
# the method keyword for `det` doesn't kick in until 4x4 matrices,
|
||||
# so there is no need to test all methods on smaller ones
|
||||
|
||||
assert a.det() == 1
|
||||
assert b.det() == 5
|
||||
assert c.det() == -2
|
||||
assert d.det() == 3
|
||||
assert e.det() == 4*x - 24
|
||||
assert e.det(method="domain-ge") == 4*x - 24
|
||||
assert e.det(method='bareiss') == 4*x - 24
|
||||
assert e.det(method='berkowitz') == 4*x - 24
|
||||
assert f.det() == i*j*k
|
||||
assert g.det() == i*j*k
|
||||
assert h.det() == 1
|
||||
raises(ValueError, lambda: e.det(iszerofunc="test"))
|
||||
|
||||
def test_permanent():
|
||||
M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
assert M.per() == 450
|
||||
for i in range(1, 12):
|
||||
assert ones(i, i).per() == ones(i, i).T.per() == factorial(i)
|
||||
assert (ones(i, i)-eye(i)).per() == (ones(i, i)-eye(i)).T.per() == subfactorial(i)
|
||||
|
||||
a1, a2, a3, a4, a5 = symbols('a_1 a_2 a_3 a_4 a_5')
|
||||
M = Matrix([a1, a2, a3, a4, a5])
|
||||
assert M.per() == M.T.per() == a1 + a2 + a3 + a4 + a5
|
||||
|
||||
def test_adjugate():
|
||||
x = Symbol('x')
|
||||
e = Matrix(4, 4,
|
||||
[x, 1, 2, 3, 4, 5, 6, 7, 2, 9, 10, 11, 12, 13, 14, 14])
|
||||
|
||||
adj = Matrix([
|
||||
[ 4, -8, 4, 0],
|
||||
[ 76, -14*x - 68, 14*x - 8, -4*x + 24],
|
||||
[-122, 17*x + 142, -21*x + 4, 8*x - 48],
|
||||
[ 48, -4*x - 72, 8*x, -4*x + 24]])
|
||||
assert e.adjugate() == adj
|
||||
assert e.adjugate(method='bareiss') == adj
|
||||
assert e.adjugate(method='berkowitz') == adj
|
||||
assert e.adjugate(method='bird') == adj
|
||||
assert e.adjugate(method='laplace') == adj
|
||||
|
||||
a = Matrix(2, 3, [1, 2, 3, 4, 5, 6])
|
||||
raises(NonSquareMatrixError, lambda: a.adjugate())
|
||||
|
||||
def test_util():
|
||||
R = Rational
|
||||
|
||||
v1 = Matrix(1, 3, [1, 2, 3])
|
||||
v2 = Matrix(1, 3, [3, 4, 5])
|
||||
assert v1.norm() == sqrt(14)
|
||||
assert v1.project(v2) == Matrix(1, 3, [R(39)/25, R(52)/25, R(13)/5])
|
||||
assert Matrix.zeros(1, 2) == Matrix(1, 2, [0, 0])
|
||||
assert ones(1, 2) == Matrix(1, 2, [1, 1])
|
||||
assert v1.copy() == v1
|
||||
# cofactor
|
||||
assert eye(3) == eye(3).cofactor_matrix()
|
||||
test = Matrix([[1, 3, 2], [2, 6, 3], [2, 3, 6]])
|
||||
assert test.cofactor_matrix() == \
|
||||
Matrix([[27, -6, -6], [-12, 2, 3], [-3, 1, 0]])
|
||||
test = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
assert test.cofactor_matrix() == \
|
||||
Matrix([[-3, 6, -3], [6, -12, 6], [-3, 6, -3]])
|
||||
|
||||
def test_cofactor_and_minors():
|
||||
x = Symbol('x')
|
||||
e = Matrix(4, 4,
|
||||
[x, 1, 2, 3, 4, 5, 6, 7, 2, 9, 10, 11, 12, 13, 14, 14])
|
||||
|
||||
m = Matrix([
|
||||
[ x, 1, 3],
|
||||
[ 2, 9, 11],
|
||||
[12, 13, 14]])
|
||||
cm = Matrix([
|
||||
[ 4, 76, -122, 48],
|
||||
[-8, -14*x - 68, 17*x + 142, -4*x - 72],
|
||||
[ 4, 14*x - 8, -21*x + 4, 8*x],
|
||||
[ 0, -4*x + 24, 8*x - 48, -4*x + 24]])
|
||||
sub = Matrix([
|
||||
[x, 1, 2],
|
||||
[4, 5, 6],
|
||||
[2, 9, 10]])
|
||||
|
||||
assert e.minor_submatrix(1, 2) == m
|
||||
assert e.minor_submatrix(-1, -1) == sub
|
||||
assert e.minor(1, 2) == -17*x - 142
|
||||
assert e.cofactor(1, 2) == 17*x + 142
|
||||
assert e.cofactor_matrix() == cm
|
||||
assert e.cofactor_matrix(method="bareiss") == cm
|
||||
assert e.cofactor_matrix(method="berkowitz") == cm
|
||||
assert e.cofactor_matrix(method="bird") == cm
|
||||
assert e.cofactor_matrix(method="laplace") == cm
|
||||
|
||||
raises(ValueError, lambda: e.cofactor(4, 5))
|
||||
raises(ValueError, lambda: e.minor(4, 5))
|
||||
raises(ValueError, lambda: e.minor_submatrix(4, 5))
|
||||
|
||||
a = Matrix(2, 3, [1, 2, 3, 4, 5, 6])
|
||||
assert a.minor_submatrix(0, 0) == Matrix([[5, 6]])
|
||||
|
||||
raises(ValueError, lambda:
|
||||
Matrix(0, 0, []).minor_submatrix(0, 0))
|
||||
raises(NonSquareMatrixError, lambda: a.cofactor(0, 0))
|
||||
raises(NonSquareMatrixError, lambda: a.minor(0, 0))
|
||||
raises(NonSquareMatrixError, lambda: a.cofactor_matrix())
|
||||
|
||||
def test_charpoly():
|
||||
x, y = Symbol('x'), Symbol('y')
|
||||
z, t = Symbol('z'), Symbol('t')
|
||||
|
||||
from sympy.abc import a,b,c
|
||||
|
||||
m = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
|
||||
assert eye_Determinant(3).charpoly(x) == Poly((x - 1)**3, x)
|
||||
assert eye_Determinant(3).charpoly(y) == Poly((y - 1)**3, y)
|
||||
assert m.charpoly() == Poly(x**3 - 15*x**2 - 18*x, x)
|
||||
raises(NonSquareMatrixError, lambda: Matrix([[1], [2]]).charpoly())
|
||||
n = Matrix(4, 4, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||
assert n.charpoly() == Poly(x**4, x)
|
||||
|
||||
n = Matrix(4, 4, [45, 0, 0, 0, 0, 23, 0, 0, 0, 0, 87, 0, 0, 0, 0, 12])
|
||||
assert n.charpoly() == Poly(x**4 - 167*x**3 + 8811*x**2 - 173457*x + 1080540, x)
|
||||
|
||||
n = Matrix(3, 3, [x, 0, 0, a, y, 0, b, c, z])
|
||||
assert n.charpoly() == Poly(t**3 - (x+y+z)*t**2 + t*(x*y+y*z+x*z) - x*y*z, t)
|
||||
@@ -0,0 +1,113 @@
|
||||
# Test Matrix/DomainMatrix interaction.
|
||||
|
||||
|
||||
from sympy import GF, ZZ, QQ, EXRAW
|
||||
from sympy.polys.matrices import DomainMatrix, DM
|
||||
|
||||
from sympy import (
|
||||
Matrix,
|
||||
MutableMatrix,
|
||||
ImmutableMatrix,
|
||||
SparseMatrix,
|
||||
MutableDenseMatrix,
|
||||
ImmutableDenseMatrix,
|
||||
MutableSparseMatrix,
|
||||
ImmutableSparseMatrix,
|
||||
)
|
||||
from sympy import symbols, S, sqrt
|
||||
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
x, y = symbols('x y')
|
||||
|
||||
|
||||
MATRIX_TYPES = (
|
||||
Matrix,
|
||||
MutableMatrix,
|
||||
ImmutableMatrix,
|
||||
SparseMatrix,
|
||||
MutableDenseMatrix,
|
||||
ImmutableDenseMatrix,
|
||||
MutableSparseMatrix,
|
||||
ImmutableSparseMatrix,
|
||||
)
|
||||
IMMUTABLE = (
|
||||
ImmutableMatrix,
|
||||
ImmutableDenseMatrix,
|
||||
ImmutableSparseMatrix,
|
||||
)
|
||||
|
||||
|
||||
def DMs(items, domain):
|
||||
return DM(items, domain).to_sparse()
|
||||
|
||||
|
||||
def test_Matrix_rep_domain():
|
||||
|
||||
for Mat in MATRIX_TYPES:
|
||||
|
||||
M = Mat([[1, 2], [3, 4]])
|
||||
assert M._rep == DMs([[1, 2], [3, 4]], ZZ)
|
||||
assert (M / 2)._rep == DMs([[(1,2), 1], [(3,2), 2]], QQ)
|
||||
if not isinstance(M, IMMUTABLE):
|
||||
M[0, 0] = x
|
||||
assert M._rep == DMs([[x, 2], [3, 4]], EXRAW)
|
||||
|
||||
M = Mat([[S(1)/2, 2], [3, 4]])
|
||||
assert M._rep == DMs([[(1,2), 2], [3, 4]], QQ)
|
||||
if not isinstance(M, IMMUTABLE):
|
||||
M[0, 0] = x
|
||||
assert M._rep == DMs([[x, 2], [3, 4]], EXRAW)
|
||||
|
||||
dM = DMs([[1, 2], [3, 4]], ZZ)
|
||||
assert Mat._fromrep(dM)._rep == dM
|
||||
|
||||
# XXX: This is not intended. Perhaps it should be coerced to EXRAW?
|
||||
# The private _fromrep method is never called like this but perhaps it
|
||||
# should be guarded.
|
||||
#
|
||||
# It is not clear how to integrate domains other than ZZ, QQ and EXRAW with
|
||||
# the rest of Matrix or if the public type for this needs to be something
|
||||
# different from Matrix somehow.
|
||||
K = QQ.algebraic_field(sqrt(2))
|
||||
dM = DM([[1, 2], [3, 4]], K)
|
||||
assert Mat._fromrep(dM)._rep.domain == K
|
||||
|
||||
|
||||
def test_Matrix_to_DM():
|
||||
|
||||
M = Matrix([[1, 2], [3, 4]])
|
||||
assert M.to_DM() == DMs([[1, 2], [3, 4]], ZZ)
|
||||
assert M.to_DM() is not M._rep
|
||||
assert M.to_DM(field=True) == DMs([[1, 2], [3, 4]], QQ)
|
||||
assert M.to_DM(domain=QQ) == DMs([[1, 2], [3, 4]], QQ)
|
||||
assert M.to_DM(domain=QQ[x]) == DMs([[1, 2], [3, 4]], QQ[x])
|
||||
assert M.to_DM(domain=GF(3)) == DMs([[1, 2], [0, 1]], GF(3))
|
||||
|
||||
M = Matrix([[1, 2], [3, 4]])
|
||||
M[0, 0] = x
|
||||
assert M._rep.domain == EXRAW
|
||||
M[0, 0] = 1
|
||||
assert M.to_DM() == DMs([[1, 2], [3, 4]], ZZ)
|
||||
|
||||
M = Matrix([[S(1)/2, 2], [3, 4]])
|
||||
assert M.to_DM() == DMs([[QQ(1,2), 2], [3, 4]], QQ)
|
||||
|
||||
M = Matrix([[x, 2], [3, 4]])
|
||||
assert M.to_DM() == DMs([[x, 2], [3, 4]], ZZ[x])
|
||||
assert M.to_DM(field=True) == DMs([[x, 2], [3, 4]], ZZ.frac_field(x))
|
||||
|
||||
M = Matrix([[1/x, 2], [3, 4]])
|
||||
assert M.to_DM() == DMs([[1/x, 2], [3, 4]], ZZ.frac_field(x))
|
||||
|
||||
M = Matrix([[1, sqrt(2)], [3, 4]])
|
||||
K = QQ.algebraic_field(sqrt(2))
|
||||
sqrt2 = K.from_sympy(sqrt(2)) # XXX: Maybe K(sqrt(2)) should work
|
||||
M_K = DomainMatrix([[K(1), sqrt2], [K(3), K(4)]], (2, 2), K)
|
||||
assert M.to_DM() == DMs([[1, sqrt(2)], [3, 4]], EXRAW)
|
||||
assert M.to_DM(extension=True) == M_K.to_sparse()
|
||||
|
||||
# Options cannot be used with the domain parameter
|
||||
M = Matrix([[1, 2], [3, 4]])
|
||||
raises(TypeError, lambda: M.to_DM(domain=QQ, field=True))
|
||||
@@ -0,0 +1,712 @@
|
||||
from sympy.core.evalf import N
|
||||
from sympy.core.numbers import (Float, I, Rational)
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.functions.elementary.trigonometric import (cos, sin)
|
||||
from sympy.matrices import eye, Matrix
|
||||
from sympy.core.singleton import S
|
||||
from sympy.testing.pytest import raises, XFAIL
|
||||
from sympy.matrices.exceptions import NonSquareMatrixError, MatrixError
|
||||
from sympy.matrices.expressions.fourier import DFT
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.matrices.immutable import ImmutableMatrix
|
||||
from sympy.testing.pytest import slow
|
||||
from sympy.testing.matrices import allclose
|
||||
|
||||
|
||||
def test_eigen():
|
||||
R = Rational
|
||||
M = Matrix.eye(3)
|
||||
assert M.eigenvals(multiple=False) == {S.One: 3}
|
||||
assert M.eigenvals(multiple=True) == [1, 1, 1]
|
||||
|
||||
assert M.eigenvects() == (
|
||||
[(1, 3, [Matrix([1, 0, 0]),
|
||||
Matrix([0, 1, 0]),
|
||||
Matrix([0, 0, 1])])])
|
||||
|
||||
assert M.left_eigenvects() == (
|
||||
[(1, 3, [Matrix([[1, 0, 0]]),
|
||||
Matrix([[0, 1, 0]]),
|
||||
Matrix([[0, 0, 1]])])])
|
||||
|
||||
M = Matrix([[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 1, 1]])
|
||||
|
||||
assert M.eigenvals() == {2*S.One: 1, -S.One: 1, S.Zero: 1}
|
||||
|
||||
assert M.eigenvects() == (
|
||||
[
|
||||
(-1, 1, [Matrix([-1, 1, 0])]),
|
||||
( 0, 1, [Matrix([0, -1, 1])]),
|
||||
( 2, 1, [Matrix([R(2, 3), R(1, 3), 1])])
|
||||
])
|
||||
|
||||
assert M.left_eigenvects() == (
|
||||
[
|
||||
(-1, 1, [Matrix([[-2, 1, 1]])]),
|
||||
(0, 1, [Matrix([[-1, -1, 1]])]),
|
||||
(2, 1, [Matrix([[1, 1, 1]])])
|
||||
])
|
||||
|
||||
a = Symbol('a')
|
||||
M = Matrix([[a, 0],
|
||||
[0, 1]])
|
||||
|
||||
assert M.eigenvals() == {a: 1, S.One: 1}
|
||||
|
||||
M = Matrix([[1, -1],
|
||||
[1, 3]])
|
||||
assert M.eigenvects() == ([(2, 2, [Matrix(2, 1, [-1, 1])])])
|
||||
assert M.left_eigenvects() == ([(2, 2, [Matrix([[1, 1]])])])
|
||||
|
||||
M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
a = R(15, 2)
|
||||
b = 3*33**R(1, 2)
|
||||
c = R(13, 2)
|
||||
d = (R(33, 8) + 3*b/8)
|
||||
e = (R(33, 8) - 3*b/8)
|
||||
|
||||
def NS(e, n):
|
||||
return str(N(e, n))
|
||||
r = [
|
||||
(a - b/2, 1, [Matrix([(12 + 24/(c - b/2))/((c - b/2)*e) + 3/(c - b/2),
|
||||
(6 + 12/(c - b/2))/e, 1])]),
|
||||
( 0, 1, [Matrix([1, -2, 1])]),
|
||||
(a + b/2, 1, [Matrix([(12 + 24/(c + b/2))/((c + b/2)*d) + 3/(c + b/2),
|
||||
(6 + 12/(c + b/2))/d, 1])]),
|
||||
]
|
||||
r1 = [(NS(r[i][0], 2), NS(r[i][1], 2),
|
||||
[NS(j, 2) for j in r[i][2][0]]) for i in range(len(r))]
|
||||
r = M.eigenvects()
|
||||
r2 = [(NS(r[i][0], 2), NS(r[i][1], 2),
|
||||
[NS(j, 2) for j in r[i][2][0]]) for i in range(len(r))]
|
||||
assert sorted(r1) == sorted(r2)
|
||||
|
||||
eps = Symbol('eps', real=True)
|
||||
|
||||
M = Matrix([[abs(eps), I*eps ],
|
||||
[-I*eps, abs(eps) ]])
|
||||
|
||||
assert M.eigenvects() == (
|
||||
[
|
||||
( 0, 1, [Matrix([[-I*eps/abs(eps)], [1]])]),
|
||||
( 2*abs(eps), 1, [ Matrix([[I*eps/abs(eps)], [1]]) ] ),
|
||||
])
|
||||
|
||||
assert M.left_eigenvects() == (
|
||||
[
|
||||
(0, 1, [Matrix([[I*eps/Abs(eps), 1]])]),
|
||||
(2*Abs(eps), 1, [Matrix([[-I*eps/Abs(eps), 1]])])
|
||||
])
|
||||
|
||||
M = Matrix(3, 3, [1, 2, 0, 0, 3, 0, 2, -4, 2])
|
||||
M._eigenvects = M.eigenvects(simplify=False)
|
||||
assert max(i.q for i in M._eigenvects[0][2][0]) > 1
|
||||
M._eigenvects = M.eigenvects(simplify=True)
|
||||
assert max(i.q for i in M._eigenvects[0][2][0]) == 1
|
||||
|
||||
M = Matrix([[Rational(1, 4), 1], [1, 1]])
|
||||
assert M.eigenvects() == [
|
||||
(Rational(5, 8) - sqrt(73)/8, 1, [Matrix([[-sqrt(73)/8 - Rational(3, 8)], [1]])]),
|
||||
(Rational(5, 8) + sqrt(73)/8, 1, [Matrix([[Rational(-3, 8) + sqrt(73)/8], [1]])])]
|
||||
|
||||
# issue 10719
|
||||
assert Matrix([]).eigenvals() == {}
|
||||
assert Matrix([]).eigenvals(multiple=True) == []
|
||||
assert Matrix([]).eigenvects() == []
|
||||
|
||||
# issue 15119
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 2], [0, 4], [0, 0]]).eigenvals())
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 0], [3, 4], [5, 6]]).eigenvals())
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 2, 3], [0, 5, 6]]).eigenvals())
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 0, 0], [4, 5, 0]]).eigenvals())
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 2, 3], [0, 5, 6]]).eigenvals(
|
||||
error_when_incomplete = False))
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([[1, 0, 0], [4, 5, 0]]).eigenvals(
|
||||
error_when_incomplete = False))
|
||||
|
||||
m = Matrix([[1, 2], [3, 4]])
|
||||
assert isinstance(m.eigenvals(simplify=True, multiple=False), dict)
|
||||
assert isinstance(m.eigenvals(simplify=True, multiple=True), list)
|
||||
assert isinstance(m.eigenvals(simplify=lambda x: x, multiple=False), dict)
|
||||
assert isinstance(m.eigenvals(simplify=lambda x: x, multiple=True), list)
|
||||
|
||||
|
||||
def test_float_eigenvals():
|
||||
m = Matrix([[1, .6, .6], [.6, .9, .9], [.9, .6, .6]])
|
||||
evals = [
|
||||
Rational(5, 4) - sqrt(385)/20,
|
||||
sqrt(385)/20 + Rational(5, 4),
|
||||
S.Zero]
|
||||
|
||||
n_evals = m.eigenvals(rational=True, multiple=True)
|
||||
n_evals = sorted(n_evals)
|
||||
s_evals = [x.evalf() for x in evals]
|
||||
s_evals = sorted(s_evals)
|
||||
|
||||
for x, y in zip(n_evals, s_evals):
|
||||
assert abs(x-y) < 10**-9
|
||||
|
||||
|
||||
@XFAIL
|
||||
def test_eigen_vects():
|
||||
m = Matrix(2, 2, [1, 0, 0, I])
|
||||
raises(NotImplementedError, lambda: m.is_diagonalizable(True))
|
||||
# !!! bug because of eigenvects() or roots(x**2 + (-1 - I)*x + I, x)
|
||||
# see issue 5292
|
||||
assert not m.is_diagonalizable(True)
|
||||
raises(MatrixError, lambda: m.diagonalize(True))
|
||||
(P, D) = m.diagonalize(True)
|
||||
|
||||
def test_issue_8240():
|
||||
# Eigenvalues of large triangular matrices
|
||||
x, y = symbols('x y')
|
||||
n = 200
|
||||
|
||||
diagonal_variables = [Symbol('x%s' % i) for i in range(n)]
|
||||
M = [[0 for i in range(n)] for j in range(n)]
|
||||
for i in range(n):
|
||||
M[i][i] = diagonal_variables[i]
|
||||
M = Matrix(M)
|
||||
|
||||
eigenvals = M.eigenvals()
|
||||
assert len(eigenvals) == n
|
||||
for i in range(n):
|
||||
assert eigenvals[diagonal_variables[i]] == 1
|
||||
|
||||
eigenvals = M.eigenvals(multiple=True)
|
||||
assert set(eigenvals) == set(diagonal_variables)
|
||||
|
||||
# with multiplicity
|
||||
M = Matrix([[x, 0, 0], [1, y, 0], [2, 3, x]])
|
||||
eigenvals = M.eigenvals()
|
||||
assert eigenvals == {x: 2, y: 1}
|
||||
|
||||
eigenvals = M.eigenvals(multiple=True)
|
||||
assert len(eigenvals) == 3
|
||||
assert eigenvals.count(x) == 2
|
||||
assert eigenvals.count(y) == 1
|
||||
|
||||
|
||||
def test_eigenvals():
|
||||
M = Matrix([[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 1, 1]])
|
||||
assert M.eigenvals() == {2*S.One: 1, -S.One: 1, S.Zero: 1}
|
||||
|
||||
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]])
|
||||
|
||||
# XXX Used dry-run test because arbitrary symbol that appears in
|
||||
# CRootOf may not be unique.
|
||||
assert m.eigenvals()
|
||||
|
||||
|
||||
def test_eigenvects():
|
||||
M = Matrix([[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 1, 1]])
|
||||
vecs = M.eigenvects()
|
||||
for val, mult, vec_list in vecs:
|
||||
assert len(vec_list) == 1
|
||||
assert M*vec_list[0] == val*vec_list[0]
|
||||
|
||||
|
||||
def test_left_eigenvects():
|
||||
M = Matrix([[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 1, 1]])
|
||||
vecs = M.left_eigenvects()
|
||||
for val, mult, vec_list in vecs:
|
||||
assert len(vec_list) == 1
|
||||
assert vec_list[0]*M == val*vec_list[0]
|
||||
|
||||
|
||||
@slow
|
||||
def test_bidiagonalize():
|
||||
M = Matrix([[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, 1]])
|
||||
assert M.bidiagonalize() == M
|
||||
assert M.bidiagonalize(upper=False) == M
|
||||
assert M.bidiagonalize() == M
|
||||
assert M.bidiagonal_decomposition() == (M, M, M)
|
||||
assert M.bidiagonal_decomposition(upper=False) == (M, M, M)
|
||||
assert M.bidiagonalize() == M
|
||||
|
||||
import random
|
||||
#Real Tests
|
||||
for real_test in range(2):
|
||||
test_values = []
|
||||
row = 2
|
||||
col = 2
|
||||
for _ in range(row * col):
|
||||
value = random.randint(-1000000000, 1000000000)
|
||||
test_values = test_values + [value]
|
||||
# L -> Lower Bidiagonalization
|
||||
# M -> Mutable Matrix
|
||||
# N -> Immutable Matrix
|
||||
# 0 -> Bidiagonalized form
|
||||
# 1,2,3 -> Bidiagonal_decomposition matrices
|
||||
# 4 -> Product of 1 2 3
|
||||
M = Matrix(row, col, test_values)
|
||||
N = ImmutableMatrix(M)
|
||||
|
||||
N1, N2, N3 = N.bidiagonal_decomposition()
|
||||
M1, M2, M3 = M.bidiagonal_decomposition()
|
||||
M0 = M.bidiagonalize()
|
||||
N0 = N.bidiagonalize()
|
||||
|
||||
N4 = N1 * N2 * N3
|
||||
M4 = M1 * M2 * M3
|
||||
|
||||
N2.simplify()
|
||||
N4.simplify()
|
||||
N0.simplify()
|
||||
|
||||
M0.simplify()
|
||||
M2.simplify()
|
||||
M4.simplify()
|
||||
|
||||
LM0 = M.bidiagonalize(upper=False)
|
||||
LM1, LM2, LM3 = M.bidiagonal_decomposition(upper=False)
|
||||
LN0 = N.bidiagonalize(upper=False)
|
||||
LN1, LN2, LN3 = N.bidiagonal_decomposition(upper=False)
|
||||
|
||||
LN4 = LN1 * LN2 * LN3
|
||||
LM4 = LM1 * LM2 * LM3
|
||||
|
||||
LN2.simplify()
|
||||
LN4.simplify()
|
||||
LN0.simplify()
|
||||
|
||||
LM0.simplify()
|
||||
LM2.simplify()
|
||||
LM4.simplify()
|
||||
|
||||
assert M == M4
|
||||
assert M2 == M0
|
||||
assert N == N4
|
||||
assert N2 == N0
|
||||
assert M == LM4
|
||||
assert LM2 == LM0
|
||||
assert N == LN4
|
||||
assert LN2 == LN0
|
||||
|
||||
#Complex Tests
|
||||
for complex_test in range(2):
|
||||
test_values = []
|
||||
size = 2
|
||||
for _ in range(size * size):
|
||||
real = random.randint(-1000000000, 1000000000)
|
||||
comp = random.randint(-1000000000, 1000000000)
|
||||
value = real + comp * I
|
||||
test_values = test_values + [value]
|
||||
M = Matrix(size, size, test_values)
|
||||
N = ImmutableMatrix(M)
|
||||
# L -> Lower Bidiagonalization
|
||||
# M -> Mutable Matrix
|
||||
# N -> Immutable Matrix
|
||||
# 0 -> Bidiagonalized form
|
||||
# 1,2,3 -> Bidiagonal_decomposition matrices
|
||||
# 4 -> Product of 1 2 3
|
||||
N1, N2, N3 = N.bidiagonal_decomposition()
|
||||
M1, M2, M3 = M.bidiagonal_decomposition()
|
||||
M0 = M.bidiagonalize()
|
||||
N0 = N.bidiagonalize()
|
||||
|
||||
N4 = N1 * N2 * N3
|
||||
M4 = M1 * M2 * M3
|
||||
|
||||
N2.simplify()
|
||||
N4.simplify()
|
||||
N0.simplify()
|
||||
|
||||
M0.simplify()
|
||||
M2.simplify()
|
||||
M4.simplify()
|
||||
|
||||
LM0 = M.bidiagonalize(upper=False)
|
||||
LM1, LM2, LM3 = M.bidiagonal_decomposition(upper=False)
|
||||
LN0 = N.bidiagonalize(upper=False)
|
||||
LN1, LN2, LN3 = N.bidiagonal_decomposition(upper=False)
|
||||
|
||||
LN4 = LN1 * LN2 * LN3
|
||||
LM4 = LM1 * LM2 * LM3
|
||||
|
||||
LN2.simplify()
|
||||
LN4.simplify()
|
||||
LN0.simplify()
|
||||
|
||||
LM0.simplify()
|
||||
LM2.simplify()
|
||||
LM4.simplify()
|
||||
|
||||
assert M == M4
|
||||
assert M2 == M0
|
||||
assert N == N4
|
||||
assert N2 == N0
|
||||
assert M == LM4
|
||||
assert LM2 == LM0
|
||||
assert N == LN4
|
||||
assert LN2 == LN0
|
||||
|
||||
M = Matrix(18, 8, range(1, 145))
|
||||
M = M.applyfunc(lambda i: Float(i))
|
||||
assert M.bidiagonal_decomposition()[1] == M.bidiagonalize()
|
||||
assert M.bidiagonal_decomposition(upper=False)[1] == M.bidiagonalize(upper=False)
|
||||
a, b, c = M.bidiagonal_decomposition()
|
||||
diff = a * b * c - M
|
||||
assert abs(max(diff)) < 10**-12
|
||||
|
||||
|
||||
def test_diagonalize():
|
||||
m = Matrix(2, 2, [0, -1, 1, 0])
|
||||
raises(MatrixError, lambda: m.diagonalize(reals_only=True))
|
||||
P, D = m.diagonalize()
|
||||
assert D.is_diagonal()
|
||||
assert D == Matrix([
|
||||
[-I, 0],
|
||||
[ 0, I]])
|
||||
|
||||
# make sure we use floats out if floats are passed in
|
||||
m = Matrix(2, 2, [0, .5, .5, 0])
|
||||
P, D = m.diagonalize()
|
||||
assert all(isinstance(e, Float) for e in D.values())
|
||||
assert all(isinstance(e, Float) for e in P.values())
|
||||
|
||||
_, D2 = m.diagonalize(reals_only=True)
|
||||
assert D == D2
|
||||
|
||||
m = Matrix(
|
||||
[[0, 1, 0, 0], [1, 0, 0, 0.002], [0.002, 0, 0, 1], [0, 0, 1, 0]])
|
||||
P, D = m.diagonalize()
|
||||
assert allclose(P*D, m*P)
|
||||
|
||||
|
||||
def test_is_diagonalizable():
|
||||
a, b, c = symbols('a b c')
|
||||
m = Matrix(2, 2, [a, c, c, b])
|
||||
assert m.is_symmetric()
|
||||
assert m.is_diagonalizable()
|
||||
assert not Matrix(2, 2, [1, 1, 0, 1]).is_diagonalizable()
|
||||
|
||||
m = Matrix(2, 2, [0, -1, 1, 0])
|
||||
assert m.is_diagonalizable()
|
||||
assert not m.is_diagonalizable(reals_only=True)
|
||||
|
||||
|
||||
def test_jordan_form():
|
||||
m = Matrix(3, 2, [-3, 1, -3, 20, 3, 10])
|
||||
raises(NonSquareMatrixError, lambda: m.jordan_form())
|
||||
|
||||
# the next two tests test the cases where the old
|
||||
# algorithm failed due to the fact that the block structure can
|
||||
# *NOT* be determined from algebraic and geometric multiplicity alone
|
||||
# This can be seen most easily when one lets compute the J.c.f. of a matrix that
|
||||
# is in J.c.f already.
|
||||
m = Matrix(4, 4, [2, 1, 0, 0,
|
||||
0, 2, 1, 0,
|
||||
0, 0, 2, 0,
|
||||
0, 0, 0, 2
|
||||
])
|
||||
P, J = m.jordan_form()
|
||||
assert m == J
|
||||
|
||||
m = Matrix(4, 4, [2, 1, 0, 0,
|
||||
0, 2, 0, 0,
|
||||
0, 0, 2, 1,
|
||||
0, 0, 0, 2
|
||||
])
|
||||
P, J = m.jordan_form()
|
||||
assert m == J
|
||||
|
||||
A = Matrix([[ 2, 4, 1, 0],
|
||||
[-4, 2, 0, 1],
|
||||
[ 0, 0, 2, 4],
|
||||
[ 0, 0, -4, 2]])
|
||||
P, J = A.jordan_form()
|
||||
assert simplify(P*J*P.inv()) == A
|
||||
|
||||
assert Matrix(1, 1, [1]).jordan_form() == (Matrix([1]), Matrix([1]))
|
||||
assert Matrix(1, 1, [1]).jordan_form(calc_transform=False) == Matrix([1])
|
||||
|
||||
# If we have eigenvalues in CRootOf form, raise errors
|
||||
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]])
|
||||
raises(MatrixError, lambda: m.jordan_form())
|
||||
|
||||
# make sure that if the input has floats, the output does too
|
||||
m = Matrix([
|
||||
[ 0.6875, 0.125 + 0.1875*sqrt(3)],
|
||||
[0.125 + 0.1875*sqrt(3), 0.3125]])
|
||||
P, J = m.jordan_form()
|
||||
assert all(isinstance(x, Float) or x == 0 for x in P)
|
||||
assert all(isinstance(x, Float) or x == 0 for x in J)
|
||||
|
||||
|
||||
def test_singular_values():
|
||||
x = Symbol('x', real=True)
|
||||
|
||||
A = Matrix([[0, 1*I], [2, 0]])
|
||||
# if singular values can be sorted, they should be in decreasing order
|
||||
assert A.singular_values() == [2, 1]
|
||||
|
||||
A = eye(3)
|
||||
A[1, 1] = x
|
||||
A[2, 2] = 5
|
||||
vals = A.singular_values()
|
||||
# since Abs(x) cannot be sorted, test set equality
|
||||
assert set(vals) == {5, 1, Abs(x)}
|
||||
|
||||
A = Matrix([[sin(x), cos(x)], [-cos(x), sin(x)]])
|
||||
vals = [sv.trigsimp() for sv in A.singular_values()]
|
||||
assert vals == [S.One, S.One]
|
||||
|
||||
A = Matrix([
|
||||
[2, 4],
|
||||
[1, 3],
|
||||
[0, 0],
|
||||
[0, 0]
|
||||
])
|
||||
assert A.singular_values() == \
|
||||
[sqrt(sqrt(221) + 15), sqrt(15 - sqrt(221))]
|
||||
assert A.T.singular_values() == \
|
||||
[sqrt(sqrt(221) + 15), sqrt(15 - sqrt(221)), 0, 0]
|
||||
|
||||
def test___eq__():
|
||||
assert (Matrix(
|
||||
[[0, 1, 1],
|
||||
[1, 0, 0],
|
||||
[1, 1, 1]]) == {}) is False
|
||||
|
||||
|
||||
def test_definite():
|
||||
# Examples from Gilbert Strang, "Introduction to Linear Algebra"
|
||||
# Positive definite matrices
|
||||
m = Matrix([[2, -1, 0], [-1, 2, -1], [0, -1, 2]])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
m = Matrix([[5, 4], [4, 5]])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
# Positive semidefinite matrices
|
||||
m = Matrix([[2, -1, -1], [-1, 2, -1], [-1, -1, 2]])
|
||||
assert m.is_positive_definite == False
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
m = Matrix([[1, 2], [2, 4]])
|
||||
assert m.is_positive_definite == False
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
# Examples from Mathematica documentation
|
||||
# Non-hermitian positive definite matrices
|
||||
m = Matrix([[2, 3], [4, 8]])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
# Hermetian matrices
|
||||
m = Matrix([[1, 2*I], [-I, 4]])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
# Symbolic matrices examples
|
||||
a = Symbol('a', positive=True)
|
||||
b = Symbol('b', negative=True)
|
||||
m = Matrix([[a, 0, 0], [0, a, 0], [0, 0, a]])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == False
|
||||
|
||||
m = Matrix([[b, 0, 0], [0, b, 0], [0, 0, b]])
|
||||
assert m.is_positive_definite == False
|
||||
assert m.is_positive_semidefinite == False
|
||||
assert m.is_negative_definite == True
|
||||
assert m.is_negative_semidefinite == True
|
||||
assert m.is_indefinite == False
|
||||
|
||||
m = Matrix([[a, 0], [0, b]])
|
||||
assert m.is_positive_definite == False
|
||||
assert m.is_positive_semidefinite == False
|
||||
assert m.is_negative_definite == False
|
||||
assert m.is_negative_semidefinite == False
|
||||
assert m.is_indefinite == True
|
||||
|
||||
m = Matrix([
|
||||
[0.0228202735623867, 0.00518748979085398,
|
||||
-0.0743036351048907, -0.00709135324903921],
|
||||
[0.00518748979085398, 0.0349045359786350,
|
||||
0.0830317991056637, 0.00233147902806909],
|
||||
[-0.0743036351048907, 0.0830317991056637,
|
||||
1.15859676366277, 0.340359081555988],
|
||||
[-0.00709135324903921, 0.00233147902806909,
|
||||
0.340359081555988, 0.928147644848199]
|
||||
])
|
||||
assert m.is_positive_definite == True
|
||||
assert m.is_positive_semidefinite == True
|
||||
assert m.is_indefinite == False
|
||||
|
||||
# test for issue 19547: https://github.com/sympy/sympy/issues/19547
|
||||
m = Matrix([
|
||||
[0, 0, 0],
|
||||
[0, 1, 2],
|
||||
[0, 2, 1]
|
||||
])
|
||||
assert not m.is_positive_definite
|
||||
assert not m.is_positive_semidefinite
|
||||
|
||||
|
||||
def test_positive_semidefinite_cholesky():
|
||||
from sympy.matrices.eigen import _is_positive_semidefinite_cholesky
|
||||
|
||||
m = Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == True
|
||||
m = Matrix([[0, 0, 0], [0, 5, -10*I], [0, 10*I, 5]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == False
|
||||
m = Matrix([[1, 0, 0], [0, 0, 0], [0, 0, -1]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == False
|
||||
m = Matrix([[0, 1], [1, 0]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == False
|
||||
|
||||
# https://www.value-at-risk.net/cholesky-factorization/
|
||||
m = Matrix([[4, -2, -6], [-2, 10, 9], [-6, 9, 14]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == True
|
||||
m = Matrix([[9, -3, 3], [-3, 2, 1], [3, 1, 6]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == True
|
||||
m = Matrix([[4, -2, 2], [-2, 1, -1], [2, -1, 5]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == True
|
||||
m = Matrix([[1, 2, -1], [2, 5, 1], [-1, 1, 9]])
|
||||
assert _is_positive_semidefinite_cholesky(m) == False
|
||||
|
||||
|
||||
def test_issue_20582():
|
||||
A = Matrix([
|
||||
[5, -5, -3, 2, -7],
|
||||
[-2, -5, 0, 2, 1],
|
||||
[-2, -7, -5, -2, -6],
|
||||
[7, 10, 3, 9, -2],
|
||||
[4, -10, 3, -8, -4]
|
||||
])
|
||||
# XXX Used dry-run test because arbitrary symbol that appears in
|
||||
# CRootOf may not be unique.
|
||||
assert A.eigenvects()
|
||||
|
||||
def test_issue_19210():
|
||||
t = Symbol('t')
|
||||
H = Matrix([[3, 0, 0, 0], [0, 1 , 2, 0], [0, 2, 2, 0], [0, 0, 0, 4]])
|
||||
A = (-I * H * t).jordan_form()
|
||||
assert A == (Matrix([
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, -4/(-1 + sqrt(17)), 4/(1 + sqrt(17))],
|
||||
[0, 0, 1, 1],
|
||||
[1, 0, 0, 0]]), Matrix([
|
||||
[-4*I*t, 0, 0, 0],
|
||||
[ 0, -3*I*t, 0, 0],
|
||||
[ 0, 0, t*(-3*I/2 + sqrt(17)*I/2), 0],
|
||||
[ 0, 0, 0, t*(-sqrt(17)*I/2 - 3*I/2)]]))
|
||||
|
||||
|
||||
def test_issue_20275():
|
||||
# XXX We use complex expansions because complex exponentials are not
|
||||
# recognized by polys.domains
|
||||
A = DFT(3).as_explicit().expand(complex=True)
|
||||
eigenvects = A.eigenvects()
|
||||
assert eigenvects[0] == (
|
||||
-1, 1,
|
||||
[Matrix([[1 - sqrt(3)], [1], [1]])]
|
||||
)
|
||||
assert eigenvects[1] == (
|
||||
1, 1,
|
||||
[Matrix([[1 + sqrt(3)], [1], [1]])]
|
||||
)
|
||||
assert eigenvects[2] == (
|
||||
-I, 1,
|
||||
[Matrix([[0], [-1], [1]])]
|
||||
)
|
||||
|
||||
A = DFT(4).as_explicit().expand(complex=True)
|
||||
eigenvects = A.eigenvects()
|
||||
assert eigenvects[0] == (
|
||||
-1, 1,
|
||||
[Matrix([[-1], [1], [1], [1]])]
|
||||
)
|
||||
assert eigenvects[1] == (
|
||||
1, 2,
|
||||
[Matrix([[1], [0], [1], [0]]), Matrix([[2], [1], [0], [1]])]
|
||||
)
|
||||
assert eigenvects[2] == (
|
||||
-I, 1,
|
||||
[Matrix([[0], [-1], [0], [1]])]
|
||||
)
|
||||
|
||||
# XXX We skip test for some parts of eigenvectors which are very
|
||||
# complicated and fragile under expression tree changes
|
||||
A = DFT(5).as_explicit().expand(complex=True)
|
||||
eigenvects = A.eigenvects()
|
||||
assert eigenvects[0] == (
|
||||
-1, 1,
|
||||
[Matrix([[1 - sqrt(5)], [1], [1], [1], [1]])]
|
||||
)
|
||||
assert eigenvects[1] == (
|
||||
1, 2,
|
||||
[Matrix([[S(1)/2 + sqrt(5)/2], [0], [1], [1], [0]]),
|
||||
Matrix([[S(1)/2 + sqrt(5)/2], [1], [0], [0], [1]])]
|
||||
)
|
||||
|
||||
|
||||
def test_issue_20752():
|
||||
b = symbols('b', nonzero=True)
|
||||
m = Matrix([[0, 0, 0], [0, b, 0], [0, 0, b]])
|
||||
assert m.is_positive_semidefinite is None
|
||||
|
||||
|
||||
def test_issue_25282():
|
||||
dd = sd = [0] * 11 + [1]
|
||||
ds = [2, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0]
|
||||
ss = ds.copy()
|
||||
ss[8] = 2
|
||||
|
||||
def rotate(x, i):
|
||||
return x[i:] + x[:i]
|
||||
|
||||
mat = []
|
||||
for i in range(12):
|
||||
mat.append(rotate(ss, i) + rotate(sd, i))
|
||||
for i in range(12):
|
||||
mat.append(rotate(ds, i) + rotate(dd, i))
|
||||
|
||||
assert sum(Matrix(mat).eigenvals().values()) == 24
|
||||
@@ -0,0 +1,108 @@
|
||||
from sympy.combinatorics import Permutation
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.matrices import Matrix
|
||||
from sympy.matrices.expressions import (
|
||||
PermutationMatrix, BlockDiagMatrix, BlockMatrix)
|
||||
|
||||
|
||||
def test_connected_components():
|
||||
a, b, c, d, e, f, g, h, i, j, k, l, m = symbols('a:m')
|
||||
|
||||
M = Matrix([
|
||||
[a, 0, 0, 0, b, 0, 0, 0, 0, 0, c, 0, 0],
|
||||
[0, d, 0, 0, 0, e, 0, 0, 0, 0, 0, f, 0],
|
||||
[0, 0, g, 0, 0, 0, h, 0, 0, 0, 0, 0, i],
|
||||
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, m, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[j, 0, 0, 0, k, 0, 0, 1, 0, 0, l, 0, 0],
|
||||
[0, j, 0, 0, 0, k, 0, 0, 1, 0, 0, l, 0],
|
||||
[0, 0, j, 0, 0, 0, k, 0, 0, 1, 0, 0, l],
|
||||
[0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1, 0, 0],
|
||||
[0, 0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0, d, 0, 0, 0, 0, 0, 1]])
|
||||
cc = M.connected_components()
|
||||
assert cc == [[0, 4, 7, 10], [1, 5, 8, 11], [2, 6, 9, 12], [3]]
|
||||
|
||||
P, B = M.connected_components_decomposition()
|
||||
p = Permutation([0, 4, 7, 10, 1, 5, 8, 11, 2, 6, 9, 12, 3])
|
||||
assert P == PermutationMatrix(p)
|
||||
|
||||
B0 = Matrix([
|
||||
[a, b, 0, c],
|
||||
[m, 1, 0, 0],
|
||||
[j, k, 1, l],
|
||||
[0, d, 0, 1]])
|
||||
B1 = Matrix([
|
||||
[d, e, 0, f],
|
||||
[m, 1, 0, 0],
|
||||
[j, k, 1, l],
|
||||
[0, d, 0, 1]])
|
||||
B2 = Matrix([
|
||||
[g, h, 0, i],
|
||||
[m, 1, 0, 0],
|
||||
[j, k, 1, l],
|
||||
[0, d, 0, 1]])
|
||||
B3 = Matrix([[1]])
|
||||
assert B == BlockDiagMatrix(B0, B1, B2, B3)
|
||||
|
||||
|
||||
def test_strongly_connected_components():
|
||||
M = Matrix([
|
||||
[11, 14, 10, 0, 15, 0],
|
||||
[0, 44, 0, 0, 45, 0],
|
||||
[1, 4, 0, 0, 5, 0],
|
||||
[0, 0, 0, 22, 0, 23],
|
||||
[0, 54, 0, 0, 55, 0],
|
||||
[0, 0, 0, 32, 0, 33]])
|
||||
scc = M.strongly_connected_components()
|
||||
assert scc == [[1, 4], [0, 2], [3, 5]]
|
||||
|
||||
P, B = M.strongly_connected_components_decomposition()
|
||||
p = Permutation([1, 4, 0, 2, 3, 5])
|
||||
assert P == PermutationMatrix(p)
|
||||
assert B == BlockMatrix([
|
||||
[
|
||||
Matrix([[44, 45], [54, 55]]),
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix.zeros(2, 2)
|
||||
],
|
||||
[
|
||||
Matrix([[14, 15], [4, 5]]),
|
||||
Matrix([[11, 10], [1, 0]]),
|
||||
Matrix.zeros(2, 2)
|
||||
],
|
||||
[
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix([[22, 23], [32, 33]])
|
||||
]
|
||||
])
|
||||
P = P.as_explicit()
|
||||
B = B.as_explicit()
|
||||
assert P.T * B * P == M
|
||||
|
||||
P, B = M.strongly_connected_components_decomposition(lower=False)
|
||||
p = Permutation([3, 5, 0, 2, 1, 4])
|
||||
assert P == PermutationMatrix(p)
|
||||
assert B == BlockMatrix([
|
||||
[
|
||||
Matrix([[22, 23], [32, 33]]),
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix.zeros(2, 2)
|
||||
],
|
||||
[
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix([[11, 10], [1, 0]]),
|
||||
Matrix([[14, 15], [4, 5]])
|
||||
],
|
||||
[
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix.zeros(2, 2),
|
||||
Matrix([[44, 45], [54, 55]])
|
||||
]
|
||||
])
|
||||
P = P.as_explicit()
|
||||
B = B.as_explicit()
|
||||
assert P.T * B * P == M
|
||||
@@ -0,0 +1,136 @@
|
||||
from itertools import product
|
||||
|
||||
from sympy.core.relational import (Equality, Unequality)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.integrals.integrals import integrate
|
||||
from sympy.matrices.dense import (Matrix, eye, zeros)
|
||||
from sympy.matrices.immutable import ImmutableMatrix
|
||||
from sympy.matrices import SparseMatrix
|
||||
from sympy.matrices.immutable import \
|
||||
ImmutableDenseMatrix, ImmutableSparseMatrix
|
||||
from sympy.abc import x, y
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
IM = ImmutableDenseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
ISM = ImmutableSparseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
ieye = ImmutableDenseMatrix(eye(3))
|
||||
|
||||
|
||||
def test_creation():
|
||||
assert IM.shape == ISM.shape == (3, 3)
|
||||
assert IM[1, 2] == ISM[1, 2] == 6
|
||||
assert IM[2, 2] == ISM[2, 2] == 9
|
||||
|
||||
|
||||
def test_immutability():
|
||||
with raises(TypeError):
|
||||
IM[2, 2] = 5
|
||||
with raises(TypeError):
|
||||
ISM[2, 2] = 5
|
||||
|
||||
|
||||
def test_slicing():
|
||||
assert IM[1, :] == ImmutableDenseMatrix([[4, 5, 6]])
|
||||
assert IM[:2, :2] == ImmutableDenseMatrix([[1, 2], [4, 5]])
|
||||
assert ISM[1, :] == ImmutableSparseMatrix([[4, 5, 6]])
|
||||
assert ISM[:2, :2] == ImmutableSparseMatrix([[1, 2], [4, 5]])
|
||||
|
||||
|
||||
def test_subs():
|
||||
A = ImmutableMatrix([[1, 2], [3, 4]])
|
||||
B = ImmutableMatrix([[1, 2], [x, 4]])
|
||||
C = ImmutableMatrix([[-x, x*y], [-(x + y), y**2]])
|
||||
assert B.subs(x, 3) == A
|
||||
assert (x*B).subs(x, 3) == 3*A
|
||||
assert (x*eye(2) + B).subs(x, 3) == 3*eye(2) + A
|
||||
assert C.subs([[x, -1], [y, -2]]) == A
|
||||
assert C.subs([(x, -1), (y, -2)]) == A
|
||||
assert C.subs({x: -1, y: -2}) == A
|
||||
assert C.subs({x: y - 1, y: x - 1}, simultaneous=True) == \
|
||||
ImmutableMatrix([[1 - y, (x - 1)*(y - 1)], [2 - x - y, (x - 1)**2]])
|
||||
|
||||
|
||||
def test_as_immutable():
|
||||
data = [[1, 2], [3, 4]]
|
||||
X = Matrix(data)
|
||||
assert sympify(X) == X.as_immutable() == ImmutableMatrix(data)
|
||||
|
||||
data = {(0, 0): 1, (0, 1): 2, (1, 0): 3, (1, 1): 4}
|
||||
X = SparseMatrix(2, 2, data)
|
||||
assert sympify(X) == X.as_immutable() == ImmutableSparseMatrix(2, 2, data)
|
||||
|
||||
|
||||
def test_function_return_types():
|
||||
# Lets ensure that decompositions of immutable matrices remain immutable
|
||||
# I.e. do MatrixBase methods return the correct class?
|
||||
X = ImmutableMatrix([[1, 2], [3, 4]])
|
||||
Y = ImmutableMatrix([[1], [0]])
|
||||
q, r = X.QRdecomposition()
|
||||
assert (type(q), type(r)) == (ImmutableMatrix, ImmutableMatrix)
|
||||
|
||||
assert type(X.LUsolve(Y)) == ImmutableMatrix
|
||||
assert type(X.QRsolve(Y)) == ImmutableMatrix
|
||||
|
||||
X = ImmutableMatrix([[5, 2], [2, 7]])
|
||||
assert X.T == X
|
||||
assert X.is_symmetric
|
||||
assert type(X.cholesky()) == ImmutableMatrix
|
||||
L, D = X.LDLdecomposition()
|
||||
assert (type(L), type(D)) == (ImmutableMatrix, ImmutableMatrix)
|
||||
|
||||
X = ImmutableMatrix([[1, 2], [2, 1]])
|
||||
assert X.is_diagonalizable()
|
||||
assert X.det() == -3
|
||||
assert X.norm(2) == 3
|
||||
|
||||
assert type(X.eigenvects()[0][2][0]) == ImmutableMatrix
|
||||
|
||||
assert type(zeros(3, 3).as_immutable().nullspace()[0]) == ImmutableMatrix
|
||||
|
||||
X = ImmutableMatrix([[1, 0], [2, 1]])
|
||||
assert type(X.lower_triangular_solve(Y)) == ImmutableMatrix
|
||||
assert type(X.T.upper_triangular_solve(Y)) == ImmutableMatrix
|
||||
|
||||
assert type(X.minor_submatrix(0, 0)) == ImmutableMatrix
|
||||
|
||||
# issue 6279
|
||||
# https://github.com/sympy/sympy/issues/6279
|
||||
# Test that Immutable _op_ Immutable => Immutable and not MatExpr
|
||||
|
||||
|
||||
def test_immutable_evaluation():
|
||||
X = ImmutableMatrix(eye(3))
|
||||
A = ImmutableMatrix(3, 3, range(9))
|
||||
assert isinstance(X + A, ImmutableMatrix)
|
||||
assert isinstance(X * A, ImmutableMatrix)
|
||||
assert isinstance(X * 2, ImmutableMatrix)
|
||||
assert isinstance(2 * X, ImmutableMatrix)
|
||||
assert isinstance(A**2, ImmutableMatrix)
|
||||
|
||||
|
||||
def test_deterimant():
|
||||
assert ImmutableMatrix(4, 4, lambda i, j: i + j).det() == 0
|
||||
|
||||
|
||||
def test_Equality():
|
||||
assert Equality(IM, IM) is S.true
|
||||
assert Unequality(IM, IM) is S.false
|
||||
assert Equality(IM, IM.subs(1, 2)) is S.false
|
||||
assert Unequality(IM, IM.subs(1, 2)) is S.true
|
||||
assert Equality(IM, 2) is S.false
|
||||
assert Unequality(IM, 2) is S.true
|
||||
M = ImmutableMatrix([x, y])
|
||||
assert Equality(M, IM) is S.false
|
||||
assert Unequality(M, IM) is S.true
|
||||
assert Equality(M, M.subs(x, 2)).subs(x, 2) is S.true
|
||||
assert Unequality(M, M.subs(x, 2)).subs(x, 2) is S.false
|
||||
assert Equality(M, M.subs(x, 2)).subs(x, 3) is S.false
|
||||
assert Unequality(M, M.subs(x, 2)).subs(x, 3) is S.true
|
||||
|
||||
|
||||
def test_integrate():
|
||||
intIM = integrate(IM, x)
|
||||
assert intIM.shape == IM.shape
|
||||
assert all(intIM[i, j] == (1 + j + 3*i)*x for i, j in
|
||||
product(range(3), range(3)))
|
||||
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
We have a few different kind of Matrices
|
||||
Matrix, ImmutableMatrix, MatrixExpr
|
||||
|
||||
Here we test the extent to which they cooperate
|
||||
"""
|
||||
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.matrices import (Matrix, MatrixSymbol, eye, Identity,
|
||||
ImmutableMatrix)
|
||||
from sympy.matrices.expressions import MatrixExpr, MatAdd
|
||||
from sympy.matrices.matrixbase import classof
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
SM = MatrixSymbol('X', 3, 3)
|
||||
SV = MatrixSymbol('v', 3, 1)
|
||||
MM = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
IM = ImmutableMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
meye = eye(3)
|
||||
imeye = ImmutableMatrix(eye(3))
|
||||
ideye = Identity(3)
|
||||
a, b, c = symbols('a,b,c')
|
||||
|
||||
|
||||
def test_IM_MM():
|
||||
assert isinstance(MM + IM, ImmutableMatrix)
|
||||
assert isinstance(IM + MM, ImmutableMatrix)
|
||||
assert isinstance(2*IM + MM, ImmutableMatrix)
|
||||
assert MM.equals(IM)
|
||||
|
||||
|
||||
def test_ME_MM():
|
||||
assert isinstance(Identity(3) + MM, MatrixExpr)
|
||||
assert isinstance(SM + MM, MatAdd)
|
||||
assert isinstance(MM + SM, MatAdd)
|
||||
assert (Identity(3) + MM)[1, 1] == 6
|
||||
|
||||
|
||||
def test_equality():
|
||||
a, b, c = Identity(3), eye(3), ImmutableMatrix(eye(3))
|
||||
for x in [a, b, c]:
|
||||
for y in [a, b, c]:
|
||||
assert x.equals(y)
|
||||
|
||||
|
||||
def test_matrix_symbol_MM():
|
||||
X = MatrixSymbol('X', 3, 3)
|
||||
Y = eye(3) + X
|
||||
assert Y[1, 1] == 1 + X[1, 1]
|
||||
|
||||
|
||||
def test_matrix_symbol_vector_matrix_multiplication():
|
||||
A = MM * SV
|
||||
B = IM * SV
|
||||
assert A == B
|
||||
C = (SV.T * MM.T).T
|
||||
assert B == C
|
||||
D = (SV.T * IM.T).T
|
||||
assert C == D
|
||||
|
||||
|
||||
def test_indexing_interactions():
|
||||
assert (a * IM)[1, 1] == 5*a
|
||||
assert (SM + IM)[1, 1] == SM[1, 1] + IM[1, 1]
|
||||
assert (SM * IM)[1, 1] == SM[1, 0]*IM[0, 1] + SM[1, 1]*IM[1, 1] + \
|
||||
SM[1, 2]*IM[2, 1]
|
||||
|
||||
|
||||
def test_classof():
|
||||
A = Matrix(3, 3, range(9))
|
||||
B = ImmutableMatrix(3, 3, range(9))
|
||||
C = MatrixSymbol('C', 3, 3)
|
||||
assert classof(A, A) == Matrix
|
||||
assert classof(B, B) == ImmutableMatrix
|
||||
assert classof(A, B) == ImmutableMatrix
|
||||
assert classof(B, A) == ImmutableMatrix
|
||||
raises(TypeError, lambda: classof(A, C))
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
||||
from sympy.testing.pytest import warns_deprecated_sympy
|
||||
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.polys.polytools import Poly
|
||||
from sympy.matrices import Matrix, randMatrix
|
||||
from sympy.matrices.normalforms import (
|
||||
invariant_factors,
|
||||
smith_normal_form,
|
||||
smith_normal_decomp,
|
||||
hermite_normal_form,
|
||||
is_smith_normal_form,
|
||||
)
|
||||
from sympy.polys.domains import ZZ, QQ
|
||||
from sympy.core.numbers import Integer
|
||||
|
||||
import random
|
||||
|
||||
|
||||
def test_smith_normal():
|
||||
m = Matrix([[12,6,4,8],[3,9,6,12],[2,16,14,28],[20,10,10,20]])
|
||||
smf = Matrix([[1, 0, 0, 0], [0, 10, 0, 0], [0, 0, 30, 0], [0, 0, 0, 0]])
|
||||
assert smith_normal_form(m) == smf
|
||||
|
||||
a, s, t = smith_normal_decomp(m)
|
||||
assert a == s * m * t
|
||||
|
||||
x = Symbol('x')
|
||||
with warns_deprecated_sympy():
|
||||
m = Matrix([[Poly(x-1), Poly(1, x),Poly(-1,x)],
|
||||
[0, Poly(x), Poly(-1,x)],
|
||||
[Poly(0,x),Poly(-1,x),Poly(x)]])
|
||||
invs = 1, x - 1, x**2 - 1
|
||||
assert invariant_factors(m, domain=QQ[x]) == invs
|
||||
|
||||
m = Matrix([[2, 4]])
|
||||
smf = Matrix([[2, 0]])
|
||||
assert smith_normal_form(m) == smf
|
||||
|
||||
prng = random.Random(0)
|
||||
for i in range(6):
|
||||
for j in range(6):
|
||||
for _ in range(10 if i*j else 1):
|
||||
m = randMatrix(i, j, max=5, percent=50, prng=prng)
|
||||
a, s, t = smith_normal_decomp(m)
|
||||
assert a == s * m * t
|
||||
assert is_smith_normal_form(a)
|
||||
s.inv().to_DM(ZZ)
|
||||
t.inv().to_DM(ZZ)
|
||||
|
||||
a, s, t = smith_normal_decomp(m, QQ)
|
||||
assert a == s * m * t
|
||||
assert is_smith_normal_form(a)
|
||||
s.inv()
|
||||
t.inv()
|
||||
|
||||
|
||||
def test_smith_normal_deprecated():
|
||||
from sympy.polys.solvers import RawMatrix as Matrix
|
||||
|
||||
with warns_deprecated_sympy():
|
||||
m = Matrix([[12, 6, 4,8],[3,9,6,12],[2,16,14,28],[20,10,10,20]])
|
||||
setattr(m, 'ring', ZZ)
|
||||
with warns_deprecated_sympy():
|
||||
smf = Matrix([[1, 0, 0, 0], [0, 10, 0, 0], [0, 0, 30, 0], [0, 0, 0, 0]])
|
||||
assert smith_normal_form(m) == smf
|
||||
|
||||
x = Symbol('x')
|
||||
with warns_deprecated_sympy():
|
||||
m = Matrix([[Poly(x-1), Poly(1, x),Poly(-1,x)],
|
||||
[0, Poly(x), Poly(-1,x)],
|
||||
[Poly(0,x),Poly(-1,x),Poly(x)]])
|
||||
setattr(m, 'ring', QQ[x])
|
||||
invs = (Poly(1, x, domain='QQ'), Poly(x - 1, domain='QQ'), Poly(x**2 - 1, domain='QQ'))
|
||||
assert invariant_factors(m) == invs
|
||||
|
||||
with warns_deprecated_sympy():
|
||||
m = Matrix([[2, 4]])
|
||||
setattr(m, 'ring', ZZ)
|
||||
with warns_deprecated_sympy():
|
||||
smf = Matrix([[2, 0]])
|
||||
assert smith_normal_form(m) == smf
|
||||
|
||||
|
||||
def test_hermite_normal():
|
||||
m = Matrix([[2, 7, 17, 29, 41], [3, 11, 19, 31, 43], [5, 13, 23, 37, 47]])
|
||||
hnf = Matrix([[1, 0, 0], [0, 2, 1], [0, 0, 1]])
|
||||
assert hermite_normal_form(m) == hnf
|
||||
|
||||
tr_hnf = Matrix([[37, 0, 19], [222, -6, 113], [48, 0, 25], [0, 2, 1], [0, 0, 1]])
|
||||
assert hermite_normal_form(m.transpose()) == tr_hnf
|
||||
|
||||
m = Matrix([[8, 28, 68, 116, 164], [3, 11, 19, 31, 43], [5, 13, 23, 37, 47]])
|
||||
hnf = Matrix([[4, 0, 0], [0, 2, 1], [0, 0, 1]])
|
||||
assert hermite_normal_form(m) == hnf
|
||||
assert hermite_normal_form(m, D=8) == hnf
|
||||
assert hermite_normal_form(m, D=ZZ(8)) == hnf
|
||||
assert hermite_normal_form(m, D=Integer(8)) == hnf
|
||||
|
||||
m = Matrix([[10, 8, 6, 30, 2], [45, 36, 27, 18, 9], [5, 4, 3, 2, 1]])
|
||||
hnf = Matrix([[26, 2], [0, 9], [0, 1]])
|
||||
assert hermite_normal_form(m) == hnf
|
||||
|
||||
m = Matrix([[2, 7], [0, 0], [0, 0]])
|
||||
hnf = Matrix([[1], [0], [0]])
|
||||
assert hermite_normal_form(m) == hnf
|
||||
|
||||
|
||||
def test_issue_23410():
|
||||
A = Matrix([[1, 12], [0, 8], [0, 5]])
|
||||
H = Matrix([[1, 0], [0, 8], [0, 5]])
|
||||
assert hermite_normal_form(A) == H
|
||||
@@ -0,0 +1,351 @@
|
||||
from sympy.core.numbers import I
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.matrices import Matrix, zeros, eye
|
||||
from sympy.core.symbol import Symbol
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.functions.elementary.miscellaneous import sqrt
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.abc import x
|
||||
|
||||
|
||||
# Matrix tests
|
||||
def test_row_op():
|
||||
e = eye(3)
|
||||
|
||||
raises(ValueError, lambda: e.elementary_row_op("abc"))
|
||||
raises(ValueError, lambda: e.elementary_row_op())
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->kn', row=5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->kn', row=-5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n<->m', row1=1, row2=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n<->m', row1=5, row2=1))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n<->m', row1=-5, row2=1))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n<->m', row1=1, row2=-5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->n+km', row1=1, row2=5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->n+km', row1=5, row2=1, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->n+km', row1=-5, row2=1, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->n+km', row1=1, row2=-5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_row_op('n->n+km', row1=1, row2=1, k=5))
|
||||
|
||||
# test various ways to set arguments
|
||||
assert e.elementary_row_op("n->kn", 0, 5) == Matrix([[5, 0, 0], [0, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->kn", 1, 5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->kn", row=1, k=5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->kn", row1=1, k=5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n<->m", 0, 1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n<->m", row1=0, row2=1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n<->m", row=0, row2=1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->n+km", 0, 5, 1) == Matrix([[1, 5, 0], [0, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->n+km", row=0, k=5, row2=1) == Matrix([[1, 5, 0], [0, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_row_op("n->n+km", row1=0, k=5, row2=1) == Matrix([[1, 5, 0], [0, 1, 0], [0, 0, 1]])
|
||||
|
||||
# make sure the matrix doesn't change size
|
||||
a = Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_row_op("n->kn", 1, 5) == Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_row_op("n<->m", 0, 1) == Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_row_op("n->n+km", 0, 5, 1) == Matrix(2, 3, [0]*6)
|
||||
|
||||
|
||||
def test_col_op():
|
||||
e = eye(3)
|
||||
|
||||
raises(ValueError, lambda: e.elementary_col_op("abc"))
|
||||
raises(ValueError, lambda: e.elementary_col_op())
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->kn', col=5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->kn', col=-5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n<->m', col1=1, col2=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n<->m', col1=5, col2=1))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n<->m', col1=-5, col2=1))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n<->m', col1=1, col2=-5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->n+km', col1=1, col2=5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->n+km', col1=5, col2=1, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->n+km', col1=-5, col2=1, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->n+km', col1=1, col2=-5, k=5))
|
||||
raises(ValueError, lambda: e.elementary_col_op('n->n+km', col1=1, col2=1, k=5))
|
||||
|
||||
# test various ways to set arguments
|
||||
assert e.elementary_col_op("n->kn", 0, 5) == Matrix([[5, 0, 0], [0, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->kn", 1, 5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->kn", col=1, k=5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->kn", col1=1, k=5) == Matrix([[1, 0, 0], [0, 5, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n<->m", 0, 1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n<->m", col1=0, col2=1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n<->m", col=0, col2=1) == Matrix([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->n+km", 0, 5, 1) == Matrix([[1, 0, 0], [5, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->n+km", col=0, k=5, col2=1) == Matrix([[1, 0, 0], [5, 1, 0], [0, 0, 1]])
|
||||
assert e.elementary_col_op("n->n+km", col1=0, k=5, col2=1) == Matrix([[1, 0, 0], [5, 1, 0], [0, 0, 1]])
|
||||
|
||||
# make sure the matrix doesn't change size
|
||||
a = Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_col_op("n->kn", 1, 5) == Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_col_op("n<->m", 0, 1) == Matrix(2, 3, [0]*6)
|
||||
assert a.elementary_col_op("n->n+km", 0, 5, 1) == Matrix(2, 3, [0]*6)
|
||||
|
||||
|
||||
def test_is_echelon():
|
||||
zro = zeros(3)
|
||||
ident = eye(3)
|
||||
|
||||
assert zro.is_echelon
|
||||
assert ident.is_echelon
|
||||
|
||||
a = Matrix(0, 0, [])
|
||||
assert a.is_echelon
|
||||
|
||||
a = Matrix(2, 3, [3, 2, 1, 0, 0, 6])
|
||||
assert a.is_echelon
|
||||
|
||||
a = Matrix(2, 3, [0, 0, 6, 3, 2, 1])
|
||||
assert not a.is_echelon
|
||||
|
||||
x = Symbol('x')
|
||||
a = Matrix(3, 1, [x, 0, 0])
|
||||
assert a.is_echelon
|
||||
|
||||
a = Matrix(3, 1, [x, x, 0])
|
||||
assert not a.is_echelon
|
||||
|
||||
a = Matrix(3, 3, [0, 0, 0, 1, 2, 3, 0, 0, 0])
|
||||
assert not a.is_echelon
|
||||
|
||||
|
||||
def test_echelon_form():
|
||||
# echelon form is not unique, but the result
|
||||
# must be row-equivalent to the original matrix
|
||||
# and it must be in echelon form.
|
||||
|
||||
a = zeros(3)
|
||||
e = eye(3)
|
||||
|
||||
# we can assume the zero matrix and the identity matrix shouldn't change
|
||||
assert a.echelon_form() == a
|
||||
assert e.echelon_form() == e
|
||||
|
||||
a = Matrix(0, 0, [])
|
||||
assert a.echelon_form() == a
|
||||
|
||||
a = Matrix(1, 1, [5])
|
||||
assert a.echelon_form() == a
|
||||
|
||||
# now we get to the real tests
|
||||
|
||||
def verify_row_null_space(mat, rows, nulls):
|
||||
for v in nulls:
|
||||
assert all(t.is_zero for t in a_echelon*v)
|
||||
for v in rows:
|
||||
if not all(t.is_zero for t in v):
|
||||
assert not all(t.is_zero for t in a_echelon*v.transpose())
|
||||
|
||||
a = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
nulls = [Matrix([
|
||||
[ 1],
|
||||
[-2],
|
||||
[ 1]])]
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
|
||||
a = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 8])
|
||||
nulls = []
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
a = Matrix(3, 3, [2, 1, 3, 0, 0, 0, 2, 1, 3])
|
||||
nulls = [Matrix([
|
||||
[Rational(-1, 2)],
|
||||
[ 1],
|
||||
[ 0]]),
|
||||
Matrix([
|
||||
[Rational(-3, 2)],
|
||||
[ 0],
|
||||
[ 1]])]
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
# this one requires a row swap
|
||||
a = Matrix(3, 3, [2, 1, 3, 0, 0, 0, 1, 1, 3])
|
||||
nulls = [Matrix([
|
||||
[ 0],
|
||||
[ -3],
|
||||
[ 1]])]
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
a = Matrix(3, 3, [0, 3, 3, 0, 2, 2, 0, 1, 1])
|
||||
nulls = [Matrix([
|
||||
[1],
|
||||
[0],
|
||||
[0]]),
|
||||
Matrix([
|
||||
[ 0],
|
||||
[-1],
|
||||
[ 1]])]
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
a = Matrix(2, 3, [2, 2, 3, 3, 3, 0])
|
||||
nulls = [Matrix([
|
||||
[-1],
|
||||
[1],
|
||||
[0]])]
|
||||
rows = [a[i, :] for i in range(a.rows)]
|
||||
a_echelon = a.echelon_form()
|
||||
assert a_echelon.is_echelon
|
||||
verify_row_null_space(a, rows, nulls)
|
||||
|
||||
|
||||
def test_rref():
|
||||
e = Matrix(0, 0, [])
|
||||
assert e.rref(pivots=False) == e
|
||||
|
||||
e = Matrix(1, 1, [1])
|
||||
a = Matrix(1, 1, [5])
|
||||
assert e.rref(pivots=False) == a.rref(pivots=False) == e
|
||||
|
||||
a = Matrix(3, 1, [1, 2, 3])
|
||||
assert a.rref(pivots=False) == Matrix([[1], [0], [0]])
|
||||
|
||||
a = Matrix(1, 3, [1, 2, 3])
|
||||
assert a.rref(pivots=False) == Matrix([[1, 2, 3]])
|
||||
|
||||
a = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
assert a.rref(pivots=False) == Matrix([
|
||||
[1, 0, -1],
|
||||
[0, 1, 2],
|
||||
[0, 0, 0]])
|
||||
|
||||
a = Matrix(3, 3, [1, 2, 3, 1, 2, 3, 1, 2, 3])
|
||||
b = Matrix(3, 3, [1, 2, 3, 0, 0, 0, 0, 0, 0])
|
||||
c = Matrix(3, 3, [0, 0, 0, 1, 2, 3, 0, 0, 0])
|
||||
d = Matrix(3, 3, [0, 0, 0, 0, 0, 0, 1, 2, 3])
|
||||
assert a.rref(pivots=False) == \
|
||||
b.rref(pivots=False) == \
|
||||
c.rref(pivots=False) == \
|
||||
d.rref(pivots=False) == b
|
||||
|
||||
e = eye(3)
|
||||
z = zeros(3)
|
||||
assert e.rref(pivots=False) == e
|
||||
assert z.rref(pivots=False) == z
|
||||
|
||||
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]])
|
||||
mat, pivot_offsets = a.rref()
|
||||
assert mat == Matrix([
|
||||
[1, -5, 0, 0, 1, 1, -1],
|
||||
[0, 0, 1, 0, 0, -1, 1],
|
||||
[0, 0, 0, 1, 1, -2, 1],
|
||||
[0, 0, 0, 0, 0, 0, 0]])
|
||||
assert pivot_offsets == (0, 2, 3)
|
||||
|
||||
a = Matrix([[Rational(1, 19), Rational(1, 5), 2, 3],
|
||||
[ 4, 5, 6, 7],
|
||||
[ 8, 9, 10, 11],
|
||||
[ 12, 13, 14, 15]])
|
||||
assert a.rref(pivots=False) == Matrix([
|
||||
[1, 0, 0, Rational(-76, 157)],
|
||||
[0, 1, 0, Rational(-5, 157)],
|
||||
[0, 0, 1, Rational(238, 157)],
|
||||
[0, 0, 0, 0]])
|
||||
|
||||
x = Symbol('x')
|
||||
a = Matrix(2, 3, [x, 1, 1, sqrt(x), x, 1])
|
||||
for i, j in zip(a.rref(pivots=False),
|
||||
[1, 0, sqrt(x)*(-x + 1)/(-x**Rational(5, 2) + x),
|
||||
0, 1, 1/(sqrt(x) + x + 1)]):
|
||||
assert simplify(i - j).is_zero
|
||||
|
||||
|
||||
def test_rref_rhs():
|
||||
a, b, c, d = symbols('a b c d')
|
||||
A = Matrix([[0, 0], [0, 0], [1, 2], [3, 4]])
|
||||
B = Matrix([a, b, c, d])
|
||||
assert A.rref_rhs(B) == (Matrix([
|
||||
[1, 0],
|
||||
[0, 1],
|
||||
[0, 0],
|
||||
[0, 0]]), Matrix([
|
||||
[ -2*c + d],
|
||||
[3*c/2 - d/2],
|
||||
[ a],
|
||||
[ b]]))
|
||||
|
||||
|
||||
def test_issue_17827():
|
||||
C = Matrix([
|
||||
[3, 4, -1, 1],
|
||||
[9, 12, -3, 3],
|
||||
[0, 2, 1, 3],
|
||||
[2, 3, 0, -2],
|
||||
[0, 3, 3, -5],
|
||||
[8, 15, 0, 6]
|
||||
])
|
||||
# Tests for row/col within valid range
|
||||
D = C.elementary_row_op('n<->m', row1=2, row2=5)
|
||||
E = C.elementary_row_op('n->n+km', row1=5, row2=3, k=-4)
|
||||
F = C.elementary_row_op('n->kn', row=5, k=2)
|
||||
assert(D[5, :] == Matrix([[0, 2, 1, 3]]))
|
||||
assert(E[5, :] == Matrix([[0, 3, 0, 14]]))
|
||||
assert(F[5, :] == Matrix([[16, 30, 0, 12]]))
|
||||
# Tests for row/col out of range
|
||||
raises(ValueError, lambda: C.elementary_row_op('n<->m', row1=2, row2=6))
|
||||
raises(ValueError, lambda: C.elementary_row_op('n->kn', row=7, k=2))
|
||||
raises(ValueError, lambda: C.elementary_row_op('n->n+km', row1=-1, row2=5, k=2))
|
||||
|
||||
def test_rank():
|
||||
m = Matrix([[1, 2], [x, 1 - 1/x]])
|
||||
assert m.rank() == 2
|
||||
n = Matrix(3, 3, range(1, 10))
|
||||
assert n.rank() == 2
|
||||
p = zeros(3)
|
||||
assert p.rank() == 0
|
||||
|
||||
def test_issue_11434():
|
||||
ax, ay, bx, by, cx, cy, dx, dy, ex, ey, t0, t1 = \
|
||||
symbols('a_x a_y b_x b_y c_x c_y d_x d_y e_x e_y t_0 t_1')
|
||||
M = Matrix([[ax, ay, ax*t0, ay*t0, 0],
|
||||
[bx, by, bx*t0, by*t0, 0],
|
||||
[cx, cy, cx*t0, cy*t0, 1],
|
||||
[dx, dy, dx*t0, dy*t0, 1],
|
||||
[ex, ey, 2*ex*t1 - ex*t0, 2*ey*t1 - ey*t0, 0]])
|
||||
assert M.rank() == 4
|
||||
|
||||
def test_rank_regression_from_so():
|
||||
# see:
|
||||
# https://stackoverflow.com/questions/19072700/why-does-sympy-give-me-the-wrong-answer-when-i-row-reduce-a-symbolic-matrix
|
||||
|
||||
nu, lamb = symbols('nu, lambda')
|
||||
A = Matrix([[-3*nu, 1, 0, 0],
|
||||
[ 3*nu, -2*nu - 1, 2, 0],
|
||||
[ 0, 2*nu, (-1*nu) - lamb - 2, 3],
|
||||
[ 0, 0, nu + lamb, -3]])
|
||||
expected_reduced = Matrix([[1, 0, 0, 1/(nu**2*(-lamb - nu))],
|
||||
[0, 1, 0, 3/(nu*(-lamb - nu))],
|
||||
[0, 0, 1, 3/(-lamb - nu)],
|
||||
[0, 0, 0, 0]])
|
||||
expected_pivots = (0, 1, 2)
|
||||
|
||||
reduced, pivots = A.rref()
|
||||
|
||||
assert simplify(expected_reduced - reduced) == zeros(*A.shape)
|
||||
assert pivots == expected_pivots
|
||||
|
||||
def test_issue_15872():
|
||||
A = Matrix([[1, 1, 1, 0], [-2, -1, 0, -1], [0, 0, -1, -1], [0, 0, 2, 1]])
|
||||
B = A - Matrix.eye(4) * I
|
||||
assert B.rank() == 3
|
||||
assert (B**2).rank() == 2
|
||||
assert (B**3).rank() == 2
|
||||
@@ -0,0 +1,62 @@
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.matrices.exceptions import NonSquareMatrixError, NonInvertibleMatrixError
|
||||
|
||||
from sympy import Matrix, Rational
|
||||
|
||||
|
||||
def test_lll():
|
||||
A = Matrix([[1, 0, 0, 0, -20160],
|
||||
[0, 1, 0, 0, 33768],
|
||||
[0, 0, 1, 0, 39578],
|
||||
[0, 0, 0, 1, 47757]])
|
||||
L = Matrix([[ 10, -3, -2, 8, -4],
|
||||
[ 3, -9, 8, 1, -11],
|
||||
[ -3, 13, -9, -3, -9],
|
||||
[-12, -7, -11, 9, -1]])
|
||||
T = Matrix([[ 10, -3, -2, 8],
|
||||
[ 3, -9, 8, 1],
|
||||
[ -3, 13, -9, -3],
|
||||
[-12, -7, -11, 9]])
|
||||
assert A.lll() == L
|
||||
assert A.lll_transform() == (L, T)
|
||||
assert T * A == L
|
||||
|
||||
|
||||
def test_matrix_inv_mod():
|
||||
A = Matrix(2, 1, [1, 0])
|
||||
raises(NonSquareMatrixError, lambda: A.inv_mod(2))
|
||||
A = Matrix(2, 2, [1, 0, 0, 0])
|
||||
raises(NonInvertibleMatrixError, lambda: A.inv_mod(2))
|
||||
A = Matrix(2, 2, [1, 2, 3, 4])
|
||||
Ai = Matrix(2, 2, [1, 1, 0, 1])
|
||||
assert A.inv_mod(3) == Ai
|
||||
A = Matrix(2, 2, [1, 0, 0, 1])
|
||||
assert A.inv_mod(2) == A
|
||||
A = Matrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
raises(NonInvertibleMatrixError, lambda: A.inv_mod(5))
|
||||
A = Matrix(3, 3, [5, 1, 3, 2, 6, 0, 2, 1, 1])
|
||||
Ai = Matrix(3, 3, [6, 8, 0, 1, 5, 6, 5, 6, 4])
|
||||
assert A.inv_mod(9) == Ai
|
||||
A = Matrix(3, 3, [1, 6, -3, 4, 1, -5, 3, -5, 5])
|
||||
Ai = Matrix(3, 3, [4, 3, 3, 1, 2, 5, 1, 5, 1])
|
||||
assert A.inv_mod(6) == Ai
|
||||
A = Matrix(3, 3, [1, 6, 1, 4, 1, 5, 3, 2, 5])
|
||||
Ai = Matrix(3, 3, [6, 0, 3, 6, 6, 4, 1, 6, 1])
|
||||
assert A.inv_mod(7) == Ai
|
||||
A = Matrix([[1, 2], [3, Rational(3,4)]])
|
||||
raises(ValueError, lambda: A.inv_mod(2))
|
||||
A = Matrix([[1, 2], [3, 4]])
|
||||
raises(TypeError, lambda: A.inv_mod(Rational(1, 2)))
|
||||
# https://github.com/sympy/sympy/issues/27663
|
||||
M = Matrix([
|
||||
[2, 3, 1, 4],
|
||||
[1, 5, 3, 2],
|
||||
[3, 2, 4, 1],
|
||||
[4, 1, 2, 5],
|
||||
])
|
||||
assert M.inv_mod(26) == Matrix([
|
||||
[7, 21, 10, 10],
|
||||
[1, 7, 19, 3],
|
||||
[14, 1, 15, 1],
|
||||
[25, 23, 3, 12],
|
||||
])
|
||||
@@ -0,0 +1,615 @@
|
||||
import pytest
|
||||
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, symbols)
|
||||
from sympy.core.sympify import sympify
|
||||
from sympy.simplify.simplify import simplify
|
||||
from sympy.matrices.exceptions import (ShapeError, NonSquareMatrixError)
|
||||
from sympy.matrices import (
|
||||
ImmutableMatrix, Matrix, eye, ones, ImmutableDenseMatrix, dotprodsimp)
|
||||
from sympy.matrices.determinant import _det_laplace
|
||||
from sympy.testing.pytest import raises
|
||||
from sympy.matrices.exceptions import NonInvertibleMatrixError
|
||||
from sympy.polys.matrices.exceptions import DMShapeError
|
||||
from sympy.solvers.solveset import linsolve
|
||||
from sympy.abc import x, y
|
||||
|
||||
def test_issue_17247_expression_blowup_29():
|
||||
M = Matrix(S('''[
|
||||
[ -3/4, 45/32 - 37*I/16, 0, 0],
|
||||
[-149/64 + 49*I/32, -177/128 - 1369*I/128, 0, -2063/256 + 541*I/128],
|
||||
[ 0, 9/4 + 55*I/16, 2473/256 + 137*I/64, 0],
|
||||
[ 0, 0, 0, -177/128 - 1369*I/128]]'''))
|
||||
with dotprodsimp(True):
|
||||
assert M.gauss_jordan_solve(ones(4, 1)) == (Matrix(S('''[
|
||||
[ -32549314808672/3306971225785 - 17397006745216*I/3306971225785],
|
||||
[ 67439348256/3306971225785 - 9167503335872*I/3306971225785],
|
||||
[-15091965363354518272/21217636514687010905 + 16890163109293858304*I/21217636514687010905],
|
||||
[ -11328/952745 + 87616*I/952745]]''')), Matrix(0, 1, []))
|
||||
|
||||
def test_issue_17247_expression_blowup_30():
|
||||
M = Matrix(S('''[
|
||||
[ -3/4, 45/32 - 37*I/16, 0, 0],
|
||||
[-149/64 + 49*I/32, -177/128 - 1369*I/128, 0, -2063/256 + 541*I/128],
|
||||
[ 0, 9/4 + 55*I/16, 2473/256 + 137*I/64, 0],
|
||||
[ 0, 0, 0, -177/128 - 1369*I/128]]'''))
|
||||
with dotprodsimp(True):
|
||||
assert M.cholesky_solve(ones(4, 1)) == Matrix(S('''[
|
||||
[ -32549314808672/3306971225785 - 17397006745216*I/3306971225785],
|
||||
[ 67439348256/3306971225785 - 9167503335872*I/3306971225785],
|
||||
[-15091965363354518272/21217636514687010905 + 16890163109293858304*I/21217636514687010905],
|
||||
[ -11328/952745 + 87616*I/952745]]'''))
|
||||
|
||||
# @XFAIL # This calculation hangs with dotprodsimp.
|
||||
# def test_issue_17247_expression_blowup_31():
|
||||
# M = Matrix([
|
||||
# [x + 1, 1 - x, 0, 0],
|
||||
# [1 - x, x + 1, 0, x + 1],
|
||||
# [ 0, 1 - x, x + 1, 0],
|
||||
# [ 0, 0, 0, x + 1]])
|
||||
# with dotprodsimp(True):
|
||||
# assert M.LDLsolve(ones(4, 1)) == Matrix([
|
||||
# [(x + 1)/(4*x)],
|
||||
# [(x - 1)/(4*x)],
|
||||
# [(x + 1)/(4*x)],
|
||||
# [ 1/(x + 1)]])
|
||||
|
||||
|
||||
def test_LUsolve_iszerofunc():
|
||||
# taken from https://github.com/sympy/sympy/issues/24679
|
||||
|
||||
M = Matrix([[(x + 1)**2 - (x**2 + 2*x + 1), x], [x, 0]])
|
||||
b = Matrix([1, 1])
|
||||
is_zero_func = lambda e: False if e._random() else True
|
||||
|
||||
x_exp = Matrix([1/x, (1-(-x**2 - 2*x + (x+1)**2 - 1)/x)/x])
|
||||
|
||||
assert (x_exp - M.LUsolve(b, iszerofunc=is_zero_func)) == Matrix([0, 0])
|
||||
|
||||
|
||||
def test_issue_17247_expression_blowup_32():
|
||||
M = Matrix([
|
||||
[x + 1, 1 - x, 0, 0],
|
||||
[1 - x, x + 1, 0, x + 1],
|
||||
[ 0, 1 - x, x + 1, 0],
|
||||
[ 0, 0, 0, x + 1]])
|
||||
with dotprodsimp(True):
|
||||
assert M.LUsolve(ones(4, 1)) == Matrix([
|
||||
[(x + 1)/(4*x)],
|
||||
[(x - 1)/(4*x)],
|
||||
[(x + 1)/(4*x)],
|
||||
[ 1/(x + 1)]])
|
||||
|
||||
def test_LUsolve():
|
||||
A = Matrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = Matrix(3, 1, [3, 7, 5])
|
||||
b = A*x
|
||||
soln = A.LUsolve(b)
|
||||
assert soln == x
|
||||
A = Matrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4]])
|
||||
x = Matrix(3, 1, [-1, 2, 5])
|
||||
b = A*x
|
||||
soln = A.LUsolve(b)
|
||||
assert soln == x
|
||||
A = Matrix([[2, 1], [1, 0], [1, 0]]) # issue 14548
|
||||
b = Matrix([3, 1, 1])
|
||||
assert A.LUsolve(b) == Matrix([1, 1])
|
||||
b = Matrix([3, 1, 2]) # inconsistent
|
||||
raises(ValueError, lambda: A.LUsolve(b))
|
||||
A = Matrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4],
|
||||
[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = Matrix([2, 1, -4])
|
||||
b = A*x
|
||||
soln = A.LUsolve(b)
|
||||
assert soln == x
|
||||
A = Matrix([[0, -1, 2], [5, 10, 7]]) # underdetermined
|
||||
x = Matrix([-1, 2, 0])
|
||||
b = A*x
|
||||
raises(NotImplementedError, lambda: A.LUsolve(b))
|
||||
|
||||
A = Matrix(4, 4, lambda i, j: 1/(i+j+1) if i != 3 else 0)
|
||||
b = Matrix.zeros(4, 1)
|
||||
raises(NonInvertibleMatrixError, lambda: A.LUsolve(b))
|
||||
|
||||
|
||||
def test_LUsolve_noncommutative():
|
||||
a0, a1, a2, a3 = symbols("a:4", commutative=False)
|
||||
b0, b1 = symbols("b:2", commutative=False)
|
||||
A = Matrix([[a0, a1], [a2, a3]])
|
||||
check = A * A.LUsolve(Matrix([b0, b1]))
|
||||
assert check[0, 0].expand() == b0
|
||||
# Because sympy simplification is very limited with noncommutative expressions,
|
||||
# perform an explicit check with the second element
|
||||
assert check[1, 0] == (
|
||||
a2*a0**(-1)*(-a1*(-a2*a0**(-1)*a1 + a3)**(-1)*(-a2*a0**(-1)*b0 + b1) + b0)
|
||||
+ a3*(-a2*a0**(-1)*a1 + a3)**(-1)*(-a2*a0**(-1)*b0 + b1)
|
||||
)
|
||||
|
||||
|
||||
def test_QRsolve():
|
||||
A = Matrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = Matrix(3, 1, [3, 7, 5])
|
||||
b = A*x
|
||||
soln = A.QRsolve(b)
|
||||
assert soln == x
|
||||
x = Matrix([[1, 2], [3, 4], [5, 6]])
|
||||
b = A*x
|
||||
soln = A.QRsolve(b)
|
||||
assert soln == x
|
||||
|
||||
A = Matrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4]])
|
||||
x = Matrix(3, 1, [-1, 2, 5])
|
||||
b = A*x
|
||||
soln = A.QRsolve(b)
|
||||
assert soln == x
|
||||
x = Matrix([[7, 8], [9, 10], [11, 12]])
|
||||
b = A*x
|
||||
soln = A.QRsolve(b)
|
||||
assert soln == x
|
||||
|
||||
def test_errors():
|
||||
raises(ShapeError, lambda: Matrix([1]).LUsolve(Matrix([[1, 2], [3, 4]])))
|
||||
|
||||
def test_cholesky_solve():
|
||||
A = Matrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = Matrix(3, 1, [3, 7, 5])
|
||||
b = A*x
|
||||
soln = A.cholesky_solve(b)
|
||||
assert soln == x
|
||||
A = Matrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4]])
|
||||
x = Matrix(3, 1, [-1, 2, 5])
|
||||
b = A*x
|
||||
soln = A.cholesky_solve(b)
|
||||
assert soln == x
|
||||
A = Matrix(((1, 5), (5, 1)))
|
||||
x = Matrix((4, -3))
|
||||
b = A*x
|
||||
soln = A.cholesky_solve(b)
|
||||
assert soln == x
|
||||
A = Matrix(((9, 3*I), (-3*I, 5)))
|
||||
x = Matrix((-2, 1))
|
||||
b = A*x
|
||||
soln = A.cholesky_solve(b)
|
||||
assert expand_mul(soln) == x
|
||||
A = Matrix(((9*I, 3), (-3 + I, 5)))
|
||||
x = Matrix((2 + 3*I, -1))
|
||||
b = A*x
|
||||
soln = A.cholesky_solve(b)
|
||||
assert expand_mul(soln) == x
|
||||
a00, a01, a11, b0, b1 = symbols('a00, a01, a11, b0, b1')
|
||||
A = Matrix(((a00, a01), (a01, a11)))
|
||||
b = Matrix((b0, b1))
|
||||
x = A.cholesky_solve(b)
|
||||
assert simplify(A*x) == b
|
||||
|
||||
|
||||
def test_LDLsolve():
|
||||
A = Matrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = Matrix(3, 1, [3, 7, 5])
|
||||
b = A*x
|
||||
soln = A.LDLsolve(b)
|
||||
assert soln == x
|
||||
|
||||
A = Matrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4]])
|
||||
x = Matrix(3, 1, [-1, 2, 5])
|
||||
b = A*x
|
||||
soln = A.LDLsolve(b)
|
||||
assert soln == x
|
||||
|
||||
A = Matrix(((9, 3*I), (-3*I, 5)))
|
||||
x = Matrix((-2, 1))
|
||||
b = A*x
|
||||
soln = A.LDLsolve(b)
|
||||
assert expand_mul(soln) == x
|
||||
|
||||
A = Matrix(((9*I, 3), (-3 + I, 5)))
|
||||
x = Matrix((2 + 3*I, -1))
|
||||
b = A*x
|
||||
soln = A.LDLsolve(b)
|
||||
assert expand_mul(soln) == x
|
||||
|
||||
A = Matrix(((9, 3), (3, 9)))
|
||||
x = Matrix((1, 1))
|
||||
b = A * x
|
||||
soln = A.LDLsolve(b)
|
||||
assert expand_mul(soln) == x
|
||||
|
||||
A = Matrix([[-5, -3, -4], [-3, -7, 7]])
|
||||
x = Matrix([[8], [7], [-2]])
|
||||
b = A * x
|
||||
raises(NotImplementedError, lambda: A.LDLsolve(b))
|
||||
|
||||
|
||||
def test_lower_triangular_solve():
|
||||
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([1, 0]).lower_triangular_solve(Matrix([0, 1])))
|
||||
raises(ShapeError,
|
||||
lambda: Matrix([[1, 0], [0, 1]]).lower_triangular_solve(Matrix([1])))
|
||||
raises(ValueError,
|
||||
lambda: Matrix([[2, 1], [1, 2]]).lower_triangular_solve(
|
||||
Matrix([[1, 0], [0, 1]])))
|
||||
|
||||
A = Matrix([[1, 0], [0, 1]])
|
||||
B = Matrix([[x, y], [y, x]])
|
||||
C = Matrix([[4, 8], [2, 9]])
|
||||
|
||||
assert A.lower_triangular_solve(B) == B
|
||||
assert A.lower_triangular_solve(C) == C
|
||||
|
||||
|
||||
def test_upper_triangular_solve():
|
||||
|
||||
raises(NonSquareMatrixError,
|
||||
lambda: Matrix([1, 0]).upper_triangular_solve(Matrix([0, 1])))
|
||||
raises(ShapeError,
|
||||
lambda: Matrix([[1, 0], [0, 1]]).upper_triangular_solve(Matrix([1])))
|
||||
raises(TypeError,
|
||||
lambda: Matrix([[2, 1], [1, 2]]).upper_triangular_solve(
|
||||
Matrix([[1, 0], [0, 1]])))
|
||||
|
||||
A = Matrix([[1, 0], [0, 1]])
|
||||
B = Matrix([[x, y], [y, x]])
|
||||
C = Matrix([[2, 4], [3, 8]])
|
||||
|
||||
assert A.upper_triangular_solve(B) == B
|
||||
assert A.upper_triangular_solve(C) == C
|
||||
|
||||
|
||||
def test_diagonal_solve():
|
||||
raises(TypeError, lambda: Matrix([1, 1]).diagonal_solve(Matrix([1])))
|
||||
A = Matrix([[1, 0], [0, 1]])*2
|
||||
B = Matrix([[x, y], [y, x]])
|
||||
assert A.diagonal_solve(B) == B/2
|
||||
|
||||
A = Matrix([[1, 0], [1, 2]])
|
||||
raises(TypeError, lambda: A.diagonal_solve(B))
|
||||
|
||||
def test_pinv_solve():
|
||||
# Fully determined system (unique result, identical to other solvers).
|
||||
A = Matrix([[1, 5], [7, 9]])
|
||||
B = Matrix([12, 13])
|
||||
assert A.pinv_solve(B) == A.cholesky_solve(B)
|
||||
assert A.pinv_solve(B) == A.LDLsolve(B)
|
||||
assert A.pinv_solve(B) == Matrix([sympify('-43/26'), sympify('71/26')])
|
||||
assert A * A.pinv() * B == B
|
||||
# Fully determined, with two-dimensional B matrix.
|
||||
B = Matrix([[12, 13, 14], [15, 16, 17]])
|
||||
assert A.pinv_solve(B) == A.cholesky_solve(B)
|
||||
assert A.pinv_solve(B) == A.LDLsolve(B)
|
||||
assert A.pinv_solve(B) == Matrix([[-33, -37, -41], [69, 75, 81]]) / 26
|
||||
assert A * A.pinv() * B == B
|
||||
# Underdetermined system (infinite results).
|
||||
A = Matrix([[1, 0, 1], [0, 1, 1]])
|
||||
B = Matrix([5, 7])
|
||||
solution = A.pinv_solve(B)
|
||||
w = {}
|
||||
for s in solution.atoms(Symbol):
|
||||
# Extract dummy symbols used in the solution.
|
||||
w[s.name] = s
|
||||
assert solution == Matrix([[w['w0_0']/3 + w['w1_0']/3 - w['w2_0']/3 + 1],
|
||||
[w['w0_0']/3 + w['w1_0']/3 - w['w2_0']/3 + 3],
|
||||
[-w['w0_0']/3 - w['w1_0']/3 + w['w2_0']/3 + 4]])
|
||||
assert A * A.pinv() * B == B
|
||||
# Overdetermined system (least squares results).
|
||||
A = Matrix([[1, 0], [0, 0], [0, 1]])
|
||||
B = Matrix([3, 2, 1])
|
||||
assert A.pinv_solve(B) == Matrix([3, 1])
|
||||
# Proof the solution is not exact.
|
||||
assert A * A.pinv() * B != B
|
||||
|
||||
def test_pinv_rank_deficient():
|
||||
# Test the four properties of the pseudoinverse for various matrices.
|
||||
As = [Matrix([[1, 1, 1], [2, 2, 2]]),
|
||||
Matrix([[1, 0], [0, 0]]),
|
||||
Matrix([[1, 2], [2, 4], [3, 6]])]
|
||||
|
||||
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
|
||||
|
||||
for A in As:
|
||||
A_pinv = A.pinv(method="ED")
|
||||
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
|
||||
|
||||
# Test solving with rank-deficient matrices.
|
||||
A = Matrix([[1, 0], [0, 0]])
|
||||
# Exact, non-unique solution.
|
||||
B = Matrix([3, 0])
|
||||
solution = A.pinv_solve(B)
|
||||
w1 = solution.atoms(Symbol).pop()
|
||||
assert w1.name == 'w1_0'
|
||||
assert solution == Matrix([3, w1])
|
||||
assert A * A.pinv() * B == B
|
||||
# Least squares, non-unique solution.
|
||||
B = Matrix([3, 1])
|
||||
solution = A.pinv_solve(B)
|
||||
w1 = solution.atoms(Symbol).pop()
|
||||
assert w1.name == 'w1_0'
|
||||
assert solution == Matrix([3, w1])
|
||||
assert A * A.pinv() * B != B
|
||||
|
||||
def test_gauss_jordan_solve():
|
||||
|
||||
# Square, full rank, unique solution
|
||||
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
|
||||
b = Matrix([3, 6, 9])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
assert sol == Matrix([[-1], [2], [0]])
|
||||
assert params == Matrix(0, 1, [])
|
||||
|
||||
# Square, full rank, unique solution, B has more columns than rows
|
||||
A = eye(3)
|
||||
B = Matrix([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
|
||||
sol, params = A.gauss_jordan_solve(B)
|
||||
assert sol == B
|
||||
assert params == Matrix(0, 4, [])
|
||||
|
||||
# Square, reduced rank, parametrized solution
|
||||
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
b = Matrix([3, 6, 9])
|
||||
sol, params, freevar = A.gauss_jordan_solve(b, freevar=True)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
# Extract dummy symbols used in the solution.
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[w['tau0'] - 1], [-2*w['tau0'] + 2], [w['tau0']]])
|
||||
assert params == Matrix([[w['tau0']]])
|
||||
assert freevar == [2]
|
||||
|
||||
# Square, reduced rank, parametrized solution, B has two columns
|
||||
A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
B = Matrix([[3, 4], [6, 8], [9, 12]])
|
||||
sol, params, freevar = A.gauss_jordan_solve(B, freevar=True)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
# Extract dummy symbols used in the solution.
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[w['tau0'] - 1, w['tau1'] - Rational(4, 3)],
|
||||
[-2*w['tau0'] + 2, -2*w['tau1'] + Rational(8, 3)],
|
||||
[w['tau0'], w['tau1']],])
|
||||
assert params == Matrix([[w['tau0'], w['tau1']]])
|
||||
assert freevar == [2]
|
||||
|
||||
# Square, reduced rank, parametrized solution
|
||||
A = Matrix([[1, 2, 3], [2, 4, 6], [3, 6, 9]])
|
||||
b = Matrix([0, 0, 0])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[-2*w['tau0'] - 3*w['tau1']],
|
||||
[w['tau0']], [w['tau1']]])
|
||||
assert params == Matrix([[w['tau0']], [w['tau1']]])
|
||||
|
||||
# Square, reduced rank, parametrized solution
|
||||
A = Matrix([[0, 0, 0], [0, 0, 0], [0, 0, 0]])
|
||||
b = Matrix([0, 0, 0])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[w['tau0']], [w['tau1']], [w['tau2']]])
|
||||
assert params == Matrix([[w['tau0']], [w['tau1']], [w['tau2']]])
|
||||
|
||||
# Square, reduced rank, no solution
|
||||
A = Matrix([[1, 2, 3], [2, 4, 6], [3, 6, 9]])
|
||||
b = Matrix([0, 0, 1])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(b))
|
||||
|
||||
# Rectangular, tall, full rank, unique solution
|
||||
A = Matrix([[1, 5, 3], [2, 1, 6], [1, 7, 9], [1, 4, 3]])
|
||||
b = Matrix([0, 0, 1, 0])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
assert sol == Matrix([[Rational(-1, 2)], [0], [Rational(1, 6)]])
|
||||
assert params == Matrix(0, 1, [])
|
||||
|
||||
# Rectangular, tall, full rank, unique solution, B has less columns than rows
|
||||
A = Matrix([[1, 5, 3], [2, 1, 6], [1, 7, 9], [1, 4, 3]])
|
||||
B = Matrix([[0,0], [0, 0], [1, 2], [0, 0]])
|
||||
sol, params = A.gauss_jordan_solve(B)
|
||||
assert sol == Matrix([[Rational(-1, 2), Rational(-2, 2)], [0, 0], [Rational(1, 6), Rational(2, 6)]])
|
||||
assert params == Matrix(0, 2, [])
|
||||
|
||||
# Rectangular, tall, full rank, no solution
|
||||
A = Matrix([[1, 5, 3], [2, 1, 6], [1, 7, 9], [1, 4, 3]])
|
||||
b = Matrix([0, 0, 0, 1])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(b))
|
||||
|
||||
# Rectangular, tall, full rank, no solution, B has two columns (2nd has no solution)
|
||||
A = Matrix([[1, 5, 3], [2, 1, 6], [1, 7, 9], [1, 4, 3]])
|
||||
B = Matrix([[0,0], [0, 0], [1, 0], [0, 1]])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(B))
|
||||
|
||||
# Rectangular, tall, full rank, no solution, B has two columns (1st has no solution)
|
||||
A = Matrix([[1, 5, 3], [2, 1, 6], [1, 7, 9], [1, 4, 3]])
|
||||
B = Matrix([[0,0], [0, 0], [0, 1], [1, 0]])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(B))
|
||||
|
||||
# Rectangular, tall, reduced rank, parametrized solution
|
||||
A = Matrix([[1, 5, 3], [2, 10, 6], [3, 15, 9], [1, 4, 3]])
|
||||
b = Matrix([0, 0, 0, 1])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[-3*w['tau0'] + 5], [-1], [w['tau0']]])
|
||||
assert params == Matrix([[w['tau0']]])
|
||||
|
||||
# Rectangular, tall, reduced rank, no solution
|
||||
A = Matrix([[1, 5, 3], [2, 10, 6], [3, 15, 9], [1, 4, 3]])
|
||||
b = Matrix([0, 0, 1, 1])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(b))
|
||||
|
||||
# Rectangular, wide, full rank, parametrized solution
|
||||
A = Matrix([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 1, 12]])
|
||||
b = Matrix([1, 1, 1])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[2*w['tau0'] - 1], [-3*w['tau0'] + 1], [0],
|
||||
[w['tau0']]])
|
||||
assert params == Matrix([[w['tau0']]])
|
||||
|
||||
# Rectangular, wide, reduced rank, parametrized solution
|
||||
A = Matrix([[1, 2, 3, 4], [5, 6, 7, 8], [2, 4, 6, 8]])
|
||||
b = Matrix([0, 1, 0])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[w['tau0'] + 2*w['tau1'] + S.Half],
|
||||
[-2*w['tau0'] - 3*w['tau1'] - Rational(1, 4)],
|
||||
[w['tau0']], [w['tau1']]])
|
||||
assert params == Matrix([[w['tau0']], [w['tau1']]])
|
||||
# watch out for clashing symbols
|
||||
x0, x1, x2, _x0 = symbols('_tau0 _tau1 _tau2 tau1')
|
||||
M = Matrix([[0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, _x0]])
|
||||
A = M[:, :-1]
|
||||
b = M[:, -1:]
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
assert params == Matrix(3, 1, [x0, x1, x2])
|
||||
assert sol == Matrix(5, 1, [x0, 0, x1, _x0, x2])
|
||||
|
||||
# Rectangular, wide, reduced rank, no solution
|
||||
A = Matrix([[1, 2, 3, 4], [5, 6, 7, 8], [2, 4, 6, 8]])
|
||||
b = Matrix([1, 1, 1])
|
||||
raises(ValueError, lambda: A.gauss_jordan_solve(b))
|
||||
|
||||
# Test for immutable matrix
|
||||
A = ImmutableMatrix([[1, 0], [0, 1]])
|
||||
B = ImmutableMatrix([1, 2])
|
||||
sol, params = A.gauss_jordan_solve(B)
|
||||
assert sol == ImmutableMatrix([1, 2])
|
||||
assert params == ImmutableMatrix(0, 1, [])
|
||||
assert sol.__class__ == ImmutableDenseMatrix
|
||||
assert params.__class__ == ImmutableDenseMatrix
|
||||
|
||||
# Test placement of free variables
|
||||
A = Matrix([[1, 0, 0, 0], [0, 0, 0, 1]])
|
||||
b = Matrix([1, 1])
|
||||
sol, params = A.gauss_jordan_solve(b)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert sol == Matrix([[1], [w['tau0']], [w['tau1']], [1]])
|
||||
assert params == Matrix([[w['tau0']], [w['tau1']]])
|
||||
|
||||
|
||||
def test_linsolve_underdetermined_AND_gauss_jordan_solve():
|
||||
#Test placement of free variables as per issue 19815
|
||||
A = Matrix([[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1]])
|
||||
B = Matrix([1, 2, 1, 1, 1, 1, 1, 2])
|
||||
sol, params = A.gauss_jordan_solve(B)
|
||||
w = {}
|
||||
for s in sol.atoms(Symbol):
|
||||
w[s.name] = s
|
||||
assert params == Matrix([[w['tau0']], [w['tau1']], [w['tau2']],
|
||||
[w['tau3']], [w['tau4']], [w['tau5']]])
|
||||
assert sol == Matrix([[1 - 1*w['tau2']],
|
||||
[w['tau2']],
|
||||
[1 - 1*w['tau0'] + w['tau1']],
|
||||
[w['tau0']],
|
||||
[w['tau3'] + w['tau4']],
|
||||
[-1*w['tau3'] - 1*w['tau4'] - 1*w['tau1']],
|
||||
[1 - 1*w['tau2']],
|
||||
[w['tau1']],
|
||||
[w['tau2']],
|
||||
[w['tau3']],
|
||||
[w['tau4']],
|
||||
[1 - 1*w['tau5']],
|
||||
[w['tau5']],
|
||||
[1]])
|
||||
|
||||
from sympy.abc import j,f
|
||||
# https://github.com/sympy/sympy/issues/20046
|
||||
A = Matrix([
|
||||
[1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||
[0, -1, 0, -1, 0, -1, 0, -1, -j],
|
||||
[0, 0, 0, 0, 1, 1, 1, 1, f]
|
||||
])
|
||||
|
||||
sol_1=Matrix(list(linsolve(A))[0])
|
||||
|
||||
tau0, tau1, tau2, tau3, tau4 = symbols('tau:5')
|
||||
|
||||
assert sol_1 == Matrix([[-f - j - tau0 + tau2 + tau4 + 1],
|
||||
[j - tau1 - tau2 - tau4],
|
||||
[tau0],
|
||||
[tau1],
|
||||
[f - tau2 - tau3 - tau4],
|
||||
[tau2],
|
||||
[tau3],
|
||||
[tau4]])
|
||||
|
||||
# https://github.com/sympy/sympy/issues/19815
|
||||
sol_2 = A[:, : -1 ] * sol_1 - A[:, -1 ]
|
||||
assert sol_2 == Matrix([[0], [0], [0]])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("det_method", ["bird", "laplace"])
|
||||
@pytest.mark.parametrize("M, rhs", [
|
||||
(Matrix([[2, 3, 5], [3, 6, 2], [8, 3, 6]]), Matrix(3, 1, [3, 7, 5])),
|
||||
(Matrix([[2, 3, 5], [3, 6, 2], [8, 3, 6]]),
|
||||
Matrix([[1, 2], [3, 4], [5, 6]])),
|
||||
(Matrix(2, 2, symbols("a:4")), Matrix(2, 1, symbols("b:2"))),
|
||||
])
|
||||
def test_cramer_solve(det_method, M, rhs):
|
||||
assert simplify(M.cramer_solve(rhs, det_method=det_method) - M.LUsolve(rhs)
|
||||
) == Matrix.zeros(M.rows, rhs.cols)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("det_method, error", [
|
||||
("bird", DMShapeError), (_det_laplace, NonSquareMatrixError)])
|
||||
def test_cramer_solve_errors(det_method, error):
|
||||
# Non-square matrix
|
||||
A = Matrix([[0, -1, 2], [5, 10, 7]])
|
||||
b = Matrix([-2, 15])
|
||||
raises(error, lambda: A.cramer_solve(b, det_method=det_method))
|
||||
|
||||
|
||||
def test_solve():
|
||||
A = Matrix([[1,2], [2,4]])
|
||||
b = Matrix([[3], [4]])
|
||||
raises(ValueError, lambda: A.solve(b)) #no solution
|
||||
b = Matrix([[ 4], [8]])
|
||||
raises(ValueError, lambda: A.solve(b)) #infinite solution
|
||||
@@ -0,0 +1,745 @@
|
||||
from sympy.core.numbers import (Float, I, Rational)
|
||||
from sympy.core.singleton import S
|
||||
from sympy.core.symbol import (Symbol, symbols)
|
||||
from sympy.functions.elementary.complexes import Abs
|
||||
from sympy.polys.polytools import PurePoly
|
||||
from sympy.matrices import \
|
||||
Matrix, MutableSparseMatrix, ImmutableSparseMatrix, SparseMatrix, eye, \
|
||||
ones, zeros, ShapeError, NonSquareMatrixError
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_sparse_creation():
|
||||
a = SparseMatrix(2, 2, {(0, 0): [[1, 2], [3, 4]]})
|
||||
assert a == SparseMatrix([[1, 2], [3, 4]])
|
||||
a = SparseMatrix(2, 2, {(0, 0): [[1, 2]]})
|
||||
assert a == SparseMatrix([[1, 2], [0, 0]])
|
||||
a = SparseMatrix(2, 2, {(0, 0): [1, 2]})
|
||||
assert a == SparseMatrix([[1, 0], [2, 0]])
|
||||
|
||||
|
||||
def test_sparse_matrix():
|
||||
def sparse_eye(n):
|
||||
return SparseMatrix.eye(n)
|
||||
|
||||
def sparse_zeros(n):
|
||||
return SparseMatrix.zeros(n)
|
||||
|
||||
# creation args
|
||||
raises(TypeError, lambda: SparseMatrix(1, 2))
|
||||
|
||||
a = SparseMatrix((
|
||||
(1, 0),
|
||||
(0, 1)
|
||||
))
|
||||
assert SparseMatrix(a) == a
|
||||
|
||||
from sympy.matrices import MutableDenseMatrix
|
||||
a = MutableSparseMatrix([])
|
||||
b = MutableDenseMatrix([1, 2])
|
||||
assert a.row_join(b) == b
|
||||
assert a.col_join(b) == b
|
||||
assert type(a.row_join(b)) == type(a)
|
||||
assert type(a.col_join(b)) == type(a)
|
||||
|
||||
# make sure 0 x n matrices get stacked correctly
|
||||
sparse_matrices = [SparseMatrix.zeros(0, n) for n in range(4)]
|
||||
assert SparseMatrix.hstack(*sparse_matrices) == Matrix(0, 6, [])
|
||||
sparse_matrices = [SparseMatrix.zeros(n, 0) for n in range(4)]
|
||||
assert SparseMatrix.vstack(*sparse_matrices) == Matrix(6, 0, [])
|
||||
|
||||
# test element assignment
|
||||
a = SparseMatrix((
|
||||
(1, 0),
|
||||
(0, 1)
|
||||
))
|
||||
|
||||
a[3] = 4
|
||||
assert a[1, 1] == 4
|
||||
a[3] = 1
|
||||
|
||||
a[0, 0] = 2
|
||||
assert a == SparseMatrix((
|
||||
(2, 0),
|
||||
(0, 1)
|
||||
))
|
||||
a[1, 0] = 5
|
||||
assert a == SparseMatrix((
|
||||
(2, 0),
|
||||
(5, 1)
|
||||
))
|
||||
a[1, 1] = 0
|
||||
assert a == SparseMatrix((
|
||||
(2, 0),
|
||||
(5, 0)
|
||||
))
|
||||
assert a.todok() == {(0, 0): 2, (1, 0): 5}
|
||||
|
||||
# test_multiplication
|
||||
a = SparseMatrix((
|
||||
(1, 2),
|
||||
(3, 1),
|
||||
(0, 6),
|
||||
))
|
||||
|
||||
b = SparseMatrix((
|
||||
(1, 2),
|
||||
(3, 0),
|
||||
))
|
||||
|
||||
c = a*b
|
||||
assert c[0, 0] == 7
|
||||
assert c[0, 1] == 2
|
||||
assert c[1, 0] == 6
|
||||
assert c[1, 1] == 6
|
||||
assert c[2, 0] == 18
|
||||
assert c[2, 1] == 0
|
||||
|
||||
try:
|
||||
eval('c = a @ b')
|
||||
except SyntaxError:
|
||||
pass
|
||||
else:
|
||||
assert c[0, 0] == 7
|
||||
assert c[0, 1] == 2
|
||||
assert c[1, 0] == 6
|
||||
assert c[1, 1] == 6
|
||||
assert c[2, 0] == 18
|
||||
assert c[2, 1] == 0
|
||||
|
||||
x = Symbol("x")
|
||||
|
||||
c = b * Symbol("x")
|
||||
assert isinstance(c, SparseMatrix)
|
||||
assert c[0, 0] == x
|
||||
assert c[0, 1] == 2*x
|
||||
assert c[1, 0] == 3*x
|
||||
assert c[1, 1] == 0
|
||||
|
||||
c = 5 * b
|
||||
assert isinstance(c, SparseMatrix)
|
||||
assert c[0, 0] == 5
|
||||
assert c[0, 1] == 2*5
|
||||
assert c[1, 0] == 3*5
|
||||
assert c[1, 1] == 0
|
||||
|
||||
#test_power
|
||||
A = SparseMatrix([[2, 3], [4, 5]])
|
||||
assert (A**5)[:] == [6140, 8097, 10796, 14237]
|
||||
A = SparseMatrix([[2, 1, 3], [4, 2, 4], [6, 12, 1]])
|
||||
assert (A**3)[:] == [290, 262, 251, 448, 440, 368, 702, 954, 433]
|
||||
|
||||
# test_creation
|
||||
x = Symbol("x")
|
||||
a = SparseMatrix([[x, 0], [0, 0]])
|
||||
m = a
|
||||
assert m.cols == m.rows
|
||||
assert m.cols == 2
|
||||
assert m[:] == [x, 0, 0, 0]
|
||||
b = SparseMatrix(2, 2, [x, 0, 0, 0])
|
||||
m = b
|
||||
assert m.cols == m.rows
|
||||
assert m.cols == 2
|
||||
assert m[:] == [x, 0, 0, 0]
|
||||
|
||||
assert a == b
|
||||
S = sparse_eye(3)
|
||||
S.row_del(1)
|
||||
assert S == SparseMatrix([
|
||||
[1, 0, 0],
|
||||
[0, 0, 1]])
|
||||
S = sparse_eye(3)
|
||||
S.col_del(1)
|
||||
assert S == SparseMatrix([
|
||||
[1, 0],
|
||||
[0, 0],
|
||||
[0, 1]])
|
||||
S = SparseMatrix.eye(3)
|
||||
S[2, 1] = 2
|
||||
S.col_swap(1, 0)
|
||||
assert S == SparseMatrix([
|
||||
[0, 1, 0],
|
||||
[1, 0, 0],
|
||||
[2, 0, 1]])
|
||||
S.row_swap(0, 1)
|
||||
assert S == SparseMatrix([
|
||||
[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[2, 0, 1]])
|
||||
|
||||
a = SparseMatrix(1, 2, [1, 2])
|
||||
b = a.copy()
|
||||
c = a.copy()
|
||||
assert a[0] == 1
|
||||
a.row_del(0)
|
||||
assert a == SparseMatrix(0, 2, [])
|
||||
b.col_del(1)
|
||||
assert b == SparseMatrix(1, 1, [1])
|
||||
|
||||
assert SparseMatrix([[1, 2, 3], [1, 2], [1]]) == Matrix([
|
||||
[1, 2, 3],
|
||||
[1, 2, 0],
|
||||
[1, 0, 0]])
|
||||
assert SparseMatrix(4, 4, {(1, 1): sparse_eye(2)}) == Matrix([
|
||||
[0, 0, 0, 0],
|
||||
[0, 1, 0, 0],
|
||||
[0, 0, 1, 0],
|
||||
[0, 0, 0, 0]])
|
||||
raises(ValueError, lambda: SparseMatrix(1, 1, {(1, 1): 1}))
|
||||
assert SparseMatrix(1, 2, [1, 2]).tolist() == [[1, 2]]
|
||||
assert SparseMatrix(2, 2, [1, [2, 3]]).tolist() == [[1, 0], [2, 3]]
|
||||
raises(ValueError, lambda: SparseMatrix(2, 2, [1]))
|
||||
raises(ValueError, lambda: SparseMatrix(1, 1, [[1, 2]]))
|
||||
assert SparseMatrix([.1]).has(Float)
|
||||
# autosizing
|
||||
assert SparseMatrix(None, {(0, 1): 0}).shape == (0, 0)
|
||||
assert SparseMatrix(None, {(0, 1): 1}).shape == (1, 2)
|
||||
assert SparseMatrix(None, None, {(0, 1): 1}).shape == (1, 2)
|
||||
raises(ValueError, lambda: SparseMatrix(None, 1, [[1, 2]]))
|
||||
raises(ValueError, lambda: SparseMatrix(1, None, [[1, 2]]))
|
||||
raises(ValueError, lambda: SparseMatrix(3, 3, {(0, 0): ones(2), (1, 1): 2}))
|
||||
|
||||
# test_determinant
|
||||
x, y = Symbol('x'), Symbol('y')
|
||||
|
||||
assert SparseMatrix(1, 1, [0]).det() == 0
|
||||
|
||||
assert SparseMatrix([[1]]).det() == 1
|
||||
|
||||
assert SparseMatrix(((-3, 2), (8, -5))).det() == -1
|
||||
|
||||
assert SparseMatrix(((x, 1), (y, 2*y))).det() == 2*x*y - y
|
||||
|
||||
assert SparseMatrix(( (1, 1, 1),
|
||||
(1, 2, 3),
|
||||
(1, 3, 6) )).det() == 1
|
||||
|
||||
assert SparseMatrix(( ( 3, -2, 0, 5),
|
||||
(-2, 1, -2, 2),
|
||||
( 0, -2, 5, 0),
|
||||
( 5, 0, 3, 4) )).det() == -289
|
||||
|
||||
assert SparseMatrix(( ( 1, 2, 3, 4),
|
||||
( 5, 6, 7, 8),
|
||||
( 9, 10, 11, 12),
|
||||
(13, 14, 15, 16) )).det() == 0
|
||||
|
||||
assert SparseMatrix(( (3, 2, 0, 0, 0),
|
||||
(0, 3, 2, 0, 0),
|
||||
(0, 0, 3, 2, 0),
|
||||
(0, 0, 0, 3, 2),
|
||||
(2, 0, 0, 0, 3) )).det() == 275
|
||||
|
||||
assert SparseMatrix(( (1, 0, 1, 2, 12),
|
||||
(2, 0, 1, 1, 4),
|
||||
(2, 1, 1, -1, 3),
|
||||
(3, 2, -1, 1, 8),
|
||||
(1, 1, 1, 0, 6) )).det() == -55
|
||||
|
||||
assert SparseMatrix(( (-5, 2, 3, 4, 5),
|
||||
( 1, -4, 3, 4, 5),
|
||||
( 1, 2, -3, 4, 5),
|
||||
( 1, 2, 3, -2, 5),
|
||||
( 1, 2, 3, 4, -1) )).det() == 11664
|
||||
|
||||
assert SparseMatrix(( ( 3, 0, 0, 0),
|
||||
(-2, 1, 0, 0),
|
||||
( 0, -2, 5, 0),
|
||||
( 5, 0, 3, 4) )).det() == 60
|
||||
|
||||
assert SparseMatrix(( ( 1, 0, 0, 0),
|
||||
( 5, 0, 0, 0),
|
||||
( 9, 10, 11, 0),
|
||||
(13, 14, 15, 16) )).det() == 0
|
||||
|
||||
assert SparseMatrix(( (3, 2, 0, 0, 0),
|
||||
(0, 3, 2, 0, 0),
|
||||
(0, 0, 3, 2, 0),
|
||||
(0, 0, 0, 3, 2),
|
||||
(0, 0, 0, 0, 3) )).det() == 243
|
||||
|
||||
assert SparseMatrix(( ( 2, 7, -1, 3, 2),
|
||||
( 0, 0, 1, 0, 1),
|
||||
(-2, 0, 7, 0, 2),
|
||||
(-3, -2, 4, 5, 3),
|
||||
( 1, 0, 0, 0, 1) )).det() == 123
|
||||
|
||||
# test_slicing
|
||||
m0 = sparse_eye(4)
|
||||
assert m0[:3, :3] == sparse_eye(3)
|
||||
assert m0[2:4, 0:2] == sparse_zeros(2)
|
||||
|
||||
m1 = SparseMatrix(3, 3, lambda i, j: i + j)
|
||||
assert m1[0, :] == SparseMatrix(1, 3, (0, 1, 2))
|
||||
assert m1[1:3, 1] == SparseMatrix(2, 1, (2, 3))
|
||||
|
||||
m2 = SparseMatrix(
|
||||
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])
|
||||
assert m2[:, -1] == SparseMatrix(4, 1, [3, 7, 11, 15])
|
||||
assert m2[-2:, :] == SparseMatrix([[8, 9, 10, 11], [12, 13, 14, 15]])
|
||||
|
||||
assert SparseMatrix([[1, 2], [3, 4]])[[1], [1]] == Matrix([[4]])
|
||||
|
||||
# test_submatrix_assignment
|
||||
m = sparse_zeros(4)
|
||||
m[2:4, 2:4] = sparse_eye(2)
|
||||
assert m == SparseMatrix([(0, 0, 0, 0),
|
||||
(0, 0, 0, 0),
|
||||
(0, 0, 1, 0),
|
||||
(0, 0, 0, 1)])
|
||||
assert len(m.todok()) == 2
|
||||
m[:2, :2] = sparse_eye(2)
|
||||
assert m == sparse_eye(4)
|
||||
m[:, 0] = SparseMatrix(4, 1, (1, 2, 3, 4))
|
||||
assert m == SparseMatrix([(1, 0, 0, 0),
|
||||
(2, 1, 0, 0),
|
||||
(3, 0, 1, 0),
|
||||
(4, 0, 0, 1)])
|
||||
m[:, :] = sparse_zeros(4)
|
||||
assert m == sparse_zeros(4)
|
||||
m[:, :] = ((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12), (13, 14, 15, 16))
|
||||
assert m == SparseMatrix((( 1, 2, 3, 4),
|
||||
( 5, 6, 7, 8),
|
||||
( 9, 10, 11, 12),
|
||||
(13, 14, 15, 16)))
|
||||
m[:2, 0] = [0, 0]
|
||||
assert m == SparseMatrix((( 0, 2, 3, 4),
|
||||
( 0, 6, 7, 8),
|
||||
( 9, 10, 11, 12),
|
||||
(13, 14, 15, 16)))
|
||||
|
||||
# test_reshape
|
||||
m0 = sparse_eye(3)
|
||||
assert m0.reshape(1, 9) == SparseMatrix(1, 9, (1, 0, 0, 0, 1, 0, 0, 0, 1))
|
||||
m1 = SparseMatrix(3, 4, lambda i, j: i + j)
|
||||
assert m1.reshape(4, 3) == \
|
||||
SparseMatrix([(0, 1, 2), (3, 1, 2), (3, 4, 2), (3, 4, 5)])
|
||||
assert m1.reshape(2, 6) == \
|
||||
SparseMatrix([(0, 1, 2, 3, 1, 2), (3, 4, 2, 3, 4, 5)])
|
||||
|
||||
# test_applyfunc
|
||||
m0 = sparse_eye(3)
|
||||
assert m0.applyfunc(lambda x: 2*x) == sparse_eye(3)*2
|
||||
assert m0.applyfunc(lambda x: 0 ) == sparse_zeros(3)
|
||||
|
||||
# test__eval_Abs
|
||||
assert abs(SparseMatrix(((x, 1), (y, 2*y)))) == SparseMatrix(((Abs(x), 1), (Abs(y), 2*Abs(y))))
|
||||
|
||||
# test_LUdecomp
|
||||
testmat = SparseMatrix([[ 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 == sparse_zeros(4)
|
||||
|
||||
testmat = SparseMatrix([[ 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 == sparse_zeros(4)
|
||||
|
||||
x, y, z = Symbol('x'), Symbol('y'), Symbol('z')
|
||||
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 == sparse_zeros(3)
|
||||
|
||||
# test_LUsolve
|
||||
A = SparseMatrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[8, 3, 6]])
|
||||
x = SparseMatrix(3, 1, [3, 7, 5])
|
||||
b = A*x
|
||||
soln = A.LUsolve(b)
|
||||
assert soln == x
|
||||
A = SparseMatrix([[0, -1, 2],
|
||||
[5, 10, 7],
|
||||
[8, 3, 4]])
|
||||
x = SparseMatrix(3, 1, [-1, 2, 5])
|
||||
b = A*x
|
||||
soln = A.LUsolve(b)
|
||||
assert soln == x
|
||||
|
||||
# test_inverse
|
||||
A = sparse_eye(4)
|
||||
assert A.inv() == sparse_eye(4)
|
||||
assert A.inv(method="CH") == sparse_eye(4)
|
||||
assert A.inv(method="LDL") == sparse_eye(4)
|
||||
|
||||
A = SparseMatrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[7, 2, 6]])
|
||||
Ainv = SparseMatrix(Matrix(A).inv())
|
||||
assert A*Ainv == sparse_eye(3)
|
||||
assert A.inv(method="CH") == Ainv
|
||||
assert A.inv(method="LDL") == Ainv
|
||||
|
||||
A = SparseMatrix([[2, 3, 5],
|
||||
[3, 6, 2],
|
||||
[5, 2, 6]])
|
||||
Ainv = SparseMatrix(Matrix(A).inv())
|
||||
assert A*Ainv == sparse_eye(3)
|
||||
assert A.inv(method="CH") == Ainv
|
||||
assert A.inv(method="LDL") == Ainv
|
||||
|
||||
# test_cross
|
||||
v1 = Matrix(1, 3, [1, 2, 3])
|
||||
v2 = Matrix(1, 3, [3, 4, 5])
|
||||
assert v1.cross(v2) == Matrix(1, 3, [-2, 4, -2])
|
||||
assert v1.norm(2)**2 == 14
|
||||
|
||||
# conjugate
|
||||
a = SparseMatrix(((1, 2 + I), (3, 4)))
|
||||
assert a.C == SparseMatrix([
|
||||
[1, 2 - I],
|
||||
[3, 4]
|
||||
])
|
||||
|
||||
# mul
|
||||
assert a*Matrix(2, 2, [1, 0, 0, 1]) == a
|
||||
assert a + Matrix(2, 2, [1, 1, 1, 1]) == SparseMatrix([
|
||||
[2, 3 + I],
|
||||
[4, 5]
|
||||
])
|
||||
|
||||
# col join
|
||||
assert a.col_join(sparse_eye(2)) == SparseMatrix([
|
||||
[1, 2 + I],
|
||||
[3, 4],
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
])
|
||||
|
||||
# row insert
|
||||
assert a.row_insert(2, sparse_eye(2)) == SparseMatrix([
|
||||
[1, 2 + I],
|
||||
[3, 4],
|
||||
[1, 0],
|
||||
[0, 1]
|
||||
])
|
||||
|
||||
# col insert
|
||||
assert a.col_insert(2, SparseMatrix.zeros(2, 1)) == SparseMatrix([
|
||||
[1, 2 + I, 0],
|
||||
[3, 4, 0],
|
||||
])
|
||||
|
||||
# symmetric
|
||||
assert not a.is_symmetric(simplify=False)
|
||||
|
||||
# col op
|
||||
M = SparseMatrix.eye(3)*2
|
||||
M[1, 0] = -1
|
||||
M.col_op(1, lambda v, i: v + 2*M[i, 0])
|
||||
assert M == SparseMatrix([
|
||||
[ 2, 4, 0],
|
||||
[-1, 0, 0],
|
||||
[ 0, 0, 2]
|
||||
])
|
||||
|
||||
# fill
|
||||
M = SparseMatrix.eye(3)
|
||||
M.fill(2)
|
||||
assert M == SparseMatrix([
|
||||
[2, 2, 2],
|
||||
[2, 2, 2],
|
||||
[2, 2, 2],
|
||||
])
|
||||
|
||||
# test_cofactor
|
||||
assert sparse_eye(3) == sparse_eye(3).cofactor_matrix()
|
||||
test = SparseMatrix([[1, 3, 2], [2, 6, 3], [2, 3, 6]])
|
||||
assert test.cofactor_matrix() == \
|
||||
SparseMatrix([[27, -6, -6], [-12, 2, 3], [-3, 1, 0]])
|
||||
test = SparseMatrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
|
||||
assert test.cofactor_matrix() == \
|
||||
SparseMatrix([[-3, 6, -3], [6, -12, 6], [-3, 6, -3]])
|
||||
|
||||
# test_jacobian
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
L = SparseMatrix(1, 2, [x**2*y, 2*y**2 + x*y])
|
||||
syms = [x, y]
|
||||
assert L.jacobian(syms) == Matrix([[2*x*y, x**2], [y, 4*y + x]])
|
||||
|
||||
L = SparseMatrix(1, 2, [x, x**2*y**3])
|
||||
assert L.jacobian(syms) == SparseMatrix([[1, 0], [2*x*y**3, x**2*3*y**2]])
|
||||
|
||||
# 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 == sparse_eye(2)
|
||||
|
||||
R = Rational
|
||||
# test nullspace
|
||||
# first test reduced row-ech form
|
||||
|
||||
M = SparseMatrix([[5, 7, 2, 1],
|
||||
[1, 6, 2, -1]])
|
||||
out, tmp = M.rref()
|
||||
assert out == Matrix([[1, 0, -R(2)/23, R(13)/23],
|
||||
[0, 1, R(8)/23, R(-6)/23]])
|
||||
|
||||
M = SparseMatrix([[ 1, 3, 0, 2, 6, 3, 1],
|
||||
[-2, -6, 0, -2, -8, 3, 1],
|
||||
[ 3, 9, 0, 0, 6, 6, 2],
|
||||
[-1, -3, 0, 1, 0, 9, 3]])
|
||||
|
||||
out, tmp = M.rref()
|
||||
assert out == Matrix([[1, 3, 0, 0, 2, 0, 0],
|
||||
[0, 0, 0, 1, 2, 0, 0],
|
||||
[0, 0, 0, 0, 0, 1, R(1)/3],
|
||||
[0, 0, 0, 0, 0, 0, 0]])
|
||||
# now check the vectors
|
||||
basis = M.nullspace()
|
||||
assert basis[0] == Matrix([-3, 1, 0, 0, 0, 0, 0])
|
||||
assert basis[1] == Matrix([0, 0, 1, 0, 0, 0, 0])
|
||||
assert basis[2] == Matrix([-2, 0, 0, -2, 1, 0, 0])
|
||||
assert basis[3] == Matrix([0, 0, 0, 0, 0, R(-1)/3, 1])
|
||||
|
||||
# test eigen
|
||||
x = Symbol('x')
|
||||
y = Symbol('y')
|
||||
sparse_eye3 = sparse_eye(3)
|
||||
assert sparse_eye3.charpoly(x) == PurePoly((x - 1)**3)
|
||||
assert sparse_eye3.charpoly(y) == PurePoly((y - 1)**3)
|
||||
|
||||
# test values
|
||||
M = Matrix([( 0, 1, -1),
|
||||
( 1, 1, 0),
|
||||
(-1, 0, 1)])
|
||||
vals = M.eigenvals()
|
||||
assert sorted(vals.keys()) == [-1, 1, 2]
|
||||
|
||||
R = Rational
|
||||
M = Matrix([[1, 0, 0],
|
||||
[0, 1, 0],
|
||||
[0, 0, 1]])
|
||||
assert M.eigenvects() == [(1, 3, [
|
||||
Matrix([1, 0, 0]),
|
||||
Matrix([0, 1, 0]),
|
||||
Matrix([0, 0, 1])])]
|
||||
M = Matrix([[5, 0, 2],
|
||||
[3, 2, 0],
|
||||
[0, 0, 1]])
|
||||
assert M.eigenvects() == [(1, 1, [Matrix([R(-1)/2, R(3)/2, 1])]),
|
||||
(2, 1, [Matrix([0, 1, 0])]),
|
||||
(5, 1, [Matrix([1, 1, 0])])]
|
||||
|
||||
assert M.zeros(3, 5) == SparseMatrix(3, 5, {})
|
||||
A = SparseMatrix(10, 10, {(0, 0): 18, (0, 9): 12, (1, 4): 18, (2, 7): 16, (3, 9): 12, (4, 2): 19, (5, 7): 16, (6, 2): 12, (9, 7): 18})
|
||||
assert A.row_list() == [(0, 0, 18), (0, 9, 12), (1, 4, 18), (2, 7, 16), (3, 9, 12), (4, 2, 19), (5, 7, 16), (6, 2, 12), (9, 7, 18)]
|
||||
assert A.col_list() == [(0, 0, 18), (4, 2, 19), (6, 2, 12), (1, 4, 18), (2, 7, 16), (5, 7, 16), (9, 7, 18), (0, 9, 12), (3, 9, 12)]
|
||||
assert SparseMatrix.eye(2).nnz() == 2
|
||||
|
||||
|
||||
def test_scalar_multiply():
|
||||
assert SparseMatrix([[1, 2]]).scalar_multiply(3) == SparseMatrix([[3, 6]])
|
||||
|
||||
|
||||
def test_transpose():
|
||||
assert SparseMatrix(((1, 2), (3, 4))).transpose() == \
|
||||
SparseMatrix(((1, 3), (2, 4)))
|
||||
|
||||
|
||||
def test_trace():
|
||||
assert SparseMatrix(((1, 2), (3, 4))).trace() == 5
|
||||
assert SparseMatrix(((0, 0), (0, 4))).trace() == 4
|
||||
|
||||
|
||||
def test_CL_RL():
|
||||
assert SparseMatrix(((1, 2), (3, 4))).row_list() == \
|
||||
[(0, 0, 1), (0, 1, 2), (1, 0, 3), (1, 1, 4)]
|
||||
assert SparseMatrix(((1, 2), (3, 4))).col_list() == \
|
||||
[(0, 0, 1), (1, 0, 3), (0, 1, 2), (1, 1, 4)]
|
||||
|
||||
|
||||
def test_add():
|
||||
assert SparseMatrix(((1, 0), (0, 1))) + SparseMatrix(((0, 1), (1, 0))) == \
|
||||
SparseMatrix(((1, 1), (1, 1)))
|
||||
a = SparseMatrix(100, 100, lambda i, j: int(j != 0 and i % j == 0))
|
||||
b = SparseMatrix(100, 100, lambda i, j: int(i != 0 and j % i == 0))
|
||||
assert (len(a.todok()) + len(b.todok()) - len((a + b).todok()) > 0)
|
||||
|
||||
|
||||
def test_errors():
|
||||
raises(ValueError, lambda: SparseMatrix(1.4, 2, lambda i, j: 0))
|
||||
raises(TypeError, lambda: SparseMatrix([1, 2, 3], [1, 2]))
|
||||
raises(ValueError, lambda: SparseMatrix([[1, 2], [3, 4]])[(1, 2, 3)])
|
||||
raises(IndexError, lambda: SparseMatrix([[1, 2], [3, 4]])[5])
|
||||
raises(ValueError, lambda: SparseMatrix([[1, 2], [3, 4]])[1, 2, 3])
|
||||
raises(TypeError,
|
||||
lambda: SparseMatrix([[1, 2], [3, 4]]).copyin_list([0, 1], set()))
|
||||
raises(
|
||||
IndexError, lambda: SparseMatrix([[1, 2], [3, 4]])[1, 2])
|
||||
raises(TypeError, lambda: SparseMatrix([1, 2, 3]).cross(1))
|
||||
raises(IndexError, lambda: SparseMatrix(1, 2, [1, 2])[3])
|
||||
raises(ShapeError,
|
||||
lambda: SparseMatrix(1, 2, [1, 2]) + SparseMatrix(2, 1, [2, 1]))
|
||||
|
||||
|
||||
def test_len():
|
||||
assert not SparseMatrix()
|
||||
assert SparseMatrix() == SparseMatrix([])
|
||||
assert SparseMatrix() == SparseMatrix([[]])
|
||||
|
||||
|
||||
def test_sparse_zeros_sparse_eye():
|
||||
assert SparseMatrix.eye(3) == eye(3, cls=SparseMatrix)
|
||||
assert len(SparseMatrix.eye(3).todok()) == 3
|
||||
assert SparseMatrix.zeros(3) == zeros(3, cls=SparseMatrix)
|
||||
assert len(SparseMatrix.zeros(3).todok()) == 0
|
||||
|
||||
|
||||
def test_copyin():
|
||||
s = SparseMatrix(3, 3, {})
|
||||
s[1, 0] = 1
|
||||
assert s[:, 0] == SparseMatrix(Matrix([0, 1, 0]))
|
||||
assert s[3] == 1
|
||||
assert s[3: 4] == [1]
|
||||
s[1, 1] = 42
|
||||
assert s[1, 1] == 42
|
||||
assert s[1, 1:] == SparseMatrix([[42, 0]])
|
||||
s[1, 1:] = Matrix([[5, 6]])
|
||||
assert s[1, :] == SparseMatrix([[1, 5, 6]])
|
||||
s[1, 1:] = [[42, 43]]
|
||||
assert s[1, :] == SparseMatrix([[1, 42, 43]])
|
||||
s[0, 0] = 17
|
||||
assert s[:, :1] == SparseMatrix([17, 1, 0])
|
||||
s[0, 0] = [1, 1, 1]
|
||||
assert s[:, 0] == SparseMatrix([1, 1, 1])
|
||||
s[0, 0] = Matrix([1, 1, 1])
|
||||
assert s[:, 0] == SparseMatrix([1, 1, 1])
|
||||
s[0, 0] = SparseMatrix([1, 1, 1])
|
||||
assert s[:, 0] == SparseMatrix([1, 1, 1])
|
||||
|
||||
|
||||
def test_sparse_solve():
|
||||
A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
|
||||
assert A.cholesky() == Matrix([
|
||||
[ 5, 0, 0],
|
||||
[ 3, 3, 0],
|
||||
[-1, 1, 3]])
|
||||
assert A.cholesky() * A.cholesky().T == Matrix([
|
||||
[25, 15, -5],
|
||||
[15, 18, 0],
|
||||
[-5, 0, 11]])
|
||||
|
||||
A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
|
||||
L, D = A.LDLdecomposition()
|
||||
assert 15*L == Matrix([
|
||||
[15, 0, 0],
|
||||
[ 9, 15, 0],
|
||||
[-3, 5, 15]])
|
||||
assert D == Matrix([
|
||||
[25, 0, 0],
|
||||
[ 0, 9, 0],
|
||||
[ 0, 0, 9]])
|
||||
assert L * D * L.T == A
|
||||
|
||||
A = SparseMatrix(((3, 0, 2), (0, 0, 1), (1, 2, 0)))
|
||||
assert A.inv() * A == SparseMatrix(eye(3))
|
||||
|
||||
A = SparseMatrix([
|
||||
[ 2, -1, 0],
|
||||
[-1, 2, -1],
|
||||
[ 0, 0, 2]])
|
||||
ans = SparseMatrix([
|
||||
[Rational(2, 3), Rational(1, 3), Rational(1, 6)],
|
||||
[Rational(1, 3), Rational(2, 3), Rational(1, 3)],
|
||||
[ 0, 0, S.Half]])
|
||||
assert A.inv(method='CH') == ans
|
||||
assert A.inv(method='LDL') == ans
|
||||
assert A * ans == SparseMatrix(eye(3))
|
||||
|
||||
s = A.solve(A[:, 0], 'LDL')
|
||||
assert A*s == A[:, 0]
|
||||
s = A.solve(A[:, 0], 'CH')
|
||||
assert A*s == A[:, 0]
|
||||
A = A.col_join(A)
|
||||
s = A.solve_least_squares(A[:, 0], 'CH')
|
||||
assert A*s == A[:, 0]
|
||||
s = A.solve_least_squares(A[:, 0], 'LDL')
|
||||
assert A*s == A[:, 0]
|
||||
|
||||
|
||||
def test_lower_triangular_solve():
|
||||
raises(NonSquareMatrixError, lambda:
|
||||
SparseMatrix([[1, 2]]).lower_triangular_solve(Matrix([[1, 2]])))
|
||||
raises(ShapeError, lambda:
|
||||
SparseMatrix([[1, 2], [0, 4]]).lower_triangular_solve(Matrix([1])))
|
||||
raises(ValueError, lambda:
|
||||
SparseMatrix([[1, 2], [3, 4]]).lower_triangular_solve(Matrix([[1, 2], [3, 4]])))
|
||||
|
||||
a, b, c, d = symbols('a:d')
|
||||
u, v, w, x = symbols('u:x')
|
||||
|
||||
A = SparseMatrix([[a, 0], [c, d]])
|
||||
B = MutableSparseMatrix([[u, v], [w, x]])
|
||||
C = ImmutableSparseMatrix([[u, v], [w, x]])
|
||||
|
||||
sol = Matrix([[u/a, v/a], [(w - c*u/a)/d, (x - c*v/a)/d]])
|
||||
assert A.lower_triangular_solve(B) == sol
|
||||
assert A.lower_triangular_solve(C) == sol
|
||||
|
||||
|
||||
def test_upper_triangular_solve():
|
||||
raises(NonSquareMatrixError, lambda:
|
||||
SparseMatrix([[1, 2]]).upper_triangular_solve(Matrix([[1, 2]])))
|
||||
raises(ShapeError, lambda:
|
||||
SparseMatrix([[1, 2], [0, 4]]).upper_triangular_solve(Matrix([1])))
|
||||
raises(TypeError, lambda:
|
||||
SparseMatrix([[1, 2], [3, 4]]).upper_triangular_solve(Matrix([[1, 2], [3, 4]])))
|
||||
|
||||
a, b, c, d = symbols('a:d')
|
||||
u, v, w, x = symbols('u:x')
|
||||
|
||||
A = SparseMatrix([[a, b], [0, d]])
|
||||
B = MutableSparseMatrix([[u, v], [w, x]])
|
||||
C = ImmutableSparseMatrix([[u, v], [w, x]])
|
||||
|
||||
sol = Matrix([[(u - b*w/d)/a, (v - b*x/d)/a], [w/d, x/d]])
|
||||
assert A.upper_triangular_solve(B) == sol
|
||||
assert A.upper_triangular_solve(C) == sol
|
||||
|
||||
|
||||
def test_diagonal_solve():
|
||||
a, d = symbols('a d')
|
||||
u, v, w, x = symbols('u:x')
|
||||
|
||||
A = SparseMatrix([[a, 0], [0, d]])
|
||||
B = MutableSparseMatrix([[u, v], [w, x]])
|
||||
C = ImmutableSparseMatrix([[u, v], [w, x]])
|
||||
|
||||
sol = Matrix([[u/a, v/a], [w/d, x/d]])
|
||||
assert A.diagonal_solve(B) == sol
|
||||
assert A.diagonal_solve(C) == sol
|
||||
|
||||
|
||||
def test_hermitian():
|
||||
x = Symbol('x')
|
||||
a = SparseMatrix([[0, I], [-I, 0]])
|
||||
assert a.is_hermitian
|
||||
a = SparseMatrix([[1, I], [-I, 1]])
|
||||
assert a.is_hermitian
|
||||
a[0, 0] = 2*I
|
||||
assert a.is_hermitian is False
|
||||
a[0, 0] = x
|
||||
assert a.is_hermitian is None
|
||||
a[0, 1] = a[1, 0]*I
|
||||
assert a.is_hermitian is False
|
||||
@@ -0,0 +1,132 @@
|
||||
from sympy.matrices.sparsetools import _doktocsr, _csrtodok, banded
|
||||
from sympy.matrices.dense import (Matrix, eye, ones, zeros)
|
||||
from sympy.matrices import SparseMatrix
|
||||
from sympy.testing.pytest import raises
|
||||
|
||||
|
||||
def test_doktocsr():
|
||||
a = SparseMatrix([[1, 2, 0, 0], [0, 3, 9, 0], [0, 1, 4, 0]])
|
||||
b = SparseMatrix(4, 6, [10, 20, 0, 0, 0, 0, 0, 30, 0, 40, 0, 0, 0, 0, 50,
|
||||
60, 70, 0, 0, 0, 0, 0, 0, 80])
|
||||
c = SparseMatrix(4, 4, [0, 0, 0, 0, 0, 12, 0, 2, 15, 0, 12, 0, 0, 0, 0, 4])
|
||||
d = SparseMatrix(10, 10, {(1, 1): 12, (3, 5): 7, (7, 8): 12})
|
||||
e = SparseMatrix([[0, 0, 0], [1, 0, 2], [3, 0, 0]])
|
||||
f = SparseMatrix(7, 8, {(2, 3): 5, (4, 5):12})
|
||||
assert _doktocsr(a) == [[1, 2, 3, 9, 1, 4], [0, 1, 1, 2, 1, 2],
|
||||
[0, 2, 4, 6], [3, 4]]
|
||||
assert _doktocsr(b) == [[10, 20, 30, 40, 50, 60, 70, 80],
|
||||
[0, 1, 1, 3, 2, 3, 4, 5], [0, 2, 4, 7, 8], [4, 6]]
|
||||
assert _doktocsr(c) == [[12, 2, 15, 12, 4], [1, 3, 0, 2, 3],
|
||||
[0, 0, 2, 4, 5], [4, 4]]
|
||||
assert _doktocsr(d) == [[12, 7, 12], [1, 5, 8],
|
||||
[0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3], [10, 10]]
|
||||
assert _doktocsr(e) == [[1, 2, 3], [0, 2, 0], [0, 0, 2, 3], [3, 3]]
|
||||
assert _doktocsr(f) == [[5, 12], [3, 5], [0, 0, 0, 1, 1, 2, 2, 2], [7, 8]]
|
||||
|
||||
|
||||
def test_csrtodok():
|
||||
h = [[5, 7, 5], [2, 1, 3], [0, 1, 1, 3], [3, 4]]
|
||||
g = [[12, 5, 4], [2, 4, 2], [0, 1, 2, 3], [3, 7]]
|
||||
i = [[1, 3, 12], [0, 2, 4], [0, 2, 3], [2, 5]]
|
||||
j = [[11, 15, 12, 15], [2, 4, 1, 2], [0, 1, 1, 2, 3, 4], [5, 8]]
|
||||
k = [[1, 3], [2, 1], [0, 1, 1, 2], [3, 3]]
|
||||
m = _csrtodok(h)
|
||||
assert isinstance(m, SparseMatrix)
|
||||
assert m == SparseMatrix(3, 4,
|
||||
{(0, 2): 5, (2, 1): 7, (2, 3): 5})
|
||||
assert _csrtodok(g) == SparseMatrix(3, 7,
|
||||
{(0, 2): 12, (1, 4): 5, (2, 2): 4})
|
||||
assert _csrtodok(i) == SparseMatrix([[1, 0, 3, 0, 0], [0, 0, 0, 0, 12]])
|
||||
assert _csrtodok(j) == SparseMatrix(5, 8,
|
||||
{(0, 2): 11, (2, 4): 15, (3, 1): 12, (4, 2): 15})
|
||||
assert _csrtodok(k) == SparseMatrix(3, 3, {(0, 2): 1, (2, 1): 3})
|
||||
|
||||
|
||||
def test_banded():
|
||||
raises(TypeError, lambda: banded())
|
||||
raises(TypeError, lambda: banded(1))
|
||||
raises(TypeError, lambda: banded(1, 2))
|
||||
raises(TypeError, lambda: banded(1, 2, 3))
|
||||
raises(TypeError, lambda: banded(1, 2, 3, 4))
|
||||
raises(ValueError, lambda: banded({0: (1, 2)}, rows=1))
|
||||
raises(ValueError, lambda: banded({0: (1, 2)}, cols=1))
|
||||
raises(ValueError, lambda: banded(1, {0: (1, 2)}))
|
||||
raises(ValueError, lambda: banded(2, 1, {0: (1, 2)}))
|
||||
raises(ValueError, lambda: banded(1, 2, {0: (1, 2)}))
|
||||
|
||||
assert isinstance(banded(2, 4, {}), SparseMatrix)
|
||||
assert banded(2, 4, {}) == zeros(2, 4)
|
||||
assert banded({0: 0, 1: 0}) == zeros(0)
|
||||
assert banded({0: Matrix([1, 2])}) == Matrix([1, 2])
|
||||
assert banded({1: [1, 2, 3, 0], -1: [4, 5, 6]}) == \
|
||||
banded({1: (1, 2, 3), -1: (4, 5, 6)}) == \
|
||||
Matrix([
|
||||
[0, 1, 0, 0],
|
||||
[4, 0, 2, 0],
|
||||
[0, 5, 0, 3],
|
||||
[0, 0, 6, 0]])
|
||||
assert banded(3, 4, {-1: 1, 0: 2, 1: 3}) == \
|
||||
Matrix([
|
||||
[2, 3, 0, 0],
|
||||
[1, 2, 3, 0],
|
||||
[0, 1, 2, 3]])
|
||||
s = lambda d: (1 + d)**2
|
||||
assert banded(5, {0: s, 2: s}) == \
|
||||
Matrix([
|
||||
[1, 0, 1, 0, 0],
|
||||
[0, 4, 0, 4, 0],
|
||||
[0, 0, 9, 0, 9],
|
||||
[0, 0, 0, 16, 0],
|
||||
[0, 0, 0, 0, 25]])
|
||||
assert banded(2, {0: 1}) == \
|
||||
Matrix([
|
||||
[1, 0],
|
||||
[0, 1]])
|
||||
assert banded(2, 3, {0: 1}) == \
|
||||
Matrix([
|
||||
[1, 0, 0],
|
||||
[0, 1, 0]])
|
||||
vert = Matrix([1, 2, 3])
|
||||
assert banded({0: vert}, cols=3) == \
|
||||
Matrix([
|
||||
[1, 0, 0],
|
||||
[2, 1, 0],
|
||||
[3, 2, 1],
|
||||
[0, 3, 2],
|
||||
[0, 0, 3]])
|
||||
assert banded(4, {0: ones(2)}) == \
|
||||
Matrix([
|
||||
[1, 1, 0, 0],
|
||||
[1, 1, 0, 0],
|
||||
[0, 0, 1, 1],
|
||||
[0, 0, 1, 1]])
|
||||
raises(ValueError, lambda: banded({0: 2, 1: ones(2)}, rows=5))
|
||||
assert banded({0: 2, 2: (ones(2),)*3}) == \
|
||||
Matrix([
|
||||
[2, 0, 1, 1, 0, 0, 0, 0],
|
||||
[0, 2, 1, 1, 0, 0, 0, 0],
|
||||
[0, 0, 2, 0, 1, 1, 0, 0],
|
||||
[0, 0, 0, 2, 1, 1, 0, 0],
|
||||
[0, 0, 0, 0, 2, 0, 1, 1],
|
||||
[0, 0, 0, 0, 0, 2, 1, 1]])
|
||||
raises(ValueError, lambda: banded({0: (2,)*5, 1: (ones(2),)*3}))
|
||||
u2 = Matrix([[1, 1], [0, 1]])
|
||||
assert banded({0: (2,)*5, 1: (u2,)*3}) == \
|
||||
Matrix([
|
||||
[2, 1, 1, 0, 0, 0, 0],
|
||||
[0, 2, 1, 0, 0, 0, 0],
|
||||
[0, 0, 2, 1, 1, 0, 0],
|
||||
[0, 0, 0, 2, 1, 0, 0],
|
||||
[0, 0, 0, 0, 2, 1, 1],
|
||||
[0, 0, 0, 0, 0, 0, 1]])
|
||||
assert banded({0:(0, ones(2)), 2: 2}) == \
|
||||
Matrix([
|
||||
[0, 0, 2],
|
||||
[0, 1, 1],
|
||||
[0, 1, 1]])
|
||||
raises(ValueError, lambda: banded({0: (0, ones(2)), 1: 2}))
|
||||
assert banded({0: 1}, cols=3) == banded({0: 1}, rows=3) == eye(3)
|
||||
assert banded({1: 1}, rows=3) == Matrix([
|
||||
[0, 1, 0],
|
||||
[0, 0, 1],
|
||||
[0, 0, 0]])
|
||||
@@ -0,0 +1,109 @@
|
||||
from sympy.matrices import Matrix
|
||||
from sympy.core.numbers import Rational
|
||||
from sympy.core.symbol import symbols
|
||||
from sympy.solvers import solve
|
||||
|
||||
|
||||
def test_columnspace_one():
|
||||
m = Matrix([[ 1, 2, 0, 2, 5],
|
||||
[-2, -5, 1, -1, -8],
|
||||
[ 0, -3, 3, 4, 1],
|
||||
[ 3, 6, 0, -7, 2]])
|
||||
|
||||
basis = m.columnspace()
|
||||
assert basis[0] == Matrix([1, -2, 0, 3])
|
||||
assert basis[1] == Matrix([2, -5, -3, 6])
|
||||
assert basis[2] == Matrix([2, -1, 4, -7])
|
||||
|
||||
assert len(basis) == 3
|
||||
assert Matrix.hstack(m, *basis).columnspace() == basis
|
||||
|
||||
|
||||
def test_rowspace():
|
||||
m = Matrix([[ 1, 2, 0, 2, 5],
|
||||
[-2, -5, 1, -1, -8],
|
||||
[ 0, -3, 3, 4, 1],
|
||||
[ 3, 6, 0, -7, 2]])
|
||||
|
||||
basis = m.rowspace()
|
||||
assert basis[0] == Matrix([[1, 2, 0, 2, 5]])
|
||||
assert basis[1] == Matrix([[0, -1, 1, 3, 2]])
|
||||
assert basis[2] == Matrix([[0, 0, 0, 5, 5]])
|
||||
|
||||
assert len(basis) == 3
|
||||
|
||||
|
||||
def test_nullspace_one():
|
||||
m = Matrix([[ 1, 2, 0, 2, 5],
|
||||
[-2, -5, 1, -1, -8],
|
||||
[ 0, -3, 3, 4, 1],
|
||||
[ 3, 6, 0, -7, 2]])
|
||||
|
||||
basis = m.nullspace()
|
||||
assert basis[0] == Matrix([-2, 1, 1, 0, 0])
|
||||
assert basis[1] == Matrix([-1, -1, 0, -1, 1])
|
||||
# make sure the null space is really gets zeroed
|
||||
assert all(e.is_zero for e in m*basis[0])
|
||||
assert all(e.is_zero for e in m*basis[1])
|
||||
|
||||
def test_nullspace_second():
|
||||
# first test reduced row-ech form
|
||||
R = Rational
|
||||
|
||||
M = Matrix([[5, 7, 2, 1],
|
||||
[1, 6, 2, -1]])
|
||||
out, tmp = M.rref()
|
||||
assert out == Matrix([[1, 0, -R(2)/23, R(13)/23],
|
||||
[0, 1, R(8)/23, R(-6)/23]])
|
||||
|
||||
M = Matrix([[-5, -1, 4, -3, -1],
|
||||
[ 1, -1, -1, 1, 0],
|
||||
[-1, 0, 0, 0, 0],
|
||||
[ 4, 1, -4, 3, 1],
|
||||
[-2, 0, 2, -2, -1]])
|
||||
assert M*M.nullspace()[0] == Matrix(5, 1, [0]*5)
|
||||
|
||||
M = Matrix([[ 1, 3, 0, 2, 6, 3, 1],
|
||||
[-2, -6, 0, -2, -8, 3, 1],
|
||||
[ 3, 9, 0, 0, 6, 6, 2],
|
||||
[-1, -3, 0, 1, 0, 9, 3]])
|
||||
out, tmp = M.rref()
|
||||
assert out == Matrix([[1, 3, 0, 0, 2, 0, 0],
|
||||
[0, 0, 0, 1, 2, 0, 0],
|
||||
[0, 0, 0, 0, 0, 1, R(1)/3],
|
||||
[0, 0, 0, 0, 0, 0, 0]])
|
||||
|
||||
# now check the vectors
|
||||
basis = M.nullspace()
|
||||
assert basis[0] == Matrix([-3, 1, 0, 0, 0, 0, 0])
|
||||
assert basis[1] == Matrix([0, 0, 1, 0, 0, 0, 0])
|
||||
assert basis[2] == Matrix([-2, 0, 0, -2, 1, 0, 0])
|
||||
assert basis[3] == Matrix([0, 0, 0, 0, 0, R(-1)/3, 1])
|
||||
|
||||
# issue 4797; just see that we can do it when rows > cols
|
||||
M = Matrix([[1, 2], [2, 4], [3, 6]])
|
||||
assert M.nullspace()
|
||||
|
||||
|
||||
def test_columnspace_second():
|
||||
M = Matrix([[ 1, 2, 0, 2, 5],
|
||||
[-2, -5, 1, -1, -8],
|
||||
[ 0, -3, 3, 4, 1],
|
||||
[ 3, 6, 0, -7, 2]])
|
||||
|
||||
# now check the vectors
|
||||
basis = M.columnspace()
|
||||
assert basis[0] == Matrix([1, -2, 0, 3])
|
||||
assert basis[1] == Matrix([2, -5, -3, 6])
|
||||
assert basis[2] == Matrix([2, -1, 4, -7])
|
||||
|
||||
#check by columnspace definition
|
||||
a, b, c, d, e = symbols('a b c d e')
|
||||
X = Matrix([a, b, c, d, e])
|
||||
for i in range(len(basis)):
|
||||
eq=M*X-basis[i]
|
||||
assert len(solve(eq, X)) != 0
|
||||
|
||||
#check if rank-nullity theorem holds
|
||||
assert M.rank() == len(basis)
|
||||
assert len(M.nullspace()) + len(M.columnspace()) == M.cols
|
||||
Reference in New Issue
Block a user