
    wg0                         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y)    )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  rt         |	|      |d ||      \  }}}}|D ]  \  }}||z  }| |z  |z   <    ||dz  }I|j                  |       |dk7  r" |
|||z          |j                  |||z   f       |du rB||}}| |z  |z   <   t	        |z  |z   dz   |dz   z        D ]  }  |   |z         |<    |}t	        |      D ]1  }||k(  r	|du r||k  r |z  |z      } ||      r' |||||       3 |dz  }|k  r||k  r|d	u r^|d	u rZt        |      D ]L  \  }} |z  |z      }| |z  |z   <   t	        |z  |z   dz   |dz   z        D ]  }  |   |z         |<    N  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    ^/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/matrices/reductions.pyget_colz!_row_reduce_list.<locals>.get_col/   s    17d7|    c                 p    |z  |dz   z   | z  | dz   z   c| z  | dz   z   |z  |dz   z   y )Nr   r   )r   jr   r   s     r   row_swapz"_row_reduce_list.<locals>.row_swap2   s]    $At|$c!D&!a%&> 	;AdFAE4< #afa!eT\":r   c                     ||z
  z  }t        |z  |dz   z        D ]  } | |   z  |||z      z  z
        |<   ! y)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   sY    UDLqvAt|, 	4A1SV8aAE
l23CF	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:   
   s|   J?4 #<0EGWJE D.Wt^,B *J-B	*i)
 . 	-MVSgF),Ctg%&	- qLG'"1WlW45LL'<'#9:; U"GqA!C$
O1T6A:>AE4<8 3s1v	12A3 I ; 	7Cg~U"sW}c$h()C#Cg6	7 	1Y D.Wt^^ )t"3%j1 	3LE5E$J./I&)Cd
U"#5:-1EAIt3CD 3s1v	12A3	3 j!5<//r   c                     t        t        |       | j                  | 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@   |   s]     .d1gqvvqvvquuJ8CU 66!&&!&&#&
E99r   c                     | j                   dk  s| j                  dk  ryt        fd| dddf   D              } | d         r|xr t        | ddddf         S |xr 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   | ]  } |        y wr   r   ).0tr(   s     r   	<genexpr>z_is_echelon.<locals>.<genexpr>   s     6jm6s   r   Nr"   )r&   r   all_is_echelon)r?   r(   zeros_belows    ` r   rG   rG      s}    
 	vv{affk6Qqr1uX66K!D'@{1QU8Z@@=;qQRy*==r   Fc                 l    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      sF      &h=x9H J5UDNC F{Jr   c                    d }t        |t              r|nt        }| j                  dk  s| j                  dk  ry| j                  dk  s| j                  dk  r| D cg c]
  } ||       }}d|v ry| j                  dk(  rU| j                  dk(  rF| D cg c]
  } ||       }}d|vrd|vry| j                         } ||      rd|v ry ||      du ry || |      \  }}	t        |||ddd	      \  }	}
}	t        |
      S c c}w c c}w )
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}t         j                        D cg c]  } ||      |f }}t        |      D cg c]  \  }}|	 }}} j                  |d      |fS c c}w c c}}w )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                 :    t        fdd d | f   D              S )Nc              3   6   K   | ]  } |      dnd  y w)Nr   r   r   )rC   er(   s     r   rE   zO_rank.<locals>._permute_complexity_right.<locals>.complexity.<locals>.<genexpr>   s     JQJqM1qq8Js   )sum)r   r?   r(   s    r   
complexityz<_rank.<locals>._permute_complexity_right.<locals>.complexity   s     J!AqD'JJJr   r   )orientation)r   r   sortedpermute)r?   r(   rV   r   complexr   perms   ``     r   _permute_complexity_rightz(_rank.<locals>._permute_complexity_right   sj    	K
 05QVV}=!JqM1%==#)'?3!Q133		$F	3T:: >3s   A%A*r   r   F   N)r(   Tr<   )rJ   r   r   r&   r   detr@   len)r?   r(   rK   r\   r)   xzerosdr   rN   rM   s              r   _rankrc      s    ;( &h=x9H
 	vv{affkvv{affk()*1A**E>vv{qvv{()*1A**$e"3EEGa=Ue^a=E!,Q:FFCsJ/LAvq v;- + +s   DD	c                 h   t        | d      sy | j                  }|j                  }|j                  r|S |j                  r	 |j                  t              S t        d | D              sy 	 |j                  t              S # t        $ r |cY S w xY w# t        $ r |j                  t              cY S w xY w)N_repc              3   4   K   | ]  }|j                     y wr   )is_Rational)rC   rT   s     r   rE   z_to_DM_ZZ_QQ.<locals>.<genexpr>  s     ,Q1==,s   )
hasattrre   domainis_ZZis_QQ
convert_tor   r   rF   r   )r?   repKs      r   _to_DM_ZZ_QQro      s     1f
&&C

Aww
	
	>>"%% ,!,,	&>>"%%  	J	  	&>>"%%	&s$   A? *B ?BBB10B1c                     | j                   }|j                  r*| j                  d      \  }}}|j                         |z  }n"|j                  r| j                         \  }}nJ |j                         }||fS )z7Compute the reduced row echelon form of a DomainMatrix.F)keep_domain)ri   rj   rref_dento_fieldrk   rref	to_Matrix)dMrn   dM_rrefdenrM   M_rrefs         r   _rref_dmrz     so    
		Aww!{{u{=f""$s*	
'')u F6>r   c                     t        |       }|t        |      \  }}n.t        |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``
    T)r+   r,   )ro   rz   rJ   r   r   r@   )
r?   r(   rK   rM   r*   rv   r   r/   r)   rN   s
             r   _rrefr|   '  si    T 
aB	~"2,Z h-H H(J$4AZ J
r   N)TTT)typesr   sympy.polys.polyerrorsr   sympy.polys.domainsr   r   	utilitiesr   r	   r
   r   determinantr   r:   r@   rG   rO   rc   ro   rz   r|   r   r   r   <module>r      st     1 & O O / AEn0d 9=+/: & >  !(%U 8  % CL&<"  %\r   