I am done

This commit is contained in:
2024-10-30 22:14:35 +01:00
parent 720dc28c09
commit 40e2a747cf
36901 changed files with 5011519 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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)))

View File

@ -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

View File

@ -0,0 +1,87 @@
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
from sympy.matrices.normalforms import (
invariant_factors,
smith_normal_form,
hermite_normal_form,
)
from sympy.polys.domains import ZZ, QQ
from sympy.core.numbers import Integer
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
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
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

View File

@ -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

View File

@ -0,0 +1,49 @@
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)))

View File

@ -0,0 +1,601 @@
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_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

View File

@ -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

View File

@ -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]])

View File

@ -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