
    g0                         d dl mZ d dlmZ d dlmZmZ ddlmZm	Z	m
Z
mZ ddlmZ 	 ddZ	 	 dd	Ze	fd
Ze	ddfdZe	dfdZd Zd Ze	dddfdZdS )    )FunctionType)CoercionFailed)ZZQQ   )_get_intermediate_simp_iszero_dotprodsimp	_simplify)_find_reasonable_pivotTc	                      fd}	 fd}
 fd}t          t                    d\  }}g }g }|k     r>||k     r7t           |	|          |d         ||          \  }}}}|D ]\  }}||z  }| |z  |z   <   ||dz  }U|                    |           |dk    r) |
|||z              |                    |||z   f           |du rJ||}}| |z  |z   <   t	          |z  |z   dz   |dz   z            D ]}  |         |z             |<   |}t	          |          D ]<}||k    r	|du r||k     r |z  |z            } ||          r. |||||           =|dz  }|k     r||k     7|d	u rk|d	u rgt          |          D ]W\  }} |z  |z            }| |z  |z   <   t	          |z  |z   dz   |dz   z            D ]}  |         |z             |<   X t          |          t          |          fS )
a  Row reduce a flat list representation of a matrix and return a tuple
    (rref_matrix, pivot_cols, swaps) where ``rref_matrix`` is a flat list,
    ``pivot_cols`` are the pivot columns and ``swaps`` are any row swaps that
    were used in the process of row reduction.

    Parameters
    ==========

    mat : list
        list of matrix elements, must be ``rows`` * ``cols`` in length

    rows, cols : integer
        number of rows and columns in flat list representation

    one : SymPy object
        represents the value one, from ``Matrix.one``

    iszerofunc : determines if an entry can be used as a pivot

    simpfunc : used to simplify elements and test if they are
        zero if ``iszerofunc`` returns `None`

    normalize_last : indicates where all row reduction should
        happen in a fraction-free manner and then the rows are
        normalized (so that the pivots are 1), or whether
        rows should be normalized along the way (like the naive
        row reduction algorithm)

    normalize : whether pivot rows should be normalized so that
        the pivot value is 1

    zero_above : whether entries above the pivot should be zeroed.
        If ``zero_above=False``, an echelon matrix will be returned.
    c                     | d          S N )icolsmats    U/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/matrices/reductions.pyget_colz!_row_reduce_list.<locals>.get_col/   s    17d7|    c                     |z  |dz   z           | z  | dz   z           c| z  | dz   z  <   |z  |dz   z  <   d S )Nr   r   )r   jr   r   s     r   row_swapz"_row_reduce_list.<locals>.row_swap2   so    $At|#$c!D&!a%*=&> 	;AdFAE4< #afa!eT\&9":":":r   c                     ||z
  z  }t          |z  |dz   z            D ](} | |         z  |||z            z  z
            |<   )dS )z,Does the row op row[i] = a*row[i] - b*row[j]r   N)range)	ar   br   qpr   isimpr   s	         r   cross_cancelz&_row_reduce_list.<locals>.cross_cancel6   sm    UDLqvAt|,, 	4 	4AU1SV8aAE
l233CFF	4 	4r   r   r   Nr   r   FT)r   r
   r   appendr   	enumeratetuple)r   rowsr   one
iszerofuncsimpfuncnormalize_last	normalize
zero_abover   r   r!   piv_rowpiv_col
pivot_colsswapspivot_offset	pivot_valassumed_nonzeronewly_determinedoffsetvalr   r   r   rowpiv_ipiv_jr    s   ` `                         @r   _row_reduce_listr:   
   sA   J     ? ? ? ? ? ?4 4 4 4 4 4 4 #<00EGWJE D..Wt^^,B  *J-B -B	*i)
 . 	- 	-MVSgF),Ctg%&&qLG'"""1HWlW4555LL'<'#9:;;; U""GqA!C$
O1T6A:>AE4<88 3 3s1v	122AI ;; 	7 	7Cg~~U""sW}}c$h()Cz# LCg66661Y D..Wt^^^ )t"3"3%j11 	3 	3LE5E$J./I&)Cd
U"#5:-1EAIt3CDD 3 3s1v	122A3 j!!5<<//r   c                     t          t          |           | j        | j        | j        |||||	  	        \  }}}|                     | j        | j        |          ||fS )Nr*   r+   r,   )r:   listr&   r   r'   _new)	Mr(   r)   r*   r+   r,   r   r/   r0   s	            r   _row_reducer@   |   sb     .d1ggqvqvquJ8 8 8CU 66!&!&#&&
E99r   c                    | j         dk    s| j        dk    rdS t          fd| dddf         D                       } | d                   r|ot          | ddddf                   S |ot          | ddddf                   S )zReturns `True` if the matrix is in echelon form. That is, all rows of
    zeros are at the bottom, and below each leading non-zero in a row are
    exclusively zeros.r   Tc              3   .   K   | ]} |          V  d S r   r   ).0tr(   s     r   	<genexpr>z_is_echelon.<locals>.<genexpr>   s+      66jjmm666666r   r   Nr"   )r&   r   all_is_echelon)r?   r(   zeros_belows    ` r   rG   rG      s    
 	v{{afkkt6666Qqrr1uX66666Kz!D' A@{1QQQU8Z@@@=;qQRRy*===r   Fc                     t          |t                    r|nt          }t          | ||ddd          \  }}}|r||fS |S )an  Returns a matrix row-equivalent to ``M`` that is in echelon form. Note
    that echelon form of a matrix is *not* unique, however, properties like the
    row space and the null space are preserved.

    Examples
    ========

    >>> from sympy import Matrix
    >>> M = Matrix([[1, 2], [3, 4]])
    >>> M.echelon_form()
    Matrix([
    [1,  2],
    [0, -2]])
    TFr<   )
isinstancer   r   r@   )r?   r(   simplifywith_pivotsr)   r   pivots_s           r   _echelon_formrO      s_      &h==Lxx9H J5UD D DNC  F{Jr   c                    d }t          |t                    r|nt          }| j        dk    s| j        dk    rdS | j        dk    s| j        dk    rfd| D             }d|v rdS | j        dk    rW| j        dk    rLfd| D             }d|vrd|vrdS |                                 } |          rd|v rdS  |          du rdS  || 	          \  }}t          ||d
dd          \  }}	}t          |	          S )zReturns the rank of a matrix.

    Examples
    ========

    >>> from sympy import Matrix
    >>> from sympy.abc import x
    >>> m = Matrix([[1, 2], [x, 1 - 1/x]])
    >>> m.rank()
    2
    >>> n = Matrix(3, 3, range(1, 10))
    >>> n.rank()
    2
    c                       fdfdt           j                  D             }d t          |          D             }                     |d          |fS )a  Permute columns with complicated elements as
        far right as they can go.  Since the ``sympy`` row reduction
        algorithms start on the left, having complexity right-shifted
        speeds things up.

        Returns a tuple (mat, perm) where perm is a permutation
        of the columns to perform to shift the complex columns right, and mat
        is the permuted matrix.c                 N    t          fdd d | f         D                       S )Nc              3   6   K   | ]} |          dndV  d S )Nr   r   r   )rC   er(   s     r   rE   zO_rank.<locals>._permute_complexity_right.<locals>.complexity.<locals>.<genexpr>   s4      JJQJJqMM1qqqJJJJJJr   )sum)r   r?   r(   s    r   
complexityz<_rank.<locals>._permute_complexity_right.<locals>.complexity   s4     JJJJ!AAAqD'JJJJJJr   c                 *    g | ]} |          |fS r   r   )rC   r   rV   s     r   
<listcomp>z<_rank.<locals>._permute_complexity_right.<locals>.<listcomp>   s&    ===!JJqMM1%===r   c                     g | ]\  }}|S r   r   )rC   r   r   s      r   rX   z<_rank.<locals>._permute_complexity_right.<locals>.<listcomp>   s    333!Q1333r   r   )orientation)r   r   sortedpermute)r?   r(   complexpermrV   s   ``  @r   _permute_complexity_rightz(_rank.<locals>._permute_complexity_right   s    	K 	K 	K 	K 	K 	K
 >===uQV}}===336'??333		$F	33T::r   r   r   c                 &    g | ]} |          S r   r   rC   xr(   s     r   rX   z_rank.<locals>.<listcomp>   !    ***1A***r   F   c                 &    g | ]} |          S r   r   ra   s     r   rX   z_rank.<locals>.<listcomp>   rc   r   N)r(   Tr<   )rJ   r   r   r&   r   detr@   len)
r?   r(   rK   r_   r)   zerosdr   rN   rM   s
    `        r   _rankrj      s\    ; ; ;( &h==Lxx9H
 	v{{afkkqv{{afkk*******E>>1v{{qv{{*******$e"3"31EEGG:a== 	Ue^^1:a==E!!1,,Q:FFFFCsJ/ / /LAvq v;;r   c                 |   t          | d          sd S | j        }|j        }|j        r|S |j        r-	 |                    t                    S # t          $ r |cY S w xY wt          d | D                       sd S 	 |                    t                    S # t          $ r |                    t                    cY S w xY w)N_repc              3   $   K   | ]}|j         V  d S r   )is_Rational)rC   rT   s     r   rE   z_to_DM_ZZ_QQ.<locals>.<genexpr>  s$      ,,Q1=,,,,,,r   )
hasattrrl   domainis_ZZis_QQ
convert_tor   r   rF   r   )r?   repKs      r   _to_DM_ZZ_QQrv      s     1f t
&C
Aw &
	
 &	>>"%%% 	 	 	JJJ	 ,,!,,,,, 	4	&>>"%%% 	& 	& 	&>>"%%%%%	&s#   A AA:B $B;:B;c                     | j         }|j        r2|                     d          \  }}}|                                |z  }n!|j        r|                                 \  }}nJ |                                }||fS )z7Compute the reduced row echelon form of a DomainMatrix.F)keep_domain)rp   rq   rref_dento_fieldrr   rref	to_Matrix)dMru   dM_rrefdenrM   M_rrefs         r   _rref_dmr     s    
	Aw !{{u{==f""$$s*	
 ''))  F6>r   c                     t          |           }|t          |          \  }}n8t          |t                    r|}nt          }t          | |||dd          \  }}}	|r||fS |S )a-	  Return reduced row-echelon form of matrix and indices
    of pivot vars.

    Parameters
    ==========

    iszerofunc : Function
        A function used for detecting whether an element can
        act as a pivot.  ``lambda x: x.is_zero`` is used by default.

    simplify : Function
        A function used to simplify elements when looking for a pivot.
        By default SymPy's ``simplify`` is used.

    pivots : True or False
        If ``True``, a tuple containing the row-reduced matrix and a tuple
        of pivot columns is returned.  If ``False`` just the row-reduced
        matrix is returned.

    normalize_last : True or False
        If ``True``, no pivots are normalized to `1` until after all
        entries above and below each pivot are zeroed.  This means the row
        reduction algorithm is fraction free until the very last step.
        If ``False``, the naive row reduction procedure is used where
        each pivot is normalized to be `1` before row operations are
        used to zero above and below the pivot.

    Examples
    ========

    >>> from sympy import Matrix
    >>> from sympy.abc import x
    >>> m = Matrix([[1, 2], [x, 1 - 1/x]])
    >>> m.rref()
    (Matrix([
    [1, 0],
    [0, 1]]), (0, 1))
    >>> rref_matrix, rref_pivots = m.rref()
    >>> rref_matrix
    Matrix([
    [1, 0],
    [0, 1]])
    >>> rref_pivots
    (0, 1)

    ``iszerofunc`` can correct rounding errors in matrices with float
    values. In the following example, calling ``rref()`` leads to
    floating point errors, incorrectly row reducing the matrix.
    ``iszerofunc= lambda x: abs(x) < 1e-9`` sets sufficiently small numbers
    to zero, avoiding this error.

    >>> m = Matrix([[0.9, -0.1, -0.2, 0], [-0.8, 0.9, -0.4, 0], [-0.1, -0.8, 0.6, 0]])
    >>> m.rref()
    (Matrix([
    [1, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 0, 1, 0]]), (0, 1, 2))
    >>> m.rref(iszerofunc=lambda x:abs(x)<1e-9)
    (Matrix([
    [1, 0, -0.301369863013699, 0],
    [0, 1, -0.712328767123288, 0],
    [0, 0,         0,          0]]), (0, 1))

    Notes
    =====

    The default value of ``normalize_last=True`` can provide significant
    speedup to row reduction, especially on matrices with symbols.  However,
    if you depend on the form row reduction algorithm leaves entries
    of the matrix, set ``normalize_last=False``
    NT)r+   r,   )rv   r   rJ   r   r   r@   )
r?   r(   rK   rM   r*   r}   r   r/   r)   rN   s
             r   _rrefr   '  s    T 
aB	~"2,,ZZ h-- 	!HH H(J$4A A AZ  J
r   N)TTT)typesr   sympy.polys.polyerrorsr   sympy.polys.domainsr   r   	utilitiesr   r	   r
   r   determinantr   r:   r@   rG   rO   rj   rv   r   r   r   r   r   <module>r      sW         1 1 1 1 1 1 & & & & & & & & O O O O O O O O O O O O / / / / / / AEn0 n0 n0 n0d 9=+/: : : : & > > > >  !(%U    8  % C C C CL& & &<  "  %\ \ \ \ \ \r   