Sparse Matrices

SparseMatrix Class Reference

class sympy.matrices.sparse.SparseMatrix(*args, **kwargs)[source]

A sparse matrix (a matrix with a large number of zero elements).

Examples

>>> from sympy.matrices import SparseMatrix, ones
>>> SparseMatrix(2, 2, range(4))
Matrix([
[0, 1],
[2, 3]])
>>> SparseMatrix(2, 2, {(1, 1): 2})
Matrix([
[0, 0],
[0, 2]])

A SparseMatrix can be instantiated from a ragged list of lists:

>>> SparseMatrix([[1, 2, 3], [1, 2], [1]])
Matrix([
[1, 2, 3],
[1, 2, 0],
[1, 0, 0]])

For safety, one may include the expected size and then an error will be raised if the indices of any element are out of range or (for a flat list) if the total number of elements does not match the expected shape:

>>> SparseMatrix(2, 2, [1, 2])
Traceback (most recent call last):
...
ValueError: List length (2) != rows*columns (4)

Here, an error is not raised because the list is not flat and no element is out of range:

>>> SparseMatrix(2, 2, [[1, 2]])
Matrix([
[1, 2],
[0, 0]])

But adding another element to the first (and only) row will cause an error to be raised:

>>> SparseMatrix(2, 2, [[1, 2, 3]])
Traceback (most recent call last):
...
ValueError: The location (0, 2) is out of designated range: (1, 1)

To autosize the matrix, pass None for rows:

>>> SparseMatrix(None, [[1, 2, 3]])
Matrix([[1, 2, 3]])
>>> SparseMatrix(None, {(1, 1): 1, (3, 3): 3})
Matrix([
[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 3]])

Values that are themselves a Matrix are automatically expanded:

>>> SparseMatrix(4, 4, {(1, 1): ones(2)})
Matrix([
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]])

A ValueError is raised if the expanding matrix tries to overwrite a different element already present:

>>> SparseMatrix(3, 3, {(0, 0): ones(2), (1, 1): 2})
Traceback (most recent call last):
...
ValueError: collision at (1, 1)
property CL

Alternate faster representation

LDLdecomposition(hermitian=True)[source]

Returns the LDL Decomposition (matrices L and D) of matrix A, such that L * D * L.T == A. A must be a square, symmetric, positive-definite and non-singular.

This method eliminates the use of square root and ensures that all the diagonal entries of L are 1.

Examples

>>> from sympy.matrices import SparseMatrix
>>> A = SparseMatrix(((25, 15, -5), (15, 18, 0), (-5, 0, 11)))
>>> L, D = A.LDLdecomposition()
>>> L
Matrix([
[   1,   0, 0],
[ 3/5,   1, 0],
[-1/5, 1/3, 1]])
>>> D
Matrix([
[25, 0, 0],
[ 0, 9, 0],
[ 0, 0, 9]])
>>> L * D * L.T == A
True
property RL

Alternate faster representation

applyfunc(f)[source]

Apply a function to each element of the matrix.

Examples

>>> from sympy.matrices import SparseMatrix
>>> m = SparseMatrix(2, 2, lambda i, j: i*2+j)
>>> m
Matrix([
[0, 1],
[2, 3]])
>>> m.applyfunc(lambda i: 2*i)
Matrix([
[0, 2],
[4, 6]])
as_immutable()[source]

Returns an Immutable version of this Matrix.

as_mutable()[source]

Returns a mutable version of this matrix.

Examples

>>> from sympy import ImmutableMatrix
>>> X = ImmutableMatrix([[1, 2], [3, 4]])
>>> Y = X.as_mutable()
>>> Y[1, 1] = 5 # Can set values in Y
>>> Y
Matrix([
[1, 2],
[3, 5]])
cholesky(hermitian=True)[source]

Returns the Cholesky decomposition L of a matrix A such that L * L.T = A

A must be a square, symmetric, positive-definite and non-singular matrix

Examples

>>> from sympy.matrices import SparseMatrix
>>> A = SparseMatrix(((25,15,-5),(15,18,0),(-5,0,11)))
>>> A.cholesky()
Matrix([
[ 5, 0, 0],
[ 3, 3, 0],
[-1, 1, 3]])
>>> A.cholesky() * A.cholesky().T == A
True

The matrix can have complex entries:

>>> from sympy import I
>>> A = SparseMatrix(((9, 3*I), (-3*I, 5)))
>>> A.cholesky()
Matrix([
[ 3, 0],
[-I, 2]])
>>> A.cholesky() * A.cholesky().H
Matrix([
[   9, 3*I],
[-3*I,   5]])

Non-hermitian Cholesky-type decomposition may be useful when the matrix is not positive-definite.

>>> A = SparseMatrix([[1, 2], [2, 1]])
>>> L = A.cholesky(hermitian=False)
>>> L
Matrix([
[1,         0],
[2, sqrt(3)*I]])
>>> L*L.T == A
True
col_list()[source]

Returns a column-sorted list of non-zero elements of the matrix.

Examples

>>> from sympy.matrices import SparseMatrix
>>> a=SparseMatrix(((1, 2), (3, 4)))
>>> a
Matrix([
[1, 2],
[3, 4]])
>>> a.CL
[(0, 0, 1), (1, 0, 3), (0, 1, 2), (1, 1, 4)]
liupc()[source]

Liu’s algorithm, for pre-determination of the Elimination Tree of the given matrix, used in row-based symbolic Cholesky factorization.

Examples

>>> from sympy.matrices import SparseMatrix
>>> S = SparseMatrix([
... [1, 0, 3, 2],
... [0, 0, 1, 0],
... [4, 0, 0, 5],
... [0, 6, 7, 0]])
>>> S.liupc()
([[0], [], [0], [1, 2]], [4, 3, 4, 4])

References

Symbolic Sparse Cholesky Factorization using Elimination Trees, Jeroen Van Grondelle (1999) http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.7582

nnz()[source]

Returns the number of non-zero elements in Matrix.

row_list()[source]

Returns a row-sorted list of non-zero elements of the matrix.

Examples

>>> from sympy.matrices import SparseMatrix
>>> a = SparseMatrix(((1, 2), (3, 4)))
>>> a
Matrix([
[1, 2],
[3, 4]])
>>> a.RL
[(0, 0, 1), (0, 1, 2), (1, 0, 3), (1, 1, 4)]
row_structure_symbolic_cholesky()[source]

Symbolic cholesky factorization, for pre-determination of the non-zero structure of the Cholesky factororization.

Examples

>>> from sympy.matrices import SparseMatrix
>>> S = SparseMatrix([
... [1, 0, 3, 2],
... [0, 0, 1, 0],
... [4, 0, 0, 5],
... [0, 6, 7, 0]])
>>> S.row_structure_symbolic_cholesky()
[[0], [], [0], [1, 2]]

References

Symbolic Sparse Cholesky Factorization using Elimination Trees, Jeroen Van Grondelle (1999) http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.7582

scalar_multiply(scalar)[source]

Scalar element-wise multiplication

solve(rhs, method='LDL')[source]

Return solution to self*soln = rhs using given inversion method.

For a list of possible inversion methods, see the .inv() docstring.

solve_least_squares(rhs, method='LDL')[source]

Return the least-square fit to the data.

By default the cholesky_solve routine is used (method=’CH’); other methods of matrix inversion can be used. To find out which are available, see the docstring of the .inv() method.

Examples

>>> from sympy.matrices import SparseMatrix, Matrix, ones
>>> A = Matrix([1, 2, 3])
>>> B = Matrix([2, 3, 4])
>>> S = SparseMatrix(A.row_join(B))
>>> S
Matrix([
[1, 2],
[2, 3],
[3, 4]])

If each line of S represent coefficients of Ax + By and x and y are [2, 3] then S*xy is:

>>> r = S*Matrix([2, 3]); r
Matrix([
[ 8],
[13],
[18]])

But let’s add 1 to the middle value and then solve for the least-squares value of xy:

>>> xy = S.solve_least_squares(Matrix([8, 14, 18])); xy
Matrix([
[ 5/3],
[10/3]])

The error is given by S*xy - r:

>>> S*xy - r
Matrix([
[1/3],
[1/3],
[1/3]])
>>> _.norm().n(2)
0.58

If a different xy is used, the norm will be higher:

>>> xy += ones(2, 1)/10
>>> (S*xy - r).norm().n(2)
1.5
class sympy.matrices.sparse.MutableSparseMatrix(*args, **kwargs)[source]
col_del(k)[source]

Delete the given column of the matrix.

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix([[0, 0], [0, 1]])
>>> M
Matrix([
[0, 0],
[0, 1]])
>>> M.col_del(0)
>>> M
Matrix([
[0],
[1]])

See also

row_del

col_join(other)[source]

Returns B augmented beneath A (row-wise joining):

[A]
[B]

Examples

>>> from sympy import SparseMatrix, Matrix, ones
>>> A = SparseMatrix(ones(3))
>>> A
Matrix([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
>>> B = SparseMatrix.eye(3)
>>> B
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> C = A.col_join(B); C
Matrix([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1],
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> C == A.col_join(Matrix(B))
True

Joining along columns is the same as appending rows at the end of the matrix:

>>> C == A.row_insert(A.rows, Matrix(B))
True
col_op(j, f)[source]

In-place operation on col j using two-arg functor whose args are interpreted as (self[i, j], i) for i in range(self.rows).

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix.eye(3)*2
>>> M[1, 0] = -1
>>> M.col_op(1, lambda v, i: v + 2*M[i, 0]); M
Matrix([
[ 2, 4, 0],
[-1, 0, 0],
[ 0, 0, 2]])
col_swap(i, j)[source]

Swap, in place, columns i and j.

Examples

>>> from sympy.matrices import SparseMatrix
>>> S = SparseMatrix.eye(3); S[2, 1] = 2
>>> S.col_swap(1, 0); S
Matrix([
[0, 1, 0],
[1, 0, 0],
[2, 0, 1]])
fill(value)[source]

Fill self with the given value.

Notes

Unless many values are going to be deleted (i.e. set to zero) this will create a matrix that is slower than a dense matrix in operations.

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix.zeros(3); M
Matrix([
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
>>> M.fill(1); M
Matrix([
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
row_del(k)[source]

Delete the given row of the matrix.

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix([[0, 0], [0, 1]])
>>> M
Matrix([
[0, 0],
[0, 1]])
>>> M.row_del(0)
>>> M
Matrix([[0, 1]])

See also

col_del

row_join(other)[source]

Returns B appended after A (column-wise augmenting):

[A B]

Examples

>>> from sympy import SparseMatrix, Matrix
>>> A = SparseMatrix(((1, 0, 1), (0, 1, 0), (1, 1, 0)))
>>> A
Matrix([
[1, 0, 1],
[0, 1, 0],
[1, 1, 0]])
>>> B = SparseMatrix(((1, 0, 0), (0, 1, 0), (0, 0, 1)))
>>> B
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> C = A.row_join(B); C
Matrix([
[1, 0, 1, 1, 0, 0],
[0, 1, 0, 0, 1, 0],
[1, 1, 0, 0, 0, 1]])
>>> C == A.row_join(Matrix(B))
True

Joining at row ends is the same as appending columns at the end of the matrix:

>>> C == A.col_insert(A.cols, B)
True
row_op(i, f)[source]

In-place operation on row i using two-arg functor whose args are interpreted as (self[i, j], j).

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix.eye(3)*2
>>> M[0, 1] = -1
>>> M.row_op(1, lambda v, j: v + 2*M[0, j]); M
Matrix([
[2, -1, 0],
[4,  0, 0],
[0,  0, 2]])

See also

row, zip_row_op, col_op

row_swap(i, j)[source]

Swap, in place, columns i and j.

Examples

>>> from sympy.matrices import SparseMatrix
>>> S = SparseMatrix.eye(3); S[2, 1] = 2
>>> S.row_swap(1, 0); S
Matrix([
[0, 1, 0],
[1, 0, 0],
[0, 2, 1]])
zip_row_op(i, k, f)[source]

In-place operation on row i using two-arg functor whose args are interpreted as (self[i, j], self[k, j]).

Examples

>>> from sympy.matrices import SparseMatrix
>>> M = SparseMatrix.eye(3)*2
>>> M[0, 1] = -1
>>> M.zip_row_op(1, 0, lambda v, u: v + 2*u); M
Matrix([
[2, -1, 0],
[4,  0, 0],
[0,  0, 2]])

See also

row, row_op, col_op

ImmutableSparseMatrix Class Reference

class sympy.matrices.immutable.ImmutableSparseMatrix(*args, **kwargs)[source]

Create an immutable version of a sparse matrix.

Examples

>>> from sympy import eye
>>> from sympy.matrices.immutable import ImmutableSparseMatrix
>>> ImmutableSparseMatrix(1, 1, {})
Matrix([[0]])
>>> ImmutableSparseMatrix(eye(3))
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> _[0, 0] = 42
Traceback (most recent call last):
...
TypeError: Cannot set values of ImmutableSparseMatrix
>>> _.shape
(3, 3)
is_diagonalizable(reals_only=False, **kwargs)[source]

Returns True if a matrix is diagonalizable.

Parameters:

reals_only : bool, optional

If True, it tests whether the matrix can be diagonalized to contain only real numbers on the diagonal.

If False, it tests whether the matrix can be diagonalized at all, even with numbers that may not be real.

Examples

Example of a diagonalizable matrix:

>>> from sympy import Matrix
>>> M = Matrix([[1, 2, 0], [0, 3, 0], [2, -4, 2]])
>>> M.is_diagonalizable()
True

Example of a non-diagonalizable matrix:

>>> M = Matrix([[0, 1], [0, 0]])
>>> M.is_diagonalizable()
False

Example of a matrix that is diagonalized in terms of non-real entries:

>>> M = Matrix([[0, 1], [-1, 0]])
>>> M.is_diagonalizable(reals_only=False)
True
>>> M.is_diagonalizable(reals_only=True)
False