B
    [9.                 @   s   d Z ddlmZmZmZmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZ ddlmZ ddl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.
    )IndexedBaseMatrixMulPoly)remprodfractiontotal_degree)range)monomial_deg)itermonomials)monomial_key)poly_from_expr)binomial)combinations_with_replacementc               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )DixonResultanta?  
    A class for retrieving the Dixon's resultant of a multivariate
    system.

    Examples
    ========
    >>> from sympy.core 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

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

    See Also
    ========
    Notebook in examples: sympy/example/notebooks.
    c                s`   |_ |_tj_tj _td  fddtjD _fdd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
        Zalphac                s   g | ]} | qS  r   ).0i)ar   Blib/python3.7/site-packages/sympy/polys/multivariate_resultants.py
<listcomp>R   s    z+DixonResultant.__init__.<locals>.<listcomp>c                s   g | ]}t |f j qS r   )r	   	variables)r   poly)selfr   r   r   U   s    N)	polynomialsr   lennmr   r
   dummy_variablesmax_degrees)r   r   r   r   )r   r   r   __init__>   s    
zDixonResultant.__init__c                s   | j | jd krtd| jg}t| j}xPt| jD ]B}| j| ||< dd t| j|D  |	 fdd| jD  q6W 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   s   i | ]\}}||qS r   r   )r   vartr   r   r   
<dictcomp>q   s    z7DixonResultant.get_dixon_polynomial.<locals>.<dictcomp>c                s   g | ]}|  qS r   )Zsubs)r   f)substitutionr   r   r   r   s    z7DixonResultant.get_dixon_polynomial.<locals>.<listcomp>c             S   s   g | ]\}}|| qS r   r   )r   r   br   r   r   r   w   s    r   )r   r   
ValueErrorr   listr   r
   r   zipappendr   r   ZdetZfactorr   )r   rowstempidxAZtermsZproduct_of_differencesZdixon_polynomialr   )r'   r   get_dixon_polynomialX   s    
z#DixonResultant.get_dixon_polynomialc                s4    fddt  jD }t|}t| }t| S )Nc                s,   g | ]$} j | |d   j|  d   qS )r"   )r   r    )r   r   )r   r   r   r   }   s   z3DixonResultant.get_upper_degree.<locals>.<listcomp>)r
   r   r   r   Zmonomsr   )r   Zlist_of_productsproductr   )r   r   get_upper_degree|   s
    
zDixonResultant.get_upper_degreec                sv   |  }ttj tdtdjdtfdd|D   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   )r8   r   r      s   z3DixonResultant.get_dixon_matrix.<locals>.<listcomp>c                s.   g | ]&}t d d  dd|f D r|qS )c             S   s   g | ]}|d kqS )r   r   )r   elementr   r   r   r      s    z>DixonResultant.get_dixon_matrix.<locals>.<listcomp>.<listcomp>N)any)r   column)dixon_matrixr   r   r      s    N)
Zcoeffsr*   r   r   r3   sortedr   r   r
   shape)r   Z
polynomialcoefficientskeepr   )r=   r9   r   r   get_dixon_matrix   s    	
zDixonResultant.get_dixon_matrixN)__name__
__module____qualname____doc__r!   r1   r3   rC   r   r   r   r   r      s
   %$r   c               @   sX   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d ZdS )MacaulayResultanta~  
    A class for calculating the Macaulay resultant. Note that the
    coefficients of the polynomials must be given as symbols.

    Examples
    ========
    >>> from sympy.core 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 - 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.get_monomials_set()
    >>> 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]])

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

    See Also
    ========
    Notebook in examples: sympy/example/notebooks.
    c                sD   | _ | _t| _ fdd j D  _   _   _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   r      s    z.MacaulayResultant.__init__.<locals>.<listcomp>N)	r   r   r   r   degrees_get_degree_mdegree_mget_sizeZmonomials_size)r   r   r   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
        r"   c             s   s   | ]}|d  V  qdS )r"   Nr   )r   dr   r   r   	<genexpr>   s    z2MacaulayResultant._get_degree_m.<locals>.<genexpr>)sumrI   )r   r   r   r   rJ      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
        r"   )r   rK   r   )r   r   r   r   rL      s    	zMacaulayResultant.get_sizec             C   s,   dd t | j|D }t|dtd| jdS )zv
        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      s    zEMacaulayResultant.get_monomials_of_certain_degree.<locals>.<listcomp>Tr4   )r5   r6   )r   r   r?   r   )r   degreer9   r   r   r   get_monomials_of_certain_degree   s
    
z1MacaulayResultant.get_monomials_of_certain_degreec             C   s   |  | j}|| _dS )z
        Returns
        -------
        self.monomial_set: set
            The set T. Set of all possible monomials of degree degree_m
        N)rR   rK   monomial_set)r   rS   r   r   r   get_monomials_set   s    z#MacaulayResultant.get_monomials_setc                s   g }g }xt | jD ]}|dkrF| j| j|  }| |}|| q|| j|d  | j|d    | j| j|  }| |}x:|D ]2}x,|D ]$ t |dkr fdd|D }qW qW || qW |S )z~
        Returns
        -------
        row_coefficients: list
            The row coefficients of Macaulay's matrix
        r   r"   c                s   g | ]}| kr|qS r   r   )r   item)pr   r   r     s    z:MacaulayResultant.get_row_coefficients.<locals>.<listcomp>)r
   r   rK   rI   rR   r,   r   r   )r   row_coefficients	divisibler   rQ   rP   Z	poss_rowsZdivr   )rV   r   get_row_coefficients  s"    



z&MacaulayResultant.get_row_coefficientsc       	      C   s   g }|   }xlt| jD ]^}xX|| D ]L}g }t| j| | f| j }x| jD ]}||| qPW || q&W qW t	|}|S )zk
        Returns
        -------
        macaulay_matrix: Matrix
            The Macaulay's matrix
        )
rY   r
   r   r   r   r   rS   r,   r7   r   )	r   r-   rW   r   Z
multiplierrA   r   ZmonoZmacaulay_matrixr   r   r   
get_matrix!  s    
zMacaulayResultant.get_matrixc                s   g }xR j D ]H}g }x4t jD ]&\}}|tt|| j| k q W || qW  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 )r"   )rO   r   )r   r   r)r   r   r   r   M  s    z<MacaulayResultant.get_reduced_nonreduced.<locals>.<listcomp>c                s&   g | ]\}}t | jd  kr|qS )r"   )rO   r   )r   r   r[   )r   r   r   r   O  s    )rS   	enumerater   r,   boolr	   rI   )r   rX   r   r.   r   vreducednon_reducedr   )r   r   get_reduced_nonreduced7  s    "z(MacaulayResultant.get_reduced_nonreducedc                s     \}}fddtjD tfddtjD }|dd|f  g }x8t jD ]* fdd|D }d|krb| qbW |||f S )a  
        Returns
        -------
        macaulay_submatrix: Matrix
            The Macaulay's matrix. Columns that are non reduced are kept.
            The row which contain one if the a_{i}s is dropped. a_{i}s
            are the coefficients of x_i ^ {d_i}.
        c                s   g | ]\}}| j |  qS r   )rI   )r   r   r^   )r   r   r   r   _  s    z3MacaulayResultant.get_submatrix.<locals>.<listcomp>c                s    g | ]}j |  | qS r   )r   Zcoeff)r   r   )reduction_setr   r   r   r   b  s   Nc                s    g | ]}| d d f kqS )Nr   )r   Zai)reduced_matrixrowr   r   r   h  s    T)ra   r\   r   r*   r
   r   r-   r,   )r   Zmatrixr_   r`   ZaisrB   Zcheckr   )rc   rb   rd   r   r   get_submatrixT  s    	
zMacaulayResultant.get_submatrixN)rD   rE   rF   rG   r!   rJ   rL   rR   rT   rY   rZ   ra   re   r   r   r   r   rH      s   '

rH   N)rG   Zsympyr   r   r   r   r   r   r   r	   Zsympy.core.compatibilityr
   Zsympy.polys.monomialsr   r   Zsympy.polys.orderingsr   Zsympy.polys.polytoolsr   Z(sympy.functions.combinatorial.factorialsr   	itertoolsr   r   rH   r   r   r   r   <module>
   s    