# Introducing the domainmatrix of the poly module¶

This page introduces the idea behind domainmatrix which is used in SymPy’s sympy.polys module. This is a relatively advanced topic so for a better understanding it is recommended to read about Domain and DDM along with sympy.matrices module.

## What is domainmatrix?¶

It is way of associating Matrix with Domain.

A domainmatrix represents a matrix with elements that are in a particular Domain. Each domainmatrix internally wraps a DDM which is used for the lower-level operations. The idea is that the domainmatrix class provides the convenience routines for converting between Expr and the poly domains as well as unifying matrices with different domains.

In general, we represent a matrix without concerning about the Domain as:
>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> A = Matrix([
... [1, 2],
... [3, 4]])
>>> A
Matrix([
[1, 2],
[3, 4]])


## DomainMatrix Class Reference¶

class sympy.polys.matrices.domainmatrix.DomainMatrix(rows, shape, domain, *, fmt=None)[source]

Associate Matrix with Domain

Explanation

DomainMatrix uses Domain for its internal representation which makes it more faster for many common operations than current sympy Matrix class, but this advantage makes it not entirely compatible with Matrix. DomainMatrix could be found analogous to numpy arrays with “dtype”. In the DomainMatrix, each matrix has a domain such as ZZ or QQ<a>.

Examples

Creating a DomainMatrix from the existing Matrix class:

>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> Matrix1 = Matrix([
...    [1, 2],
...    [3, 4]])
>>> A = DomainMatrix.from_Matrix(Matrix1)
>>> A
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ)


Driectly forming a DomainMatrix:

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> A
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ)


add(B)[source]

Adds two DomainMatrix matrices of the same Domain

Parameters

A, B: DomainMatrix

Returns

DomainMatrix

Raises

ShapeError

If the dimensions of the two DomainMatrix are not equal

ValueError

If the domain of the two DomainMatrix are not same

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(4), ZZ(3)],
...    [ZZ(2), ZZ(1)]], (2, 2), ZZ)

>>> A.add(B)
DomainMatrix([[5, 5], [5, 5]], (2, 2), ZZ)


charpoly()[source]

Returns the coefficients of the characteristic polynomial of the DomainMatrix. These elements will be domain elements. The domain of the elements will be same as domain of the DomainMatrix.

Returns

list

coefficients of the characteristic polynomial

Raises

NonSquareMatrixError

If the DomainMatrix is not a not Square DomainMatrix

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.charpoly()
[1, -5, -2]

convert_to(K)[source]

Change the domain of DomainMatrix to desired domain or field

Parameters

K : Represents the desired domain or field

Returns

DomainMatrix

DomainMatrix with the desired domain or field

Examples

>>> from sympy import ZZ, ZZ_I
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.convert_to(ZZ_I)
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ_I)

det()[source]

Returns the determinant of a Square DomainMatrix

Returns

S.Complexes

determinant of Square DomainMatrix

Raises

ValueError

If the domain of DomainMatrix not a Field

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.det()
-2

classmethod eye(n, domain)[source]

Return identity matrix of size n

Examples

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> DomainMatrix.eye(3, QQ)
DomainMatrix({0: {0: 1}, 1: {1: 1}, 2: {2: 1}}, (3, 3), QQ)

classmethod from_Matrix(M, **kwargs)[source]

Convert Matrix to DomainMatrix

Parameters

M: Matrix

Returns

Returns DomainMatrix with identical elements as M

Examples

>>> from sympy import Matrix
>>> from sympy.polys.matrices import DomainMatrix
>>> M = Matrix([
...    [1.0, 3.4],
...    [2.4, 1]])
>>> A = DomainMatrix.from_Matrix(M)
>>> A
DomainMatrix([[1.0, 3.4], [2.4, 1.0]], (2, 2), RR)

classmethod from_list_sympy(nrows, ncols, rows, **kwargs)[source]

Convert a list of lists of Expr into a DomainMatrix using construct_domain

Parameters

nrows: number of rows

ncols: number of columns

rows: list of lists

Returns

DomainMatrix containing elements of rows

Examples

>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix.from_list_sympy(1, 2, [[1, 0]])
>>> A
DomainMatrix([[1, 0]], (1, 2), ZZ)

classmethod from_rep(rep)[source]

Create a new DomainMatrix efficiently from DDM/SDM.

Parameters

rep: SDM or DDM

The internal sparse or dense representation of the matrix.

Returns

DomainMatrix

Examples

Create a DomainMatrix with an dense internal representation as DDM:

>>> from sympy.polys.domains import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.ddm import DDM
>>> drep = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> dM = DomainMatrix.from_rep(drep)
>>> dM
DomainMatrix([[1, 2], [3, 4]], (2, 2), ZZ)


Create a DomainMatrix with a sparse internal representation as SDM:

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy.polys.matrices.sdm import SDM
>>> from sympy import ZZ
>>> drep = SDM({0:{1:ZZ(1)},1:{0:ZZ(2)}}, (2, 2), ZZ)
>>> dM = DomainMatrix.from_rep(drep)
>>> dM
DomainMatrix({0: {1: 1}, 1: {0: 2}}, (2, 2), ZZ)


Notes

This takes ownership of rep as its internal representation. If rep is being mutated elsewhere then a copy should be provided to from_rep. Only minimal verification or checking is done on rep as this is supposed to be an efficient internal routine.

hstack(B)[source]

Horizontally stacks 2 Domain Matrices.

Parameters

A, B: DomainMatrix

to stack the rows horizontally

Returns

DomainMatrix

DomainMatrix by stacking the rows horizontally

Examples

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(2), ZZ(3)]], (1, 3), ZZ)
>>> B = DomainMatrix([[QQ(-1, 2), QQ(1, 2), QQ(1, 3)]],(1, 3), QQ)
>>> A.hstack(B)
DomainMatrix([[1, 2, 3, -1/2, 1/2, 1/3]], (1, 6), QQ)

inv()[source]

Finds the inverse of the DomainMatrix if exists

Returns

DomainMatrix

DomainMatrix after inverse

Raises

ValueError

If the domain of DomainMatrix not a Field

NonSquareMatrixError

If the DomainMatrix is not a not Square DomainMatrix

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [QQ(2), QQ(-1), QQ(0)],
...     [QQ(-1), QQ(2), QQ(-1)],
...     [QQ(0), QQ(0), QQ(2)]], (3, 3), QQ)
>>> A.inv()
DomainMatrix([[2/3, 1/3, 1/6], [1/3, 2/3, 1/3], [0, 0, 1/2]], (3, 3), QQ)

lu()[source]

Returns Lower and Upper decomposition of the DomainMatrix

Returns

(L, U, exchange)

L, U are Lower and Upper decomposition of the DomainMatrix, exchange is the list of indices of rows exchanged in the decomposition.

Raises

ValueError

If the domain of DomainMatrix not a Field

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(-1)],
...    [QQ(2), QQ(-2)]], (2, 2), QQ)
>>> A.lu()
(DomainMatrix([[1, 0], [2, 1]], (2, 2), QQ), DomainMatrix([[1, -1], [0, 0]], (2, 2), QQ), [])

lu_solve(rhs)[source]

Solver for DomainMatrix x in the A*x = B

Parameters

rhs : DomainMatrix B

Returns

DomainMatrix

x in A*x = B

Raises

ShapeError

If the DomainMatrix A and rhs have different number of rows

ValueError

If the domain of DomainMatrix A not a Field

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(2)],
...    [QQ(3), QQ(4)]], (2, 2), QQ)
>>> B = DomainMatrix([
...    [QQ(1), QQ(1)],
...    [QQ(0), QQ(1)]], (2, 2), QQ)

>>> A.lu_solve(B)
DomainMatrix([[-2, -1], [3/2, 1]], (2, 2), QQ)


lu

matmul(B)[source]

Performs matrix multiplication of two DomainMatrix matrices

Parameters

A, B: DomainMatrix

to multiply

Returns

DomainMatrix

DomainMatrix after multiplication

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(1), ZZ(1)],
...    [ZZ(0), ZZ(1)]], (2, 2), ZZ)

>>> A.matmul(B)
DomainMatrix([[1, 3], [3, 7]], (2, 2), ZZ)


mul(b)[source]

Performs term by term multiplication for the second DomainMatrix w.r.t first DomainMatrix. Returns a DomainMatrix whose rows are list of DomainMatrix matrices created after term by term multiplication.

Parameters

A, B: DomainMatrix

matrices to multiply term-wise

Returns

DomainMatrix

DomainMatrix after term by term multiplication

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(1), ZZ(1)],
...    [ZZ(0), ZZ(1)]], (2, 2), ZZ)

>>> A.mul(B)
DomainMatrix([[DomainMatrix([[1, 1], [0, 1]], (2, 2), ZZ),
DomainMatrix([[2, 2], [0, 2]], (2, 2), ZZ)],
[DomainMatrix([[3, 3], [0, 3]], (2, 2), ZZ),
DomainMatrix([[4, 4], [0, 4]], (2, 2), ZZ)]], (2, 2), ZZ)

neg()[source]

Returns the negative of DomainMatrix

Parameters

A : Represents a DomainMatrix

Returns

DomainMatrix

DomainMatrix after Negation

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.neg()
DomainMatrix([[-1, -2], [-3, -4]], (2, 2), ZZ)

nullspace()[source]

Returns the Null Space for the DomainMatrix

Returns

DomainMatrix

Null Space of the DomainMatrix

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [QQ(1), QQ(-1)],
...    [QQ(2), QQ(-2)]], (2, 2), QQ)
>>> A.nullspace()
DomainMatrix([[1, 1]], (1, 2), QQ)

pow(n)[source]

Computes A**n

Parameters

A : DomainMatrix

n : exponent for A

Returns

DomainMatrix

DomainMatrix on computing A**n

Raises

NotImplementedError

if n is negative.

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(1)],
...    [ZZ(0), ZZ(1)]], (2, 2), ZZ)

>>> A.pow(2)
DomainMatrix([[1, 2], [0, 1]], (2, 2), ZZ)

rref()[source]

Returns reduced-row echelon form and list of pivots for the DomainMatrix

Returns

(DomainMatrix, list)

reduced-row echelon form and list of pivots for the DomainMatrix

Raises

ValueError

If the domain of DomainMatrix not a Field

Examples

>>> from sympy import QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...     [QQ(2), QQ(-1), QQ(0)],
...     [QQ(-1), QQ(2), QQ(-1)],
...     [QQ(0), QQ(0), QQ(2)]], (3, 3), QQ)

>>> rref_matrix, rref_pivots = A.rref()
>>> rref_matrix
DomainMatrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]], (3, 3), QQ)
>>> rref_pivots
(0, 1, 2)


sub(B)[source]

Subtracts two DomainMatrix matrices of the same Domain

Parameters

A, B: DomainMatrix

matrices to substract

Returns

DomainMatrix

DomainMatrix after Substraction

Raises

ShapeError

If the dimensions of the two DomainMatrix are not equal

ValueError

If the domain of the two DomainMatrix are not same

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)
>>> B = DomainMatrix([
...    [ZZ(4), ZZ(3)],
...    [ZZ(2), ZZ(1)]], (2, 2), ZZ)

>>> A.sub(B)
DomainMatrix([[-3, -1], [1, 3]], (2, 2), ZZ)


to_Matrix()[source]

Convert DomainMatrix to Matrix

Returns

Matrix

MutableDenseMatrix for the DomainMatrix

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.to_Matrix()
Matrix([
[1, 2],
[3, 4]])

to_dense()[source]

Return a dense DomainMatrix representation of self.

Examples

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix({0: {0: 1}, 1: {1: 2}}, (2, 2), QQ)
>>> A.rep
{0: {0: 1}, 1: {1: 2}}
>>> B = A.to_dense()
>>> B.rep
[[1, 0], [0, 2]]

to_field()[source]

Returns a DomainMatrix with the appropriate field

Returns

DomainMatrix

DomainMatrix with the appropriate field

Examples

>>> from sympy import ZZ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([
...    [ZZ(1), ZZ(2)],
...    [ZZ(3), ZZ(4)]], (2, 2), ZZ)

>>> A.to_field()
DomainMatrix([[1, 2], [3, 4]], (2, 2), QQ)

to_sparse()[source]

Return a sparse DomainMatrix representation of self.

Examples

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> A = DomainMatrix([[1, 0],[0, 2]], (2, 2), QQ)
>>> A.rep
[[1, 0], [0, 2]]
>>> B = A.to_sparse()
>>> B.rep
{0: {0: 1}, 1: {1: 2}}

unify(other, *, fmt=None)[source]

Unifies the domains and the format of self and other matrices.

Parameters

other : another DomainMatrix

fmt: string ‘dense’, ‘sparse’ or None (default)

The preferred format to convert to if self and other are not already in the same format. If $$None$$ or not specified then no conversion if performed.

Returns

(dM1, dM2)

dM1, dM2 DomainMatrix matrices with unified Domain and format

Examples

Unify the domain of DomainMatrix that have different domains:

>>> from sympy import ZZ, QQ
>>> from sympy.polys.matrices import DomainMatrix
>>> A = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ)
>>> B = DomainMatrix([[QQ(1, 2), QQ(2)]], (1, 2), QQ)
>>> Aq, Bq = A.unify(B)
>>> Aq
DomainMatrix([[1, 2]], (1, 2), QQ)
>>> Bq
DomainMatrix([[1/2, 2]], (1, 2), QQ)


Unify the format (dense or sparse):

>>> A = DomainMatrix([[ZZ(1), ZZ(2)]], (1, 2), ZZ)
>>> B = DomainMatrix({0:{0: ZZ(1)}}, (2, 2), ZZ)
>>> B.rep
{0: {0: 1}}

>>> A2, B2 = A.unify(B, fmt='dense')
>>> B2.rep
[[1, 0], [0, 0]]

classmethod zeros(shape, domain, *, fmt='sparse')[source]

Returns a zero DomainMatrix of size shape, belonging to the specified domain

Examples

>>> from sympy.polys.matrices import DomainMatrix
>>> from sympy import QQ
>>> DomainMatrix.zeros((2, 3), QQ)
DomainMatrix({}, (2, 3), QQ)


## DDM Class Reference¶

class sympy.polys.matrices.ddm.DDM(rowslist, shape, domain)[source]

Dense matrix based on polys domain elements

This is a list subclass and is a wrapper for a list of lists that supports basic matrix arithmetic +, -, , *.

add(b)[source]

a + b

charpoly()[source]

Coefficients of characteristic polynomial of a

det()[source]

Determinant of a

inv()[source]

Inverse of a

lu()[source]

L, U decomposition of a

lu_solve(b)[source]

x where a*x = b

matmul(b)[source]

a @ b (matrix product)

neg()[source]

-a

rref()[source]

Reduced-row echelon form of a and list of pivots

sub(b)[source]

a - b

## SDM Class Reference¶

class sympy.polys.matrices.sdm.SDM(elemsdict, shape, domain)[source]

Sparse matrix based on polys domain elements

This is a dict subclass and is a wrapper for a dict of dicts that supports basic matrix arithmetic +, -, , *.