123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- from sympy.assumptions import Predicate
- from sympy.multipledispatch import Dispatcher
- class SquarePredicate(Predicate):
- """
- Square matrix predicate.
- Explanation
- ===========
- ``Q.square(x)`` is true iff ``x`` is a square matrix. A square matrix
- is a matrix with the same number of rows and columns.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, ZeroMatrix, Identity
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('X', 2, 3)
- >>> ask(Q.square(X))
- True
- >>> ask(Q.square(Y))
- False
- >>> ask(Q.square(ZeroMatrix(3, 3)))
- True
- >>> ask(Q.square(Identity(3)))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Square_matrix
- """
- name = 'square'
- handler = Dispatcher("SquareHandler", doc="Handler for Q.square.")
- class SymmetricPredicate(Predicate):
- """
- Symmetric matrix predicate.
- Explanation
- ===========
- ``Q.symmetric(x)`` is true iff ``x`` is a square matrix and is equal to
- its transpose. Every square diagonal matrix is a symmetric matrix.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('Y', 2, 3)
- >>> Z = MatrixSymbol('Z', 2, 2)
- >>> ask(Q.symmetric(X*Z), Q.symmetric(X) & Q.symmetric(Z))
- True
- >>> ask(Q.symmetric(X + Z), Q.symmetric(X) & Q.symmetric(Z))
- True
- >>> ask(Q.symmetric(Y))
- False
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Symmetric_matrix
- """
- # TODO: Add handlers to make these keys work with
- # actual matrices and add more examples in the docstring.
- name = 'symmetric'
- handler = Dispatcher("SymmetricHandler", doc="Handler for Q.symmetric.")
- class InvertiblePredicate(Predicate):
- """
- Invertible matrix predicate.
- Explanation
- ===========
- ``Q.invertible(x)`` is true iff ``x`` is an invertible matrix.
- A square matrix is called invertible only if its determinant is 0.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('Y', 2, 3)
- >>> Z = MatrixSymbol('Z', 2, 2)
- >>> ask(Q.invertible(X*Y), Q.invertible(X))
- False
- >>> ask(Q.invertible(X*Z), Q.invertible(X) & Q.invertible(Z))
- True
- >>> ask(Q.invertible(X), Q.fullrank(X) & Q.square(X))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Invertible_matrix
- """
- name = 'invertible'
- handler = Dispatcher("InvertibleHandler", doc="Handler for Q.invertible.")
- class OrthogonalPredicate(Predicate):
- """
- Orthogonal matrix predicate.
- Explanation
- ===========
- ``Q.orthogonal(x)`` is true iff ``x`` is an orthogonal matrix.
- A square matrix ``M`` is an orthogonal matrix if it satisfies
- ``M^TM = MM^T = I`` where ``M^T`` is the transpose matrix of
- ``M`` and ``I`` is an identity matrix. Note that an orthogonal
- matrix is necessarily invertible.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, Identity
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('Y', 2, 3)
- >>> Z = MatrixSymbol('Z', 2, 2)
- >>> ask(Q.orthogonal(Y))
- False
- >>> ask(Q.orthogonal(X*Z*X), Q.orthogonal(X) & Q.orthogonal(Z))
- True
- >>> ask(Q.orthogonal(Identity(3)))
- True
- >>> ask(Q.invertible(X), Q.orthogonal(X))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Orthogonal_matrix
- """
- name = 'orthogonal'
- handler = Dispatcher("OrthogonalHandler", doc="Handler for key 'orthogonal'.")
- class UnitaryPredicate(Predicate):
- """
- Unitary matrix predicate.
- Explanation
- ===========
- ``Q.unitary(x)`` is true iff ``x`` is a unitary matrix.
- Unitary matrix is an analogue to orthogonal matrix. A square
- matrix ``M`` with complex elements is unitary if :math:``M^TM = MM^T= I``
- where :math:``M^T`` is the conjugate transpose matrix of ``M``.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, Identity
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('Y', 2, 3)
- >>> Z = MatrixSymbol('Z', 2, 2)
- >>> ask(Q.unitary(Y))
- False
- >>> ask(Q.unitary(X*Z*X), Q.unitary(X) & Q.unitary(Z))
- True
- >>> ask(Q.unitary(Identity(3)))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Unitary_matrix
- """
- name = 'unitary'
- handler = Dispatcher("UnitaryHandler", doc="Handler for key 'unitary'.")
- class FullRankPredicate(Predicate):
- """
- Fullrank matrix predicate.
- Explanation
- ===========
- ``Q.fullrank(x)`` is true iff ``x`` is a full rank matrix.
- A matrix is full rank if all rows and columns of the matrix
- are linearly independent. A square matrix is full rank iff
- its determinant is nonzero.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, ZeroMatrix, Identity
- >>> X = MatrixSymbol('X', 2, 2)
- >>> ask(Q.fullrank(X.T), Q.fullrank(X))
- True
- >>> ask(Q.fullrank(ZeroMatrix(3, 3)))
- False
- >>> ask(Q.fullrank(Identity(3)))
- True
- """
- name = 'fullrank'
- handler = Dispatcher("FullRankHandler", doc="Handler for key 'fullrank'.")
- class PositiveDefinitePredicate(Predicate):
- r"""
- Positive definite matrix predicate.
- Explanation
- ===========
- If $M$ is a :math:`n \times n` symmetric real matrix, it is said
- to be positive definite if :math:`Z^TMZ` is positive for
- every non-zero column vector $Z$ of $n$ real numbers.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, Identity
- >>> X = MatrixSymbol('X', 2, 2)
- >>> Y = MatrixSymbol('Y', 2, 3)
- >>> Z = MatrixSymbol('Z', 2, 2)
- >>> ask(Q.positive_definite(Y))
- False
- >>> ask(Q.positive_definite(Identity(3)))
- True
- >>> ask(Q.positive_definite(X + Z), Q.positive_definite(X) &
- ... Q.positive_definite(Z))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Positive-definite_matrix
- """
- name = "positive_definite"
- handler = Dispatcher("PositiveDefiniteHandler", doc="Handler for key 'positive_definite'.")
- class UpperTriangularPredicate(Predicate):
- """
- Upper triangular matrix predicate.
- Explanation
- ===========
- A matrix $M$ is called upper triangular matrix if :math:`M_{ij}=0`
- for :math:`i<j`.
- Examples
- ========
- >>> from sympy import Q, ask, ZeroMatrix, Identity
- >>> ask(Q.upper_triangular(Identity(3)))
- True
- >>> ask(Q.upper_triangular(ZeroMatrix(3, 3)))
- True
- References
- ==========
- .. [1] http://mathworld.wolfram.com/UpperTriangularMatrix.html
- """
- name = "upper_triangular"
- handler = Dispatcher("UpperTriangularHandler", doc="Handler for key 'upper_triangular'.")
- class LowerTriangularPredicate(Predicate):
- """
- Lower triangular matrix predicate.
- Explanation
- ===========
- A matrix $M$ is called lower triangular matrix if :math:`M_{ij}=0`
- for :math:`i>j`.
- Examples
- ========
- >>> from sympy import Q, ask, ZeroMatrix, Identity
- >>> ask(Q.lower_triangular(Identity(3)))
- True
- >>> ask(Q.lower_triangular(ZeroMatrix(3, 3)))
- True
- References
- ==========
- .. [1] http://mathworld.wolfram.com/LowerTriangularMatrix.html
- """
- name = "lower_triangular"
- handler = Dispatcher("LowerTriangularHandler", doc="Handler for key 'lower_triangular'.")
- class DiagonalPredicate(Predicate):
- """
- Diagonal matrix predicate.
- Explanation
- ===========
- ``Q.diagonal(x)`` is true iff ``x`` is a diagonal matrix. A diagonal
- matrix is a matrix in which the entries outside the main diagonal
- are all zero.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol, ZeroMatrix
- >>> X = MatrixSymbol('X', 2, 2)
- >>> ask(Q.diagonal(ZeroMatrix(3, 3)))
- True
- >>> ask(Q.diagonal(X), Q.lower_triangular(X) &
- ... Q.upper_triangular(X))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Diagonal_matrix
- """
- name = "diagonal"
- handler = Dispatcher("DiagonalHandler", doc="Handler for key 'diagonal'.")
- class IntegerElementsPredicate(Predicate):
- """
- Integer elements matrix predicate.
- Explanation
- ===========
- ``Q.integer_elements(x)`` is true iff all the elements of ``x``
- are integers.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.integer(X[1, 2]), Q.integer_elements(X))
- True
- """
- name = "integer_elements"
- handler = Dispatcher("IntegerElementsHandler", doc="Handler for key 'integer_elements'.")
- class RealElementsPredicate(Predicate):
- """
- Real elements matrix predicate.
- Explanation
- ===========
- ``Q.real_elements(x)`` is true iff all the elements of ``x``
- are real numbers.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.real(X[1, 2]), Q.real_elements(X))
- True
- """
- name = "real_elements"
- handler = Dispatcher("RealElementsHandler", doc="Handler for key 'real_elements'.")
- class ComplexElementsPredicate(Predicate):
- """
- Complex elements matrix predicate.
- Explanation
- ===========
- ``Q.complex_elements(x)`` is true iff all the elements of ``x``
- are complex numbers.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.complex(X[1, 2]), Q.complex_elements(X))
- True
- >>> ask(Q.complex_elements(X), Q.integer_elements(X))
- True
- """
- name = "complex_elements"
- handler = Dispatcher("ComplexElementsHandler", doc="Handler for key 'complex_elements'.")
- class SingularPredicate(Predicate):
- """
- Singular matrix predicate.
- A matrix is singular iff the value of its determinant is 0.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.singular(X), Q.invertible(X))
- False
- >>> ask(Q.singular(X), ~Q.invertible(X))
- True
- References
- ==========
- .. [1] http://mathworld.wolfram.com/SingularMatrix.html
- """
- name = "singular"
- handler = Dispatcher("SingularHandler", doc="Predicate fore key 'singular'.")
- class NormalPredicate(Predicate):
- """
- Normal matrix predicate.
- A matrix is normal if it commutes with its conjugate transpose.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.normal(X), Q.unitary(X))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Normal_matrix
- """
- name = "normal"
- handler = Dispatcher("NormalHandler", doc="Predicate fore key 'normal'.")
- class TriangularPredicate(Predicate):
- """
- Triangular matrix predicate.
- Explanation
- ===========
- ``Q.triangular(X)`` is true if ``X`` is one that is either lower
- triangular or upper triangular.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.triangular(X), Q.upper_triangular(X))
- True
- >>> ask(Q.triangular(X), Q.lower_triangular(X))
- True
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Triangular_matrix
- """
- name = "triangular"
- handler = Dispatcher("TriangularHandler", doc="Predicate fore key 'triangular'.")
- class UnitTriangularPredicate(Predicate):
- """
- Unit triangular matrix predicate.
- Explanation
- ===========
- A unit triangular matrix is a triangular matrix with 1s
- on the diagonal.
- Examples
- ========
- >>> from sympy import Q, ask, MatrixSymbol
- >>> X = MatrixSymbol('X', 4, 4)
- >>> ask(Q.triangular(X), Q.unit_triangular(X))
- True
- """
- name = "unit_triangular"
- handler = Dispatcher("UnitTriangularHandler", doc="Predicate fore key 'unit_triangular'.")
|