o
    Hۂi{                     @   sV   d Z ddlmZmZmZ ddlmZmZmZ ddl	m
Z
 dddZdd	 Zd
d ZdS )z1Gosper's algorithm for hypergeometric summation.     )SDummysymbols)Polyparallel_poly_from_exprfactor)is_sequenceTc                 C   s$  t | |f|ddd\\}}}| | }}| | }	}
|j||	 }}td}t|| |||jd}||
|}dd |	 
 D }t|D ]+}||
|
 }||}|
|| }
td|d D ]
}||| 9 }qnqN||}|s| }|
 }
| }||
|fS )a`  
    Compute the Gosper's normal form of ``f`` and ``g``.

    Explanation
    ===========

    Given relatively prime univariate polynomials ``f`` and ``g``,
    rewrite their quotient to a normal form defined as follows:

    .. math::
        \frac{f(n)}{g(n)} = Z \cdot \frac{A(n) C(n+1)}{B(n) C(n)}

    where ``Z`` is an arbitrary constant and ``A``, ``B``, ``C`` are
    monic polynomials in ``n`` with the following properties:

    1. `\gcd(A(n), B(n+h)) = 1 \forall h \in \mathbb{N}`
    2. `\gcd(B(n), C(n+1)) = 1`
    3. `\gcd(A(n), C(n)) = 1`

    This normal form, or rational factorization in other words, is a
    crucial step in Gosper's algorithm and in solving of difference
    equations. It can be also used to decide if two hypergeometric
    terms are similar or not.

    This procedure will return a tuple containing elements of this
    factorization in the form ``(Z*A, B, C)``.

    Examples
    ========

    >>> from sympy.concrete.gosper import gosper_normal
    >>> from sympy.abc import n

    >>> gosper_normal(4*n+5, 2*(4*n+1)*(2*n+3), n, polys=False)
    (1/4, n + 3/2, n + 1/4)

    T)field	extensionhdomainc                 S   s   h | ]}|j r|d kr|qS )r   )
is_Integer).0r r   X/home/ubuntu/maya3_transcribe/venv/lib/python3.10/site-packages/sympy/concrete/gosper.py	<setcomp>:   s    z gosper_normal.<locals>.<setcomp>   )r   LCmoniconer   r   r   	resultantcomposeground_rootskeyssortedgcdshiftquorange
mul_groundas_expr)fgnpolyspqoptaAbBCZr   DRrootsidjr   r   r   gosper_normal   s.   &


r6   c                 C   s  ddl m} || |}|du rdS | \}}t|||\}}}|d}t| }	t| }
t| }|	|
ksC| | krL|t|	|
 h}n$|	sX||	 d tj	h}n||	 d |
|	d |
|	d  |  h}t|D ]}|jr}|dk r|| qt|sdS t|}td|d  td}| j| }t|||d}||d ||  | }dd	lm} || |}|du rdS | |}|D ]}||vr||d}q|jrdS | | |  S )
a&  
    Compute Gosper's hypergeometric term for ``f``.

    Explanation
    ===========

    Suppose ``f`` is a hypergeometric term such that:

    .. math::
        s_n = \sum_{k=0}^{n-1} f_k

    and `f_k` does not depend on `n`. Returns a hypergeometric
    term `g_n` such that `g_{n+1} - g_n = f_n`.

    Examples
    ========

    >>> from sympy.concrete.gosper import gosper_term
    >>> from sympy import factorial
    >>> from sympy.abc import n

    >>> gosper_term((4*n + 1)*factorial(n)/factorial(2*n + 1), n)
    (-n - 1/2)/(n + 1/4)

    r   )	hypersimpNr   zc:%s)clsr   )solve)sympy.simplifyr7   as_numer_denomr6   r   r   degreer   maxZeronthsetr   remover   r   
get_domaininjectr   sympy.solvers.solversr:   coeffsr"   subsis_zero)r#   r%   r7   r   r'   r(   r+   r-   r.   NMKr0   r4   rF   r   xHr:   solutioncoeffr   r   r   gosper_termN   sL   

0
rP   c                 C   s   d}t |r|\}}}nd}t| |}|du rdS |r#| | }t|S | |d  ||| | || }|tju r`z| |d  ||| | || }W t|S  ty_   d}Y t|S w t|S )aB  
    Gosper's hypergeometric summation algorithm.

    Explanation
    ===========

    Given a hypergeometric term ``f`` such that:

    .. math ::
        s_n = \sum_{k=0}^{n-1} f_k

    and `f(n)` does not depend on `n`, returns `g_{n} - g(0)` where
    `g_{n+1} - g_n = f_n`, or ``None`` if `s_n` cannot be expressed
    in closed form as a sum of hypergeometric terms.

    Examples
    ========

    >>> from sympy.concrete.gosper import gosper_sum
    >>> from sympy import factorial
    >>> from sympy.abc import n, k

    >>> f = (4*k + 1)*factorial(k)/factorial(2*k + 1)
    >>> gosper_sum(f, (k, 0, n))
    (-factorial(n) + 2*factorial(2*n + 1))/factorial(2*n + 1)
    >>> _.subs(n, 2) == sum(f.subs(k, i) for i in [0, 1, 2])
    True
    >>> gosper_sum(f, (k, 3, n))
    (-60*factorial(n) + factorial(2*n + 1))/(60*factorial(2*n + 1))
    >>> _.subs(n, 5) == sum(f.subs(k, i) for i in [3, 4, 5])
    True

    References
    ==========

    .. [1] Marko Petkovsek, Herbert S. Wilf, Doron Zeilberger, A = B,
           AK Peters, Ltd., Wellesley, MA, USA, 1997, pp. 73--100

    FTNr   )r   rP   rG   r   NaNlimitNotImplementedErrorr   )r#   k
indefiniter*   r,   r$   resultr   r   r   
gosper_sum   s(   (

$
&rW   N)T)__doc__
sympy.corer   r   r   sympy.polysr   r   r   sympy.utilities.iterablesr   r6   rP   rW   r   r   r   r   <module>   s    
FQ