
    wg                     R   d dl mZ d dlmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZmZ 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mZmZmZ eefdZedfdZ d Z!d Z"d#dZ#defdZ$d#dZ%d#dZ&d Z'd Z(d$dZ)efdZ*d Z+edfdZ,ed        Z-d Z.d  Z/d#d!Z0d" Z1y)%    )FunctionType)cacheit)FloatInteger)S)uniquely_named_symbol)Mul)PurePolycancel)nC)DomainMatrix)DDM   )NonSquareMatrixError)_get_intermediate_simp_get_intermediate_simp_bool_iszero_is_zero_after_expand_mul_dotprodsimp	_simplifyc                    g }t        |       } t        d | D              rt        d | D              ru| D cg c]  }t        |       }}t	        |      } ||      r0|dk7  r%t        |       D cg c]  \  }}|dk7  s|df }}}ddd|fS |j                  |      }|| |   d|fS g }	t        |       D ]+  \  }} ||      }
|
dk(  r||d|fc S |	j                  |
       - t        |	      rddd|fS t        |       D ]D  \  }}|	|    ||      } ||      }
|
dv r|j                  ||f       |
dk(  r||d|fc S |
|	|<   F t        |	      rddd|fS t        |       D ]Q  \  }}|	|   |j                  t        j                        s,d|	|<   |j                  |t        j                  f       S t        |	      rddd|fS |	j                  d      }|| |   d|fS c c}w c c}}w )a   Find the lowest index of an item in ``col`` that is
    suitable for a pivot.  If ``col`` consists only of
    Floats, the pivot with the largest norm is returned.
    Otherwise, the first element where ``iszerofunc`` returns
    False is used.  If ``iszerofunc`` does not return false,
    items are simplified and retested until a suitable
    pivot is found.

    Returns a 4-tuple
        (pivot_offset, pivot_val, assumed_nonzero, newly_determined)
    where pivot_offset is the index of the pivot, pivot_val is
    the (possibly simplified) value of the pivot, assumed_nonzero
    is True if an assumption that the pivot was non-zero
    was made without being proved, and newly_determined are
    elements that were simplified during the process of pivot
    finding.c              3   H   K   | ]  }t        |t        t        f        y wN)
isinstancer   r   .0xs     _/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/matrices/determinant.py	<genexpr>z)_find_reasonable_pivot.<locals>.<genexpr>*   s     
8q:a%)*
8s    "c              3   <   K   | ]  }t        |t                y wr   )r   r   r   s     r   r   z)_find_reasonable_pivot.<locals>.<genexpr>*   s      A/%&Jq% A/s   r   NF)TFT)listallanyabsmax	enumerateindexappendequalsr   Zero)col
iszerofuncsimpfuncnewly_determinedr   col_abs	max_valueir'   possible_zerosis_zerosimpeds               r   _find_reasonable_pivotr5      sd   $ 
s)C 
8C
88S A/*-A/ >/#&'a3q6''L	i  A~7@~#Ptq!aQF#P #P$'788i(s5z5*:;; N# '1Q- eq%!122g&' > dE#344 # 	$1!(!V$m###QK0evu&677#q	$ > dE#344 # 	11!(88AFF
 !%N1##QK0	1 >dE#344 	T"As1vt-..Y ( $Qs   G 0G%>G%Nc                    g }t        |       D ]0  \  }} ||      }|dk(  r||dg fc S ||j                  ||f       2 t        |      dk(  rdddg fS ||d   d   |d   d   dg fS g }|D ]K  \  }} ||      }t        |      t        |      k7  s&|j                  ||f        ||      dk(  sE||d|fc S  |d   d   |d   d   d|fS )a  
    Helper that computes the pivot value and location from a
    sequence of contiguous matrix column elements. As a side effect
    of the pivot search, this function may simplify some of the elements
    of the input column. A list of these simplified entries and their
    indices are also returned.
    This function mimics the behavior of _find_reasonable_pivot(),
    but does less work trying to determine if an indeterminate candidate
    pivot simplifies to zero. This more naive approach can be much faster,
    with the trade-off that it may erroneously return a pivot that is zero.

    ``col`` is a sequence of contiguous column entries to be searched for
    a suitable pivot.
    ``iszerofunc`` is a callable that returns a Boolean that indicates
    if its input is zero, or None if no such determination can be made.
    ``simpfunc`` is a callable that simplifies its input. It must return
    its input if it does not simplify its input. Passing in
    ``simpfunc=None`` indicates that the pivot search should not attempt
    to simplify any candidate pivots.

    Returns a 4-tuple:
    (pivot_offset, pivot_val, assumed_nonzero, newly_determined)
    ``pivot_offset`` is the sequence index of the pivot.
    ``pivot_val`` is the value of the pivot.
    pivot_val and col[pivot_index] are equivalent, but will be different
    when col[pivot_index] was simplified during the pivot search.
    ``assumed_nonzero`` is a boolean indicating if the pivot cannot be
    guaranteed to be zero. If assumed_nonzero is true, then the pivot
    may or may not be non-zero. If assumed_nonzero is false, then
    the pivot is non-zero.
    ``newly_determined`` is a list of index-value pairs of pivot candidates
    that were simplified during the pivot search.
    FNr   r   T)r&   r(   lenid)	r+   r,   r-   indeterminatesr1   col_valcol_val_is_zeror.   tmp_col_vals	            r   _find_reasonable_pivot_naiver=   {   s2   V Nn 0
7$W-e#gub(($ !!1g,/0 >a T5"$$
 a #^A%6q%94CC $ ?
7w'g;"[/)##Q$45+&%/+u.>>>? !Q!21!5t=MMM    c                 ,   	  j                   dk(  r- j                  dk(  r j                  dd j                  g      S  d    dddf   }} dddf    ddddf   }}|g	t	         j                   dz
        D ]'  }	j                  |j                  	|   d             ) 	D cg c]  }| j                  |d      d    c}	 j                  | g	z   	 	fd} j                   j                  dz    j                   |      }||fS c c}w )zReturn (A,T) where T the Toeplitz matrix used in the Berkowitz algorithm
    corresponding to ``M`` and A is the first principal submatrix.
    r   r   r   r   N   dotprodsimpc                 6    || kD  rj                   S | |z
     S r   )zero)r1   jMdiagss     r   entryz)_berkowitz_toeplitz_matrix.<locals>.entry   s!    q566MQU|r>   )rowscols_newoneranger(   multiply)
rG   aRCAr1   drI   toeplitzrH   s
   `        @r   _berkowitz_toeplitz_matrixrV      s    	vv{qvv{vvaAEE7## S6Qq!"uXqAQRU8Qqr!"uXqA  CE166A: =QZZadZ;<=?DE!qb]]1$]/5EEUUQBK%E
 vvaffqj!&&%0Hx= Fs   *Dc                 P   | j                   dk(  r-| j                  dk(  r| j                  dd| j                  g      S | j                   dk(  r2| j                  dk(  r#| j                  dd| j                  | d    g      S t	        |       \  }}|j                  t        |      d      S )ap   Run the Berkowitz algorithm and return a vector whose entries
        are the coefficients of the characteristic polynomial of ``M``.

        Given N x N matrix, efficiently compute
        coefficients of characteristic polynomials of ``M``
        without division in the ground domain.

        This method is particularly useful for computing determinant,
        principal minors and characteristic polynomial when ``M``
        has complicated coefficients e.g. polynomials. Semi-direct
        usage of this algorithm is also important in computing
        efficiently sub-resultant PRS.

        Assuming that M is a square matrix of dimension N x N and
        I is N x N identity matrix, then the Berkowitz vector is
        an N x 1 vector whose entries are coefficients of the
        polynomial

                        charpoly(M) = det(t*I - M)

        As a consequence, all polynomials generated by Berkowitz
        algorithm are monic.

        For more information on the implemented algorithm refer to:

        [1] S.J. Berkowitz, On computing the determinant in small
            parallel time using a small number of processors, ACM,
            Information Processing Letters 18, 1984, pp. 147-150

        [2] M. Keber, Division-Free computation of sub-resultants
            using Bezout matrices, Tech. Report MPI-I-2006-1-006,
            Saarbrucken, 2006
    r   r   rA   r@   NrB   )rJ   rK   rL   rM   rV   rO   _berkowitz_vector)rG   submatrU   s      r   rX   rX      s    H 	vv{qvv{vvaQUUG$$	
11vvaQUUQsVG,--1!4FH.v6DIIr>   c                 B    | j                  |      j                         S )aR  Returns the adjugate, or classical adjoint, of
    a matrix.  That is, the transpose of the matrix of cofactors.

    https://en.wikipedia.org/wiki/Adjugate

    Parameters
    ==========

    method : string, optional
        Method to use to find the cofactors, can be "bareiss", "berkowitz",
        "bird", "laplace" or "lu".

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2], [3, 4]])
    >>> M.adjugate()
    Matrix([
    [ 4, -2],
    [-3,  1]])

    See Also
    ========

    cofactor_matrix
    sympy.matrices.matrixbase.MatrixBase.transpose
    method)cofactor_matrix	transposerG   r\   s     r   	_adjugater`   *  s!    < F+5577r>   lambdac                    | j                   s
t               | j                         }|j                  }|j	                         }t        || gd       }|j                  s|t        urA|D cg c]  }|j                  |       }}|D cg c]
  } ||       }}t        ||      }	|	S t        |||      }	|	S c c}w c c}w )a  Computes characteristic polynomial det(x*I - M) where I is
    the identity matrix.

    A PurePoly is returned, so using different variables for ``x`` does
    not affect the comparison or the polynomials:

    Parameters
    ==========

    x : string, optional
        Name for the "lambda" variable, defaults to "lambda".

    simplify : function, optional
        Simplification function to use on the characteristic polynomial
        calculated. Defaults to ``simplify``.

    Examples
    ========

    >>> from sympy import Matrix
    >>> from sympy.abc import x, y
    >>> M = Matrix([[1, 3], [2, 0]])
    >>> M.charpoly()
    PurePoly(lambda**2 - lambda - 6, lambda, domain='ZZ')
    >>> M.charpoly(x) == M.charpoly(y)
    True
    >>> M.charpoly(x) == M.charpoly(y)
    True

    Specifying ``x`` is optional; a symbol named ``lambda`` is used by
    default (which looks good when pretty-printed in unicode):

    >>> M.charpoly().as_expr()
    lambda**2 - lambda - 6

    And if ``x`` clashes with an existing symbol, underscores will
    be prepended to the name to make it unique:

    >>> M = Matrix([[1, 2], [x, 0]])
    >>> M.charpoly(x).as_expr()
    _x**2 - _x - 2*x

    Whether you pass a symbol or not, the generator can be obtained
    with the gen attribute since it may not be the same as the symbol
    that was passed:

    >>> M.charpoly(x).gen
    _x
    >>> M.charpoly(x).gen == x
    False

    Notes
    =====

    The Samuelson-Berkowitz algorithm is used to compute
    the characteristic polynomial efficiently and without any
    division operations.  Thus the characteristic polynomial over any
    commutative ring without zero divisors can be computed.

    If the determinant det(x*I - M) can be found out easily as
    in the case of an upper or a lower triangular matrix, then
    instead of Samuelson-Berkowitz algorithm, eigenvalues are computed
    and the characteristic polynomial with their help.

    See Also
    ========

    det
    c                     d| z   S )N_ )ss    r   <lambda>z_charpoly.<locals>.<lambda>  s
    sQw r>   )modify)domain)
	is_squarer   to_DMri   charpolyr   is_EXRAWr   to_sympyr
   )
rG   r   simplifydMKcpcberk_vectorrP   ps
             r   	_charpolyrv   L  s    N ;;"$$ 
B
		A	Ba!->?AzzXY. /11qzz!}11,78qx{88[!$ H R1%H 28s   +B8	B=c                     | j                   r| j                  dk  r
t               t        j                  ||z   dz  z  | j                  |||      z  S )a  Calculate the cofactor of an element.

    Parameters
    ==========

    method : string, optional
        Method to use to find the cofactors, can be "bareiss", "berkowitz",
        "bird", "laplace" or "lu".

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2], [3, 4]])
    >>> M.cofactor(0, 1)
    -3

    See Also
    ========

    cofactor_matrix
    minor
    minor_submatrix
    r   rA   )rj   rJ   r   r   NegativeOneminorrG   r1   rF   r\   s       r   	_cofactorr{     sG    4 ;;!&&1*"$$==AEQ;'!''!Q*???r>   c                       j                   s
t                j                   j                   j                   fd      S )a  Return a matrix containing the cofactor of each element.

    Parameters
    ==========

    method : string, optional
        Method to use to find the cofactors, can be "bareiss", "berkowitz",
        "bird", "laplace" or "lu".

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2], [3, 4]])
    >>> M.cofactor_matrix()
    Matrix([
    [ 4, -3],
    [-2,  1]])

    See Also
    ========

    cofactor
    minor
    minor_submatrix
    c                 *    j                  | |      S r   )cofactor)r1   rF   rG   r\   s     r   rg   z"_cofactor_matrix.<locals>.<lambda>  s    Aq&1 r>   )rj   r   rL   rJ   rK   r_   s   ``r   _cofactor_matrixr     s5    8 ;;"$$66!&&!&&13 3r>   c                 "   
 ddl } j                  \  }}||kD  r j                   ||}}t        t	        |            }g }t	        d|dz         D ].  
|t        t        t        |j                  |
                  z  }0 d}|D ]c  }d}t        |      }	t	        |      D ]  
|t         
fd|D              z  } ||t        j                  |	z  z  t        ||	z
  ||	z
        z  z  }e |t        j                  |z  z  }|j                         S )a  Returns the permanent of a matrix. Unlike determinant,
    permanent is defined for both square and non-square matrices.

    For an m x n matrix, with m less than or equal to n,
    it is given as the sum over the permutations s of size
    less than or equal to m on [1, 2, . . . n] of the product
    from i = 1 to m of M[i, s[i]]. Taking the transpose will
    not affect the value of the permanent.

    In the case of a square matrix, this is the same as the permutation
    definition of the determinant, but it does not take the sign of the
    permutation into account. Computing the permanent with this definition
    is quite inefficient, so here the Ryser formula is used.

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> M.per()
    450
    >>> M = Matrix([1, 5, 7])
    >>> M.per()
    13

    References
    ==========

    .. [1] Prof. Frank Ben's notes: https://math.berkeley.edu/~bernd/ban275.pdf
    .. [2] Wikipedia article on Permanent: https://en.wikipedia.org/wiki/Permanent_%28mathematics%29
    .. [3] https://reference.wolfram.com/language/ref/Permanent.html
    .. [4] Permanent of a rectangular matrix : https://arxiv.org/pdf/0904.3251.pdf
    r   Nr   c              3   ,   K   | ]  }|f     y wr   re   )r   rF   rG   r1   s     r   r   z_per.<locals>.<genexpr>.  s     1Q1a41s   )	itertoolsshapeTr!   rN   mapcombinationsr7   sumr   rx   r   ro   )rG   r   mnrf   subsetspermsubsetprodsub_lenr1   s   `         @r   _perr     s   D 77DAq1uCC!1U1XAG1a!e_ A4D)"8"8A">?@@A D Mf+q 	2AS1&111T	2q}}g--1w;G0LLLM 	AMM1D==?r>   c                     t        j                  | dd      }|j                  }|j                  |j	                               S )NT)field	extension)r   from_Matrixri   rn   det)rG   DOMrq   s      r   _det_DOMr   3  s4    

"
"1DD
AC

A::cggi  r>   c                 L   |j                         }|dk(  rd}n|dk(  rd}|dvrt        d|z        ||dk(  rt        }n*|dk(  r%t        }nt	        |t
              st        d|z        | j                  }|| j                  k(  r|dk(  r| j                  S |d	k(  r| d
   S |dk(  r,| d
   | d   z  | d   | d   z  z
  } t        t              |      S |dk(  r| d
   | d   z  | d   z  | d   | d   z  | d   z  z   | d   | d   z  | d   z  z   | d   | d   z  | d   z  z
  | d
   | d   z  | d   z  z
  | d   | d   z  | d   z  z
  } t        t              |      S g }| j                         D ]  }|dk(  rt        | ||f         }n|dk(  r| ||f   j                  |      }nm|dk(  r| ||f   j                         }nR|dk(  r| ||f   j                  |      }n5|dk(  r| ||f   j!                         }n|dk(  r| ||f   j#                         }|j%                          t'        | S )a
  Computes the determinant of a matrix if ``M`` is a concrete matrix object
    otherwise return an expressions ``Determinant(M)`` if ``M`` is a
    ``MatrixSymbol`` or other expression.

    Parameters
    ==========

    method : string, optional
        Specifies the algorithm used for computing the matrix determinant.

        If the matrix is at most 3x3, a hard-coded formula is used and the
        specified method is ignored. Otherwise, it defaults to
        ``'bareiss'``.

        Also, if the matrix is an upper or a lower triangular matrix, determinant
        is computed by simple multiplication of diagonal elements, and the
        specified method is ignored.

        If it is set to ``'domain-ge'``, then Gaussian elimination method will
        be used via using DomainMatrix.

        If it is set to ``'bareiss'``, Bareiss' fraction-free algorithm will
        be used.

        If it is set to ``'berkowitz'``, Berkowitz' algorithm will be used.

        If it is set to ``'bird'``, Bird's algorithm will be used [1]_.

        If it is set to ``'laplace'``, Laplace's algorithm will be used.

        Otherwise, if it is set to ``'lu'``, LU decomposition will be used.

        .. note::
            For backward compatibility, legacy keys like "bareis" and
            "det_lu" can still be used to indicate the corresponding
            methods.
            And the keys are also case-insensitive for now. However, it is
            suggested to use the precise keys for specifying the method.

    iszerofunc : FunctionType or None, optional
        If it is set to ``None``, it will be defaulted to ``_iszero`` if the
        method is set to ``'bareiss'``, and ``_is_zero_after_expand_mul`` if
        the method is set to ``'lu'``.

        It can also accept any user-specified zero testing function, if it
        is formatted as a function which accepts a single symbolic argument
        and returns ``True`` if it is tested as zero and ``False`` if it
        tested as non-zero, and also ``None`` if it is undecidable.

    Returns
    =======

    det : Basic
        Result of determinant.

    Raises
    ======

    ValueError
        If unrecognized keys are given for ``method`` or ``iszerofunc``.

    NonSquareMatrixError
        If attempted to calculate determinant from a non-square matrix.

    Examples
    ========

    >>> from sympy import Matrix, eye, det
    >>> I3 = eye(3)
    >>> det(I3)
    1
    >>> M = Matrix([[1, 2], [3, 4]])
    >>> det(M)
    -2
    >>> det(M) == M.det()
    True
    >>> M.det(method="domain-ge")
    -2

    References
    ==========

    .. [1] Bird, R. S. (2011). A simple division-free algorithm for computing
           determinants. Inf. Process. Lett., 111(21), 1072-1074. doi:
           10.1016/j.ipl.2011.08.006
    bareisbareissdet_lulu)r   	berkowitzr   	domain-gebirdlaplacez$Determinant method '%s' unrecognizedz%Zero testing method '%s' unrecognizedr   r   r@   rA   r   r   r   r   r   r      )rA   rA   )r   rA   )rA   r   )r   rA   )rA   r   r   r,   r   r   r   )lower
ValueErrorr   r   r   r   rJ   rK   rM   r   r   strongly_connected_componentsr   _eval_det_bareiss_eval_det_berkowitz_eval_det_lu_eval_det_bird_eval_det_laplacer(   r	   )rG   r\   r,   r   r   detsbr   s           r   _detr   9  s   r \\^F	8	 ! !?&HIIY2Jt^ J
L1@:MNN	AAFF{655L!VT7N!V$!D'!AdGag$55A7),7::!VD'AdG#ag-D'AdG#ag-.D'AdG#ag-. D'AdG#ag-. D'AdG#ag-	.
 D'AdG#ag-.A 8),7::D,,. [ 1QT7#Cy AqD'++z+BC{"AqD'--/Ct^AqD'&&*&=CvAqD'((*Cy AqD'++-CC :r>   c                      d fd	 j                   s
t                j                  dk(  r j                  S         S )a  Compute matrix determinant using Bareiss' fraction-free
    algorithm which is an extension of the well known Gaussian
    elimination method. This approach is best suited for dense
    symbolic matrices and will result in a determinant with
    minimal number of fractions. It means that less term
    rewriting is needed on resulting formulae.

    Parameters
    ==========

    iszerofunc : function, optional
        The function to use to determine zeros when doing an LU decomposition.
        Defaults to ``lambda x: x.is_zero``.

    TODO: Implement algorithm for sparse matrices (SFF),
    http://www.eecis.udel.edu/~saunders/papers/sffge/it5.ps.
    c                    	
  j                   dk(  r j                  S  j                   dk(  r d   S t         d d df         \  	}} j                  S ddz  z  }t	         j                         D cg c]
  }|k7  s	| }}t        t	         j                              } j                  ||      
 	
fd}| j                   j                   dz
   j                  dz
  |      	      z  S c c}w )Nr   r   r@   r   rA   c                     | |dz   f   z  |dz   f   | df   z  z
  z  }t        d      rt        |      S |j                  st        |      S |S )Nr   r   T)r   r   is_Atomr   )r1   rF   retcummmat	pivot_pos	pivot_valtmp_mats      r   rI   z,_det_bareiss.<locals>.bareiss.<locals>.entry  sj    WQAX..YA5E1FwqRSt}1TTX\\C*40#C(([[c{"Jr>   )	rJ   rM   r5   rE   rN   r!   rK   extractrL   )r   r   rd   signr1   rJ   rK   rI   r   r   r   rG   r   r,   s   ``      @@@r   r   z_det_bareiss.<locals>.bareiss  s    88q=77NXX]t9 &<C1IR\%]"	9a88O 	A& !?=aa9n==E#((O$++dD)	 	 GAFF388a<AuEyQQQ >s   <
C=C=r   )r   )rj   r   rJ   rM   )rG   r,   r   s   ``@r   _det_bareissr     s<    *RB ;;"$$vv{uu
 1:r>   c                     | j                   s
t               | j                  dk(  r| j                  S t	        |       }dt        |      dz
  z  |d   z  S )z8 Use the Berkowitz algorithm to compute the determinant.r   r   r   )rj   r   rJ   rM   rX   r7   )rG   rt   s     r   _det_berkowitzr     sR     ;;"$$vv{uu
 $A&K#k"Q&'+b/99r>   c                    | j                   s
t               | j                  dk(  r| j                  S | j	                  ||      \  }} |||j                  dz
  |j                  dz
  f         r| j
                  S t        |      dz  r| j                   n| j                  }t        |j                        D ]  }||||f   z  } |S )a   Computes the determinant of a matrix from its LU decomposition.
    This function uses the LU decomposition computed by
    LUDecomposition_Simple().

    The keyword arguments iszerofunc and simpfunc are passed to
    LUDecomposition_Simple().
    iszerofunc is a callable that returns a boolean indicating if its
    input is zero, or None if it cannot make the determination.
    simpfunc is a callable that simplifies its input.
    The default is simpfunc=None, which indicate that the pivot search
    algorithm should not attempt to simplify any candidate pivots.
    If simpfunc fails to simplify its input, then it must return its input
    instead of a copy.

    Parameters
    ==========

    iszerofunc : function, optional
        The function to use to determine zeros when doing an LU decomposition.
        Defaults to ``lambda x: x.is_zero``.

    simpfunc : function, optional
        The simplification function to use when looking for zeros for pivots.
    r   )r,   r-   r   rA   )rj   r   rJ   rM   LUdecomposition_SimplerE   r7   rN   )rG   r,   r-   r   	row_swapsr   ks          r   _det_LUr     s    4 ;;"$$vv{uu
 ,,
 - MB	 "RWWQY	)*+vv 	N1$155&!%%C
 277^ r!Q$x Jr>   c                       j                   d   }|dk(  r d   S |dk(  r d    d   z   d    d   z  z
  S t         fdt        |      D              S )	a  Compute the determinant of a matrix using Laplace expansion.

    This is a recursive function, and it should not be called directly.
    Use _det_laplace() instead. The reason for splitting this function
    into two is to allow caching of determinants of submatrices. While
    one could also define this function inside _det_laplace(), that
    would remove the advantage of using caching in Cramer Solve.
    r   r   rA   r@   r   r   r   c              3   p   K   | ]-  }d |z  d|f   z  t        j                  d|            z   / yw)r   r   N)__det_laplaceminor_submatrix)r   r1   rG   s     r   r   z __det_laplace.<locals>.<genexpr>n  sF      M>? 19qAw& !2!21a!89: Ms   36)r   r   rN   )rG   r   s   ` r   r   r   ^  sp     	

AAvt	
aw4 1T7QtW#444 MCH8M M 	Mr>   c                     | j                   s
t               | j                  d   dk(  r| j                  S t	        | j                               S )aP  Compute the determinant of a matrix using Laplace expansion.

    While Laplace expansion is not the most efficient method of computing
    a determinant, it is a simple one, and it has the advantage of
    being division free. To improve efficiency, this function uses
    caching to avoid recomputing determinants of submatrices.
    r   )rj   r   r   rM   r   as_immutable)rG   s    r   _det_laplacer   r  s@     ;;"$$wwqzQuu )**r>   c                 0   d }| j                   j                         }| j                  d   }|dk(  r| j                  S |}t	        |dz
        D ]  } ||      j                  |      } |d   d   }|dz  dk(  r| }|j                  j                  |      S )a  Compute the determinant of a matrix using Bird's algorithm.

    Bird's algorithm is a simple division-free algorithm for computing, which
    is of lower order than the Laplace's algorithm. It is described in [1]_.

    References
    ==========

    .. [1] Bird, R. S. (2011). A simple division-free algorithm for computing
           determinants. Inf. Process. Lett., 111(21), 1072-1074. doi:
           10.1016/j.ipl.2011.08.006
    c                    | j                   d   }| j                  j                  }|}|g}t        t	        d|            D ]  }|| |   |   z  }|j                  |         |d d d   }t        |       D cg c]  \  }}|g|z  ||   gz   ||dz   d  z    }}}t        || j                   | j                        S c c}}w )Nr   r   r   )r   ri   rE   reversedrN   r(   r&   r   )Xr   rE   total	diag_sumsr1   X_ielemss           r   muz_det_bird.<locals>.mu  s    GGAJxx}}F	%1+& 	$AQqT!WEU#	$ ddO	 1vq#$!y|n,s1q56{:  5!''188,,s   7 B;r   r   rA   )_repto_ddmr   rM   rN   matmulri   rn   )rG   r   Mddmr   Fn1rd   detAs          r   	_det_birdr     s    - 66==?D	
AAvuu C1q5\ #gnnT"#q6!9D1uzu;;%%r>   c                 r    | j                   s
t               | j                  ||      j                  |      S )a  Return the (i,j) minor of ``M``.  That is,
    return the determinant of the matrix obtained by deleting
    the `i`th row and `j`th column from ``M``.

    Parameters
    ==========

    i, j : int
        The row and column to exclude to obtain the submatrix.

    method : string, optional
        Method to use to find the determinant of the submatrix, can be
        "bareiss", "berkowitz", "bird", "laplace" or "lu".

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> M.minor(1, 1)
    -12

    See Also
    ========

    minor_submatrix
    cofactor
    det
    r[   )rj   r   r   r   rz   s       r   _minorr     s5    > ;;"$$Q"&&f&55r>   c                    |dk  r|| j                   z  }|dk  r|| j                  z  }d|cxk  r| j                   k  rn nd|cxk  r| j                  k  s*n t        d| j                   z  d| j                  z  z         t        | j                         D cg c]
  }||k7  s	| }}t        | j                        D cg c]
  }||k7  s	| }}| j	                  ||      S c c}w c c}w )a  Return the submatrix obtained by removing the `i`th row
    and `j`th column from ``M`` (works with Pythonic negative indices).

    Parameters
    ==========

    i, j : int
        The row and column to exclude to obtain the submatrix.

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> M.minor_submatrix(1, 1)
    Matrix([
    [1, 3],
    [7, 9]])

    See Also
    ========

    minor
    cofactor
    r   z1`i` and `j` must satisfy 0 <= i < ``M.rows`` (%d)zand 0 <= j < ``M.cols`` (%d).)rJ   rK   r   rN   r   )rG   r1   rF   rP   rJ   rK   s         r   _minor_submatrixr     s    6 	1u	QVV1u	QVV?AFF?!q/166/ #%&VV,.MPQPVPV.VW X 	X QVV}/!QA/D/QVV}/!QA/D/99T4   0/s   
C""C"?
C'
C')r   )r   N)2typesr   sympy.core.cacher   sympy.core.numbersr   r   sympy.core.singletonr   sympy.core.symbolr   sympy.core.mulr	   sympy.polysr
   r   %sympy.functions.combinatorial.numbersr   !sympy.polys.matrices.domainmatrixr   sympy.polys.matrices.ddmr   
exceptionsr   	utilitiesr   r   r   r   r   r   r5   r=   rV   rX   r`   rv   r{   r   r   r   r   r   r   r   r   r   r   r   r   re   r>   r   <module>r      s     $ - " 3  ( 4 : ( ,A A
 ,3Y e/P 294 NNd+^+J\8D i jZ@@ 3D6p!Of  9 ?D:" "D <~ 	M 	M&+$*&Z"6J'!r>   