B
    [.  γ               @   sl   d Z ddlmZmZ ddlmZmZ ddlmZ dd Z	dd Z
d	d
 Zdd Zdd Zdd Zdd ZdS )zCImplementation of matrix FGLM Groebner basis conversion algorithm. ι    )Ϊprint_functionΪdivision)Ϊmonomial_mulΪmonomial_div)Ϊrangec                s
  |j |j}|jd}t| |}t|| |}|jgjgjgt|d   g}g  dd t	|D }|j
fdddd | ‘ }	tt|}
xjtt||	d	  ||	d  }t|
|tfd
dt	t|D rJ| t|	d  |	d	 j‘}| fddt	D ‘}||  |‘}|rΌ  |‘ nrt|
}
 t|	d  |	d	 ‘ | |‘ | fddt	|D ‘ tt|}|j
fdddd  fdd|D }|sϊdd  D  t fddddS | ‘ }	qW dS )aE  
    Converts the reduced Groebner basis ``F`` of a zero-dimensional
    ideal w.r.t. ``O_from`` to a reduced Groebner basis
    w.r.t. ``O_to``.

    References
    ==========

    J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient
    Computation of Zero-dimensional Groebner Bases by Change of
    Ordering
    )Ϊorderι   c             S   s   g | ]}|d fqS )r   © )Ϊ.0Ϊir	   r	   ϊ4lib/python3.7/site-packages/sympy/polys/fglmtools.pyϊ
<listcomp>"   s    zmatrix_fglm.<locals>.<listcomp>c                s    t | d  | d S )Nr   r   )Ϊ_incr_k)Ϊk_l)ΪO_toΪSr	   r   Ϊ<lambda>#   s    zmatrix_fglm.<locals>.<lambda>T)ΪkeyΪreverser   c             3   s   | ]} | j kV  qd S )N)Ϊzero)r
   r   )Ϊ_lambdaΪdomainr	   r   ϊ	<genexpr>-   s    zmatrix_fglm.<locals>.<genexpr>c                s   i | ]}|  | qS r	   r	   )r
   r   )r   r   r	   r   ϊ
<dictcomp>0   s    zmatrix_fglm.<locals>.<dictcomp>c                s   g | ]}| fqS r	   r	   )r
   r   )Ϊsr	   r   r   ;   s    c                s    t | d  | d S )Nr   r   )r   )r   )r   r   r	   r   r   =   s    c                s2   g | ]*\ t  fd dD r fqS )c             3   s(   | ] }t t  |jd kV  qd S )N)r   r   ΪLM)r
   Ϊg)r   ΪkΪlr	   r   r   ?   s    z)matrix_fglm.<locals>.<listcomp>.<genexpr>)Ϊall)r
   )ΪGr   )r   r   r   r   ?   s    c             S   s   g | ]}|  ‘ qS r	   )Zmonic)r
   r   r	   r	   r   r   B   s    c                s
    | j S )N)r   )r   )r   r	   r   r   C   s    N)r   ΪngensZcloneΪ_basisΪ_representing_matricesΪ
zero_monomΪoner   Ϊlenr   ΪsortΪpopΪ_identity_matrixΪ_matrix_mulr   Ϊterm_newr   Z	from_dictZset_ringΪappendΪ_updateΪextendΪlistΪsetΪsorted)ΪFΪringr   r!   Zring_toZ	old_basisΪMΪVΪLΪtΪPΪvΪltΪrestr   r	   )r    r   r   r   r   r   r   Ϊmatrix_fglm   sB    

$ 
r<   c             C   s6   t t| d | | | d g t| |d d   S )Nr   )Ϊtupler/   )Ϊmr   r	   r	   r   r   H   s    r   c                s<    fddt D }xt D ]} j|| |< q"W |S )Nc                s   g | ]} j g qS r	   )r   )r
   Ϊ_)r   Ϊnr	   r   r   M   s    z$_identity_matrix.<locals>.<listcomp>)r   r%   )r@   r   r4   r   r	   )r   r@   r   r)   L   s    r)   c                s    fdd| D S )Nc                s,   g | ]$ t  fd dttD qS )c                s   g | ]} | |  qS r	   r	   )r
   r   )Ϊrowr9   r	   r   r   V   s    z*_matrix_mul.<locals>.<listcomp>.<listcomp>)Ϊsumr   r&   )r
   )r9   )rA   r   r   V   s    z_matrix_mul.<locals>.<listcomp>r	   )r4   r9   r	   )r9   r   r*   U   s    r*   c                sͺ   t fddt| tD xDttD ]4kr. fddtt  D  < q.W  fddtt  D  <  |      <  | <  S )zE
    Update ``P`` such that for the updated `P'` `P' v = e_{s}`.
    c                s   g | ]} | d kr|qS )r   r	   )r
   Ϊj)r   r	   r   r   ]   s    z_update.<locals>.<listcomp>c                s4   g | ],}  |   |      qS r	   r	   )r
   rC   )r8   r   r   Ϊrr	   r   r   a   s    c                s    g | ]}  |   qS r	   r	   )r
   rC   )r8   r   r   r	   r   r   c   s    )Ϊminr   r&   )r   r   r8   r	   )r8   r   r   rD   r   r-   Y   s     ,&r-   c                sJ   j jd fdd fddfddtd D S )zn
    Compute the matrices corresponding to the linear maps `m \mapsto
    x_i m` for all variables `x_i`.
    r   c                s"   t dg|  dg dg |    S )Nr   r   )r=   )r   )Ϊur	   r   Ϊvarq   s    z#_representing_matrices.<locals>.varc                s|   fddt tD }xZtD ]N\}} t| |j‘  ‘}x*| ‘ D ]\}} |‘}||| |< qRW q&W |S )Nc                s   g | ]}j gt  qS r	   )r   r&   )r
   r?   )Ϊbasisr   r	   r   r   u   s    zG_representing_matrices.<locals>.representing_matrix.<locals>.<listcomp>)	r   r&   Ϊ	enumerater+   r   r%   ZremZtermsΪindex)r>   r4   r   r9   rD   ZmonomZcoeffrC   )r    rH   r   r3   r	   r   Ϊrepresenting_matrixt   s    
z3_representing_matrices.<locals>.representing_matrixc                s   g | ]} |qS r	   r	   )r
   r   )rK   rG   r	   r   r      s    z*_representing_matrices.<locals>.<listcomp>)r   r!   r   )rH   r    r3   r	   )r    rH   r   rK   r3   rF   rG   r   r#   i   s
    
r#   c                s   |j dd | D  |jg}g }xT|rt| ‘ | ‘  fddt|jD }| |‘ |jfdddd q"W tt	|}t
|fddd	S )
z°
    Computes a list of monomials which are not divisible by the leading
    monomials wrt to ``O`` of ``G``. These monomials are a basis of
    `K[X_1, \ldots, X_n]/(G)`.
    c             S   s   g | ]
}|j qS r	   )r   )r
   r   r	   r	   r   r      s    z_basis.<locals>.<listcomp>c                s.   g | ]& t  fd dD rt qS )c             3   s"   | ]}t t |d kV  qd S )N)r   r   )r
   Zlmg)r   r7   r	   r   r      s   z$_basis.<locals>.<listcomp>.<genexpr>)r   r   )r
   )Ϊleading_monomialsr7   )r   r   r      s    c                s    | S )Nr	   )r>   )r   r	   r   r      s    z_basis.<locals>.<lambda>T)r   r   c                s    | S )Nr	   )r>   )r   r	   r   r      s    )r   )r   r$   r(   r,   r   r!   r.   r'   r/   r0   r1   )r    r3   Z
candidatesrH   Znew_candidatesr	   )rL   r   r7   r   r"      s    

r"   N)Ϊ__doc__Z
__future__r   r   Zsympy.polys.monomialsr   r   Zsympy.core.compatibilityr   r<   r   r)   r*   r-   r#   r"   r	   r	   r	   r   Ϊ<module>   s   @	