Matrix Expressions

The Matrix expression module allows users to write down statements like

>>> from sympy import MatrixSymbol, Matrix
>>> X = MatrixSymbol('X', 3, 3)
>>> Y = MatrixSymbol('Y', 3, 3)
>>> (X.T*X).I*Y
X**(-1)*X.T**(-1)*Y
>>> Matrix(X)
Matrix([
[X[0, 0], X[0, 1], X[0, 2]],
[X[1, 0], X[1, 1], X[1, 2]],
[X[2, 0], X[2, 1], X[2, 2]]])
>>> (X*Y)[1, 2]
X[1, 0]*Y[0, 2] + X[1, 1]*Y[1, 2] + X[1, 2]*Y[2, 2]

where X and Y are MatrixSymbol’s rather than scalar symbols.

Matrix Expressions Core Reference

class sympy.matrices.expressions.MatrixExpr(*args, **kwargs)[source]

Superclass for Matrix Expressions

MatrixExprs represent abstract matrices, linear transformations represented within a particular basis.

Examples

>>> from sympy import MatrixSymbol
>>> A = MatrixSymbol('A', 3, 3)
>>> y = MatrixSymbol('y', 3, 1)
>>> x = (A.T*A).I * A * y
property T

Matrix transposition.

as_coeff_Mul(rational=False)[source]

Efficiently extract the coefficient of a product.

as_explicit()[source]

Returns a dense Matrix with elements represented explicitly

Returns an object of type ImmutableDenseMatrix.

Examples

>>> from sympy import Identity
>>> I = Identity(3)
>>> I
I
>>> I.as_explicit()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])

See also

as_mutable

returns mutable Matrix type

as_mutable()[source]

Returns a dense, mutable matrix with elements represented explicitly

Examples

>>> from sympy import Identity
>>> I = Identity(3)
>>> I
I
>>> I.shape
(3, 3)
>>> I.as_mutable()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])

See also

as_explicit

returns ImmutableDenseMatrix

equals(other)[source]

Test elementwise equality between matrices, potentially of different types

>>> from sympy import Identity, eye
>>> Identity(3).equals(eye(3))
True
static from_index_summation(expr, first_index=None, last_index=None, dimensions=None)[source]

Parse expression of matrices with explicitly summed indices into a matrix expression without indices, if possible.

This transformation expressed in mathematical notation:

\(\sum_{j=0}^{N-1} A_{i,j} B_{j,k} \Longrightarrow \mathbf{A}\cdot \mathbf{B}\)

Optional parameter first_index: specify which free index to use as the index starting the expression.

Examples

>>> from sympy import MatrixSymbol, MatrixExpr, Sum, Symbol
>>> from sympy.abc import i, j, k, l, N
>>> A = MatrixSymbol("A", N, N)
>>> B = MatrixSymbol("B", N, N)
>>> expr = Sum(A[i, j]*B[j, k], (j, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A*B

Transposition is detected:

>>> expr = Sum(A[j, i]*B[j, k], (j, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A.T*B

Detect the trace:

>>> expr = Sum(A[i, i], (i, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
Trace(A)

More complicated expressions:

>>> expr = Sum(A[i, j]*B[k, j]*A[l, k], (j, 0, N-1), (k, 0, N-1))
>>> MatrixExpr.from_index_summation(expr)
A*B.T*A.T
class sympy.matrices.expressions.MatrixSymbol(name, n, m)[source]

Symbolic representation of a Matrix object

Creates a SymPy Symbol to represent a Matrix. This matrix has a shape and can be included in Matrix Expressions

Examples

>>> from sympy import MatrixSymbol, Identity
>>> A = MatrixSymbol('A', 3, 4) # A 3 by 4 Matrix
>>> B = MatrixSymbol('B', 4, 3) # A 4 by 3 Matrix
>>> A.shape
(3, 4)
>>> 2*A*B + Identity(3)
I + 2*A*B
class sympy.matrices.expressions.MatAdd(*args, **kwargs)[source]

A Sum of Matrix Expressions

MatAdd inherits from and operates like SymPy Add

Examples

>>> from sympy import MatAdd, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 5)
>>> B = MatrixSymbol('B', 5, 5)
>>> C = MatrixSymbol('C', 5, 5)
>>> MatAdd(A, B, C)
A + B + C
class sympy.matrices.expressions.MatMul(*args, **kwargs)[source]

A product of matrix expressions

Examples

>>> from sympy import MatMul, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 4)
>>> B = MatrixSymbol('B', 4, 3)
>>> C = MatrixSymbol('C', 3, 6)
>>> MatMul(A, B, C)
A*B*C
class sympy.matrices.expressions.MatPow(base, exp)[source]
class sympy.matrices.expressions.HadamardProduct(*args, **kwargs)[source]

Elementwise product of matrix expressions

Examples

Hadamard product for matrix symbols:

>>> from sympy.matrices import hadamard_product, HadamardProduct, MatrixSymbol
>>> A = MatrixSymbol('A', 5, 5)
>>> B = MatrixSymbol('B', 5, 5)
>>> isinstance(hadamard_product(A, B), HadamardProduct)
True

Notes

This is a symbolic object that simply stores its argument without evaluating it. To actually compute the product, use the function hadamard_product() or HadamardProduct.doit

class sympy.matrices.expressions.HadamardPower(base, exp)[source]

Elementwise power of matrix expressions

Parameters

base : scalar or matrix

exp : scalar or matrix

Notes

There are four definitions for the hadamard power which can be used. Let’s consider \(A, B\) as \((m, n)\) matrices, and \(a, b\) as scalars.

Matrix raised to a scalar exponent:

\[\begin{split}A^{\circ b} = \begin{bmatrix} A_{0, 0}^b & A_{0, 1}^b & \cdots & A_{0, n-1}^b \\ A_{1, 0}^b & A_{1, 1}^b & \cdots & A_{1, n-1}^b \\ \vdots & \vdots & \ddots & \vdots \\ A_{m-1, 0}^b & A_{m-1, 1}^b & \cdots & A_{m-1, n-1}^b \end{bmatrix}\end{split}\]

Scalar raised to a matrix exponent:

\[\begin{split}a^{\circ B} = \begin{bmatrix} a^{B_{0, 0}} & a^{B_{0, 1}} & \cdots & a^{B_{0, n-1}} \\ a^{B_{1, 0}} & a^{B_{1, 1}} & \cdots & a^{B_{1, n-1}} \\ \vdots & \vdots & \ddots & \vdots \\ a^{B_{m-1, 0}} & a^{B_{m-1, 1}} & \cdots & a^{B_{m-1, n-1}} \end{bmatrix}\end{split}\]

Matrix raised to a matrix exponent:

\[\begin{split}A^{\circ B} = \begin{bmatrix} A_{0, 0}^{B_{0, 0}} & A_{0, 1}^{B_{0, 1}} & \cdots & A_{0, n-1}^{B_{0, n-1}} \\ A_{1, 0}^{B_{1, 0}} & A_{1, 1}^{B_{1, 1}} & \cdots & A_{1, n-1}^{B_{1, n-1}} \\ \vdots & \vdots & \ddots & \vdots \\ A_{m-1, 0}^{B_{m-1, 0}} & A_{m-1, 1}^{B_{m-1, 1}} & \cdots & A_{m-1, n-1}^{B_{m-1, n-1}} \end{bmatrix}\end{split}\]

Scalar raised to a scalar exponent:

\[a^{\circ b} = a^b\]
class sympy.matrices.expressions.Inverse(mat, exp=- 1)[source]

The multiplicative inverse of a matrix expression

This is a symbolic object that simply stores its argument without evaluating it. To actually compute the inverse, use the .inverse() method of matrices.

Examples

>>> from sympy import MatrixSymbol, Inverse
>>> A = MatrixSymbol('A', 3, 3)
>>> B = MatrixSymbol('B', 3, 3)
>>> Inverse(A)
A**(-1)
>>> A.inverse() == Inverse(A)
True
>>> (A*B).inverse()
B**(-1)*A**(-1)
>>> Inverse(A*B)
(A*B)**(-1)
class sympy.matrices.expressions.Transpose(*args, **kwargs)[source]

The transpose of a matrix expression.

This is a symbolic object that simply stores its argument without evaluating it. To actually compute the transpose, use the transpose() function, or the .T attribute of matrices.

Examples

>>> from sympy.matrices import MatrixSymbol, Transpose
>>> from sympy.functions import transpose
>>> A = MatrixSymbol('A', 3, 5)
>>> B = MatrixSymbol('B', 5, 3)
>>> Transpose(A)
A.T
>>> A.T == transpose(A) == Transpose(A)
True
>>> Transpose(A*B)
(A*B).T
>>> transpose(A*B)
B.T*A.T
class sympy.matrices.expressions.Trace(mat)[source]

Matrix Trace

Represents the trace of a matrix expression.

Examples

>>> from sympy import MatrixSymbol, Trace, eye
>>> A = MatrixSymbol('A', 3, 3)
>>> Trace(A)
Trace(A)
class sympy.matrices.expressions.FunctionMatrix(rows, cols, lamda)[source]

Represents a matrix using a function (Lambda) which gives outputs according to the coordinates of each matrix entries.

Parameters

rows : nonnegative integer. Can be symbolic.

cols : nonnegative integer. Can be symbolic.

lamda : Function, Lambda or str

If it is a SymPy Function or Lambda instance, it should be able to accept two arguments which represents the matrix coordinates.

If it is a pure string containing python lambda semantics, it is interpreted by the SymPy parser and casted into a SymPy Lambda instance.

Examples

Creating a FunctionMatrix from Lambda:

>>> from sympy import FunctionMatrix, symbols, Lambda, MatPow, Matrix
>>> i, j, n, m = symbols('i,j,n,m')
>>> FunctionMatrix(n, m, Lambda((i, j), i + j))
FunctionMatrix(n, m, Lambda((i, j), i + j))

Creating a FunctionMatrix from a sympy function:

>>> from sympy.functions import KroneckerDelta
>>> X = FunctionMatrix(3, 3, KroneckerDelta)
>>> X.as_explicit()
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])

Creating a FunctionMatrix from a sympy undefined function:

>>> from sympy.core.function import Function
>>> f = Function('f')
>>> X = FunctionMatrix(3, 3, f)
>>> X.as_explicit()
Matrix([
[f(0, 0), f(0, 1), f(0, 2)],
[f(1, 0), f(1, 1), f(1, 2)],
[f(2, 0), f(2, 1), f(2, 2)]])

Creating a FunctionMatrix from python lambda:

>>> FunctionMatrix(n, m, 'lambda i, j: i + j')
FunctionMatrix(n, m, Lambda((i, j), i + j))

Example of lazy evaluation of matrix product:

>>> Y = FunctionMatrix(1000, 1000, Lambda((i, j), i + j))
>>> isinstance(Y*Y, MatPow) # this is an expression object
True
>>> (Y**2)[10,10] # So this is evaluated lazily
342923500

Notes

This class provides an alternative way to represent an extremely dense matrix with entries in some form of a sequence, in a most sparse way.

class sympy.matrices.expressions.Identity(n)[source]

The Matrix Identity I - multiplicative identity

Examples

>>> from sympy.matrices import Identity, MatrixSymbol
>>> A = MatrixSymbol('A', 3, 5)
>>> I = Identity(3)
>>> I*A
A
class sympy.matrices.expressions.ZeroMatrix(m, n)[source]

The Matrix Zero 0 - additive identity

Examples

>>> from sympy import MatrixSymbol, ZeroMatrix
>>> A = MatrixSymbol('A', 3, 5)
>>> Z = ZeroMatrix(3, 5)
>>> A + Z
A
>>> Z*A.T
0

Block Matrices

Block matrices allow you to construct larger matrices out of smaller sub-blocks. They can work with MatrixExpr or ImmutableMatrix objects.

class sympy.matrices.expressions.blockmatrix.BlockMatrix(*args, **kwargs)[source]

A BlockMatrix is a Matrix comprised of other matrices.

The submatrices are stored in a SymPy Matrix object but accessed as part of a Matrix Expression

>>> from sympy import (MatrixSymbol, BlockMatrix, symbols,
...     Identity, ZeroMatrix, block_collapse)
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m ,m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]])
>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]])
>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]])

Some matrices might be comprised of rows of blocks with the matrices in each row having the same height and the rows all having the same total number of columns but not having the same number of columns for each matrix in each row. In this case, the matrix is not a block matrix and should be instantiated by Matrix.

>>> from sympy import ones, Matrix
>>> dat = [
... [ones(3,2), ones(3,3)*2],
... [ones(2,3)*3, ones(2,2)*4]]
...
>>> BlockMatrix(dat)
Traceback (most recent call last):
...
ValueError:
Although this matrix is comprised of blocks, the blocks do not fill
the matrix in a size-symmetric fashion. To create a full matrix from
these arguments, pass them directly to Matrix.
>>> Matrix(dat)
Matrix([
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[1, 1, 2, 2, 2],
[3, 3, 3, 4, 4],
[3, 3, 3, 4, 4]])
transpose()[source]

Return transpose of matrix.

Examples

>>> from sympy import MatrixSymbol, BlockMatrix, ZeroMatrix
>>> from sympy.abc import l, m, n
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m ,m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m,n), Y]])
>>> B.transpose()
Matrix([
[X.T,  0],
[Z.T, Y.T]])
>>> _.transpose()
Matrix([
[X, Z],
[0, Y]])
class sympy.matrices.expressions.blockmatrix.BlockDiagMatrix(*mats)[source]

A BlockDiagMatrix is a BlockMatrix with matrices only along the diagonal

>>> from sympy import MatrixSymbol, BlockDiagMatrix, symbols, Identity
>>> n, m, l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m ,m)
>>> BlockDiagMatrix(X, Y)
Matrix([
[X, 0],
[0, Y]])
sympy.matrices.expressions.blockmatrix.block_collapse(expr)[source]

Evaluates a block matrix expression

>>> from sympy import MatrixSymbol, BlockMatrix, symbols,                           Identity, Matrix, ZeroMatrix, block_collapse
>>> n,m,l = symbols('n m l')
>>> X = MatrixSymbol('X', n, n)
>>> Y = MatrixSymbol('Y', m ,m)
>>> Z = MatrixSymbol('Z', n, m)
>>> B = BlockMatrix([[X, Z], [ZeroMatrix(m, n), Y]])
>>> print(B)
Matrix([
[X, Z],
[0, Y]])
>>> C = BlockMatrix([[Identity(n), Z]])
>>> print(C)
Matrix([[I, Z]])
>>> print(block_collapse(C*B))
Matrix([[X, Z + Z*Y]])