o
    oh;                     @   s   d Z 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 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mZ ddlmZ ddlmZ ddlmZ G dd dZG dd dZdS )a  
This module contains functions for two multivariate resultants. These
are:

- Dixon's resultant.
- Macaulay's resultant.

Multivariate resultants are used to identify whether a multivariate
system has common roots. That is when the resultant is equal to zero.
    )prodMul)Matrixdiag)Polydegree_listrem)simplify)IndexedBase)itermonomialsmonomial_deg)monomial_key)poly_from_exprtotal_degree)binomial)combinations_with_replacement)sympy_deprecation_warningc                   @   sd   e Zd ZdZdd Zedd Zdd Zdd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd ZdS )DixonResultantaG  
    A class for retrieving the Dixon's resultant of a multivariate
    system.

    Examples
    ========

    >>> from sympy import symbols

    >>> from sympy.polys.multivariate_resultants import DixonResultant
    >>> x, y = symbols('x, y')

    >>> p = x + y
    >>> q = x ** 2 + y ** 3
    >>> h = x ** 2 + y

    >>> dixon = DixonResultant(variables=[x, y], polynomials=[p, q, h])
    >>> poly = dixon.get_dixon_polynomial()
    >>> matrix = dixon.get_dixon_matrix(polynomial=poly)
    >>> matrix
    Matrix([
    [ 0,  0, -1,  0, -1],
    [ 0, -1,  0, -1,  0],
    [-1,  0,  1,  0,  0],
    [ 0, -1,  0,  0,  1],
    [-1,  0,  0,  1,  0]])
    >>> matrix.det()
    0

    See Also
    ========

    Notebook in examples: sympy/example/notebooks.

    References
    ==========

    .. [1] [Kapur1994]_
    .. [2] [Palancz08]_

    c                    sd   |_ |_tj_tj _td  fddtjD _fddtjD _dS )aV  
        A class that takes two lists, a list of polynomials and list of
        variables. Returns the Dixon matrix of the multivariate system.

        Parameters
        ----------
        polynomials : list of polynomials
            A  list of m n-degree polynomials
        variables: list
            A list of all n variables
        alphac                    s   g | ]} | qS  r   .0i)ar   w/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/polys/multivariate_resultants.py
<listcomp>X       z+DixonResultant.__init__.<locals>.<listcomp>c                    s$   g | ] t  fd djD qS )c                 3   s    | ]	}t |  V  qd S N)r   r   polyr   r   r   	<genexpr>[   s    z5DixonResultant.__init__.<locals>.<listcomp>.<genexpr>)maxpolynomialsr   selfr!   r   r   [       N)	r$   	variableslennmr   rangedummy_variables_max_degreesr'   r$   r)   r   )r   r'   r   __init__D   s   
zDixonResultant.__init__c                 C   s   t dddd | jS )NzS
            The max_degrees property of DixonResultant is deprecated.
            1.5$deprecated-dixonresultant-propertiesdeprecated_since_versionactive_deprecations_target)r   r/   r&   r   r   r   max_degrees^   s   zDixonResultant.max_degreesc                    s   | j | jd krtd| jg}t| j}t| jD ]}| j| ||< tt	| j| |
 fdd| jD  qt|}t	| j| j}tdd |D  }| |  }t|| jd S )a  
        Returns
        =======

        dixon_polynomial: polynomial
            Dixon's polynomial is calculated as:

            delta = Delta(A) / ((x_1 - a_1) ... (x_n - a_n)) where,

            A =  |p_1(x_1,... x_n), ..., p_n(x_1,... x_n)|
                 |p_1(a_1,... x_n), ..., p_n(a_1,... x_n)|
                 |...             , ...,              ...|
                 |p_1(a_1,... a_n), ..., p_n(a_1,... a_n)|
           z%Method invalid for given combination.c                    s   g | ]}|  qS r   )subs)r   fsubstitutionr   r   r      s    z7DixonResultant.get_dixon_polynomial.<locals>.<listcomp>c                 S   s   g | ]\}}|| qS r   r   )r   r   br   r   r   r      s    r   )r,   r+   
ValueErrorr$   listr)   r-   r.   dictzipappendr   r   detfactorr   )r'   rowstempidxAtermsproduct_of_differencesdixon_polynomialr   r;   r   get_dixon_polynomiali   s   
z#DixonResultant.get_dixon_polynomialc                    sB   t dddd  fddt jD }t|}t| }t| S )Nz
            The get_upper_degree() method of DixonResultant is deprecated. Use
            get_max_degrees() instead.
            r2   r3   r4   c                    s    g | ]} j |  j|  qS r   )r)   r/   r   r&   r   r   r          z3DixonResultant.get_upper_degree.<locals>.<listcomp>)r   r-   r+   r   r   monomsr   )r'   list_of_productsproductr   r&   r   get_upper_degree   s   
zDixonResultant.get_upper_degreec                    s,    fdd|  D }dd t| D }|S )z
        Returns a list of the maximum degree of each variable appearing
        in the coefficients of the Dixon polynomial. The coefficients are
        viewed as polys in $x_1, x_2, \dots, x_n$.
        c                    s   g | ]
}t t| jqS r   )r   r   r)   r   r&   r   r   r      s    z2DixonResultant.get_max_degrees.<locals>.<listcomp>c                 S   s   g | ]}t |qS r   )r#   )r   degsr   r   r   r      r   )coeffsrA   )r'   
polynomial	deg_listsr7   r   r&   r   get_max_degrees   s
   
zDixonResultant.get_max_degreesc                    s    |}tj|tdtdjdtfdd| D   jd  jd krD fddt jd	 D } d
d
|f   S )z
        Construct the Dixon matrix from the coefficients of polynomial
        \alpha. Each coefficient is viewed as a polynomial of x_1, ...,
        x_n.
        Tlexreversekeyc                    s    g | ]  fd dD qS )c                    s$   g | ]}t  gjR  |qS r   )r   r)   coeff_monomial)r   r,   )cr'   r   r   r      r(   z>DixonResultant.get_dixon_matrix.<locals>.<listcomp>.<listcomp>r   r%   )	monomialsr'   )r\   r   r      s
    
z3DixonResultant.get_dixon_matrix.<locals>.<listcomp>r   r8   c                    s.   g | ]}t d d  dd|f D r|qS )c                 s   s    | ]}|d kV  qdS r   Nr   )r   elementr   r   r   r"          z=DixonResultant.get_dixon_matrix.<locals>.<listcomp>.<genexpr>N)any)r   column)dixon_matrixr   r   r      s
    
N)	rV   r   r)   sortedr   r   rS   shaper-   )r'   rT   r7   keepr   )rc   r]   r'   r   get_dixon_matrix   s   

zDixonResultant.get_dixon_matrixc                    s    j rdS  j\}t  d   fddt|D } |ddf  tdgd  dg g} dddf |kr?dS dS )	a  
        Test for the validity of the Kapur-Saxena-Yang precondition.

        The precondition requires that the column corresponding to the
        monomial 1 = x_1 ^ 0 * x_2 ^ 0 * ... * x_n ^ 0 is not a linear
        combination of the remaining ones. In SymPy notation this is
        the last column. For the precondition to hold the last non-zero
        row of the rref matrix should be of the form [0, 0, ..., 1].
        Fr   c                    s,   g | ] t  fd dtD r qS )c                 3   s     | ]} |f d kV  qdS r^   r   r   j)r   matrixr   r   r"      s    z=DixonResultant.KSY_precondition.<locals>.<listcomp>.<genexpr>)ra   r-   r%   rk   r+   r!   r   r      s   , z3DixonResultant.KSY_precondition.<locals>.<listcomp>Nr8   rd   T)is_zero_matrixrf   r
   rrefr-   r   )r'   rk   r,   rE   	conditionr   rl   r   KSY_precondition   s   

zDixonResultant.KSY_preconditionc                    s<    fddt  jD } fddt  jD } ||f S )z/Remove the zero rows and columns of the matrix.c                       g | ]
}  |js|qS r   )rowrm   r   rk   r   r   r      
    z?DixonResultant.delete_zero_rows_and_columns.<locals>.<listcomp>c                    rq   r   )colrm   ri   rs   r   r   r      rt   )r-   rE   cols)r'   rk   rE   rv   r   rs   r   delete_zero_rows_and_columns   s   

z+DixonResultant.delete_zero_rows_and_columnsc                 C   s<   d}t |jD ]}||D ]}|dkr|| } nqq|S )z;Calculate the product of the leading entries of the matrix.r8   r   )r-   rE   rr   )r'   rk   resrr   elr   r   r   product_leading_entries   s   z&DixonResultant.product_leading_entriesc                 C   s0   |  |}| \}}}|  t|}| |S )z@Calculate the Kapur-Saxena-Yang approach to the Dixon Resultant.)rw   LUdecompositionr
   rz   )r'   rk   _Ur   r   r   get_KSY_Dixon_resultant   s   

z&DixonResultant.get_KSY_Dixon_resultantN)__name__
__module____qualname____doc__r1   propertyr7   rL   rQ   rV   rh   rp   rw   rz   r~   r   r   r   r   r      s    *

$	
r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )MacaulayResultanta-  
    A class for calculating the Macaulay resultant. Note that the
    polynomials must be homogenized and their coefficients must be
    given as symbols.

    Examples
    ========

    >>> from sympy import symbols

    >>> from sympy.polys.multivariate_resultants import MacaulayResultant
    >>> x, y, z = symbols('x, y, z')

    >>> a_0, a_1, a_2 = symbols('a_0, a_1, a_2')
    >>> b_0, b_1, b_2 = symbols('b_0, b_1, b_2')
    >>> c_0, c_1, c_2,c_3, c_4 = symbols('c_0, c_1, c_2, c_3, c_4')

    >>> f = a_0 * y -  a_1 * x + a_2 * z
    >>> g = b_1 * x ** 2 + b_0 * y ** 2 - b_2 * z ** 2
    >>> h = c_0 * y * z ** 2 - c_1 * x ** 3 + c_2 * x ** 2 * z - c_3 * x * z ** 2 + c_4 * z ** 3

    >>> mac = MacaulayResultant(polynomials=[f, g, h], variables=[x, y, z])
    >>> mac.monomial_set
    [x**4, x**3*y, x**3*z, x**2*y**2, x**2*y*z, x**2*z**2, x*y**3,
    x*y**2*z, x*y*z**2, x*z**3, y**4, y**3*z, y**2*z**2, y*z**3, z**4]
    >>> matrix = mac.get_matrix()
    >>> submatrix = mac.get_submatrix(matrix)
    >>> submatrix
    Matrix([
    [-a_1,  a_0,  a_2,    0],
    [   0, -a_1,    0,    0],
    [   0,    0, -a_1,    0],
    [   0,    0,    0, -a_1]])

    See Also
    ========

    Notebook in examples: sympy/example/notebooks.

    References
    ==========

    .. [1] [Bruce97]_
    .. [2] [Stiller96]_

    c                    sR   | _ | _t| _ fdd j D  _   _   _ 	 j _
dS )z
        Parameters
        ==========

        variables: list
            A list of all n variables
        polynomials : list of SymPy polynomials
            A  list of m n-degree polynomials
        c                    s   g | ]}t |g jR  qS r   )r   r)   r   r&   r   r   r   :      z.MacaulayResultant.__init__.<locals>.<listcomp>N)r$   r)   r*   r+   degrees_get_degree_mdegree_mget_sizemonomials_sizeget_monomials_of_certain_degreemonomial_setr0   r   r&   r   r1   +  s   




zMacaulayResultant.__init__c                 C   s   dt dd | jD  S )z
        Returns
        =======

        degree_m: int
            The degree_m is calculated as  1 + \sum_1 ^ n (d_i - 1),
            where d_i is the degree of the i polynomial
        r8   c                 s   s    | ]}|d  V  qdS )r8   Nr   )r   dr   r   r   r"   L  r`   z2MacaulayResultant._get_degree_m.<locals>.<genexpr>)sumr   r&   r   r   r   r   C  s   	zMacaulayResultant._get_degree_mc                 C   s   t | j| j d | jd S )z
        Returns
        =======

        size: int
            The size of set T. Set T is the set of all possible
            monomials of the n variables for degree equal to the
            degree_m
        r8   )r   r   r+   r&   r   r   r   r   N  s   
zMacaulayResultant.get_sizec                 C   s,   dd t | j|D }t|dtd| jdS )zw
        Returns
        =======

        monomials: list
            A list of monomials of a certain degree.
        c                 S   s   g | ]}t | qS r   r   )r   monomialr   r   r   r   b  r   zEMacaulayResultant.get_monomials_of_certain_degree.<locals>.<listcomp>TrW   rX   )r   r)   re   r   )r'   degreer]   r   r   r   r   Z  s   
z1MacaulayResultant.get_monomials_of_certain_degreec                    s   g }g }t | jD ]V}|dkr"| j| j|  }| |}|| q	|| j|d  | j|d    | j| j|  }| |}|D ]}|D ] t |dkrX fdd|D }qFqB|| q	|S )z
        Returns
        =======

        row_coefficients: list
            The row coefficients of Macaulay's matrix
        r   r8   c                    s   g | ]}| kr|qS r   r   )r   itempr   r   r     s    z:MacaulayResultant.get_row_coefficients.<locals>.<listcomp>)r-   r+   r   r   r   rB   r)   r	   )r'   row_coefficients	divisibler   r   r   	poss_rowsdivr   r   r   get_row_coefficientsi  s(   

z&MacaulayResultant.get_row_coefficientsc           	      C   s|   g }|   }t| jD ],}|| D ]%}g }t| j| | g| jR  }| jD ]
}||| q&|| qqt	|}|S )zt
        Returns
        =======

        macaulay_matrix: Matrix
            The Macaulay numerator matrix
        )
r   r-   r+   r   r$   r)   r   rB   r[   r   )	r'   rE   r   r   
multipliercoefficientsr    monomacaulay_matrixr   r   r   
get_matrix  s   
	zMacaulayResultant.get_matrixc                    s   g } j D ]"}g }t jD ]\}}|tt|| j| k q|| q fddt|D } fddt|D }||fS )a  
        Returns
        =======

        reduced: list
            A list of the reduced monomials
        non_reduced: list
            A list of the monomials that are not reduced

        Definition
        ==========

        A polynomial is said to be reduced in x_i, if its degree (the
        maximum degree of its monomials) in x_i is less than d_i. A
        polynomial that is reduced in all variables but one is said
        simply to be reduced.
        c                    s&   g | ]\}}t | jd  k r|qS r8   r   r+   r   r   rr&   r   r   r         z<MacaulayResultant.get_reduced_nonreduced.<locals>.<listcomp>c                    s&   g | ]\}}t | jd  kr|qS r   r   r   r&   r   r   r     r   )r   	enumerater)   rB   boolr   r   )r'   r   r,   rF   r   vreducednon_reducedr   r&   r   get_reduced_nonreduced  s   
 z(MacaulayResultant.get_reduced_nonreducedc                    s     \}}|g krtdgS fddtjD fddtjD }|dd|f  g }t jD ] fdd|D }d|vrL| q7|||f S )a  
        Returns
        =======

        macaulay_submatrix: Matrix
            The Macaulay denominator matrix. Columns that are non reduced are kept.
            The row which contains one of the a_{i}s is dropped. a_{i}s
            are the coefficients of x_i ^ {d_i}.
        r8   c                    s   g | ]\}}| j |  qS r   )r   )r   r   r   r&   r   r   r     r   z3MacaulayResultant.get_submatrix.<locals>.<listcomp>c                    s    g | ]}j |  | qS r   )r$   coeffr   )reduction_setr'   r   r   r     rM   Nc                    s    g | ]}| d d f v qS r   r   )r   ai)reduced_matrixrr   r   r   r     s     T)r   r   r   r)   r-   r+   rE   rB   )r'   rk   r   r   aisrg   checkr   )r   r   rr   r'   r   get_submatrix  s"   



zMacaulayResultant.get_submatrixN)r   r   r   r   r1   r   r   r   r   r   r   r   r   r   r   r   r      s    .r   N)r   mathr   sympy.core.mulr   sympy.matrices.denser   r   sympy.polys.polytoolsr   r   r	   sympy.simplify.simplifyr
   sympy.tensor.indexedr   sympy.polys.monomialsr   r   sympy.polys.orderingsr   r   r   (sympy.functions.combinatorial.factorialsr   	itertoolsr   sympy.utilities.exceptionsr   r   r   r   r   r   r   <module>   s     
 d