K in3ddlmZddlmZddlmZmZmZddlm Z dZ dZ dZ dd Z e fd Ze fd Ze fd Ze fd Ze fdZe fdZe fdZddZdZddZe fdZde dfdZy))DMNonInvertibleMatrixError)EX) MatrixErrorNonSquareMatrixErrorNonInvertibleMatrixError_iszerocl|jr |jS|j|jk\rB|jj |j j |jS|jj |j |jj S)aSubroutine 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_matrixHrowscolsmultiplyinv)Ms \/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/matrices/inverse.py_pinv_full_rankrsx ss vvss||A""$--acc22ss||AJJqssO//122c|jr |jS|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_decompositionrr)rBCBpCps r_pinv_rank_decompositionrsJ ss   !DAq  B  B ;;r?rcn|jr |jS|}|j} |j|jk\ro|j |j d\}}|j d}|j |j |jj |S|j |j d\}}|j d}|j |j |j |jS#t$r tdwxYw)zSubroutine using diagonalization This routine can sometimes fail if SymPy's eigenvalue computation is not reliable. T) normalizec&t|rdSd|z SNrrr xs rz'_pinv_diagonalization..< 1Arc&t|rdSd|z Sr r r!s rr#z'_pinv_diagonalization..Cr$rz[pinv for rank-deficient matrices where diagonalization of A.H*A fails is not supported yet.) r r rrr diagonalize applyfuncrNotImplementedError)rAAHPDD_pinvs r_pinv_diagonalizationr.,s ss A BD 66QVV [[^//$/?DAq[[!EFF::f%..qss3<**62;;ACC@ @ D! CD DDsBD0A.DD4c|jr |jS|dk(r t|S|dk(r t|St dt |z)aCalculate 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 RDEDzinvalid pinv method %s)r r rr. ValueErrorrepr)rmethods r_pinvr5LsPl ss  ~'** 4$Q''1DL@AArc|js td|jd}|jd}|=|j ddt fdt jD}|r td|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)r4rT)simplifyc38K|]}||fywN).0j iszerofuncoks r z%_verify_invertible..s@A:bAh'@ Matrix det == 0; not invertible.) is_squarerdetequalsrrefanyrangerr)rr?dzeror@s ` @r_verify_invertiblerLs{ ;;"#GHH 55 5 $A 88A;D |vvtv$Q'@rww@@ &'IJJ HrcBt||}|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?)rLadjugate)rr?rJs r_inv_ADJrPs! 14A ::r?reds rrAz_inv_GE..s :Q:c!Q$i :rBrCN) denserRrDrhstack as_mutableeyerrGrHrIr_new)rr?rRbigrTs ` @r_inv_GEr[s ;;"#GHH --  166(: ;C ((j4( 8 ;C :%/ ::&'IJJ 66#al# $$rc|js td|jr t|||j |j |j tS)zCalculates the inverse using LU decomposition. See Also ======== inv inverse_ADJ inverse_GE inverse_CH inverse_LDL r7rN)rDr free_symbolsrLLUsolverXrr rr?s r_inv_LUr`sG ;;"#GHH~~14 99QUU166]w9 77rcpt|||j|j|jS)zCalculates the inverse using cholesky decomposition. See Also ======== inv inverse_ADJ inverse_GE inverse_LU inverse_LDL rN)rLcholesky_solverXrr_s r_inv_CHrcs+qZ0  AEE!&&M **rcpt|||j|j|jS)zCalculates the inverse using LDL decomposition. See Also ======== inv inverse_ADJ inverse_GE inverse_LU inverse_CH rN)rLLDLsolverXrr_s r_inv_LDLrfs)qZ0 ::aeeAFFm $$rcpt|||j|j|jS)zCalculates the inverse using QR decomposition. See Also ======== inv inverse_ADJ inverse_GE inverse_CH inverse_LDL rN)rLQRsolverXrr_s r_inv_QRris)qZ0 99QUU166] ##rFc|j}|j}|s |jry|jr|jtS|S)z.Try to convert a matrix to a ``DomainMatrix``.N)to_DMdomainis_EXRAW convert_tor)ruse_EXdMKs r_try_DMrrs? B A ajj }}R   rcN|js |jry|j S)z,Check whether to convert to an exact domain.F)is_RRis_CCis_Exact)doms r_use_exact_domainrx s!  yyCII<<rc,|j\}}|j}||k7r tdt|}|r!|j }|j |} |j \}}|r#|j |}|j|}|r;|jjs|j}||z j} | S|j|jj|z } | S#t$r tdwxYw)zCalculates the inverse using ``DomainMatrix``. See Also ======== inv inverse_ADJ inverse_GE inverse_CH inverse_LDL sympy.polys.matrices.domainmatrix.DomainMatrix.inv r7rC)shaperlrrx get_exactrninv_denrr convert_fromis_Fieldto_field to_Matrixto_sympy) rpcancelmnrw use_exact dom_exactdMidenMis r_inv_DMr+s 88DAq ))CAv"#GHH"#&IMMO ]]9 %K::<SnnS!sI. zz"",,.CCi " " $ I]]_szz2237 7 I! &K&'IJJKs C>>DcBddlm}|jd}|dkr|jdtS|d|dzd|dzf}|d|dz|dzdf}||dzdd|dzf}||dzd|dzdf} t |}||z} | |z} || z } t | } | | z} ||z} | | z}|| | zz}|| | g||ggj}|S#t $r|jdtcYSwxYw#t $r|jdtcYSwxYw)zCalculates the inverse using BLOCKWISE inversion. See Also ======== inv inverse_ADJ inverse_GE inverse_CH inverse_LDL r) BlockMatrixLUr4r?N)&sympy.matrices.expressions.blockmatrixrrzrr _inv_blockr as_explicit)rr?rir)rrr,D_invB_D_iBDCA_nB_ndcC_nD_nnns rrrYswC  ABwuuDWu55 '16'6AE6/A '16'167 A !q&'7AF7 A !q&'167 A61  eGE 'C c'C6o $u*C qB #c'C "cT'/C sCj3*- . : : >> 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 SparseMatrixr7rF)roDM)rDMNCTLDLGEr)rrNrADJCHQRBLOCKzInversion method unrecognized)sympy.matricesrrrDrget_diag_blocksappendrr rr isinstancer inverse_GE inverse_LU inverse_ADJ inverse_CH inverse_LDL inverse_QR inverse_BLOCKr2rY) rr4r?try_block_diagrrblocksrblockrprvs r_invrsr2 ;;"#GHH""$ FE HHUYYfYD E FQx~*/ Qu % >F > ! Qt $~ a &FF ~ R[ 6  R & 4 \\Z\ 0 4 \\Z\ 0 5 ]]j] 1 4 \\Z\ 0 5 ]]j] 1 4 \\Z\ 0 7  __ _ 3899 66":r)r0)F)T)sympy.polys.matrices.exceptionsrsympy.polys.domainsr exceptionsrrr utilitiesr rrr.r5rLrPr[r`rcrfrirrrxrrrr<rrrsF"SS3$$D@>BB&- &#""%4"8("+"#%""$"  ,\%$LGEMr