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
See also
- property T¶
Matrix transposition
- 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, evaluate=False, **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, evaluate=False, **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.HadamardProduct(*args, evaluate=False, **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()
orHadamardProduct.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
orLambda
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 SymPyLambda
instance.
Examples
Creating a
FunctionMatrix
fromLambda
:>>> 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 pythonlambda
:>>> 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.PermutationMatrix(perm)[source]¶
A Permutation Matrix
- Parameters:
perm : Permutation
The permutation the matrix uses.
The size of the permutation determines the matrix size.
See the documentation of
sympy.combinatorics.permutations.Permutation
for the further information of how to create a permutation object.
Examples
>>> from sympy.matrices import Matrix, PermutationMatrix >>> from sympy.combinatorics import Permutation
Creating a permutation matrix:
>>> p = Permutation(1, 2, 0) >>> P = PermutationMatrix(p) >>> P = P.as_explicit() >>> P Matrix([ [0, 1, 0], [0, 0, 1], [1, 0, 0]])
Permuting a matrix row and column:
>>> M = Matrix([0, 1, 2]) >>> Matrix(P*M) Matrix([ [1], [2], [0]])
>>> Matrix(M.T*P) Matrix([[2, 0, 1]])
- class sympy.matrices.expressions.MatrixPermute(mat, perm, axis=0)[source]¶
Symbolic representation for permuting matrix rows or columns.
- Parameters:
perm : Permutation, PermutationMatrix
The permutation to use for permuting the matrix. The permutation can be resized to the suitable one,
axis : 0 or 1
The axis to permute alongside. If \(0\), it will permute the matrix rows. If \(1\), it will permute the matrix columns.
Notes
This follows the same notation used in
sympy.matrices.common.MatrixCommon.permute()
.Examples
>>> from sympy.matrices import Matrix, MatrixPermute >>> from sympy.combinatorics import Permutation
Permuting the matrix rows:
>>> p = Permutation(1, 2, 0) >>> A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> B = MatrixPermute(A, p, axis=0) >>> B.as_explicit() Matrix([ [4, 5, 6], [7, 8, 9], [1, 2, 3]])
Permuting the matrix columns:
>>> B = MatrixPermute(A, p, axis=1) >>> B.as_explicit() Matrix([ [2, 3, 1], [5, 6, 4], [8, 9, 7]])
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 sparse matrix with block matrices along its diagonals
Examples
>>> 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]])
Notes
If you want to get the individual diagonal blocks, use
get_diag_blocks()
.See also
- get_diag_blocks()[source]¶
Return the list of diagonal blocks of the matrix.
Examples
>>> from sympy.matrices import BlockDiagMatrix, Matrix
>>> A = Matrix([[1, 2], [3, 4]]) >>> B = Matrix([[5, 6], [7, 8]]) >>> M = BlockDiagMatrix(A, B)
How to get diagonal blocks from the block diagonal matrix:
>>> diag_blocks = M.get_diag_blocks() >>> diag_blocks[0] Matrix([ [1, 2], [3, 4]]) >>> diag_blocks[1] Matrix([ [5, 6], [7, 8]])
- 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]])