B
    [                 @   s  d Z ddl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 ddlZd	d
 Zdd Ze ZZe Z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d  Zd!d" Z d#d$ Z!d%d& Z"dd'd(Z#d)d* Z$d+d, Z%d-d. Z&d/d0 Z'd1d2 Z(d3d4 Z)d5d6 Z*d7d8 Z+d9d: Z,d;d< Z-d=d> Z.d?d@ Z/dAdB Z0dCdD Z1dEdF Z2dGdH Z3dIdJ Z4dKdL Z5dMdN Z6dOdP Z7dQdR Z8dSdT Z9dUdV Z:dWdX Z;dYdZ Z<d[d\ Z=d]d^ Z>dd`daZ?ddbdcZ@ddddeZAdfdg ZBdhdi ZCdjdk ZDdldm ZEdndo ZFdpdq ZGdrds ZHdtdu ZIdvdw ZJdxdy ZKdzd{ ZLd|d} ZMd~d ZNdddZOdddZPdd ZQdd ZRdd ZSdddZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdS )zEBasic tools for dense recursive polynomials in ``K[x]`` or ``K[X]``.     )print_functiondivision)igcd)oo)monomial_minmonomial_div)monomial_key)rangeNc             C   s   | s
|j S | d S dS )z
    Return leading coefficient of ``f``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import poly_LC

    >>> poly_LC([], ZZ)
    0
    >>> poly_LC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
    1

    r   N)zero)fK r   5lib/python3.7/site-packages/sympy/polys/densebasic.pypoly_LC   s    r   c             C   s   | s
|j S | d S dS )z
    Return trailing coefficient of ``f``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import poly_TC

    >>> poly_TC([], ZZ)
    0
    >>> poly_TC([ZZ(1), ZZ(2), ZZ(3)], ZZ)
    3

    N)r
   )r   r   r   r   r   poly_TC$   s    r   c             C   s&   x|rt | |} |d8 }qW t| |S )z
    Return the ground leading coefficient.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_ground_LC

    >>> f = ZZ.map([[[1], [2, 3]]])

    >>> dmp_ground_LC(f, 2, ZZ)
    1

       )dmp_LCdup_LC)r   ur   r   r   r   dmp_ground_LC=   s    
r   c             C   s&   x|rt | |} |d8 }qW t| |S )z
    Return the ground trailing coefficient.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_ground_TC

    >>> f = ZZ.map([[[1], [2, 3]]])

    >>> dmp_ground_TC(f, 2, ZZ)
    3

    r   )dmp_TCdup_TC)r   r   r   r   r   r   dmp_ground_TCT   s    
r   c             C   sf   g }x,|r0| t| d  | d |d  } }qW | sB| d n| t| d  t|t| |fS )a  
    Return the leading term ``c * x_1**n_1 ... x_k**n_k``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_true_LT

    >>> f = ZZ.map([[4], [2, 0], [3, 0, 0]])

    >>> dmp_true_LT(f, 1, ZZ)
    ((2, 0), 4)

    r   r   )appendlentupler   )r   r   r   monomr   r   r   dmp_true_LTk   s    r   c             C   s   | s
t  S t| d S )aB  
    Return the leading degree of ``f`` in ``K[x]``.

    Note that the degree of 0 is negative infinity (the SymPy object -oo).

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_degree

    >>> f = ZZ.map([1, 2, 0, 3])

    >>> dup_degree(f)
    3

    r   )r   r   )r   r   r   r   
dup_degree   s    r   c             C   s    t | |rt S t| d S dS )a{  
    Return the leading degree of ``f`` in ``x_0`` in ``K[X]``.

    Note that the degree of 0 is negative infinity (the SymPy object -oo).

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_degree

    >>> dmp_degree([[[]]], 2)
    -oo

    >>> f = ZZ.map([[2], [1, 2, 3]])

    >>> dmp_degree(f, 1)
    1

    r   N)
dmp_zero_pr   r   )r   r   r   r   r   
dmp_degree   s    
r!   c                s>    krt | S d  d   t fdd| D S )z4Recursive helper function for :func:`dmp_degree_in`.r   c                s   g | ]}t | qS r   )_rec_degree_in).0c)ijvr   r   
<listcomp>   s    z"_rec_degree_in.<locals>.<listcomp>)r!   max)gr'   r%   r&   r   )r%   r&   r'   r   r"      s    
r"   c             C   s<   |st | |S |dk s||kr.td||f t| |d|S )a6  
    Return the leading degree of ``f`` in ``x_j`` in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_degree_in

    >>> f = ZZ.map([[2], [1, 2, 3]])

    >>> dmp_degree_in(f, 0, 1)
    1
    >>> dmp_degree_in(f, 1, 1)
    2

    r   z0 <= j <= %s expected, got %s)r!   
IndexErrorr"   )r   r&   r   r   r   r   dmp_degree_in   s
    
r,   c             C   sR   t || t| |||< |dkrN|d |d  }}x| D ]}t|||| q8W dS )z-Recursive helper for :func:`dmp_degree_list`.r   r   N)r)   r!   _rec_degree_list)r*   r'   r%   degsr$   r   r   r   r-      s
    
r-   c             C   s&   t  g|d  }t| |d| t|S )a  
    Return a list of degrees of ``f`` in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_degree_list

    >>> f = ZZ.map([[1], [1, 2, 3]])

    >>> dmp_degree_list(f, 1)
    (1, 2)

    r   r   )r   r-   r   )r   r   r.   r   r   r   dmp_degree_list   s    r/   c             C   s>   | r| d r| S d}x| D ]}|r&P q|d7 }qW | |d S )z
    Remove leading zeros from ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dup_strip

    >>> dup_strip([0, 0, 1, 2, 3, 0])
    [1, 2, 3, 0]

    r   r   Nr   )r   r%   Zcfr   r   r   	dup_strip   s    
r0   c             C   sp   |st | S t| |r| S d|d  }}x"| D ]}t||s@P q.|d7 }q.W |t| kr`t|S | |d S dS )z
    Remove leading zeros from ``f`` in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_strip

    >>> dmp_strip([[], [0, 1, 2], [1]], 1)
    [[0, 1, 2], [1]]

    r   r   N)r0   r    r   dmp_zero)r   r   r%   r'   r$   r   r   r   	dmp_strip  s    


r2   c             C   s   t |tk	r@|dk	r2||s2td|| |jf t|d gS |sNt|gS |d tg  }}x"|D ]}|t| ||d |O }qfW |S dS )z*Recursive helper for :func:`dmp_validate`.Nz%s in %s in not of type %sr   )typelistZof_type	TypeErrorZdtypeset_rec_validate)r   r*   r%   r   r&   levelsr$   r   r   r   r7   ;  s    

r7   c                s,   |st | S |d  t fdd| D |S )z(Recursive helper for :func:`_rec_strip`.r   c                s   g | ]}t | qS r   )
_rec_strip)r#   r$   )wr   r   r(   T  s    z_rec_strip.<locals>.<listcomp>)r0   r2   )r*   r'   r   )r:   r   r9   M  s    r9   c             C   s4   t | | d|}| }|s(t| ||fS tddS )at  
    Return the number of levels in ``f`` and recursively strip it.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_validate

    >>> dmp_validate([[], [0, 1, 2], [1]])
    ([[1, 2], [1]], 1)

    >>> dmp_validate([[1], 1])
    Traceback (most recent call last):
    ...
    ValueError: invalid data structure for a multivariate polynomial

    r   z4invalid data structure for a multivariate polynomialN)r7   popr9   
ValueError)r   r   r8   r   r   r   r   dmp_validateW  s    r=   c             C   s   t tt| S )a  
    Compute ``x**n * f(1/x)``, i.e.: reverse ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_reverse

    >>> f = ZZ.map([1, 2, 3, 0])

    >>> dup_reverse(f)
    [3, 2, 1]

    )r0   r4   reversed)r   r   r   r   dup_reverset  s    r?   c             C   s   t | S )a  
    Create a new copy of a polynomial ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_copy

    >>> f = ZZ.map([1, 2, 3, 0])

    >>> dup_copy([1, 2, 3, 0])
    [1, 2, 3, 0]

    )r4   )r   r   r   r   dup_copy  s    r@   c                s&   |st | S |d   fdd| D S )a  
    Create a new copy of a polynomial ``f`` in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_copy

    >>> f = ZZ.map([[1], [1, 2]])

    >>> dmp_copy(f, 1)
    [[1], [1, 2]]

    r   c                s   g | ]}t | qS r   )dmp_copy)r#   r$   )r'   r   r   r(     s    zdmp_copy.<locals>.<listcomp>)r4   )r   r   r   )r'   r   rA     s    rA   c             C   s   t | S )a2  
    Convert `f` into a tuple.

    This is needed for hashing. This is similar to dup_copy().

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_copy

    >>> f = ZZ.map([1, 2, 3, 0])

    >>> dup_copy([1, 2, 3, 0])
    [1, 2, 3, 0]

    )r   )r   r   r   r   dup_to_tuple  s    rB   c                s*   |st | S |d  t  fdd| D S )aG  
    Convert `f` into a nested tuple of tuples.

    This is needed for hashing.  This is similar to dmp_copy().

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_to_tuple

    >>> f = ZZ.map([[1], [1, 2]])

    >>> dmp_to_tuple(f, 1)
    ((1,), (1, 2))

    r   c             3   s   | ]}t | V  qd S )N)dmp_to_tuple)r#   r$   )r'   r   r   	<genexpr>  s    zdmp_to_tuple.<locals>.<genexpr>)r   )r   r   r   )r'   r   rC     s    rC   c                s   t  fdd| D S )z
    Normalize univariate polynomial in the given domain.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_normal

    >>> dup_normal([0, 1.5, 2, 3], ZZ)
    [1, 2, 3]

    c                s   g | ]}  |qS r   )Znormal)r#   r$   )r   r   r   r(     s    zdup_normal.<locals>.<listcomp>)r0   )r   r   r   )r   r   
dup_normal  s    rE   c                s0   |st |  S |d t fdd| D |S )z
    Normalize a multivariate polynomial in the given domain.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_normal

    >>> dmp_normal([[], [0, 1.5, 2]], 1, ZZ)
    [[1, 2]]

    r   c                s   g | ]}t | qS r   )
dmp_normal)r#   r$   )r   r'   r   r   r(     s    zdmp_normal.<locals>.<listcomp>)rE   r2   )r   r   r   r   )r   r'   r   rF     s    
rF   c                s0    dk	r kr| S t  fdd| D S dS )a  
    Convert the ground domain of ``f`` from ``K0`` to ``K1``.

    Examples
    ========

    >>> from sympy.polys.rings import ring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_convert

    >>> R, x = ring("x", ZZ)

    >>> dup_convert([R(1), R(2)], R.to_domain(), ZZ)
    [1, 2]
    >>> dup_convert([ZZ(1), ZZ(2)], ZZ, R.to_domain())
    [1, 2]

    Nc                s   g | ]} | qS r   )convert)r#   r$   )K0K1r   r   r(     s    zdup_convert.<locals>.<listcomp>)r0   )r   rH   rI   r   )rH   rI   r   dup_convert  s    rJ   c                sH   |st |  S  dk	r$ kr$| S |d t fdd| D |S )a  
    Convert the ground domain of ``f`` from ``K0`` to ``K1``.

    Examples
    ========

    >>> from sympy.polys.rings import ring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_convert

    >>> R, x = ring("x", ZZ)

    >>> dmp_convert([[R(1)], [R(2)]], 1, R.to_domain(), ZZ)
    [[1], [2]]
    >>> dmp_convert([[ZZ(1)], [ZZ(2)]], 1, ZZ, R.to_domain())
    [[1], [2]]

    Nr   c                s   g | ]}t | qS r   )dmp_convert)r#   r$   )rH   rI   r'   r   r   r(   :  s    zdmp_convert.<locals>.<listcomp>)rJ   r2   )r   r   rH   rI   r   )rH   rI   r'   r   rK      s    rK   c                s   t  fdd| D S )a$  
    Convert the ground domain of ``f`` from SymPy to ``K``.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_from_sympy

    >>> dup_from_sympy([S(1), S(2)], ZZ) == [ZZ(1), ZZ(2)]
    True

    c                s   g | ]}  |qS r   )Z
from_sympy)r#   r$   )r   r   r   r(   L  s    z"dup_from_sympy.<locals>.<listcomp>)r0   )r   r   r   )r   r   dup_from_sympy=  s    rL   c                s0   |st |  S |d t fdd| D |S )a/  
    Convert the ground domain of ``f`` from SymPy to ``K``.

    Examples
    ========

    >>> from sympy import S
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_from_sympy

    >>> dmp_from_sympy([[S(1)], [S(2)]], 1, ZZ) == [[ZZ(1)], [ZZ(2)]]
    True

    r   c                s   g | ]}t | qS r   )dmp_from_sympy)r#   r$   )r   r'   r   r   r(   c  s    z"dmp_from_sympy.<locals>.<listcomp>)rL   r2   )r   r   r   r   )r   r'   r   rM   O  s    
rM   c             C   s<   |dk rt d| n"|t| kr(|jS | t| |  S dS )a  
    Return the ``n``-th coefficient of ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_nth

    >>> f = ZZ.map([1, 2, 3])

    >>> dup_nth(f, 0, ZZ)
    3
    >>> dup_nth(f, 4, ZZ)
    0

    r   z 'n' must be non-negative, got %iN)r+   r   r
   r   )r   nr   r   r   r   dup_nthf  s
    rO   c             C   sD   |dk rt d| n*|t| kr.t|d S | t| ||  S dS )a)  
    Return the ``n``-th coefficient of ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_nth

    >>> f = ZZ.map([[1], [2], [3]])

    >>> dmp_nth(f, 0, 1, ZZ)
    [3]
    >>> dmp_nth(f, 4, 1, ZZ)
    []

    r   z 'n' must be non-negative, got %ir   N)r+   r   r1   r!   )r   rN   r   r   r   r   r   dmp_nth  s
    rP   c             C   sl   |}xb|D ]Z}|dk r$t d| q
|t| kr6|jS t| |}|t krNd}| ||  |d  } }q
W | S )a  
    Return the ground ``n``-th coefficient of ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_ground_nth

    >>> f = ZZ.map([[1], [2, 3]])

    >>> dmp_ground_nth(f, (0, 1), 1, ZZ)
    2

    r   z `n` must be non-negative, got %ir   r   )r+   r   r
   r!   r   )r   Nr   r   r'   rN   dr   r   r   dmp_ground_nth  s    


rS   c             C   s0   x(|r(t | dkrdS | d } |d8 }qW |  S )z
    Return ``True`` if ``f`` is zero in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_zero_p

    >>> dmp_zero_p([[[[[]]]]], 4)
    True
    >>> dmp_zero_p([[[[[1]]]]], 4)
    False

    r   Fr   )r   )r   r   r   r   r   r      s    r    c             C   s    g }xt | D ]
}|g}qW |S )z
    Return a multivariate zero.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_zero

    >>> dmp_zero(4)
    [[[[[]]]]]

    )r	   )r   rr%   r   r   r   r1     s    
r1   c             C   s   t | |j|S )z
    Return ``True`` if ``f`` is one in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_one_p

    >>> dmp_one_p([[[ZZ(1)]]], 2, ZZ)
    True

    )dmp_ground_pone)r   r   r   r   r   r   	dmp_one_p  s    rW   c             C   s   t |j| S )z
    Return a multivariate one over ``K``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_one

    >>> dmp_one(2, ZZ)
    [[[1]]]

    )
dmp_groundrV   )r   r   r   r   r   dmp_one  s    rY   c             C   sb   |dk	r|st | |S x(|r>t| dkr,dS | d } |d8 }qW |dkrTt| dkS | |gkS dS )z
    Return True if ``f`` is constant in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_ground_p

    >>> dmp_ground_p([[[3]]], 3, 2)
    True
    >>> dmp_ground_p([[[4]]], None, 2)
    True

    Nr   Fr   )r    r   )r   r$   r   r   r   r   rU   
  s    
rU   c             C   s,   | st |S xt|d D ]
}| g} qW | S )z
    Return a multivariate constant.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_ground

    >>> dmp_ground(3, 5)
    [[[[[[3]]]]]]
    >>> dmp_ground(1, -1)
    1

    r   )r1   r	   )r$   r   r%   r   r   r   rX   (  s
    
rX   c                s6   | sg S  dk r|j g|  S  fddt| D S dS )a  
    Return a list of multivariate zeros.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_zeros

    >>> dmp_zeros(3, 2, ZZ)
    [[[[]]], [[[]]], [[[]]]]
    >>> dmp_zeros(3, -1, ZZ)
    [0, 0, 0]

    r   c                s   g | ]}t  qS r   )r1   )r#   r%   )r   r   r   r(   V  s    zdmp_zeros.<locals>.<listcomp>N)r
   r	   )rN   r   r   r   )r   r   	dmp_zeros@  s
    rZ   c                s6   |sg S dk r g| S  fddt |D S dS )a#  
    Return a list of multivariate constants.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_grounds

    >>> dmp_grounds(ZZ(4), 3, 2)
    [[[[4]]], [[[4]]], [[[4]]]]
    >>> dmp_grounds(ZZ(4), 3, -1)
    [4, 4, 4]

    r   c                s   g | ]}t  qS r   )rX   )r#   r%   )r$   r   r   r   r(   o  s    zdmp_grounds.<locals>.<listcomp>N)r	   )r$   rN   r   r   )r$   r   r   dmp_groundsY  s
    
r[   c             C   s   | t| ||S )a/  
    Return ``True`` if ``LC(f)`` is negative.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_negative_p

    >>> dmp_negative_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
    False
    >>> dmp_negative_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
    True

    )Zis_negativer   )r   r   r   r   r   r   dmp_negative_pr  s    r\   c             C   s   | t| ||S )a/  
    Return ``True`` if ``LC(f)`` is positive.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_positive_p

    >>> dmp_positive_p([[ZZ(1)], [-ZZ(1)]], 1, ZZ)
    True
    >>> dmp_positive_p([[-ZZ(1)], [ZZ(1)]], 1, ZZ)
    False

    )Zis_positiver   )r   r   r   r   r   r   dmp_positive_p  s    r]   c             C   s   | sg S t |  g  }}t|tkrRx\t|ddD ]}|| ||j q4W n2|\}x*t|ddD ]}|| |f|j qfW t|S )a5  
    Create a ``K[x]`` polynomial from a ``dict``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_from_dict

    >>> dup_from_dict({(0,): ZZ(7), (2,): ZZ(5), (4,): ZZ(1)}, ZZ)
    [1, 0, 5, 0, 7]
    >>> dup_from_dict({}, ZZ)
    []

    r   )	r)   keysr3   intr	   r   getr
   r0   )r   r   rN   hkr   r   r   dup_from_dict  s    rc   c             C   sL   | sg S t |  g  }}x(t|ddD ]}|| ||j q(W t|S )a  
    Create a ``K[x]`` polynomial from a raw ``dict``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_from_raw_dict

    >>> dup_from_raw_dict({0: ZZ(7), 2: ZZ(5), 4: ZZ(1)}, ZZ)
    [1, 0, 5, 0, 7]

    r   )r)   r^   r	   r   r`   r
   r0   )r   r   rN   ra   rb   r   r   r   dup_from_raw_dict  s    rd   c             C   s   |st | |S | st|S i }xL|  D ]@\}}|d |dd  }}||kr\||| |< q(||i||< q(W t| |d g   }}	}
xHt|ddD ]8}||}|dk	r|
t||	| q|
t|	 qW t	|
|S )aF  
    Create a ``K[X]`` polynomial from a ``dict``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_from_dict

    >>> dmp_from_dict({(0, 0): ZZ(3), (0, 1): ZZ(2), (2, 1): ZZ(1)}, 1, ZZ)
    [[1, 0], [], [2, 3]]
    >>> dmp_from_dict({}, 0, ZZ)
    []

    r   r   Nr   )
rc   r1   itemsr)   r^   r	   r`   r   dmp_from_dictr2   )r   r   r   Zcoeffsr   coeffheadtailrN   r'   ra   rb   r   r   r   rf     s"    

rf   Fc             C   s^   | s|rd|j iS t| d i  }}x4td|d D ]"}| ||  r4| ||  ||f< q4W |S )z
    Convert ``K[x]`` polynomial to a ``dict``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dup_to_dict

    >>> dup_to_dict([1, 0, 5, 0, 7])
    {(0,): 7, (2,): 5, (4,): 1}
    >>> dup_to_dict([])
    {}

    )r   r   r   )r
   r   r	   )r   r   r
   rN   resultrb   r   r   r   dup_to_dict  s    
rk   c             C   s\   | s|rd|j iS t| d i  }}x2td|d D ] }| ||  r4| ||  ||< q4W |S )z
    Convert a ``K[x]`` polynomial to a raw ``dict``.

    Examples
    ========

    >>> from sympy.polys.densebasic import dup_to_raw_dict

    >>> dup_to_raw_dict([1, 0, 5, 0, 7])
    {0: 7, 2: 5, 4: 1}

    r   r   )r
   r   r	   )r   r   r
   rN   rj   rb   r   r   r   dup_to_raw_dict  s    
rl   c             C   s   |st | ||dS t| |r2|r2d|d  |jiS t| ||d i   }}}|t krZd}xLtd|d D ]:}t| ||  |}x"| D ]\}	}
|
||f|	 < qW qjW |S )a  
    Convert a ``K[X]`` polynomial to a ``dict````.

    Examples
    ========

    >>> from sympy.polys.densebasic import dmp_to_dict

    >>> dmp_to_dict([[1, 0], [], [2, 3]], 1)
    {(0, 0): 3, (0, 1): 2, (2, 1): 1}
    >>> dmp_to_dict([], 0)
    {}

    )r
   )r   r   r   r   )rk   r    r
   r!   r   r	   dmp_to_dictre   )r   r   r   r
   rN   r'   rj   rb   ra   exprg   r   r   r   rm   2  s    
rm   c       	      C   s   |dk s |dk s ||ks ||kr.t d| n||kr:| S t| |i  }}xX| D ]L\}}|||d| || f ||d |  || f ||d d  < qTW t|||S )a  
    Transform ``K[..x_i..x_j..]`` to ``K[..x_j..x_i..]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_swap

    >>> f = ZZ.map([[[2], [1, 0]], []])

    >>> dmp_swap(f, 0, 1, 2, ZZ)
    [[[2], []], [[1, 0], []]]
    >>> dmp_swap(f, 1, 2, 2, ZZ)
    [[[1], [2, 0]], [[]]]
    >>> dmp_swap(f, 0, 2, 2, ZZ)
    [[[1, 0]], [[2, 0], []]]

    r   z0 <= i < j <= %s expectedNr   )r+   rm   re   rf   )	r   r%   r&   r   r   FHrn   rg   r   r   r   dmp_swapU  s     Hrq   c             C   sl   t | |i  }}xN| D ]B\}}dgt| }xt||D ]\}	}
|	||
< q<W ||t|< qW t|||S )at  
    Return a polynomial in ``K[x_{P(1)},..,x_{P(n)}]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_permute

    >>> f = ZZ.map([[[2], [1, 0]], []])

    >>> dmp_permute(f, [1, 0, 2], 2, ZZ)
    [[[2], []], [[1, 0], []]]
    >>> dmp_permute(f, [1, 2, 0], 2, ZZ)
    [[[1], []], [[2, 0], []]]

    r   )rm   re   r   zipr   rf   )r   Pr   r   ro   rp   rn   rg   Znew_expepr   r   r   dmp_permutex  s    rv   c             C   s0   t | tst| |S xt|D ]
}| g} qW | S )z
    Return a multivariate value nested ``l``-levels.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_nest

    >>> dmp_nest([[ZZ(1)]], 2, ZZ)
    [[[[1]]]]

    )
isinstancer4   rX   r	   )r   lr   r%   r   r   r   dmp_nest  s
    


ry   c                sP   s| S |s2| st S d fdd| D S |d  fdd| D S )a  
    Return a multivariate polynomial raised ``l``-levels.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_raise

    >>> f = ZZ.map([[], [1, 2]])

    >>> dmp_raise(f, 2, 1, ZZ)
    [[[[]]], [[[1]], [[2]]]]

    r   c                s   g | ]}t | qS r   )rX   )r#   r$   )rb   r   r   r(     s    zdmp_raise.<locals>.<listcomp>c                s   g | ]}t | qS r   )	dmp_raise)r#   r$   )r   rx   r'   r   r   r(     s    )r1   )r   rx   r   r   r   )r   rb   rx   r'   r   rz     s    rz   c             C   sj   t | dkrd| fS d}x>tt| D ].}| | d  s:q&t||}|dkr&d| fS q&W || dd| fS )a  
    Map ``x**m`` to ``y`` in a polynomial in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_deflate

    >>> f = ZZ.map([1, 0, 0, 1, 0, 0, 1])

    >>> dup_deflate(f, ZZ)
    (3, [1, 1, 1])

    r   r   N)r   r	   r   r   )r   r   r*   r%   r   r   r   dup_deflate  s    
r{   c             C   s   t | |rd|d  | fS t| |}dg|d  }x8| D ],}x&t|D ]\}}t|| |||< qJW q<W x t|D ]\}}|svd||< qvW t|}tdd |D r|| fS i }	x4| D ](\}
}dd t|
|D }||	t|< qW |t	|	||fS )a5  
    Map ``x_i**m_i`` to ``y_i`` in a polynomial in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_deflate

    >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])

    >>> dmp_deflate(f, 1, ZZ)
    ((2, 3), [[1, 2], [3, 4]])

    )r   r   r   c             s   s   | ]}|d kV  qdS )r   Nr   )r#   br   r   r   rD     s    zdmp_deflate.<locals>.<genexpr>c             S   s   g | ]\}}|| qS r   r   )r#   ar|   r   r   r   r(     s    zdmp_deflate.<locals>.<listcomp>)
r    rm   r^   	enumerater   r   allre   rr   rf   )r   r   r   ro   BMr%   mr|   rp   Arg   rQ   r   r   r   dmp_deflate  s$    

r   c                s   d xn| D ]f}t |dkr"d| fS d}x>tt|D ].}|| d  sHq4t||}|dkr4d| fS q4W t | q
W  t fdd| D fS )aP  
    Map ``x**m`` to ``y`` in a set of polynomials in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_multi_deflate

    >>> f = ZZ.map([1, 0, 2, 0, 3])
    >>> g = ZZ.map([4, 0, 0])

    >>> dup_multi_deflate((f, g), ZZ)
    (2, ([1, 2, 3], [4, 0]))

    r   r   c                s   g | ]}|d d   qS )Nr   )r#   ru   )Gr   r   r(   ?  s    z%dup_multi_deflate.<locals>.<listcomp>)r   r	   r   r   r   )polysr   ru   r*   r%   r   )r   r   dup_multi_deflate  s    

r   c             C   sD  |st | |\}}|f|fS g dg|d   }}xd| D ]\}t||}t||sx8| D ],}x&t|D ]\}	}
t||	 |
||	< qfW qXW || q6W x t|D ]\}	}|sd||	< qW t|}tdd |D r|| fS g }xX|D ]P}i }x4|	 D ](\}}dd t
||D }||t|< qW |t||| qW |t|fS )a  
    Map ``x_i**m_i`` to ``y_i`` in a set of polynomials in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_multi_deflate

    >>> f = ZZ.map([[1, 0, 0, 2], [], [3, 0, 0, 4]])
    >>> g = ZZ.map([[1, 0, 2], [], [3, 0, 4]])

    >>> dmp_multi_deflate((f, g), 1, ZZ)
    ((2, 1), ([[1, 0, 0, 2], [3, 0, 0, 4]], [[1, 0, 2], [3, 0, 4]]))

    r   r   c             s   s   | ]}|d kV  qdS )r   Nr   )r#   r|   r   r   r   rD   i  s    z$dmp_multi_deflate.<locals>.<genexpr>c             S   s   g | ]\}}|| qS r   r   )r#   r}   r|   r   r   r   r(   r  s    z%dmp_multi_deflate.<locals>.<listcomp>)r   rm   r    r^   r~   r   r   r   r   re   rr   rf   )r   r   r   r   rp   ro   r   ru   r   r%   r   r|   ra   r   rg   rQ   r   r   r   dmp_multi_deflateB  s2    




r   c             C   sh   |dkrt d| |dks | s$| S | d g}x4| dd D ]$}||jg|d   || q<W |S )a  
    Map ``y`` to ``x**m`` in a polynomial in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_inflate

    >>> f = ZZ.map([1, 1, 1])

    >>> dup_inflate(f, 3, ZZ)
    [1, 0, 0, 1, 0, 0, 1]

    r   z'm' must be positive, got %sr   N)r+   extendr
   r   )r   r   r   rj   rg   r   r   r   dup_inflatez  s    
r   c                s   |st | |  S | dkr0td|  |d |d   fdd| D } | d g}xD| dd D ]4}x$td| D ]}|t qW || qrW |S )z)Recursive helper for :func:`dmp_inflate`.r   z!all M[i] must be positive, got %sr   c                s   g | ]}t | qS r   )_rec_inflate)r#   r$   )r   r   r&   r:   r   r   r(     s    z _rec_inflate.<locals>.<listcomp>N)r   r+   r	   r   r1   )r*   r   r'   r%   r   rj   rg   _r   )r   r   r&   r:   r   r     s    
r   c             C   s>   |st | |d |S tdd |D r*| S t| ||d|S dS )a3  
    Map ``y_i`` to ``x_i**k_i`` in a polynomial in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_inflate

    >>> f = ZZ.map([[1, 2], [3, 4]])

    >>> dmp_inflate(f, (2, 3), 1, ZZ)
    [[1, 0, 0, 2], [], [3, 0, 0, 4]]

    r   c             s   s   | ]}|d kV  qdS )r   Nr   )r#   r   r   r   r   rD     s    zdmp_inflate.<locals>.<genexpr>N)r   r   r   )r   r   r   r   r   r   r   dmp_inflate  s
    r   c             C   s   |rt | d|rg | |fS g t| | }}x<td|d D ]*}x$| D ]}|| rHP qHW || q:W |svg | |fS i } x@| D ]4\}}t|}xt|D ]
}||= qW || t|< qW |t	|8 }|t
| |||fS )a[  
    Exclude useless levels from ``f``.

    Return the levels excluded, the new excluded ``f``, and the new ``u``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_exclude

    >>> f = ZZ.map([[[1]], [[1], [2]]])

    >>> dmp_exclude(f, 2, ZZ)
    ([2], [[1], [1, 2]], 1)

    Nr   r   )rU   rm   r	   r^   r   re   r4   r>   r   r   rf   )r   r   r   Jro   r&   r   rg   r   r   r   dmp_exclude  s$    


r   c             C   st   |s| S t | |i  }} xB| D ]6\}}t|}x|D ]}||d q8W || t|< q"W |t|7 }t| ||S )a  
    Include useless levels in ``f``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_include

    >>> f = ZZ.map([[1], [1, 2]])

    >>> dmp_include(f, [2], 1, ZZ)
    [[[1]], [[1], [2]]]

    r   )rm   re   r4   insertr   r   rf   )r   r   r   r   ro   r   rg   r&   r   r   r   dmp_include  s    
r   c             C   s   t | |i  } }|jd }xP|  D ]D\}}| }x2| D ]&\}}	|rX|	||| < q>|	||| < q>W q$W || d }
t||
|j|
fS )a  
    Convert ``f`` from ``K[X][Y]`` to ``K[X,Y]``.

    Examples
    ========

    >>> from sympy.polys.rings import ring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_inject

    >>> R, x,y = ring("x,y", ZZ)

    >>> dmp_inject([R(1), x + 2], 0, R.to_domain())
    ([[[1]], [[1], [2]]], 2)
    >>> dmp_inject([R(1), x + 2], 0, R.to_domain(), front=True)
    ([[[1]], [[1, 2]]], 2)

    r   )rm   ngensre   Zto_dictrf   Zdom)r   r   r   frontra   r'   f_monomr*   g_monomr$   r:   r   r   r   
dmp_inject  s    
r   c             C   s   t | |i  } }|j}||j d }xt|  D ]h\}}|rV|d| ||d  }	}
n|| d |d|   }	}
|
|kr|||
 |	< q.|	|i||
< q.W x | D ]\}}||||< qW t||d |S )z
    Convert ``f`` from ``K[X,Y]`` to ``K[X][Y]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_eject

    >>> dmp_eject([[[1]], [[1], [2]]], 2, ZZ['x', 'y'])
    [1, x + 2]

    r   N)rm   r   re   rf   )r   r   r   r   ra   rN   r'   r   r$   r   r   r   r   r   	dmp_eject>  s    r   c             C   sN   t | |s| sd| fS d}x t| D ]}|s6|d7 }q$P q$W || d|  fS )a  
    Remove GCD of terms from ``f`` in ``K[x]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_terms_gcd

    >>> f = ZZ.map([1, 0, 1, 0, 0])

    >>> dup_terms_gcd(f, ZZ)
    (2, [1, 0, 1])

    r   r   N)r   r>   )r   r   r%   r$   r   r   r   dup_terms_gcdb  s    
r   c             C   s   t | ||st| |r&d|d  | fS t| |}tt|  }tdd |D rZ|| fS i } x"| D ]\}}|| t||< qhW |t	| ||fS )a$  
    Remove GCD of terms from ``f`` in ``K[X]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_terms_gcd

    >>> f = ZZ.map([[1, 0], [1, 0, 0], [], []])

    >>> dmp_terms_gcd(f, 1, ZZ)
    ((2, 1), [[1], [1, 0]])

    )r   r   c             s   s   | ]}|d kV  qdS )r   Nr   )r#   r*   r   r   r   rD     s    z dmp_terms_gcd.<locals>.<genexpr>)
r   r    rm   r   r4   r^   r   re   r   rf   )r   r   r   ro   r   r   rg   r   r   r   dmp_terms_gcd  s    
r   c          	   C   s   t | |g  }}|sJxnt| D ]&\}}|s,q|||| f |f qW n:|d }x0t| D ]$\}}|t||||| f  q\W |S )z,Recursive helper for :func:`dmp_list_terms`.r   )r!   r~   r   r   _rec_list_terms)r*   r'   r   rR   termsr%   r$   r:   r   r   r   r     s     r   c             C   sJ   dd }t | |d}|s,d|d  |jfgS |dkr8|S ||t|S dS )a  
    List all non-zero terms from ``f`` in the given order ``order``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_list_terms

    >>> f = ZZ.map([[1, 1], [2, 3]])

    >>> dmp_list_terms(f, 1, ZZ)
    [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]
    >>> dmp_list_terms(f, 1, ZZ, order='grevlex')
    [((1, 1), 1), ((1, 0), 1), ((0, 1), 2), ((0, 0), 3)]

    c                s   t |  fddddS )Nc                s    | d S )Nr   r   )Zterm)Or   r   <lambda>  s    z.dmp_list_terms.<locals>.sort.<locals>.<lambda>T)keyreverse)sorted)r   r   r   )r   r   sort  s    zdmp_list_terms.<locals>.sortr   )r   r   N)r   r
   r   )r   r   r   orderr   r   r   r   r   dmp_list_terms  s    r   c       
      C   s   t | t | }}||krL||kr8|jg||  | }n|jg||  |  } g }x,t| |D ]\}}	||||	f|  q\W t|S )a8  
    Apply ``h`` to pairs of coefficients of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_apply_pairs

    >>> h = lambda x, y, z: 2*x + y - z

    >>> dup_apply_pairs([1, 2, 3], [3, 2, 1], h, (1,), ZZ)
    [4, 5, 6]

    )r   r
   rr   r   r0   )
r   r*   ra   argsr   rN   r   rj   r}   r|   r   r   r   dup_apply_pairs  s    r   c          
   C   s   |st | ||||S t| t||d   }}}||krj||krVt|| ||| }nt|| |||  } g }	x.t| |D ] \}
}|	t|
||||| qzW t|	|S )aG  
    Apply ``h`` to pairs of coefficients of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dmp_apply_pairs

    >>> h = lambda x, y, z: 2*x + y - z

    >>> dmp_apply_pairs([[1], [2, 3]], [[3], [2, 1]], h, (1,), 1, ZZ)
    [[4], [5, 6]]

    r   )r   r   rZ   rr   r   dmp_apply_pairsr2   )r   r*   ra   r   r   r   rN   r   r'   rj   r}   r|   r   r   r   r     s    r   c             C   s\   t | }||kr|| }nd}||kr0|| }nd}| || } | sHg S | |jg|  S dS )z=Take a continuous subsequence of terms of ``f`` in ``K[x]``. r   N)r   r
   )r   r   rN   r   rb   r   rQ   r   r   r   	dup_slice  s    

r   c             C   s   t | ||d||S )z=Take a continuous subsequence of terms of ``f`` in ``K[X]``. r   )dmp_slice_in)r   r   rN   r   r   r   r   r   	dmp_slice,  s    r   c       
      C   s   |dk s||kr"t d|||f |s4t| |||S t| |i  } }xn|  D ]b\}}|| }	|	|k sn|	|kr|d| d ||d d  }||kr||  |7  < qN|||< qNW t|||S )zHTake a continuous subsequence of terms of ``f`` in ``x_j`` in ``K[X]``. r   z-%s <= j < %s expected, got %sN)r   r   )r+   r   rm   re   rf   )
r   r   rN   r&   r   r   r*   r   rg   rb   r   r   r   r   1  s     r   c                sH    fddt d| d D }x"|d sB t|d< q"W |S )a  
    Return a polynomial of degree ``n`` with coefficients in ``[a, b]``.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.densebasic import dup_random

    >>> dup_random(3, -10, 10, ZZ) #doctest: +SKIP
    [-2, -8, 9, -4]

    c                s   g | ]}  tqS r   )rG   randomrandint)r#   r   )r   r}   r|   r   r   r(   W  s    zdup_random.<locals>.<listcomp>r   r   )r	   rG   r   r   )rN   r}   r|   r   r   r   )r   r}   r|   r   
dup_randomI  s     
r   )N)NF)NF)NF)F)F)N)[__doc__Z
__future__r   r   Z
sympy.corer   Zsympyr   Zsympy.polys.monomialsr   r   Zsympy.polys.orderingsr   Zsympy.core.compatibilityr	   r   r   r   r   r   r   r   r   r   r   r   r!   r"   r,   r-   r/   r0   r2   r7   r9   r=   r?   r@   rA   rB   rC   rE   rF   rJ   rK   rL   rM   rO   rP   rS   r    r1   rW   rY   rU   rX   rZ   r[   r\   r]   rc   rd   rf   rk   rl   rm   rq   rv   ry   rz   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s   
!

 !,


## !,'80"
%
$!
  #