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({0: {0: 1, 1: 2}, 1: {0: 3, 1: 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
matrices to add
- Returns:
DomainMatrix
DomainMatrix after Addition
- Raises:
DMShapeError
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:
DMNonSquareMatrixError
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]
- columnspace()[source]#
Returns the columnspace for the DomainMatrix
- Returns:
DomainMatrix
The columns of this matrix form a basis for the columnspace.
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.columnspace() DomainMatrix([[1], [2]], (2, 1), QQ)
- convert_to(K)[source]#
Change the domain of DomainMatrix to desired domain or field
- Parameters:
K : Represents the desired domain or field.
Alternatively,
None
may be passed, in which case this method just returns a copy of this DomainMatrix.- 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 diag(diagonal, domain, shape=None)[source]#
Return diagonal matrix with entries from
diagonal
.Examples
>>> from sympy.polys.matrices import DomainMatrix >>> from sympy import ZZ >>> DomainMatrix.diag([ZZ(5), ZZ(6)], ZZ) DomainMatrix({0: {0: 5}, 1: {1: 6}}, (2, 2), ZZ)
- classmethod eye(shape, 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, fmt='sparse', **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({0: {0: 1.0, 1: 3.4}, 1: {0: 2.4, 1: 1.0}}, (2, 2), RR)
We can keep internal representation as ddm using fmt=’dense’ >>> from sympy import Matrix, QQ >>> from sympy.polys.matrices import DomainMatrix >>> A = DomainMatrix.from_Matrix(Matrix([[QQ(1, 2), QQ(3, 4)], [QQ(0, 1), QQ(0, 1)]]), fmt=’dense’) >>> A.rep [[1/2, 3/4], [0, 0]]
See also
- classmethod from_dict_sympy(nrows, ncols, elemsdict, **kwargs)[source]#
- Parameters:
nrows: number of rows
ncols: number of cols
elemsdict: dict of dicts containing non-zero elements of the DomainMatrix
- Returns:
DomainMatrix containing elements of elemsdict
Examples
>>> from sympy.polys.matrices import DomainMatrix >>> from sympy.abc import x,y,z >>> elemsdict = {0: {0:x}, 1:{1: y}, 2: {2: z}} >>> A = DomainMatrix.from_dict_sympy(3, 3, elemsdict) >>> A DomainMatrix({0: {0: x}, 1: {1: y}, 2: {2: z}}, (3, 3), ZZ[x,y,z])
See also
- classmethod from_list(rows, domain)[source]#
Convert a list of lists into a DomainMatrix
- Parameters:
rows: list of lists
Each element of the inner lists should be either the single arg, or tuple of args, that would be passed to the domain constructor in order to form an element of the domain. See examples.
- Returns:
DomainMatrix containing elements defined in rows
Examples
>>> from sympy.polys.matrices import DomainMatrix >>> from sympy import FF, QQ, ZZ >>> A = DomainMatrix.from_list([[1, 0, 1], [0, 0, 1]], ZZ) >>> A DomainMatrix([[1, 0, 1], [0, 0, 1]], (2, 3), ZZ) >>> B = DomainMatrix.from_list([[1, 0, 1], [0, 0, 1]], FF(7)) >>> B DomainMatrix([[1 mod 7, 0 mod 7, 1 mod 7], [0 mod 7, 0 mod 7, 1 mod 7]], (2, 3), GF(7)) >>> C = DomainMatrix.from_list([[(1, 2), (3, 1)], [(1, 4), (5, 1)]], QQ) >>> C DomainMatrix([[1/2, 3], [1/4, 5]], (2, 2), QQ)
See also
- 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 >>> from sympy.abc import x, y, z >>> A = DomainMatrix.from_list_sympy(1, 3, [[x, y, z]]) >>> A DomainMatrix([[x, y, z]], (1, 3), ZZ[x,y,z])
- 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
A
DomainMatrix
wrapping rep.
Examples
Create a
DomainMatrix
with an dense internal representation asDDM
:>>> 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 asSDM
:>>> 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 stack the given matrices.
- Parameters:
B: DomainMatrix
Matrices to stack horizontally.
- Returns:
DomainMatrix
DomainMatrix by stacking horizontally.
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(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ) >>> A.hstack(B) DomainMatrix([[1, 2, 5, 6], [3, 4, 7, 8]], (2, 4), ZZ)
>>> C = DomainMatrix([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ) >>> A.hstack(B, C) DomainMatrix([[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]], (2, 6), ZZ)
See also
- 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
DMNonSquareMatrixError
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)
See also
- property is_lower#
Says whether this matrix is lower-triangular. True can be returned even if the matrix is not square.
- property is_upper#
Says whether this matrix is upper-triangular. True can be returned even if the matrix is not square.
- 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), [])
See also
- 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:
DMShapeError
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)
See also
- 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)
See also
- 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 nullspace for the DomainMatrix
- Returns:
DomainMatrix
The rows of this matrix form a basis for the nullspace.
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)
- classmethod ones(shape, domain)[source]#
Returns a DomainMatrix of 1s, of size shape, belonging to the specified domain
Examples
>>> from sympy.polys.matrices import DomainMatrix >>> from sympy import QQ >>> DomainMatrix.ones((2,3), QQ) DomainMatrix([[1, 1, 1], [1, 1, 1]], (2, 3), 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)
See also
- rowspace()[source]#
Returns the rowspace for the DomainMatrix
- Returns:
DomainMatrix
The rows of this matrix form a basis for the rowspace.
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.rowspace() DomainMatrix([[1, -1]], (1, 2), QQ)
- 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)
See also
- scc()[source]#
Compute the strongly connected components of a DomainMatrix
- Returns:
List of lists of integers
Each list represents a strongly connected component.
Explanation
A square matrix can be considered as the adjacency matrix for a directed graph where the row and column indices are the vertices. In this graph if there is an edge from vertex
i
to vertexj
ifM[i, j]
is nonzero. This routine computes the strongly connected components of that graph which are subsets of the rows and columns that are connected by some nonzero element of the matrix. The strongly connected components are useful because many operations such as the determinant can be computed by working with the submatrices corresponding to each component.Examples
Find the strongly connected components of a matrix:
>>> from sympy import ZZ >>> from sympy.polys.matrices import DomainMatrix >>> M = DomainMatrix([[ZZ(1), ZZ(0), ZZ(2)], ... [ZZ(0), ZZ(3), ZZ(0)], ... [ZZ(4), ZZ(6), ZZ(5)]], (3, 3), ZZ) >>> M.scc() [[1], [0, 2]]
Compute the determinant from the components:
>>> MM = M.to_Matrix() >>> MM Matrix([ [1, 0, 2], [0, 3, 0], [4, 6, 5]]) >>> MM[[1], [1]] Matrix([[3]]) >>> MM[[0, 2], [0, 2]] Matrix([ [1, 2], [4, 5]]) >>> MM.det() -9 >>> MM[[1], [1]].det() * MM[[0, 2], [0, 2]].det() -9
The components are given in reverse topological order and represent a permutation of the rows and columns that will bring the matrix into block lower-triangular form:
>>> MM[[1, 0, 2], [1, 0, 2]] Matrix([ [3, 0, 0], [0, 1, 2], [6, 4, 5]])
- sub(B)[source]#
Subtracts two DomainMatrix matrices of the same Domain
- Parameters:
A, B: DomainMatrix
matrices to substract
- Returns:
DomainMatrix
DomainMatrix after Substraction
- Raises:
DMShapeError
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]])
See also
- 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(*others, fmt=None)[source]#
Unifies the domains and the format of self and other matrices.
- Parameters:
others : 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:
Tuple[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]]
See also
- vstack(*B)[source]#
Vertically stack the given matrices.
- Parameters:
B: DomainMatrix
Matrices to stack vertically.
- Returns:
DomainMatrix
DomainMatrix by stacking vertically.
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(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ) >>> A.vstack(B) DomainMatrix([[1, 2], [3, 4], [5, 6], [7, 8]], (4, 2), ZZ)
>>> C = DomainMatrix([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ) >>> A.vstack(B, C) DomainMatrix([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]], (6, 2), ZZ)
See also
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 +, -, , *.
- hstack(*B)[source]#
Horizontally stacks
DDM
matrices.Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import DDM
>>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) >>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ) >>> A.hstack(B) [[1, 2, 5, 6], [3, 4, 7, 8]]
>>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ) >>> A.hstack(B, C) [[1, 2, 5, 6, 9, 10], [3, 4, 7, 8, 11, 12]]
- is_lower()[source]#
Says whether this matrix is lower-triangular. True can be returned even if the matrix is not square.
- is_upper()[source]#
Says whether this matrix is upper-triangular. True can be returned even if the matrix is not square.
- scc()[source]#
Strongly connected components of a square matrix a.
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import DDM >>> A = DDM([[ZZ(1), ZZ(0)], [ZZ(0), ZZ(1)]], (2, 2), ZZ) >>> A.scc() [[0], [1]]
- vstack(*B)[source]#
Vertically stacks
DDM
matrices.Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import DDM
>>> A = DDM([[ZZ(1), ZZ(2)], [ZZ(3), ZZ(4)]], (2, 2), ZZ) >>> B = DDM([[ZZ(5), ZZ(6)], [ZZ(7), ZZ(8)]], (2, 2), ZZ) >>> A.vstack(B) [[1, 2], [3, 4], [5, 6], [7, 8]]
>>> C = DDM([[ZZ(9), ZZ(10)], [ZZ(11), ZZ(12)]], (2, 2), ZZ) >>> A.vstack(B, C) [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
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 +, -, , *.
In order to create a new
SDM
, a dict of dicts mapping non-zero elements to their corresponding row and column in the matrix is needed.We also need to specify the shape and
Domain
of ourSDM
object.We declare a 2x2
SDM
matrix belonging to QQ domain as shown below. The 2x2 Matrix in the example is\[\begin{split}A = \left[\begin{array}{ccc} 0 & \frac{1}{2} \\ 0 & 0 \end{array} \right]\end{split}\]>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> elemsdict = {0:{1:QQ(1, 2)}} >>> A = SDM(elemsdict, (2, 2), QQ) >>> A {0: {1: 1/2}}
We can manipulate
SDM
the same way as a Matrix class>>> from sympy import ZZ >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> B = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ) >>> A + B {0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}}
Multiplication
>>> A*B {0: {1: 8}, 1: {0: 3}} >>> A*ZZ(2) {0: {1: 4}, 1: {0: 2}}
- add(B)[source]#
Adds two
SDM
matricesExamples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> B = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ) >>> A.add(B) {0: {0: 3, 1: 2}, 1: {0: 1, 1: 4}}
- charpoly()[source]#
Returns the coefficients of the characteristic polynomial of the
SDM
matrix. These elements will be domain elements. The domain of the elements will be same as domain of theSDM
.Examples
>>> from sympy import QQ, Symbol >>> from sympy.polys.matrices.sdm import SDM >>> from sympy.polys import Poly >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ) >>> A.charpoly() [1, -5, -2]
We can create a polynomial using the coefficients using
Poly
>>> x = Symbol('x') >>> p = Poly(A.charpoly(), x, domain=A.domain) >>> p Poly(x**2 - 5*x - 2, x, domain='QQ')
- convert_to(K)[source]#
Converts the
Domain
of aSDM
matrix to KExamples
>>> from sympy import ZZ, QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> A.convert_to(QQ) {0: {1: 2}, 1: {0: 1}}
- copy()[source]#
Returns the copy of a
SDM
objectExamples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> elemsdict = {0:{1:QQ(2)}, 1:{}} >>> A = SDM(elemsdict, (2, 2), QQ) >>> B = A.copy() >>> B {0: {1: 2}, 1: {}}
- det()[source]#
Returns determinant of A
Examples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ) >>> A.det() -2
- classmethod eye(shape, domain)[source]#
Returns a identity
SDM
matrix of dimensions size x size, belonging to the specified domainExamples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> I = SDM.eye((2, 2), QQ) >>> I {0: {0: 1}, 1: {1: 1}}
- classmethod from_ddm(ddm)[source]#
-
Examples
>>> from sympy.polys.matrices.ddm import DDM >>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> ddm = DDM( [[QQ(1, 2), 0], [0, QQ(3, 4)]], (2, 2), QQ) >>> A = SDM.from_ddm(ddm) >>> A {0: {0: 1/2}, 1: {1: 3/4}}
- classmethod from_list(ddm, shape, domain)[source]#
- Parameters:
ddm:
list of lists containing domain elements
shape:
Dimensions of
SDM
matrixdomain:
- Returns:
SDM
containing elements of ddm
Examples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> ddm = [[QQ(1, 2), QQ(0)], [QQ(0), QQ(3, 4)]] >>> A = SDM.from_list(ddm, (2, 2), QQ) >>> A {0: {0: 1/2}, 1: {1: 3/4}}
- hstack(*B)[source]#
Horizontally stacks
SDM
matrices.Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) >>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ) >>> A.hstack(B) {0: {0: 1, 1: 2, 2: 5, 3: 6}, 1: {0: 3, 1: 4, 2: 7, 3: 8}}
>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ) >>> A.hstack(B, C) {0: {0: 1, 1: 2, 2: 5, 3: 6, 4: 9, 5: 10}, 1: {0: 3, 1: 4, 2: 7, 3: 8, 4: 11, 5: 12}}
- inv()[source]#
Returns inverse of a matrix A
Examples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ) >>> A.inv() {0: {0: -2, 1: 1}, 1: {0: 3/2, 1: -1/2}}
- is_lower()[source]#
Says whether this matrix is lower-triangular. True can be returned even if the matrix is not square.
- is_upper()[source]#
Says whether this matrix is upper-triangular. True can be returned even if the matrix is not square.
- lu()[source]#
Returns LU decomposition for a matrix A
Examples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ) >>> A.lu() ({0: {0: 1}, 1: {0: 3, 1: 1}}, {0: {0: 1, 1: 2}, 1: {1: -2}}, [])
- lu_solve(b)[source]#
Uses LU decomposition to solve Ax = b,
Examples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(3), 1:QQ(4)}}, (2, 2), QQ) >>> b = SDM({0:{0:QQ(1)}, 1:{0:QQ(2)}}, (2, 1), QQ) >>> A.lu_solve(b) {1: {0: 1/2}}
- matmul(B)[source]#
Performs matrix multiplication of two SDM matrices
- Parameters:
A, B: SDM to multiply
- Returns:
SDM
SDM after multiplication
- Raises:
DomainError
If domain of A does not match with that of B
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> B = SDM({0:{0:ZZ(2), 1:ZZ(3)}, 1:{0:ZZ(4)}}, (2, 2), ZZ) >>> A.matmul(B) {0: {0: 8}, 1: {0: 2, 1: 3}}
- mul(b)[source]#
Multiplies each element of A with a scalar b
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> A.mul(ZZ(3)) {0: {1: 6}, 1: {0: 3}}
- neg()[source]#
Returns the negative of a
SDM
matrixExamples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> A.neg() {0: {1: -2}, 1: {0: -1}}
- classmethod new(sdm, shape, domain)[source]#
- Parameters:
sdm: A dict of dicts for non-zero elements in SDM
shape: tuple representing dimension of SDM
domain: Represents :py:class:`~.Domain` of SDM
- Returns:
An
SDM
object
Examples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> elemsdict = {0:{1: QQ(2)}} >>> A = SDM.new(elemsdict, (2, 2), QQ) >>> A {0: {1: 2}}
- nullspace()[source]#
Returns nullspace for a
SDM
matrix AExamples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0: QQ(2), 1: QQ(4)}}, (2, 2), QQ) >>> A.nullspace() ({0: {0: -2, 1: 1}}, [1])
- rref()[source]#
Returns reduced-row echelon form and list of pivots for the
SDM
Examples
>>> from sympy import QQ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0:QQ(1), 1:QQ(2)}, 1:{0:QQ(2), 1:QQ(4)}}, (2, 2), QQ) >>> A.rref() ({0: {0: 1, 1: 2}}, [0])
- scc()[source]#
Strongly connected components of a square matrix A.
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{0: ZZ(2)}, 1:{1:ZZ(1)}}, (2, 2), ZZ) >>> A.scc() [[0], [1]]
- sub(B)[source]#
Subtracts two
SDM
matricesExamples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM >>> A = SDM({0:{1: ZZ(2)}, 1:{0:ZZ(1)}}, (2, 2), ZZ) >>> B = SDM({0:{0: ZZ(3)}, 1:{1:ZZ(4)}}, (2, 2), ZZ) >>> A.sub(B) {0: {0: -3, 1: 2}, 1: {0: 1, 1: -4}}
- to_ddm()[source]#
Convert a
SDM
object to aDDM
objectExamples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ) >>> A.to_ddm() [[0, 2], [0, 0]]
- to_list()[source]#
Converts a
SDM
object to a listExamples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> elemsdict = {0:{1:QQ(2)}, 1:{}} >>> A = SDM(elemsdict, (2, 2), QQ) >>> A.to_list() [[0, 2], [0, 0]]
- transpose()[source]#
Returns the transpose of a
SDM
matrixExamples
>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> A = SDM({0:{1:QQ(2)}, 1:{}}, (2, 2), QQ) >>> A.transpose() {1: {0: 2}}
- vstack(*B)[source]#
Vertically stacks
SDM
matrices.Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices.sdm import SDM
>>> A = SDM({0: {0: ZZ(1), 1: ZZ(2)}, 1: {0: ZZ(3), 1: ZZ(4)}}, (2, 2), ZZ) >>> B = SDM({0: {0: ZZ(5), 1: ZZ(6)}, 1: {0: ZZ(7), 1: ZZ(8)}}, (2, 2), ZZ) >>> A.vstack(B) {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}}
>>> C = SDM({0: {0: ZZ(9), 1: ZZ(10)}, 1: {0: ZZ(11), 1: ZZ(12)}}, (2, 2), ZZ) >>> A.vstack(B, C) {0: {0: 1, 1: 2}, 1: {0: 3, 1: 4}, 2: {0: 5, 1: 6}, 3: {0: 7, 1: 8}, 4: {0: 9, 1: 10}, 5: {0: 11, 1: 12}}
- classmethod zeros(shape, domain)[source]#
Returns a
SDM
of size shape, belonging to the specified domainIn the example below we declare a matrix A where,
\[\begin{split}A := \left[\begin{array}{ccc} 0 & 0 & 0 \\ 0 & 0 & 0 \end{array} \right]\end{split}\]>>> from sympy.polys.matrices.sdm import SDM >>> from sympy import QQ >>> A = SDM.zeros((2, 3), QQ) >>> A {}
Normal Forms#
- sympy.polys.matrices.normalforms.smith_normal_form(m)[source]#
Return the Smith Normal Form of a matrix \(m\) over the ring \(domain\). This will only work if the ring is a principal ideal domain.
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices import DomainMatrix >>> from sympy.polys.matrices.normalforms import smith_normal_form >>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)], ... [ZZ(3), ZZ(9), ZZ(6)], ... [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ) >>> print(smith_normal_form(m).to_Matrix()) Matrix([[1, 0, 0], [0, 10, 0], [0, 0, -30]])
- sympy.polys.matrices.normalforms.hermite_normal_form(A, *, D=None, check_rank=False)[source]#
Compute the Hermite Normal Form of
DomainMatrix
A over ZZ.- Parameters:
A : \(m \times n\)
DomainMatrix
over ZZ.D : ZZ, optional
Let \(W\) be the HNF of A. If known in advance, a positive integer D being any multiple of \(\det(W)\) may be provided. In this case, if A also has rank \(m\), then we may use an alternative algorithm that works mod D in order to prevent coefficient explosion.
check_rank : boolean, optional (default=False)
The basic assumption is that, if you pass a value for D, then you already believe that A has rank \(m\), so we do not waste time checking it for you. If you do want this to be checked (and the ordinary, non-modulo D algorithm to be used if the check fails), then set check_rank to
True
.- Returns:
-
The HNF of matrix A.
- Raises:
DMDomainError
DMShapeError
If the mod D algorithm is used but the matrix has more rows than columns.
Examples
>>> from sympy import ZZ >>> from sympy.polys.matrices import DomainMatrix >>> from sympy.polys.matrices.normalforms import hermite_normal_form >>> m = DomainMatrix([[ZZ(12), ZZ(6), ZZ(4)], ... [ZZ(3), ZZ(9), ZZ(6)], ... [ZZ(2), ZZ(16), ZZ(14)]], (3, 3), ZZ) >>> print(hermite_normal_form(m).to_Matrix()) Matrix([[10, 0, 2], [0, 15, 3], [0, 0, 2]])
References
[R694]Cohen, H. A Course in Computational Algebraic Number Theory. (See Algorithms 2.4.5 and 2.4.8.)