U
    ZÊ¹j�;  ã                   @   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   úb/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/polys/multivariate_resultants.pyÚ
<listcomp>X   s     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   [   s   ÿ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©Zdeprecated_since_versionZ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 ƒ¡ q4t|ƒ}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©Z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   ZdetÚfactorr   )r&   ÚrowsÚtempÚidxÚAZtermsZproduct_of_differencesZdixon_polynomialr   r7   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.
            r0   r1   r2   c                    s    g | ]}ˆ j | ˆ j|  ‘qS r   )r'   r-   r   r%   r   r   r   –   s   ÿz3DixonResultant.get_upper_degree.<locals>.<listcomp>)r   r+   r)   r   r   Zmonomsr   )r&   Z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   Zdegsr   r   r   r   ¦   s     )Úcoeffsr<   )r&   Ú
polynomialZ	deg_listsr3   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rˆ‡ 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 ˆ fˆjžŽ  |¡‘qS r   )r   r'   Úcoeff_monomial)r   r*   )Úcr&   r   r   r   ¸   s   ÿz>DixonResultant.get_dixon_matrix.<locals>.<listcomp>.<listcomp>r   r$   )Ú	monomialsr&   )rN   r   r   ¸   s   þÿz3DixonResultant.get_dixon_matrix.<locals>.<listcomp>r   r4   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!   ¿   s     z=DixonResultant.get_dixon_matrix.<locals>.<listcomp>.<genexpr>N)Úany)r   Úcolumn)Údixon_matrixr   r   r   ¾   s
    ÿÿéÿÿÿÿN)	rH   r   r'   Úsortedr   r   rF   Úshaper+   )r&   rG   r3   Úkeepr   )rT   rO   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 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 rP   r   ©r   Új)r   Úmatrixr   r   r!   ×   s     z=DixonResultant.KSY_precondition.<locals>.<listcomp>.<genexpr>)rR   r+   r$   ©r\   r)   r    r   r   ×   s      z3DixonResultant.KSY_precondition.<locals>.<listcomp>Nr4   rU   T)Úis_zero_matrixrW   r
   Zrrefr+   r   )r&   r\   r*   r?   Ú	conditionr   r]   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                    s   g | ]}ˆ   |¡js|‘qS r   )Úrowr^   r   ©r\   r   r   r   ã   s     z?DixonResultant.delete_zero_rows_and_columns.<locals>.<listcomp>c                    s   g | ]}ˆ   |¡js|‘qS r   )Úcolr^   rZ   rb   r   r   r   å   s     )r+   r?   Úcols)r&   r\   r?   rd   r   rb   r   Údelete_zero_rows_and_columnsá   s    
ÿ
ÿz+DixonResultant.delete_zero_rows_and_columnsc                 C   s<   d}t |jƒD ](}| |¡D ]}|dkr|| } qqq|S )z;Calculate the product of the leading entries of the matrix.r4   r   )r+   r?   ra   )r&   r\   Úresra   Ú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.)re   ZLUdecompositionr
   rh   )r&   r\   Ú_ÚUr   r   r   Úget_KSY_Dixon_resultantô   s    
z&DixonResultant.get_KSY_Dixon_resultantN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   Úpropertyr3   rC   rE   rH   rY   r`   re   rh   rk   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 |fˆ jžŽ ‘qS r   )r   r'   r   r%   r   r   r   :  s     z.MacaulayResultant.__init__.<locals>.<listcomp>N)r#   r'   r(   r)   ÚdegreesÚ_get_degree_mÚdegree_mÚget_sizeZmonomials_sizeÚget_monomials_of_certain_degreeÚmonomial_setr.   r   r%   r   r/   +  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
        r4   c                 s   s   | ]}|d  V  qdS )r4   Nr   )r   Údr   r   r   r!   L  s     z2MacaulayResultant._get_degree_m.<locals>.<genexpr>)Úsumrr   r%   r   r   r   rs   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
        r4   )r   rt   r)   r%   r   r   r   ru   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  s     zEMacaulayResultant.get_monomials_of_certain_degree.<locals>.<listcomp>TrI   rJ   )r   r'   rV   r   )r&   ÚdegreerO   r   r   r   rv   Z  s    ÿÿ
ÿz1MacaulayResultant.get_monomials_of_certain_degreec                    sÄ   g }g }t | jƒD ]¬}|dkrD| j| j|  }|  |¡}| |¡ q| | j|d  | j|d   ¡ | j| j|  }|  |¡}|D ].}|D ]$‰ tˆ |ƒdkrŒ‡ fdd„|D ƒ}qŒq„| |¡ q|S )z
        Returns
        =======

        row_coefficients: list
            The row coefficients of Macaulay's matrix
        r   r4   c                    s   g | ]}|ˆ kr|‘qS r   r   )r   Úitem©Úpr   r   r   €  s    ÿz:MacaulayResultant.get_row_coefficients.<locals>.<listcomp>)r+   r)   rt   rr   rv   r=   r'   r	   )r&   Úrow_coefficientsÚ	divisibler   r{   rz   Z	poss_rowsÚdivr   r}   r   Úget_row_coefficientsi  s$    
ÿ
z&MacaulayResultant.get_row_coefficientsc           	      C   sz   g }|   ¡ }t| jƒD ]V}|| D ]H}g }t| j| | f| jžŽ }| jD ]}| | |¡¡ qJ| |¡ q"qt	|ƒ}|S )zt
        Returns
        =======

        macaulay_matrix: Matrix
            The Macaulay numerator matrix
        )
r‚   r+   r)   r   r#   r'   rw   r=   rM   r   )	r&   r?   r   r   Z
multiplierZcoefficientsr   ÚmonoZmacaulay_matrixr   r   r   Ú
get_matrix…  s    ÿ
zMacaulayResultant.get_matrixc                    s„   g }ˆ j D ]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 ©r4   ©ry   r)   ©r   r   Úrr%   r   r   r   ´  s    ÿz<MacaulayResultant.get_reduced_nonreduced.<locals>.<listcomp>c                    s&   g | ]\}}t |ƒˆ jd  kr|‘qS r…   r†   r‡   r%   r   r   r   ¶  s    ÿ)rw   Ú	enumerater'   r=   Úboolr   rr   )r&   r€   r*   r@   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|krn| ˆ¡ qn|||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}.
        r4   c                    s   g | ]\}}|ˆ j |  ‘qS r   )rr   )r   r   r‹   r%   r   r   r   Ì  s     z3MacaulayResultant.get_submatrix.<locals>.<listcomp>c                    s    g | ]}ˆj |  ˆ | ¡‘qS r   )r#   Zcoeffr   )Úreduction_setr&   r   r   r   Ï  s   ÿNc                    s    g | ]}|ˆ ˆd d …f k‘qS r   r   )r   Zai)Úreduced_matrixra   r   r   r   Õ  s     T)rŽ   r   r‰   r'   r+   r)   r?   r=   )r&   r\   rŒ   r�   ZaisrX   Úcheckr   )r�   r�   ra   r&   r   Úget_submatrix»  s     


ÿÿzMacaulayResultant.get_submatrixN)rl   rm   rn   ro   r/   rs   ru   rv   r‚   r„   rŽ   r’   r   r   r   r   rq   ü   s   .rq   N)ro   Úmathr   Zsympy.core.mulr   Zsympy.matrices.denser   r   Zsympy.polys.polytoolsr   r   r	   Zsympy.simplify.simplifyr
   Zsympy.tensor.indexedr   Zsympy.polys.monomialsr   r   Zsympy.polys.orderingsr   r   r   Z(sympy.functions.combinatorial.factorialsr   Ú	itertoolsr   Zsympy.utilities.exceptionsr   r   rq   r   r   r   r   Ú<module>   s   
 d