U
    @f[                     @   sr  d dl mZ d dlmZ ddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZmZm Z  dd	l!m"Z"m#Z#m$Z$m%Z% dd
l&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6 ddgiZ7G dd deZ8G dd de8Z9G dd de9Z:G dd de:Z;G dd deZ<G dd deZ=dS )    )Basic)Dummy   )MatrixCommon)NonSquareMatrixError)_iszero_is_zero_after_expand_mul	_simplify)_find_reasonable_pivot_find_reasonable_pivot_naive	_adjugate	_charpoly	_cofactor_cofactor_matrix_per_det_det_bareiss_det_berkowitz	_det_bird_det_laplace_det_LU_minor_minor_submatrix)_is_echelon_echelon_form_rank_rref)_columnspace
_nullspace	_rowspace_orthogonalize)
_eigenvals_eigenvects_bidiagonalize_bidiagonal_decomposition_is_diagonalizable_diagonalize_is_positive_definite_is_positive_semidefinite_is_negative_definite_is_negative_semidefinite_is_indefinite_jordan_form_left_eigenvects_singular_values)
MatrixBase)MatrixEigen.is_indefinite MatrixEigen.is_negative_definite$MatrixEigen.is_negative_semidefinite MatrixEigen.is_positive_definite$MatrixEigen.is_positive_semidefiniteZ
matplotlibc                   @   s  e Zd ZdZefddZdd ZedfddZd	d
 Z	dd Z
dd Zd"ddZdefddZd#ddZd$ddZd%ddZdd Zd&ddZd d! Zeje_eje_eje_eje_eje	_eje
_eje_eje_eje_eje_eje_e je_eje_e!je_e"je_e#je_dS )'MatrixDeterminantzProvides basic matrix determinant operations. Should not be instantiated
    directly. See ``determinant.py`` for their implementations.c                 C   s   t | |dS )N)
iszerofuncr   )selfr6    r9   ;/tmp/pip-unpacked-wheel-6uje5nh9/sympy/matrices/matrices.py_eval_det_bareiss3   s    z#MatrixDeterminant._eval_det_bareissc                 C   s   t | S N)r   r8   r9   r9   r:   _eval_det_berkowitz6   s    z%MatrixDeterminant._eval_det_berkowitzNc                 C   s   t | ||dS )N)r6   simpfunc)r   )r8   r6   r?   r9   r9   r:   _eval_det_lu9   s    zMatrixDeterminant._eval_det_luc                 C   s   t | S r<   )r   r=   r9   r9   r:   _eval_det_bird<   s    z MatrixDeterminant._eval_det_birdc                 C   s   t | S r<   )r   r=   r9   r9   r:   _eval_det_laplace?   s    z#MatrixDeterminant._eval_det_laplacec                 C   s   t | S r<   r   r=   r9   r9   r:   _eval_determinantB   s    z#MatrixDeterminant._eval_determinant	berkowitzc                 C   s   t | |dS Nmethod)r   r8   rH   r9   r9   r:   adjugateE   s    zMatrixDeterminant.adjugatelambdac                 C   s   t | ||dS )N)xsimplify)r   r8   rL   rM   r9   r9   r:   charpolyH   s    zMatrixDeterminant.charpolyc                 C   s   t | |||dS rF   )r   r8   ijrH   r9   r9   r:   cofactorK   s    zMatrixDeterminant.cofactorc                 C   s   t | |dS rF   )r   rI   r9   r9   r:   cofactor_matrixN   s    z!MatrixDeterminant.cofactor_matrixbareissc                 C   s   t | ||dS )N)rH   r6   rC   )r8   rH   r6   r9   r9   r:   detQ   s    zMatrixDeterminant.detc                 C   s   t | S r<   )r   r=   r9   r9   r:   perT   s    zMatrixDeterminant.perc                 C   s   t | |||dS rF   )r   rP   r9   r9   r:   minorW   s    zMatrixDeterminant.minorc                 C   s   t | ||S r<   )r   r8   rQ   rR   r9   r9   r:   minor_submatrixZ   s    z!MatrixDeterminant.minor_submatrix)rE   )rE   )rE   )rU   N)rE   )$__name__
__module____qualname____doc__r   r;   r>   r   r@   rA   rB   rD   rJ   r	   rO   rS   rT   rV   rW   rX   rZ   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r9   r9   r9   r:   r5   /   s>   




r5   c                   @   s   e Zd ZdZeddfddZedd ZedfddZd	d
 Z	edddfddZ
eje_eje_eje_eje
_d#ddZdd Zdd Zdd Zdd Zdd Zdd Zd$dd Zd%d!d"ZdS )&MatrixReductionszProvides basic matrix row/column operations. Should not be instantiated
    directly. See ``reductions.py`` for some of their implementations.Fc                 C   s   t | |||dS )N)r6   rM   with_pivots)r   )r8   r6   rM   r`   r9   r9   r:   echelon_forms   s    zMatrixReductions.echelon_formc                 C   s   t | S r<   )r   r=   r9   r9   r:   
is_echelonw   s    zMatrixReductions.is_echelonc                 C   s   t | ||dS )N)r6   rM   )r   )r8   r6   rM   r9   r9   r:   rank{   s    zMatrixReductions.rankc                 C   sL   t | | | | j|\}}|ddd| jf |dd|j df fS )a  Return reduced row-echelon form of matrix, matrix showing
        rhs after reduction steps. ``rhs`` must have the same number
        of rows as ``self``.

        Examples
        ========

        >>> from sympy import Matrix, symbols
        >>> r1, r2 = symbols('r1 r2')
        >>> Matrix([[1, 1], [2, 1]]).rref_rhs(Matrix([r1, r2]))
        (Matrix([
        [1, 0],
        [0, 1]]), Matrix([
        [ -r1 + r2],
        [2*r1 - r2]]))
        N)r   ZhstackZeyerowscols)r8   rhsr_r9   r9   r:   rref_rhs~   s    zMatrixReductions.rref_rhsTc                 C   s   t | ||||dS )N)r6   rM   pivotsnormalize_last)r   )r8   r6   rM   rj   rk   r9   r9   r:   rref   s     zMatrixReductions.rrefcolc           	      C   s&  |dkrt d|||dkr&| jn| j}|dkr|dk	r@|n|}|dksT|dkrbt d|d|  krv|k sn t d||n|d	kr@||||hdg}t|d
kr|||hdg}t|d
krt d||\}}d|  kr|k sn t d||d|  kr,|k sn t d||n|dkr|dkrX|n|}|dkrj|n|}|dks|dks|dkrt d|||krt d|d|  kr|k sn t d||d|  kr|k sn t d||nt dt| |||||fS )zValidate the arguments for a row/column operation.  ``error_str``
        can be one of "row" or "col" depending on the arguments being parsed.)n->knn<->mn->n+kmzOUnknown {} operation '{}'. Valid col operations are 'n->kn', 'n<->m', 'n->n+km'rm   rn   NzEFor a {0} operation 'n->kn' you must provide the kwargs `{0}` and `k`r   z#This matrix does not have a {} '{}'ro      zIFor a {0} operation 'n<->m' you must provide the kwargs `{0}1` and `{0}2`rp   zPFor a {0} operation 'n->n+km' you must provide the kwargs `{0}`, `k`, and `{0}2`zAFor a {0} operation 'n->n+km' `{0}` and `{0}2` must be different.zinvalid operation %s)
ValueErrorformatre   rd   
differencelenrepr)	r8   oprm   kcol1col2Z	error_strZ	self_colsre   r9   r9   r:   _normalize_op_args   sX     


z#MatrixReductions._normalize_op_argsc                    s"    fdd} jj|S )Nc                    s$   | kr| |f  S | |f S r<   r9   rQ   rR   rm   rx   r8   r9   r:   entry   s    zBMatrixReductions._eval_col_op_multiply_col_by_const.<locals>.entry_newrd   re   )r8   rm   rx   r~   r9   r}   r:   "_eval_col_op_multiply_col_by_const   s    z3MatrixReductions._eval_col_op_multiply_col_by_constc                    s"    fdd} jj|S )Nc                    s4   | kr| f S |kr(|  f S | |f S r<   r9   r|   ry   rz   r8   r9   r:   r~      s
    z1MatrixReductions._eval_col_op_swap.<locals>.entryr   )r8   ry   rz   r~   r9   r   r:   _eval_col_op_swap   s    z"MatrixReductions._eval_col_op_swapc                    s$    fdd} jj|S )Nc                    s0   | kr$| |f | f   S | |f S r<   r9   r|   rm   rz   rx   r8   r9   r:   r~      s    zFMatrixReductions._eval_col_op_add_multiple_to_other_col.<locals>.entryr   )r8   rm   rx   rz   r~   r9   r   r:   &_eval_col_op_add_multiple_to_other_col   s    z7MatrixReductions._eval_col_op_add_multiple_to_other_colc                    s"    fdd} jj|S )Nc                    s4   |  kr|f S | kr( |f S | |f S r<   r9   r|   row1row2r8   r9   r:   r~      s
    z1MatrixReductions._eval_row_op_swap.<locals>.entryr   )r8   r   r   r~   r9   r   r:   _eval_row_op_swap   s    z"MatrixReductions._eval_row_op_swapc                    s"    fdd} jj|S )Nc                    s$   | kr | |f  S | |f S r<   r9   r|   rx   rowr8   r9   r:   r~      s    zBMatrixReductions._eval_row_op_multiply_row_by_const.<locals>.entryr   )r8   r   rx   r~   r9   r   r:   "_eval_row_op_multiply_row_by_const   s    z3MatrixReductions._eval_row_op_multiply_row_by_constc                    s$    fdd} jj|S )Nc                    s0   | kr$| |f  |f   S | |f S r<   r9   r|   rx   r   r   r8   r9   r:   r~      s    zFMatrixReductions._eval_row_op_add_multiple_to_other_row.<locals>.entryr   )r8   r   rx   r   r~   r9   r   r:   &_eval_row_op_add_multiple_to_other_row   s    z7MatrixReductions._eval_row_op_add_multiple_to_other_rowrn   Nc                 C   s`   |  |||||d\}}}}}|dkr2| ||S |dkrF| ||S |dkr\| |||S dS )ad  Performs the elementary column operation `op`.

        `op` may be one of

            * ``"n->kn"`` (column n goes to k*n)
            * ``"n<->m"`` (swap column n and column m)
            * ``"n->n+km"`` (column n goes to column n + k*column m)

        Parameters
        ==========

        op : string; the elementary row operation
        col : the column to apply the column operation
        k : the multiple to apply in the column operation
        col1 : one column of a column swap
        col2 : second column of a column swap or column "m" in the column operation
               "n->n+km"
        rm   rn   ro   rp   N)r{   r   r   r   )r8   rw   rm   rx   ry   rz   r9   r9   r:   elementary_col_op  s    z"MatrixReductions.elementary_col_opc                 C   s`   |  |||||d\}}}}}|dkr2| ||S |dkrF| ||S |dkr\| |||S dS )a4  Performs the elementary row operation `op`.

        `op` may be one of

            * ``"n->kn"`` (row n goes to k*n)
            * ``"n<->m"`` (swap row n and row m)
            * ``"n->n+km"`` (row n goes to row n + k*row m)

        Parameters
        ==========

        op : string; the elementary row operation
        row : the row to apply the row operation
        k : the multiple to apply in the row operation
        row1 : one row of a row swap
        row2 : second row of a row swap or row "m" in the row operation
               "n->n+km"
        r   rn   ro   rp   N)r{   r   r   r   )r8   rw   r   rx   r   r   r9   r9   r:   elementary_row_op  s    z"MatrixReductions.elementary_row_op)rm   )rn   NNNN)rn   NNNN)r[   r\   r]   r^   r   ra   propertyrb   rc   ri   rl   r   r   r   r   r{   r   r   r   r   r   r   r   r   r9   r9   r9   r:   r_   o   s,   


7		
r_   c                   @   sb   e Zd ZdZdddZdefddZdddZd	d
 Ze	je_e
je_eje_eje_eeZdS )MatrixSubspaceszProvides methods relating to the fundamental subspaces of a matrix.
    Should not be instantiated directly. See ``subspaces.py`` for their
    implementations.Fc                 C   s   t | |dS N)rM   )r   r8   rM   r9   r9   r:   columnspaceC  s    zMatrixSubspaces.columnspacec                 C   s   t | ||dS )N)rM   r6   )r   )r8   rM   r6   r9   r9   r:   	nullspaceF  s    zMatrixSubspaces.nullspacec                 C   s   t | |dS r   )r   r   r9   r9   r:   rowspaceI  s    zMatrixSubspaces.rowspacec                 O   s   t | f||S r<   )r    )clsZvecskwargsr9   r9   r:   orthogonalizeO  s    zMatrixSubspaces.orthogonalizeN)F)F)r[   r\   r]   r^   r   r   r   r   r   r   r   r   r    classmethodr9   r9   r9   r:   r   >  s   

r   c                   @   s  e Zd ZdZd!ddZdefddZd"dd	Zd#d
dZd$ddZ	d%ddZ
edd Zedd Zedd Zedd Zedd Zd&ddZdd Zdd Zeje_eje_eje_eje_eje_eje_eje_eje_eje_eje_eje_eje_e je	_e!je
_d S )'MatrixEigenzProvides basic matrix eigenvalue/vector operations.
    Should not be instantiated directly. See ``eigen.py`` for their
    implementations.Tc                 K   s   t | fd|i|S )Nerror_when_incomplete)r!   )r8   r   flagsr9   r9   r:   	eigenvals_  s    zMatrixEigen.eigenvalsc                 K   s   t | f||d|S )N)r   r6   )r"   )r8   r   r6   r   r9   r9   r:   
eigenvectsb  s
    zMatrixEigen.eigenvectsFc                 K   s   t | fd|i|S )N
reals_only)r%   )r8   r   r   r9   r9   r:   is_diagonalizablef  s    zMatrixEigen.is_diagonalizablec                 C   s   t | |||dS )N)r   sort	normalize)r&   )r8   r   r   r   r9   r9   r:   diagonalizei  s    zMatrixEigen.diagonalizec                 C   s   t | |dS N)upper)r#   r8   r   r9   r9   r:   bidiagonalizem  s    zMatrixEigen.bidiagonalizec                 C   s   t | |dS r   )r$   r   r9   r9   r:   bidiagonal_decompositionp  s    z$MatrixEigen.bidiagonal_decompositionc                 C   s   t | S r<   )r'   r=   r9   r9   r:   is_positive_definites  s    r3   c                 C   s   t | S r<   )r(   r=   r9   r9   r:   is_positive_semidefinitew  s    r4   c                 C   s   t | S r<   )r)   r=   r9   r9   r:   is_negative_definite{  s    r1   c                 C   s   t | S r<   )r*   r=   r9   r9   r:   is_negative_semidefinite  s    r2   c                 C   s   t | S r<   )r+   r=   r9   r9   r:   is_indefinite  s    r0   c                 K   s   t | fd|i|S )Ncalc_transform)r,   )r8   r   r   r9   r9   r:   jordan_form  s    zMatrixEigen.jordan_formc                 K   s   t | f|S r<   )r-   r8   r   r9   r9   r:   left_eigenvects  s    zMatrixEigen.left_eigenvectsc                 C   s   t | S r<   )r.   r=   r9   r9   r:   singular_values  s    zMatrixEigen.singular_valuesN)T)F)FFF)T)T)T)"r[   r\   r]   r^   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r"   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r#   r$   r9   r9   r9   r:   r   Z  sD   










r   c                   @   s>   e Zd ZdZddddZdd Zdd	 Zd
d Zdd ZdS )MatrixCalculusz,Provides calculus-related matrix operations.T)evaluatec                O   s:   ddl m} || f|d|i}t| ts6|r6| S |S )ae  Calculate the derivative of each element in the matrix.

        Examples
        ========

        >>> from sympy import Matrix
        >>> from sympy.abc import x, y
        >>> M = Matrix([[x, y], [1, 0]])
        >>> M.diff(x)
        Matrix([
        [1, 0],
        [0, 0]])

        See Also
        ========

        integrate
        limit
        r   )ArrayDerivativer   )Z$sympy.tensor.array.array_derivativesr   
isinstancer   Z
as_mutable)r8   r   argsr   r   Zderivr9   r9   r:   diff  s
    zMatrixCalculus.diffc                    s   |   fddS )Nc                    s
   |   S r<   r   rL   argr9   r:   <lambda>      z1MatrixCalculus._eval_derivative.<locals>.<lambda>Z	applyfunc)r8   r   r9   r   r:   _eval_derivative  s    zMatrixCalculus._eval_derivativec                    s   |   fddS )a  Integrate each element of the matrix.  ``args`` will
        be passed to the ``integrate`` function.

        Examples
        ========

        >>> from sympy import Matrix
        >>> from sympy.abc import x, y
        >>> M = Matrix([[x, y], [1, 0]])
        >>> M.integrate((x, ))
        Matrix([
        [x**2/2, x*y],
        [     x,   0]])
        >>> M.integrate((x, 0, 2))
        Matrix([
        [2, 2*y],
        [2,   0]])

        See Also
        ========

        limit
        diff
        c                    s   | j  S r<   )	integrater   r   r   r9   r:   r     r   z*MatrixCalculus.integrate.<locals>.<lambda>r   )r8   r   r   r9   r   r:   r     s    zMatrixCalculus.integratec                    s   t  ts  jd dkr.jd }n"jd dkrHjd }ntd jd dkrj jd }n" jd dkr jd }ntd|| fddS )a  Calculates the Jacobian matrix (derivative of a vector-valued function).

        Parameters
        ==========

        ``self`` : vector of expressions representing functions f_i(x_1, ..., x_n).
        X : set of x_i's in order, it can be a list or a Matrix

        Both ``self`` and X can be a row or a column matrix in any order
        (i.e., jacobian() should always work).

        Examples
        ========

        >>> from sympy import sin, cos, Matrix
        >>> from sympy.abc import rho, phi
        >>> X = Matrix([rho*cos(phi), rho*sin(phi), rho**2])
        >>> Y = Matrix([rho, phi])
        >>> X.jacobian(Y)
        Matrix([
        [cos(phi), -rho*sin(phi)],
        [sin(phi),  rho*cos(phi)],
        [   2*rho,             0]])
        >>> X = Matrix([rho*cos(phi), rho*sin(phi)])
        >>> X.jacobian(Y)
        Matrix([
        [cos(phi), -rho*sin(phi)],
        [sin(phi),  rho*cos(phi)]])

        See Also
        ========

        hessian
        wronskian
        r   r   z)``self`` must be a row or a column matrixz"X must be a row or a column matrixc                    s   |    | S r<   r   )rR   rQ   Xr8   r9   r:   r     r   z)MatrixCalculus.jacobian.<locals>.<lambda>)r   r/   r   shape	TypeError)r8   r   mnr9   r   r:   jacobian  s    $

zMatrixCalculus.jacobianc                    s   |   fddS )a  Calculate the limit of each element in the matrix.
        ``args`` will be passed to the ``limit`` function.

        Examples
        ========

        >>> from sympy import Matrix
        >>> from sympy.abc import x, y
        >>> M = Matrix([[x, y], [1, 0]])
        >>> M.limit(x, 2)
        Matrix([
        [2, y],
        [1, 0]])

        See Also
        ========

        integrate
        diff
        c                    s
   | j   S r<   )limitr   r   r9   r:   r   +  r   z&MatrixCalculus.limit.<locals>.<lambda>r   )r8   r   r9   r   r:   r     s    zMatrixCalculus.limitN)	r[   r\   r]   r^   r   r   r   r   r   r9   r9   r9   r:   r     s   9r   c                   @   s   e Zd ZdZedefddZdd Zdd Zd	d
 Z	dd Z
d"ddZdd Zdd Zdd Zd#ddZd$ddZdd Zdd Zdd  Zd!S )%MatrixDeprecatedz+A class to house deprecated matrix methods.rK   c                 C   s   | j |dS )Nr   )rO   rN   r9   r9   r:   berkowitz_charpoly1  s    z#MatrixDeprecated.berkowitz_charpolyc                 C   s   | j ddS )zwComputes determinant using Berkowitz method.

        See Also
        ========

        det
        berkowitz
        rE   rG   rV   r=   r9   r9   r:   berkowitz_det4  s    	zMatrixDeprecated.berkowitz_detc                 K   s   | j f |S )zwComputes eigenvalues of a Matrix using Berkowitz method.

        See Also
        ========

        berkowitz
        )r   r   r9   r9   r:   berkowitz_eigenvals?  s    z$MatrixDeprecated.berkowitz_eigenvalsc                 C   s:   | j g  }}|  D ]}|||d   | }qt|S )zpComputes principal minors using Berkowitz method.

        See Also
        ========

        berkowitz
        )onerE   appendtuple)r8   signZminorsZpolyr9   r9   r:   berkowitz_minorsI  s
    z!MatrixDeprecated.berkowitz_minorsc                 C   s  ddl m} d}| s|S | js$t | | j }}dg|d  }t|ddD  ]}||d ||d  }}||d |f  |d ||f  }	}
|d |d |f |||f   }}|
g}td|d D ]}||||   qt|D ]\}}|	| d ||< q| j|g| }t|D ]&}|d || d  ||d |f< q|||d < qJ| 	| j|d  gg}t|D ]\}}||||   qj|t
tt
| S )Nr   )zeros))r   r   r   rq   )r   r   )Zsympy.matricesr   Z	is_squarer   rd   ranger   	enumerater   r   r   map)r8   r   ZberkANZ
transformsr   Trx   RCaitemsrQ   BZpolysr9   r9   r:   rE   Y  s2    $$$zMatrixDeprecated.berkowitzrE   c                 C   s   | j |dS rF   )rT   rI   r9   r9   r:   cofactorMatrix  s    zMatrixDeprecated.cofactorMatrixc                 C   s   t | S r<   r7   r=   r9   r9   r:   
det_bareis  s    zMatrixDeprecated.det_bareisc                 C   s   | j ddS )a  Compute matrix determinant using LU decomposition.


        Note that this method fails if the LU decomposition itself
        fails. In particular, if the matrix has no inverse this method
        will fail.

        TODO: Implement algorithm for sparse matrices (SFF),
        https://www.eecis.udel.edu/~saunders/papers/sffge/it5.ps

        See Also
        ========


        det
        det_bareiss
        berkowitz_det
        ZlurG   r   r=   r9   r9   r:   det_LU_decomposition  s    z%MatrixDeprecated.det_LU_decompositionc                 C   s   | j ||dS )N)sizeZ
eigenvalue)Zjordan_block)r8   Zeigenvalr   r9   r9   r:   jordan_cell  s    zMatrixDeprecated.jordan_cellTc                 C   s   |   \}}|| fS r<   )r   Zget_diag_blocks)r8   Zcalc_transformationPJr9   r9   r:   jordan_cells  s    zMatrixDeprecated.jordan_cellsc                 C   s   | j |||dS rF   )rX   rP   r9   r9   r:   
minorEntry  s    zMatrixDeprecated.minorEntryc                 C   s   |  ||S r<   )rZ   rY   r9   r9   r:   minorMatrix  s    zMatrixDeprecated.minorMatrixc                 C   s   | j |ddS )zEPermute the rows of the matrix with the given permutation in reverse.Zbackward	directionZpermute_rowsr8   permr9   r9   r:   permuteBkwd  s    zMatrixDeprecated.permuteBkwdc                 C   s   | j |ddS )z:Permute the rows of the matrix with the given permutation.Zforwardr   r   r   r9   r9   r:   
permuteFwd  s    zMatrixDeprecated.permuteFwdN)rE   )T)rE   )r[   r\   r]   r^   r   r	   r   r   r   r   rE   r   r   r   r   r   r   r   r   r   r9   r9   r9   r:   r   /  s   
(


r   N)>Zsympy.core.basicr   Zsympy.core.symbolr   commonr   
exceptionsr   Z	utilitiesr   r   r	   Zdeterminantr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Z
reductionsr   r   r   r   Z	subspacesr   r   r   r    Zeigenr!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   Z
matrixbaser/   Z__doctest_requires__r5   r_   r   r   r   r   r9   r9   r9   r:   <module>   s(   D@	@ PF 