
    wgn3                         d dl mZ d dlmZ ddlmZmZmZ ddlm	Z	 d Z
d Zd Zdd	Ze	fd
Ze	fdZe	fdZe	fdZe	fdZe	fdZe	fdZddZd ZddZe	fdZde	dfdZy)    )DMNonInvertibleMatrixError)EX   )MatrixErrorNonSquareMatrixErrorNonInvertibleMatrixError_iszeroc                 l   | j                   r| j                  S | j                  | j                  k\  rB| j                  j	                  |       j                         j	                  | j                        S | j                  j	                  | j	                  | j                        j                               S )a  Subroutine for full row or column rank matrices.

    For full row rank matrices, inverse of ``A * A.H`` Exists.
    For full column rank matrices, inverse of ``A.H * A`` Exists.

    This routine can apply for both cases by checking the shape
    and have small decision.
    )is_zero_matrixHrowscolsmultiplyinv)Ms    [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/matrices/inverse.py_pinv_full_rankr      sx     	ss
vvss||A""$--acc22ss||AJJqssO//122    c                     | j                   r| j                  S | j                         \  }}t        |      }t        |      }|j	                  |      S )zSubroutine for rank decomposition

    With rank decompositions, `A` can be decomposed into two full-
    rank matrices, and each matrix can take pseudoinverse
    individually.
    )r   r   rank_decompositionr   r   )r   BCBpCps        r   _pinv_rank_decompositionr      sJ     	ss
!DAq		B		B;;r?r   c                 n   | j                   r| j                  S | }| j                  }	 | j                  | j                  k\  ro|j	                  |      j                  d      \  }}|j                  d       }|j	                  |      j	                  |j                        j	                  |      S |j	                  |      j                  d      \  }}|j                  d       }|j	                  |      j	                  |      j	                  |j                        S # t        $ r t        d      w xY w)zSubroutine using diagonalization

    This routine can sometimes fail if SymPy's eigenvalue
    computation is not reliable.
    T)	normalizec                 &    t        |       rdS d| z  S Nr   r   r	   xs    r   <lambda>z'_pinv_diagonalization.<locals>.<lambda><       
1 A r   c                 &    t        |       rdS d| z  S r    r	   r!   s    r   r#   z'_pinv_diagonalization.<locals>.<lambda>C   r$   r   z[pinv for rank-deficient matrices where diagonalization of A.H*A fails is not supported yet.)	r   r   r   r   r   diagonalize	applyfuncr   NotImplementedError)r   AAHPDD_pinvs         r   _pinv_diagonalizationr.   ,   s    	ss
	
A	
BD66QVV[[^//$/?DAq[[!EFF::f%..qss3<<R@@ ZZ^//"& 0 (DAq[[!EFF;;q>**62;;ACC@@ D!CD 	DDs   BD 0A.D D4c                     | j                   r| j                  S |dk(  rt        |       S |dk(  rt        |       S t	        dt        |      z        )a  Calculate the Moore-Penrose pseudoinverse of the matrix.

    The Moore-Penrose pseudoinverse exists and is unique for any matrix.
    If the matrix is invertible, the pseudoinverse is the same as the
    inverse.

    Parameters
    ==========

    method : String, optional
        Specifies the method for computing the pseudoinverse.

        If ``'RD'``, Rank-Decomposition will be used.

        If ``'ED'``, Diagonalization will be used.

    Examples
    ========

    Computing pseudoinverse by rank decomposition :

    >>> from sympy import Matrix
    >>> A = Matrix([[1, 2, 3], [4, 5, 6]])
    >>> A.pinv()
    Matrix([
    [-17/18,  4/9],
    [  -1/9,  1/9],
    [ 13/18, -2/9]])

    Computing pseudoinverse by diagonalization :

    >>> B = A.pinv(method='ED')
    >>> B.simplify()
    >>> B
    Matrix([
    [-17/18,  4/9],
    [  -1/9,  1/9],
    [ 13/18, -2/9]])

    See Also
    ========

    inv
    pinv_solve

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Moore-Penrose_pseudoinverse

    RDEDzinvalid pinv method %s)r   r   r   r.   
ValueErrorrepr)r   methods     r   _pinvr5   L   sP    l 	ss
~'**	4$Q''1DL@AAr   c                    | j                   st        d      | j                  d      }|j                  d      }|=| j	                  d      d   t        fdt        j                        D              }|rt        d      |S )	zfInitial check to see if a matrix is invertible. Raises or returns
    determinant for use in _inv_ADJ."A Matrix must be square to invert.	berkowitz)r4   r   T)simplifyc              3   8   K   | ]  } ||f           y wN ).0j
iszerofuncoks     r   	<genexpr>z%_verify_invertible.<locals>.<genexpr>   s     @A:bAh'@    Matrix det == 0; not invertible.)		is_squarer   detequalsrrefanyranger   r   )r   r?   dzeror@   s    `  @r   _verify_invertiblerL      s{     ;;"#GHH555$A88A;D|vvtv$Q'@rww@@&'IJJHr   c                 B    t        | |      }| j                         |z  S )zCalculates the inverse using the adjugate matrix and a determinant.

    See Also
    ========

    inv
    inverse_GE
    inverse_LU
    inverse_CH
    inverse_LDL
    r?   )rL   adjugate)r   r?   rJ   s      r   _inv_ADJrP      s!     	14A::<!r   c                    ddl m} | j                  st        d      |j	                  | j                         |j                  | j                              }|j                  d      d   t        fdt        j                        D              rt        d      | j                  d	d	|j                  d	f         S )
zCalculates the inverse using Gaussian elimination.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_LU
    inverse_CH
    inverse_LDL
    r   )Matrixr7   T)r?   r9   r   c              3   8   K   | ]  } ||f           y wr;   r<   )r=   r>   r?   reds     r   rA   z_inv_GE.<locals>.<genexpr>   s     
:Q:c!Q$i 
:rB   rC   N)denserR   rD   r   hstack
as_mutableeyer   rG   rH   rI   r   _new)r   r?   rR   bigrT   s    `  @r   _inv_GEr[      s     ;;"#GHH
--

166(:
;C
((j4(
8
;C

:%/
::&'IJJ66#al#$$r   c                     | j                   st        d      | j                  rt        | |       | j	                  | j                  | j                        t              S )zCalculates the inverse using LU decomposition.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_CH
    inverse_LDL
    r7   rN   )rD   r   free_symbolsrL   LUsolverX   r   r
   r   r?   s     r   _inv_LUr`      sG     ;;"#GHH~~1499QUU166]w977r   c                 p    t        | |       | j                  | j                  | j                              S )zCalculates the inverse using cholesky decomposition.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_LU
    inverse_LDL
    rN   )rL   cholesky_solverX   r   r_   s     r   _inv_CHrc      s+     qZ0AEE!&&M**r   c                 p    t        | |       | j                  | j                  | j                              S )zCalculates the inverse using LDL decomposition.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_LU
    inverse_CH
    rN   )rL   LDLsolverX   r   r_   s     r   _inv_LDLrf      s)     qZ0::aeeAFFm$$r   c                 p    t        | |       | j                  | j                  | j                              S )zCalculates the inverse using QR decomposition.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_CH
    inverse_LDL
    rN   )rL   QRsolverX   r   r_   s     r   _inv_QRri     s)     qZ099QUU166]##r   Fc                     | j                         }|j                  }|s|j                  ry|j                  r|j                  t              S |S )z.Try to convert a matrix to a ``DomainMatrix``.N)to_DMdomainis_EXRAW
convert_tor   )r   use_EXdMKs       r   _try_DMrr     s?    	
B
		A ajj	
}}R  	r   c                 N    | j                   s| j                  ry| j                   S )z,Check whether to convert to an exact domain.F)is_RRis_CCis_Exact)doms    r   _use_exact_domainrx      s!    
 yyCII<<r   c                 ,   | j                   \  }}| j                  }||k7  rt        d      t        |      }|r!|j	                         }| j                  |      } 	 | j                         \  }}|r#|j                  |      }|j                  |      }|r;|j                  j                  s|j                         }||z  j                         }	|	S |j                         |j                  j                  |      z  }	|	S # t        $ r t        d      w xY w)zCalculates the inverse using ``DomainMatrix``.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_CH
    inverse_LDL
    sympy.polys.matrices.domainmatrix.DomainMatrix.inv
    r7   rC   )shaperl   r   rx   	get_exactrn   inv_denr   r   convert_fromis_Fieldto_field	to_Matrixto_sympy)
rp   cancelmnrw   	use_exact	dom_exactdMidenMis
             r   _inv_DMr   +  s    88DAq
))CAv"#GHH "#&IMMO	]]9%K::<S nnS!sI.zz"",,.CCi""$
 I ]]_szz22377I! & K&'IJJKs   C> >Dc                 B   ddl m} | j                  d   }|dk  r| j                  dt              S | d|dz  d|dz  f   }| d|dz  |dz  df   }| |dz  dd|dz  f   }| |dz  d|dz  df   }	 t        |      }||z  }	|	|z  }
||
z
  }	 t        |      }| |	z  }||z  }| |z  }||| z  z   } |||g||gg      j                         }|S # t        $ r | j                  dt              cY S w xY w# t        $ r | j                  dt              cY S w xY w)zCalculates the inverse using BLOCKWISE inversion.

    See Also
    ========

    inv
    inverse_ADJ
    inverse_GE
    inverse_CH
    inverse_LDL
    r   )BlockMatrix   LUr4   r?   N   )&sympy.matrices.expressions.blockmatrixr   rz   r   r
   
_inv_blockr   as_explicit)r   r?   r   ir)   r   r   r,   D_invB_D_iBDCA_nB_ndcC_nD_nnns                    r   r   r   Y  sw    C	
ABwuuDWu55	'16'6AE6/A	'16'167
A	!q&'7AF7
A	!q&'167
A61 eGE
'C
c'C6o $u*C	qB#c'C
"cT'/C	sCj3*-	.	:	:	<BI $ 6uuDWu556 $ 6uuDWu556s$   7C C;  C87C8; DDNc                    ddl m}m} | j                  st	        d      |r@| j                         }g }|D ]$  }|j                  |j                  ||             &  || S ||t        u rt        | d      }	|	d}n|dv rt        | d	      }	|t        | |      rd
}nd}|dk(  rt        	      }
n|dk(  rt        	d      }
n|dk(  r| j                  |      }
n|dk(  r| j                  |      }
n|dk(  r| j                  |      }
nk|dk(  r| j                  |      }
nS|d
k(  r| j!                  |      }
n;|dk(  r| j#                  |      }
n#|dk(  r| j%                  |      }
nt'        d      | j)                  |
      S )ac	  
    Return the inverse of a matrix using the method indicated. The default
    is DM if a suitable domain is found or otherwise GE for dense matrices
    LDL for sparse matrices.

    Parameters
    ==========

    method : ('DM', 'DMNC', 'GE', 'LU', 'ADJ', 'CH', 'LDL', 'QR')

    iszerofunc : function, optional
        Zero-testing function to use.

    try_block_diag : bool, optional
        If True then will try to form block diagonal matrices using the
        method get_diag_blocks(), invert these individually, and then
        reconstruct the full inverse matrix.

    Examples
    ========

    >>> from sympy import SparseMatrix, Matrix
    >>> A = SparseMatrix([
    ... [ 2, -1,  0],
    ... [-1,  2, -1],
    ... [ 0,  0,  2]])
    >>> A.inv('CH')
    Matrix([
    [2/3, 1/3, 1/6],
    [1/3, 2/3, 1/3],
    [  0,   0, 1/2]])
    >>> A.inv(method='LDL') # use of 'method=' is optional
    Matrix([
    [2/3, 1/3, 1/6],
    [1/3, 2/3, 1/3],
    [  0,   0, 1/2]])
    >>> A * _
    Matrix([
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]])
    >>> A = Matrix(A)
    >>> A.inv('CH')
    Matrix([
    [2/3, 1/3, 1/6],
    [1/3, 2/3, 1/3],
    [  0,   0, 1/2]])
    >>> A.inv('ADJ') == A.inv('GE') == A.inv('LU') == A.inv('CH') == A.inv('LDL') == A.inv('QR')
    True

    Notes
    =====

    According to the ``method`` keyword, it calls the appropriate method:

        DM .... Use DomainMatrix ``inv_den`` method
        DMNC .... Use DomainMatrix ``inv_den`` method without cancellation
        GE .... inverse_GE(); default for dense matrices
        LU .... inverse_LU()
        ADJ ... inverse_ADJ()
        CH ... inverse_CH()
        LDL ... inverse_LDL(); default for sparse matrices
        QR ... inverse_QR()

    Note, the GE and LU methods may require the matrix to be simplified
    before it is inverted in order to properly detect zeros during
    pivoting. In difficult cases a custom zero detection function can
    be provided by setting the ``iszerofunc`` argument to a function that
    should return True if its argument is zero. The ADJ routine computes
    the determinant and uses that to detect singular matrices in addition
    to testing for zeros on the diagonal.

    See Also
    ========

    inverse_ADJ
    inverse_GE
    inverse_LU
    inverse_CH
    inverse_LDL

    Raises
    ======

    ValueError
        If the determinant of the matrix is zero.
    r   )diagSparseMatrixr7   r   F)ro   DM)r   DMNCTLDLGEr   )r   rN   r   ADJCHQRBLOCKzInversion method unrecognized)sympy.matricesr   r   rD   r   get_diag_blocksappendr   r
   rr   
isinstancer   
inverse_GE
inverse_LUinverse_ADJ
inverse_CHinverse_LDL
inverse_QRinverse_BLOCKr2   rY   )r   r4   r?   try_block_diagr   r   blocksrblockrp   rvs              r   _invr     s   r 2;;"#GHH""$ 	FEHHUYYfYDE	F Qx ~*/Qu%>F	>	!Qt$ ~a&FF~R[	6	R&	4\\Z\0	4\\Z\0	5]]j]1	4\\Z\0	5]]j]1	4\\Z\0	7	__
_389966":r   )r0   )F)T)sympy.polys.matrices.exceptionsr   sympy.polys.domainsr   
exceptionsr   r   r   	utilitiesr
   r   r   r.   r5   rL   rP   r[   r`   rc   rf   ri   rr   rx   r   r   r   r<   r   r   <module>r      s    F " S S 3$$D@>BB &- & # " " %4 " 8( " +" # %" " $" ,\ % $L GE Mr   