chore: 添加虚拟环境到仓库
- 添加 backend_service/venv 虚拟环境 - 包含所有Python依赖包 - 注意:虚拟环境约393MB,包含12655个文件
This commit is contained in:
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