o
    oh0                     @   s   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d	Z		dd
dZe	fddZe	ddfddZe	dfddZdd Zdd Ze	dddfddZdS )    )FunctionType)CoercionFailed)ZZQQ   )_get_intermediate_simp_iszero_dotprodsimp	_simplify)_find_reasonable_pivotTc	                    s8   fdd}	 fdd}
 fdd}t td\}}g }g }| k r||k rt|	||d ||\}}}}|D ]\}}||7 }||  | < q<|du rV|d	7 }q"|| |d
kro|
|||  |||| f |du r||}}||  | < t|  | d	 |d	   D ]}| | |< q|}t|D ]$}||krq|du r||k rq|  |  }||rq||||| q|d	7 }| k r||k s*|du r|du rt|D ]1\}}|  |  }||  | < t|  | d	 |d	   D ]}| | |< qq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                    s   | d   S N icolsmatr   m/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/matrices/reductions.pyget_col/   s   z!_row_reduce_list.<locals>.get_colc                    s^   |  |d    |   | d    |   | d   < |  |d   < d S )Nr   r   )r   jr   r   r   row_swap2   s   .0z"_row_reduce_list.<locals>.row_swapc                    sP   ||   }t |  |d   D ]}| |  |||    |< qdS )z,Does the row op row[i] = a*row[i] - b*row[j]r   N)range)ar   br   qpr   isimpr   r   r   cross_cancel6   s   &z&_row_reduce_list.<locals>.cross_cancel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   r   r   _row_reduce_list
   s`   %

"/"r7   c           	      C   sB   t t| | j| j| j|||||d	\}}}| | j| j|||fS )Nr'   r(   r)   )r7   listr#   r   r$   _new)	Mr%   r&   r'   r(   r)   r   r,   r-   r   r   r   _row_reduce|   s
   r<   c                    s   | j dks
| jdkrdS t fdd| dddf D } | d r2|o1t| 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   s    | ]} |V  qd S r   r   ).0tr%   r   r   	<genexpr>   s    z_is_echelon.<locals>.<genexpr>r   Nr   )r#   r   all_is_echelon)r;   r%   zeros_belowr   r?   r   rB      s   "rB   Fc                 C   s<   t |tr|nt}t| ||d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]])
    TFr8   )
isinstancer   r
   r<   )r;   r%   simplifywith_pivotsr&   r   pivots_r   r   r   _echelon_form   s   rI   c           
         s   dd }t |tr|nt}| jdks| jdkrdS | jdks#| jdkr2 fdd| D }d|v r2dS | jdkre| jdkre fd	d| D }d|vrOd
|vrOdS |  } |r]d|v r]dS  |du redS ||  d\}}t| |d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                    sJ    fddfddt  jD }dd t|D } j|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                    s"   t fdd d d | f D S )Nc                 3   s$    | ]} |d u rdndV  qd S )Nr   r   r   r=   er?   r   r   r@      s   " zO_rank.<locals>._permute_complexity_right.<locals>.complexity.<locals>.<genexpr>)sumr   )r;   r%   r   r   
complexity   s   "z<_rank.<locals>._permute_complexity_right.<locals>.complexityc                    s   g | ]} ||fqS r   r   )r=   r   )rM   r   r   
<listcomp>   s    z<_rank.<locals>._permute_complexity_right.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   )r=   r   r   r   r   r   rN          r   )orientation)r   r   sortedpermute)r;   r%   complexpermr   )r;   rM   r%   r   _permute_complexity_right   s   
z(_rank.<locals>._permute_complexity_rightr   r   c                       g | ]} |qS r   r   r=   xr?   r   r   rN      rO   z_rank.<locals>.<listcomp>F   c                    rV   r   r   rW   r?   r   r   rN      rO   Nr?   Tr8   )rD   r   r
   r#   r   detr<   len)
r;   r%   rE   rU   r&   zerosdr   rH   rG   r   r?   r   _rank   s,   
r^   c                 C   s   t | dsd S | j}|j}|jr|S |jr'z|tW S  ty&   | Y S w tdd | D s2d S z|tW S  tyF   |t	 Y S w )N_repc                 s   s    | ]}|j V  qd S r   )is_RationalrJ   r   r   r   r@     s    z_to_DM_ZZ_QQ.<locals>.<genexpr>)
hasattrr_   domainis_ZZis_QQ
convert_tor   r   rA   r   )r;   repKr   r   r   _to_DM_ZZ_QQ   s&   
rh   c                 C   sT   | j }|jr| jdd\}}}| | }n|jr |  \}}nJ | }||fS )z7Compute the reduced row echelon form of a DomainMatrix.F)keep_domain)rb   rc   rref_dento_fieldrd   rref	to_Matrix)dMrg   dM_rrefdenrG   M_rrefr   r   r   _rref_dm  s   rr   c           
      C   s\   t | }|durt|\}}nt|tr|}nt}t| |||d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)   )rh   rr   rD   r   r
   r<   )
r;   r%   rE   rG   r'   rn   r   r,   r&   rH   r   r   r   _rref'  s   J
rs   N)TTT)typesr   sympy.polys.polyerrorsr   sympy.polys.domainsr   r   	utilitiesr   r   r	   r
   determinantr   r7   r<   rB   rI   r^   rh   rr   rs   r   r   r   r   <module>   s$    
r

F