Kano001's picture
Upload 3077 files
6a86ad5 verified
raw
history blame
40.8 kB
#
# Code for testing deprecated matrix classes. New test code should not be added
# here. Instead, add it to test_matrixbase.py.
#
# This entire test module and the corresponding sympy/matrices/common.py
# module will be removed in a future release.
#
from sympy.testing.pytest import raises, XFAIL, warns_deprecated_sympy
from sympy.assumptions import Q
from sympy.core.expr import Expr
from sympy.core.add import Add
from sympy.core.function import Function
from sympy.core.kind import NumberKind, UndefinedKind
from sympy.core.numbers import I, Integer, oo, pi, Rational
from sympy.core.singleton import S
from sympy.core.symbol import Symbol, symbols
from sympy.functions.elementary.complexes import Abs
from sympy.functions.elementary.exponential import exp
from sympy.functions.elementary.miscellaneous import sqrt
from sympy.functions.elementary.trigonometric import cos, sin
from sympy.matrices.exceptions import ShapeError, NonSquareMatrixError
from sympy.matrices.kind import MatrixKind
from sympy.matrices.common import (
_MinimalMatrix, _CastableMatrix, MatrixShaping, MatrixProperties,
MatrixOperations, MatrixArithmetic, MatrixSpecial)
from sympy.matrices.matrices import MatrixCalculus
from sympy.matrices import (Matrix, diag, eye,
matrix_multiply_elementwise, ones, zeros, SparseMatrix, banded,
MutableDenseMatrix, MutableSparseMatrix, ImmutableDenseMatrix,
ImmutableSparseMatrix)
from sympy.polys.polytools import Poly
from sympy.utilities.iterables import flatten
from sympy.tensor.array.dense_ndim_array import ImmutableDenseNDimArray as Array
from sympy.abc import x, y, z
def test_matrix_deprecated_isinstance():
# Test that e.g. isinstance(M, MatrixCommon) still gives True when M is a
# Matrix for each of the deprecated matrix classes.
from sympy.matrices.common import (
MatrixRequired,
MatrixShaping,
MatrixSpecial,
MatrixProperties,
MatrixOperations,
MatrixArithmetic,
MatrixCommon
)
from sympy.matrices.matrices import (
MatrixDeterminant,
MatrixReductions,
MatrixSubspaces,
MatrixEigen,
MatrixCalculus,
MatrixDeprecated
)
from sympy import (
Matrix,
ImmutableMatrix,
SparseMatrix,
ImmutableSparseMatrix
)
all_mixins = (
MatrixRequired,
MatrixShaping,
MatrixSpecial,
MatrixProperties,
MatrixOperations,
MatrixArithmetic,
MatrixCommon,
MatrixDeterminant,
MatrixReductions,
MatrixSubspaces,
MatrixEigen,
MatrixCalculus,
MatrixDeprecated
)
all_matrices = (
Matrix,
ImmutableMatrix,
SparseMatrix,
ImmutableSparseMatrix
)
Ms = [M([[1, 2], [3, 4]]) for M in all_matrices]
t = ()
for mixin in all_mixins:
for M in Ms:
with warns_deprecated_sympy():
assert isinstance(M, mixin) is True
with warns_deprecated_sympy():
assert isinstance(t, mixin) is False
# classes to test the deprecated matrix classes. We use warns_deprecated_sympy
# to suppress the deprecation warnings because subclassing the deprecated
# classes causes a warning to be raised.
with warns_deprecated_sympy():
class ShapingOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixShaping):
pass
def eye_Shaping(n):
return ShapingOnlyMatrix(n, n, lambda i, j: int(i == j))
def zeros_Shaping(n):
return ShapingOnlyMatrix(n, n, lambda i, j: 0)
with warns_deprecated_sympy():
class PropertiesOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixProperties):
pass
def eye_Properties(n):
return PropertiesOnlyMatrix(n, n, lambda i, j: int(i == j))
def zeros_Properties(n):
return PropertiesOnlyMatrix(n, n, lambda i, j: 0)
with warns_deprecated_sympy():
class OperationsOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixOperations):
pass
def eye_Operations(n):
return OperationsOnlyMatrix(n, n, lambda i, j: int(i == j))
def zeros_Operations(n):
return OperationsOnlyMatrix(n, n, lambda i, j: 0)
with warns_deprecated_sympy():
class ArithmeticOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixArithmetic):
pass
def eye_Arithmetic(n):
return ArithmeticOnlyMatrix(n, n, lambda i, j: int(i == j))
def zeros_Arithmetic(n):
return ArithmeticOnlyMatrix(n, n, lambda i, j: 0)
with warns_deprecated_sympy():
class SpecialOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixSpecial):
pass
with warns_deprecated_sympy():
class CalculusOnlyMatrix(_MinimalMatrix, _CastableMatrix, MatrixCalculus):
pass
def test__MinimalMatrix():
x = _MinimalMatrix(2, 3, [1, 2, 3, 4, 5, 6])
assert x.rows == 2
assert x.cols == 3
assert x[2] == 3
assert x[1, 1] == 5
assert list(x) == [1, 2, 3, 4, 5, 6]
assert list(x[1, :]) == [4, 5, 6]
assert list(x[:, 1]) == [2, 5]
assert list(x[:, :]) == list(x)
assert x[:, :] == x
assert _MinimalMatrix(x) == x
assert _MinimalMatrix([[1, 2, 3], [4, 5, 6]]) == x
assert _MinimalMatrix(([1, 2, 3], [4, 5, 6])) == x
assert _MinimalMatrix([(1, 2, 3), (4, 5, 6)]) == x
assert _MinimalMatrix(((1, 2, 3), (4, 5, 6))) == x
assert not (_MinimalMatrix([[1, 2], [3, 4], [5, 6]]) == x)
def test_kind():
assert Matrix([[1, 2], [3, 4]]).kind == MatrixKind(NumberKind)
assert Matrix([[0, 0], [0, 0]]).kind == MatrixKind(NumberKind)
assert Matrix(0, 0, []).kind == MatrixKind(NumberKind)
assert Matrix([[x]]).kind == MatrixKind(NumberKind)
assert Matrix([[1, Matrix([[1]])]]).kind == MatrixKind(UndefinedKind)
assert SparseMatrix([[1]]).kind == MatrixKind(NumberKind)
assert SparseMatrix([[1, Matrix([[1]])]]).kind == MatrixKind(UndefinedKind)
# ShapingOnlyMatrix tests
def test_vec():
m = ShapingOnlyMatrix(2, 2, [1, 3, 2, 4])
m_vec = m.vec()
assert m_vec.cols == 1
for i in range(4):
assert m_vec[i] == i + 1
def test_todok():
a, b, c, d = symbols('a:d')
m1 = MutableDenseMatrix([[a, b], [c, d]])
m2 = ImmutableDenseMatrix([[a, b], [c, d]])
m3 = MutableSparseMatrix([[a, b], [c, d]])
m4 = ImmutableSparseMatrix([[a, b], [c, d]])
assert m1.todok() == m2.todok() == m3.todok() == m4.todok() == \
{(0, 0): a, (0, 1): b, (1, 0): c, (1, 1): d}
def test_tolist():
lst = [[S.One, S.Half, x*y, S.Zero], [x, y, z, x**2], [y, -S.One, z*x, 3]]
flat_lst = [S.One, S.Half, x*y, S.Zero, x, y, z, x**2, y, -S.One, z*x, 3]
m = ShapingOnlyMatrix(3, 4, flat_lst)
assert m.tolist() == lst
def test_todod():
m = ShapingOnlyMatrix(3, 2, [[S.One, 0], [0, S.Half], [x, 0]])
dict = {0: {0: S.One}, 1: {1: S.Half}, 2: {0: x}}
assert m.todod() == dict
def test_row_col_del():
e = ShapingOnlyMatrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
raises(IndexError, lambda: e.row_del(5))
raises(IndexError, lambda: e.row_del(-5))
raises(IndexError, lambda: e.col_del(5))
raises(IndexError, lambda: e.col_del(-5))
assert e.row_del(2) == e.row_del(-1) == Matrix([[1, 2, 3], [4, 5, 6]])
assert e.col_del(2) == e.col_del(-1) == Matrix([[1, 2], [4, 5], [7, 8]])
assert e.row_del(1) == e.row_del(-2) == Matrix([[1, 2, 3], [7, 8, 9]])
assert e.col_del(1) == e.col_del(-2) == Matrix([[1, 3], [4, 6], [7, 9]])
def test_get_diag_blocks1():
a = Matrix([[1, 2], [2, 3]])
b = Matrix([[3, x], [y, 3]])
c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
assert a.get_diag_blocks() == [a]
assert b.get_diag_blocks() == [b]
assert c.get_diag_blocks() == [c]
def test_get_diag_blocks2():
a = Matrix([[1, 2], [2, 3]])
b = Matrix([[3, x], [y, 3]])
c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
A, B, C, D = diag(a, b, b), diag(a, b, c), diag(a, c, b), diag(c, c, b)
A = ShapingOnlyMatrix(A.rows, A.cols, A)
B = ShapingOnlyMatrix(B.rows, B.cols, B)
C = ShapingOnlyMatrix(C.rows, C.cols, C)
D = ShapingOnlyMatrix(D.rows, D.cols, D)
assert A.get_diag_blocks() == [a, b, b]
assert B.get_diag_blocks() == [a, b, c]
assert C.get_diag_blocks() == [a, c, b]
assert D.get_diag_blocks() == [c, c, b]
def test_shape():
m = ShapingOnlyMatrix(1, 2, [0, 0])
assert m.shape == (1, 2)
def test_reshape():
m0 = eye_Shaping(3)
assert m0.reshape(1, 9) == Matrix(1, 9, (1, 0, 0, 0, 1, 0, 0, 0, 1))
m1 = ShapingOnlyMatrix(3, 4, lambda i, j: i + j)
assert m1.reshape(
4, 3) == Matrix(((0, 1, 2), (3, 1, 2), (3, 4, 2), (3, 4, 5)))
assert m1.reshape(2, 6) == Matrix(((0, 1, 2, 3, 1, 2), (3, 4, 2, 3, 4, 5)))
def test_row_col():
m = ShapingOnlyMatrix(3, 3, [1, 2, 3, 4, 5, 6, 7, 8, 9])
assert m.row(0) == Matrix(1, 3, [1, 2, 3])
assert m.col(0) == Matrix(3, 1, [1, 4, 7])
def test_row_join():
assert eye_Shaping(3).row_join(Matrix([7, 7, 7])) == \
Matrix([[1, 0, 0, 7],
[0, 1, 0, 7],
[0, 0, 1, 7]])
def test_col_join():
assert eye_Shaping(3).col_join(Matrix([[7, 7, 7]])) == \
Matrix([[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[7, 7, 7]])
def test_row_insert():
r4 = Matrix([[4, 4, 4]])
for i in range(-4, 5):
l = [1, 0, 0]
l.insert(i, 4)
assert flatten(eye_Shaping(3).row_insert(i, r4).col(0).tolist()) == l
def test_col_insert():
c4 = Matrix([4, 4, 4])
for i in range(-4, 5):
l = [0, 0, 0]
l.insert(i, 4)
assert flatten(zeros_Shaping(3).col_insert(i, c4).row(0).tolist()) == l
# issue 13643
assert eye_Shaping(6).col_insert(3, Matrix([[2, 2], [2, 2], [2, 2], [2, 2], [2, 2], [2, 2]])) == \
Matrix([[1, 0, 0, 2, 2, 0, 0, 0],
[0, 1, 0, 2, 2, 0, 0, 0],
[0, 0, 1, 2, 2, 0, 0, 0],
[0, 0, 0, 2, 2, 1, 0, 0],
[0, 0, 0, 2, 2, 0, 1, 0],
[0, 0, 0, 2, 2, 0, 0, 1]])
def test_extract():
m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
assert m.extract([0, 1, 3], [0, 1]) == Matrix(3, 2, [0, 1, 3, 4, 9, 10])
assert m.extract([0, 3], [0, 0, 2]) == Matrix(2, 3, [0, 0, 2, 9, 9, 11])
assert m.extract(range(4), range(3)) == m
raises(IndexError, lambda: m.extract([4], [0]))
raises(IndexError, lambda: m.extract([0], [3]))
def test_hstack():
m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
m2 = ShapingOnlyMatrix(3, 4, lambda i, j: i*3 + j)
assert m == m.hstack(m)
assert m.hstack(m, m, m) == ShapingOnlyMatrix.hstack(m, m, m) == Matrix([
[0, 1, 2, 0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5, 3, 4, 5],
[6, 7, 8, 6, 7, 8, 6, 7, 8],
[9, 10, 11, 9, 10, 11, 9, 10, 11]])
raises(ShapeError, lambda: m.hstack(m, m2))
assert Matrix.hstack() == Matrix()
# test regression #12938
M1 = Matrix.zeros(0, 0)
M2 = Matrix.zeros(0, 1)
M3 = Matrix.zeros(0, 2)
M4 = Matrix.zeros(0, 3)
m = ShapingOnlyMatrix.hstack(M1, M2, M3, M4)
assert m.rows == 0 and m.cols == 6
def test_vstack():
m = ShapingOnlyMatrix(4, 3, lambda i, j: i*3 + j)
m2 = ShapingOnlyMatrix(3, 4, lambda i, j: i*3 + j)
assert m == m.vstack(m)
assert m.vstack(m, m, m) == ShapingOnlyMatrix.vstack(m, m, m) == Matrix([
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 10, 11],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 10, 11],
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[9, 10, 11]])
raises(ShapeError, lambda: m.vstack(m, m2))
assert Matrix.vstack() == Matrix()
# PropertiesOnlyMatrix tests
def test_atoms():
m = PropertiesOnlyMatrix(2, 2, [1, 2, x, 1 - 1/x])
assert m.atoms() == {S.One, S(2), S.NegativeOne, x}
assert m.atoms(Symbol) == {x}
def test_free_symbols():
assert PropertiesOnlyMatrix([[x], [0]]).free_symbols == {x}
def test_has():
A = PropertiesOnlyMatrix(((x, y), (2, 3)))
assert A.has(x)
assert not A.has(z)
assert A.has(Symbol)
A = PropertiesOnlyMatrix(((2, y), (2, 3)))
assert not A.has(x)
def test_is_anti_symmetric():
x = symbols('x')
assert PropertiesOnlyMatrix(2, 1, [1, 2]).is_anti_symmetric() is False
m = PropertiesOnlyMatrix(3, 3, [0, x**2 + 2*x + 1, y, -(x + 1)**2, 0, x*y, -y, -x*y, 0])
assert m.is_anti_symmetric() is True
assert m.is_anti_symmetric(simplify=False) is False
assert m.is_anti_symmetric(simplify=lambda x: x) is False
m = PropertiesOnlyMatrix(3, 3, [x.expand() for x in m])
assert m.is_anti_symmetric(simplify=False) is True
m = PropertiesOnlyMatrix(3, 3, [x.expand() for x in [S.One] + list(m)[1:]])
assert m.is_anti_symmetric() is False
def test_diagonal_symmetrical():
m = PropertiesOnlyMatrix(2, 2, [0, 1, 1, 0])
assert not m.is_diagonal()
assert m.is_symmetric()
assert m.is_symmetric(simplify=False)
m = PropertiesOnlyMatrix(2, 2, [1, 0, 0, 1])
assert m.is_diagonal()
m = PropertiesOnlyMatrix(3, 3, diag(1, 2, 3))
assert m.is_diagonal()
assert m.is_symmetric()
m = PropertiesOnlyMatrix(3, 3, [1, 0, 0, 0, 2, 0, 0, 0, 3])
assert m == diag(1, 2, 3)
m = PropertiesOnlyMatrix(2, 3, zeros(2, 3))
assert not m.is_symmetric()
assert m.is_diagonal()
m = PropertiesOnlyMatrix(((5, 0), (0, 6), (0, 0)))
assert m.is_diagonal()
m = PropertiesOnlyMatrix(((5, 0, 0), (0, 6, 0)))
assert m.is_diagonal()
m = Matrix(3, 3, [1, x**2 + 2*x + 1, y, (x + 1)**2, 2, 0, y, 0, 3])
assert m.is_symmetric()
assert not m.is_symmetric(simplify=False)
assert m.expand().is_symmetric(simplify=False)
def test_is_hermitian():
a = PropertiesOnlyMatrix([[1, I], [-I, 1]])
assert a.is_hermitian
a = PropertiesOnlyMatrix([[2*I, I], [-I, 1]])
assert a.is_hermitian is False
a = PropertiesOnlyMatrix([[x, I], [-I, 1]])
assert a.is_hermitian is None
a = PropertiesOnlyMatrix([[x, 1], [-I, 1]])
assert a.is_hermitian is False
def test_is_Identity():
assert eye_Properties(3).is_Identity
assert not PropertiesOnlyMatrix(zeros(3)).is_Identity
assert not PropertiesOnlyMatrix(ones(3)).is_Identity
# issue 6242
assert not PropertiesOnlyMatrix([[1, 0, 0]]).is_Identity
def test_is_symbolic():
a = PropertiesOnlyMatrix([[x, x], [x, x]])
assert a.is_symbolic() is True
a = PropertiesOnlyMatrix([[1, 2, 3, 4], [5, 6, 7, 8]])
assert a.is_symbolic() is False
a = PropertiesOnlyMatrix([[1, 2, 3, 4], [5, 6, x, 8]])
assert a.is_symbolic() is True
a = PropertiesOnlyMatrix([[1, x, 3]])
assert a.is_symbolic() is True
a = PropertiesOnlyMatrix([[1, 2, 3]])
assert a.is_symbolic() is False
a = PropertiesOnlyMatrix([[1], [x], [3]])
assert a.is_symbolic() is True
a = PropertiesOnlyMatrix([[1], [2], [3]])
assert a.is_symbolic() is False
def test_is_upper():
a = PropertiesOnlyMatrix([[1, 2, 3]])
assert a.is_upper is True
a = PropertiesOnlyMatrix([[1], [2], [3]])
assert a.is_upper is False
def test_is_lower():
a = PropertiesOnlyMatrix([[1, 2, 3]])
assert a.is_lower is False
a = PropertiesOnlyMatrix([[1], [2], [3]])
assert a.is_lower is True
def test_is_square():
m = PropertiesOnlyMatrix([[1], [1]])
m2 = PropertiesOnlyMatrix([[2, 2], [2, 2]])
assert not m.is_square
assert m2.is_square
def test_is_symmetric():
m = PropertiesOnlyMatrix(2, 2, [0, 1, 1, 0])
assert m.is_symmetric()
m = PropertiesOnlyMatrix(2, 2, [0, 1, 0, 1])
assert not m.is_symmetric()
def test_is_hessenberg():
A = PropertiesOnlyMatrix([[3, 4, 1], [2, 4, 5], [0, 1, 2]])
assert A.is_upper_hessenberg
A = PropertiesOnlyMatrix(3, 3, [3, 2, 0, 4, 4, 1, 1, 5, 2])
assert A.is_lower_hessenberg
A = PropertiesOnlyMatrix(3, 3, [3, 2, -1, 4, 4, 1, 1, 5, 2])
assert A.is_lower_hessenberg is False
assert A.is_upper_hessenberg is False
A = PropertiesOnlyMatrix([[3, 4, 1], [2, 4, 5], [3, 1, 2]])
assert not A.is_upper_hessenberg
def test_is_zero():
assert PropertiesOnlyMatrix(0, 0, []).is_zero_matrix
assert PropertiesOnlyMatrix([[0, 0], [0, 0]]).is_zero_matrix
assert PropertiesOnlyMatrix(zeros(3, 4)).is_zero_matrix
assert not PropertiesOnlyMatrix(eye(3)).is_zero_matrix
assert PropertiesOnlyMatrix([[x, 0], [0, 0]]).is_zero_matrix == None
assert PropertiesOnlyMatrix([[x, 1], [0, 0]]).is_zero_matrix == False
a = Symbol('a', nonzero=True)
assert PropertiesOnlyMatrix([[a, 0], [0, 0]]).is_zero_matrix == False
def test_values():
assert set(PropertiesOnlyMatrix(2, 2, [0, 1, 2, 3]
).values()) == {1, 2, 3}
x = Symbol('x', real=True)
assert set(PropertiesOnlyMatrix(2, 2, [x, 0, 0, 1]
).values()) == {x, 1}
# OperationsOnlyMatrix tests
def test_applyfunc():
m0 = OperationsOnlyMatrix(eye(3))
assert m0.applyfunc(lambda x: 2*x) == eye(3)*2
assert m0.applyfunc(lambda x: 0) == zeros(3)
assert m0.applyfunc(lambda x: 1) == ones(3)
def test_adjoint():
dat = [[0, I], [1, 0]]
ans = OperationsOnlyMatrix([[0, 1], [-I, 0]])
assert ans.adjoint() == Matrix(dat)
def test_as_real_imag():
m1 = OperationsOnlyMatrix(2, 2, [1, 2, 3, 4])
m3 = OperationsOnlyMatrix(2, 2,
[1 + S.ImaginaryUnit, 2 + 2*S.ImaginaryUnit,
3 + 3*S.ImaginaryUnit, 4 + 4*S.ImaginaryUnit])
a, b = m3.as_real_imag()
assert a == m1
assert b == m1
def test_conjugate():
M = OperationsOnlyMatrix([[0, I, 5],
[1, 2, 0]])
assert M.T == Matrix([[0, 1],
[I, 2],
[5, 0]])
assert M.C == Matrix([[0, -I, 5],
[1, 2, 0]])
assert M.C == M.conjugate()
assert M.H == M.T.C
assert M.H == Matrix([[ 0, 1],
[-I, 2],
[ 5, 0]])
def test_doit():
a = OperationsOnlyMatrix([[Add(x, x, evaluate=False)]])
assert a[0] != 2*x
assert a.doit() == Matrix([[2*x]])
def test_evalf():
a = OperationsOnlyMatrix(2, 1, [sqrt(5), 6])
assert all(a.evalf()[i] == a[i].evalf() for i in range(2))
assert all(a.evalf(2)[i] == a[i].evalf(2) for i in range(2))
assert all(a.n(2)[i] == a[i].n(2) for i in range(2))
def test_expand():
m0 = OperationsOnlyMatrix([[x*(x + y), 2], [((x + y)*y)*x, x*(y + x*(x + y))]])
# Test if expand() returns a matrix
m1 = m0.expand()
assert m1 == Matrix(
[[x*y + x**2, 2], [x*y**2 + y*x**2, x*y + y*x**2 + x**3]])
a = Symbol('a', real=True)
assert OperationsOnlyMatrix(1, 1, [exp(I*a)]).expand(complex=True) == \
Matrix([cos(a) + I*sin(a)])
def test_refine():
m0 = OperationsOnlyMatrix([[Abs(x)**2, sqrt(x**2)],
[sqrt(x**2)*Abs(y)**2, sqrt(y**2)*Abs(x)**2]])
m1 = m0.refine(Q.real(x) & Q.real(y))
assert m1 == Matrix([[x**2, Abs(x)], [y**2*Abs(x), x**2*Abs(y)]])
m1 = m0.refine(Q.positive(x) & Q.positive(y))
assert m1 == Matrix([[x**2, x], [x*y**2, x**2*y]])
m1 = m0.refine(Q.negative(x) & Q.negative(y))
assert m1 == Matrix([[x**2, -x], [-x*y**2, -x**2*y]])
def test_replace():
F, G = symbols('F, G', cls=Function)
K = OperationsOnlyMatrix(2, 2, lambda i, j: G(i+j))
M = OperationsOnlyMatrix(2, 2, lambda i, j: F(i+j))
N = M.replace(F, G)
assert N == K
def test_replace_map():
F, G = symbols('F, G', cls=Function)
K = OperationsOnlyMatrix(2, 2, [(G(0), {F(0): G(0)}), (G(1), {F(1): G(1)}), (G(1), {F(1) \
: G(1)}), (G(2), {F(2): G(2)})])
M = OperationsOnlyMatrix(2, 2, lambda i, j: F(i+j))
N = M.replace(F, G, True)
assert N == K
def test_rot90():
A = Matrix([[1, 2], [3, 4]])
assert A == A.rot90(0) == A.rot90(4)
assert A.rot90(2) == A.rot90(-2) == A.rot90(6) == Matrix(((4, 3), (2, 1)))
assert A.rot90(3) == A.rot90(-1) == A.rot90(7) == Matrix(((2, 4), (1, 3)))
assert A.rot90() == A.rot90(-7) == A.rot90(-3) == Matrix(((3, 1), (4, 2)))
def test_simplify():
n = Symbol('n')
f = Function('f')
M = OperationsOnlyMatrix([[ 1/x + 1/y, (x + x*y) / x ],
[ (f(x) + y*f(x))/f(x), 2 * (1/n - cos(n * pi)/n) / pi ]])
assert M.simplify() == Matrix([[ (x + y)/(x * y), 1 + y ],
[ 1 + y, 2*((1 - 1*cos(pi*n))/(pi*n)) ]])
eq = (1 + x)**2
M = OperationsOnlyMatrix([[eq]])
assert M.simplify() == Matrix([[eq]])
assert M.simplify(ratio=oo) == Matrix([[eq.simplify(ratio=oo)]])
# https://github.com/sympy/sympy/issues/19353
m = Matrix([[30, 2], [3, 4]])
assert (1/(m.trace())).simplify() == Rational(1, 34)
def test_subs():
assert OperationsOnlyMatrix([[1, x], [x, 4]]).subs(x, 5) == Matrix([[1, 5], [5, 4]])
assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs([[x, -1], [y, -2]]) == \
Matrix([[-1, 2], [-3, 4]])
assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs([(x, -1), (y, -2)]) == \
Matrix([[-1, 2], [-3, 4]])
assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).subs({x: -1, y: -2}) == \
Matrix([[-1, 2], [-3, 4]])
assert OperationsOnlyMatrix([[x*y]]).subs({x: y - 1, y: x - 1}, simultaneous=True) == \
Matrix([[(x - 1)*(y - 1)]])
def test_trace():
M = OperationsOnlyMatrix([[1, 0, 0],
[0, 5, 0],
[0, 0, 8]])
assert M.trace() == 14
def test_xreplace():
assert OperationsOnlyMatrix([[1, x], [x, 4]]).xreplace({x: 5}) == \
Matrix([[1, 5], [5, 4]])
assert OperationsOnlyMatrix([[x, 2], [x + y, 4]]).xreplace({x: -1, y: -2}) == \
Matrix([[-1, 2], [-3, 4]])
def test_permute():
a = OperationsOnlyMatrix(3, 4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
raises(IndexError, lambda: a.permute([[0, 5]]))
raises(ValueError, lambda: a.permute(Symbol('x')))
b = a.permute_rows([[0, 2], [0, 1]])
assert a.permute([[0, 2], [0, 1]]) == b == Matrix([
[5, 6, 7, 8],
[9, 10, 11, 12],
[1, 2, 3, 4]])
b = a.permute_cols([[0, 2], [0, 1]])
assert a.permute([[0, 2], [0, 1]], orientation='cols') == b ==\
Matrix([
[ 2, 3, 1, 4],
[ 6, 7, 5, 8],
[10, 11, 9, 12]])
b = a.permute_cols([[0, 2], [0, 1]], direction='backward')
assert a.permute([[0, 2], [0, 1]], orientation='cols', direction='backward') == b ==\
Matrix([
[ 3, 1, 2, 4],
[ 7, 5, 6, 8],
[11, 9, 10, 12]])
assert a.permute([1, 2, 0, 3]) == Matrix([
[5, 6, 7, 8],
[9, 10, 11, 12],
[1, 2, 3, 4]])
from sympy.combinatorics import Permutation
assert a.permute(Permutation([1, 2, 0, 3])) == Matrix([
[5, 6, 7, 8],
[9, 10, 11, 12],
[1, 2, 3, 4]])
def test_upper_triangular():
A = OperationsOnlyMatrix([
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]
])
R = A.upper_triangular(2)
assert R == OperationsOnlyMatrix([
[0, 0, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]
])
R = A.upper_triangular(-2)
assert R == OperationsOnlyMatrix([
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[0, 1, 1, 1]
])
R = A.upper_triangular()
assert R == OperationsOnlyMatrix([
[1, 1, 1, 1],
[0, 1, 1, 1],
[0, 0, 1, 1],
[0, 0, 0, 1]
])
def test_lower_triangular():
A = OperationsOnlyMatrix([
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]
])
L = A.lower_triangular()
assert L == ArithmeticOnlyMatrix([
[1, 0, 0, 0],
[1, 1, 0, 0],
[1, 1, 1, 0],
[1, 1, 1, 1]])
L = A.lower_triangular(2)
assert L == ArithmeticOnlyMatrix([
[1, 1, 1, 0],
[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]
])
L = A.lower_triangular(-2)
assert L == ArithmeticOnlyMatrix([
[0, 0, 0, 0],
[0, 0, 0, 0],
[1, 0, 0, 0],
[1, 1, 0, 0]
])
# ArithmeticOnlyMatrix tests
def test_abs():
m = ArithmeticOnlyMatrix([[1, -2], [x, y]])
assert abs(m) == ArithmeticOnlyMatrix([[1, 2], [Abs(x), Abs(y)]])
def test_add():
m = ArithmeticOnlyMatrix([[1, 2, 3], [x, y, x], [2*y, -50, z*x]])
assert m + m == ArithmeticOnlyMatrix([[2, 4, 6], [2*x, 2*y, 2*x], [4*y, -100, 2*z*x]])
n = ArithmeticOnlyMatrix(1, 2, [1, 2])
raises(ShapeError, lambda: m + n)
def test_multiplication():
a = ArithmeticOnlyMatrix((
(1, 2),
(3, 1),
(0, 6),
))
b = ArithmeticOnlyMatrix((
(1, 2),
(3, 0),
))
raises(ShapeError, lambda: b*a)
raises(TypeError, lambda: a*{})
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
h = a.multiply_elementwise(c)
assert h == matrix_multiply_elementwise(a, c)
assert h[0, 0] == 7
assert h[0, 1] == 4
assert h[1, 0] == 18
assert h[1, 1] == 6
assert h[2, 0] == 0
assert h[2, 1] == 0
raises(ShapeError, lambda: a.multiply_elementwise(b))
c = b * Symbol("x")
assert isinstance(c, ArithmeticOnlyMatrix)
assert c[0, 0] == x
assert c[0, 1] == 2*x
assert c[1, 0] == 3*x
assert c[1, 1] == 0
c2 = x * b
assert c == c2
c = 5 * b
assert isinstance(c, ArithmeticOnlyMatrix)
assert c[0, 0] == 5
assert c[0, 1] == 2*5
assert c[1, 0] == 3*5
assert c[1, 1] == 0
try:
eval('c = 5 @ b')
except SyntaxError:
pass
else:
assert isinstance(c, ArithmeticOnlyMatrix)
assert c[0, 0] == 5
assert c[0, 1] == 2*5
assert c[1, 0] == 3*5
assert c[1, 1] == 0
# https://github.com/sympy/sympy/issues/22353
A = Matrix(ones(3, 1))
_h = -Rational(1, 2)
B = Matrix([_h, _h, _h])
assert A.multiply_elementwise(B) == Matrix([
[_h],
[_h],
[_h]])
def test_matmul():
a = Matrix([[1, 2], [3, 4]])
assert a.__matmul__(2) == NotImplemented
assert a.__rmatmul__(2) == NotImplemented
#This is done this way because @ is only supported in Python 3.5+
#To check 2@a case
try:
eval('2 @ a')
except SyntaxError:
pass
except TypeError: #TypeError is raised in case of NotImplemented is returned
pass
#Check a@2 case
try:
eval('a @ 2')
except SyntaxError:
pass
except TypeError: #TypeError is raised in case of NotImplemented is returned
pass
def test_non_matmul():
"""
Test that if explicitly specified as non-matrix, mul reverts
to scalar multiplication.
"""
class foo(Expr):
is_Matrix=False
is_MatrixLike=False
shape = (1, 1)
A = Matrix([[1, 2], [3, 4]])
b = foo()
assert b*A == Matrix([[b, 2*b], [3*b, 4*b]])
assert A*b == Matrix([[b, 2*b], [3*b, 4*b]])
def test_power():
raises(NonSquareMatrixError, lambda: Matrix((1, 2))**2)
A = ArithmeticOnlyMatrix([[2, 3], [4, 5]])
assert (A**5)[:] == (6140, 8097, 10796, 14237)
A = ArithmeticOnlyMatrix([[2, 1, 3], [4, 2, 4], [6, 12, 1]])
assert (A**3)[:] == (290, 262, 251, 448, 440, 368, 702, 954, 433)
assert A**0 == eye(3)
assert A**1 == A
assert (ArithmeticOnlyMatrix([[2]]) ** 100)[0, 0] == 2**100
assert ArithmeticOnlyMatrix([[1, 2], [3, 4]])**Integer(2) == ArithmeticOnlyMatrix([[7, 10], [15, 22]])
A = Matrix([[1,2],[4,5]])
assert A.pow(20, method='cayley') == A.pow(20, method='multiply')
def test_neg():
n = ArithmeticOnlyMatrix(1, 2, [1, 2])
assert -n == ArithmeticOnlyMatrix(1, 2, [-1, -2])
def test_sub():
n = ArithmeticOnlyMatrix(1, 2, [1, 2])
assert n - n == ArithmeticOnlyMatrix(1, 2, [0, 0])
def test_div():
n = ArithmeticOnlyMatrix(1, 2, [1, 2])
assert n/2 == ArithmeticOnlyMatrix(1, 2, [S.Half, S(2)/2])
# SpecialOnlyMatrix tests
def test_eye():
assert list(SpecialOnlyMatrix.eye(2, 2)) == [1, 0, 0, 1]
assert list(SpecialOnlyMatrix.eye(2)) == [1, 0, 0, 1]
assert type(SpecialOnlyMatrix.eye(2)) == SpecialOnlyMatrix
assert type(SpecialOnlyMatrix.eye(2, cls=Matrix)) == Matrix
def test_ones():
assert list(SpecialOnlyMatrix.ones(2, 2)) == [1, 1, 1, 1]
assert list(SpecialOnlyMatrix.ones(2)) == [1, 1, 1, 1]
assert SpecialOnlyMatrix.ones(2, 3) == Matrix([[1, 1, 1], [1, 1, 1]])
assert type(SpecialOnlyMatrix.ones(2)) == SpecialOnlyMatrix
assert type(SpecialOnlyMatrix.ones(2, cls=Matrix)) == Matrix
def test_zeros():
assert list(SpecialOnlyMatrix.zeros(2, 2)) == [0, 0, 0, 0]
assert list(SpecialOnlyMatrix.zeros(2)) == [0, 0, 0, 0]
assert SpecialOnlyMatrix.zeros(2, 3) == Matrix([[0, 0, 0], [0, 0, 0]])
assert type(SpecialOnlyMatrix.zeros(2)) == SpecialOnlyMatrix
assert type(SpecialOnlyMatrix.zeros(2, cls=Matrix)) == Matrix
def test_diag_make():
diag = SpecialOnlyMatrix.diag
a = Matrix([[1, 2], [2, 3]])
b = Matrix([[3, x], [y, 3]])
c = Matrix([[3, x, 3], [y, 3, z], [x, y, z]])
assert diag(a, b, b) == Matrix([
[1, 2, 0, 0, 0, 0],
[2, 3, 0, 0, 0, 0],
[0, 0, 3, x, 0, 0],
[0, 0, y, 3, 0, 0],
[0, 0, 0, 0, 3, x],
[0, 0, 0, 0, y, 3],
])
assert diag(a, b, c) == Matrix([
[1, 2, 0, 0, 0, 0, 0],
[2, 3, 0, 0, 0, 0, 0],
[0, 0, 3, x, 0, 0, 0],
[0, 0, y, 3, 0, 0, 0],
[0, 0, 0, 0, 3, x, 3],
[0, 0, 0, 0, y, 3, z],
[0, 0, 0, 0, x, y, z],
])
assert diag(a, c, b) == Matrix([
[1, 2, 0, 0, 0, 0, 0],
[2, 3, 0, 0, 0, 0, 0],
[0, 0, 3, x, 3, 0, 0],
[0, 0, y, 3, z, 0, 0],
[0, 0, x, y, z, 0, 0],
[0, 0, 0, 0, 0, 3, x],
[0, 0, 0, 0, 0, y, 3],
])
a = Matrix([x, y, z])
b = Matrix([[1, 2], [3, 4]])
c = Matrix([[5, 6]])
# this "wandering diagonal" is what makes this
# a block diagonal where each block is independent
# of the others
assert diag(a, 7, b, c) == Matrix([
[x, 0, 0, 0, 0, 0],
[y, 0, 0, 0, 0, 0],
[z, 0, 0, 0, 0, 0],
[0, 7, 0, 0, 0, 0],
[0, 0, 1, 2, 0, 0],
[0, 0, 3, 4, 0, 0],
[0, 0, 0, 0, 5, 6]])
raises(ValueError, lambda: diag(a, 7, b, c, rows=5))
assert diag(1) == Matrix([[1]])
assert diag(1, rows=2) == Matrix([[1, 0], [0, 0]])
assert diag(1, cols=2) == Matrix([[1, 0], [0, 0]])
assert diag(1, rows=3, cols=2) == Matrix([[1, 0], [0, 0], [0, 0]])
assert diag(*[2, 3]) == Matrix([
[2, 0],
[0, 3]])
assert diag(Matrix([2, 3])) == Matrix([
[2],
[3]])
assert diag([1, [2, 3], 4], unpack=False) == \
diag([[1], [2, 3], [4]], unpack=False) == Matrix([
[1, 0],
[2, 3],
[4, 0]])
assert type(diag(1)) == SpecialOnlyMatrix
assert type(diag(1, cls=Matrix)) == Matrix
assert Matrix.diag([1, 2, 3]) == Matrix.diag(1, 2, 3)
assert Matrix.diag([1, 2, 3], unpack=False).shape == (3, 1)
assert Matrix.diag([[1, 2, 3]]).shape == (3, 1)
assert Matrix.diag([[1, 2, 3]], unpack=False).shape == (1, 3)
assert Matrix.diag([[[1, 2, 3]]]).shape == (1, 3)
# kerning can be used to move the starting point
assert Matrix.diag(ones(0, 2), 1, 2) == Matrix([
[0, 0, 1, 0],
[0, 0, 0, 2]])
assert Matrix.diag(ones(2, 0), 1, 2) == Matrix([
[0, 0],
[0, 0],
[1, 0],
[0, 2]])
def test_diagonal():
m = Matrix(3, 3, range(9))
d = m.diagonal()
assert d == m.diagonal(0)
assert tuple(d) == (0, 4, 8)
assert tuple(m.diagonal(1)) == (1, 5)
assert tuple(m.diagonal(-1)) == (3, 7)
assert tuple(m.diagonal(2)) == (2,)
assert type(m.diagonal()) == type(m)
s = SparseMatrix(3, 3, {(1, 1): 1})
assert type(s.diagonal()) == type(s)
assert type(m) != type(s)
raises(ValueError, lambda: m.diagonal(3))
raises(ValueError, lambda: m.diagonal(-3))
raises(ValueError, lambda: m.diagonal(pi))
M = ones(2, 3)
assert banded({i: list(M.diagonal(i))
for i in range(1-M.rows, M.cols)}) == M
def test_jordan_block():
assert SpecialOnlyMatrix.jordan_block(3, 2) == SpecialOnlyMatrix.jordan_block(3, eigenvalue=2) \
== SpecialOnlyMatrix.jordan_block(size=3, eigenvalue=2) \
== SpecialOnlyMatrix.jordan_block(3, 2, band='upper') \
== SpecialOnlyMatrix.jordan_block(
size=3, eigenval=2, eigenvalue=2) \
== Matrix([
[2, 1, 0],
[0, 2, 1],
[0, 0, 2]])
assert SpecialOnlyMatrix.jordan_block(3, 2, band='lower') == Matrix([
[2, 0, 0],
[1, 2, 0],
[0, 1, 2]])
# missing eigenvalue
raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(2))
# non-integral size
raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(3.5, 2))
# size not specified
raises(ValueError, lambda: SpecialOnlyMatrix.jordan_block(eigenvalue=2))
# inconsistent eigenvalue
raises(ValueError,
lambda: SpecialOnlyMatrix.jordan_block(
eigenvalue=2, eigenval=4))
# Using alias keyword
assert SpecialOnlyMatrix.jordan_block(size=3, eigenvalue=2) == \
SpecialOnlyMatrix.jordan_block(size=3, eigenval=2)
def test_orthogonalize():
m = Matrix([[1, 2], [3, 4]])
assert m.orthogonalize(Matrix([[2], [1]])) == [Matrix([[2], [1]])]
assert m.orthogonalize(Matrix([[2], [1]]), normalize=True) == \
[Matrix([[2*sqrt(5)/5], [sqrt(5)/5]])]
assert m.orthogonalize(Matrix([[1], [2]]), Matrix([[-1], [4]])) == \
[Matrix([[1], [2]]), Matrix([[Rational(-12, 5)], [Rational(6, 5)]])]
assert m.orthogonalize(Matrix([[0], [0]]), Matrix([[-1], [4]])) == \
[Matrix([[-1], [4]])]
assert m.orthogonalize(Matrix([[0], [0]])) == []
n = Matrix([[9, 1, 9], [3, 6, 10], [8, 5, 2]])
vecs = [Matrix([[-5], [1]]), Matrix([[-5], [2]]), Matrix([[-5], [-2]])]
assert n.orthogonalize(*vecs) == \
[Matrix([[-5], [1]]), Matrix([[Rational(5, 26)], [Rational(25, 26)]])]
vecs = [Matrix([0, 0, 0]), Matrix([1, 2, 3]), Matrix([1, 4, 5])]
raises(ValueError, lambda: Matrix.orthogonalize(*vecs, rankcheck=True))
vecs = [Matrix([1, 2, 3]), Matrix([4, 5, 6]), Matrix([7, 8, 9])]
raises(ValueError, lambda: Matrix.orthogonalize(*vecs, rankcheck=True))
def test_wilkinson():
wminus, wplus = Matrix.wilkinson(1)
assert wminus == Matrix([
[-1, 1, 0],
[1, 0, 1],
[0, 1, 1]])
assert wplus == Matrix([
[1, 1, 0],
[1, 0, 1],
[0, 1, 1]])
wminus, wplus = Matrix.wilkinson(3)
assert wminus == Matrix([
[-3, 1, 0, 0, 0, 0, 0],
[1, -2, 1, 0, 0, 0, 0],
[0, 1, -1, 1, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 2, 1],
[0, 0, 0, 0, 0, 1, 3]])
assert wplus == Matrix([
[3, 1, 0, 0, 0, 0, 0],
[1, 2, 1, 0, 0, 0, 0],
[0, 1, 1, 1, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0],
[0, 0, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 1, 2, 1],
[0, 0, 0, 0, 0, 1, 3]])
# CalculusOnlyMatrix tests
@XFAIL
def test_diff():
x, y = symbols('x y')
m = CalculusOnlyMatrix(2, 1, [x, y])
# TODO: currently not working as ``_MinimalMatrix`` cannot be sympified:
assert m.diff(x) == Matrix(2, 1, [1, 0])
def test_integrate():
x, y = symbols('x y')
m = CalculusOnlyMatrix(2, 1, [x, y])
assert m.integrate(x) == Matrix(2, 1, [x**2/2, y*x])
def test_jacobian2():
rho, phi = symbols("rho,phi")
X = CalculusOnlyMatrix(3, 1, [rho*cos(phi), rho*sin(phi), rho**2])
Y = CalculusOnlyMatrix(2, 1, [rho, phi])
J = Matrix([
[cos(phi), -rho*sin(phi)],
[sin(phi), rho*cos(phi)],
[ 2*rho, 0],
])
assert X.jacobian(Y) == J
m = CalculusOnlyMatrix(2, 2, [1, 2, 3, 4])
m2 = CalculusOnlyMatrix(4, 1, [1, 2, 3, 4])
raises(TypeError, lambda: m.jacobian(Matrix([1, 2])))
raises(TypeError, lambda: m2.jacobian(m))
def test_limit():
x, y = symbols('x y')
m = CalculusOnlyMatrix(2, 1, [1/x, y])
assert m.limit(x, 5) == Matrix(2, 1, [Rational(1, 5), y])
def test_issue_13774():
M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
v = [1, 1, 1]
raises(TypeError, lambda: M*v)
raises(TypeError, lambda: v*M)
def test_companion():
x = Symbol('x')
y = Symbol('y')
raises(ValueError, lambda: Matrix.companion(1))
raises(ValueError, lambda: Matrix.companion(Poly([1], x)))
raises(ValueError, lambda: Matrix.companion(Poly([2, 1], x)))
raises(ValueError, lambda: Matrix.companion(Poly(x*y, [x, y])))
c0, c1, c2 = symbols('c0:3')
assert Matrix.companion(Poly([1, c0], x)) == Matrix([-c0])
assert Matrix.companion(Poly([1, c1, c0], x)) == \
Matrix([[0, -c0], [1, -c1]])
assert Matrix.companion(Poly([1, c2, c1, c0], x)) == \
Matrix([[0, 0, -c0], [1, 0, -c1], [0, 1, -c2]])
def test_issue_10589():
x, y, z = symbols("x, y z")
M1 = Matrix([x, y, z])
M1 = M1.subs(zip([x, y, z], [1, 2, 3]))
assert M1 == Matrix([[1], [2], [3]])
M2 = Matrix([[x, x, x, x, x], [x, x, x, x, x], [x, x, x, x, x]])
M2 = M2.subs(zip([x], [1]))
assert M2 == Matrix([[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1]])
def test_rmul_pr19860():
class Foo(ImmutableDenseMatrix):
_op_priority = MutableDenseMatrix._op_priority + 0.01
a = Matrix(2, 2, [1, 2, 3, 4])
b = Foo(2, 2, [1, 2, 3, 4])
# This would throw a RecursionError: maximum recursion depth
# since b always has higher priority even after a.as_mutable()
c = a*b
assert isinstance(c, Foo)
assert c == Matrix([[7, 10], [15, 22]])
def test_issue_18956():
A = Array([[1, 2], [3, 4]])
B = Matrix([[1,2],[3,4]])
raises(TypeError, lambda: B + A)
raises(TypeError, lambda: A + B)
def test__eq__():
class My(object):
def __iter__(self):
yield 1
yield 2
return
def __getitem__(self, i):
return list(self)[i]
a = Matrix(2, 1, [1, 2])
assert a != My()
class My_sympy(My):
def _sympy_(self):
return Matrix(self)
assert a == My_sympy()