K i{PdZddlmZmZmZddlmZmZmZddl m Z d dZ dZ dZ y) z1Gosper's algorithm for hypergeometric summation. )SDummysymbols)Polyparallel_poly_from_exprfactor) is_sequencect||f|dd\\}}}|j|j}}|j|j} } |j|| z } } t d} t || z|| |j }|j| j|}|jjDchc]}|js|dk\s|}}t|D]~}|j| j|}|j|}| j|j| } t!d|dzD]}| |j| z} |j#| }|s0|j%}| j%} | j%} || | fScc}w)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 extensionhdomainr)rLCmoniconerrr resultantcompose ground_rootskeys is_Integersortedgcdshiftquorange mul_groundas_expr)fgnpolyspqoptaAbBCZr DRrrootsidjs [/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/concrete/gosper.py gosper_normalr5sL* A/KFQC 4461779qA 4461779qA 55!A#qA c A QUAq,A AIIaL!A(--/ K11<>> 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) hypersimpNrzc:%s)clsr)solve)sympy.simplifyr7as_numer_denomr5rrdegreermaxZeronthsetrremoverr get_domaininjectrsympy.solvers.solversr:coeffsrsubsis_zero)r r"r7r/r$r%r(r*r+NMKr-r2rFrxHr:solutioncoeffs r4 gosper_termrPNs4)!QAy   DAqAq!$GAq!  A !((* A !((* A !((* A QADDFaddf$ Q]O  UQY  UQYq1ua!e 4addf< = V||q1u HHQK  AA Vq1u%5 1F "Q\\^ " "F +F VQv&A !''!* qsQA+QXXZ(H "A!  ua A! yyyy{1}QYY[((cd}t|r|\}}}nd}t||}|y|r||z}t|S||dzzj|||zj|z }|tjur: ||dzzj ||||zj ||z }t|St|S#t $rd}Yt|SwxYw)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 rPrGrNaNlimitNotImplementedErrorr)r k indefiniter'r)r!results r4 gosper_sumrYsPJ1~1a AqAy1 &>QU)!!!Q'1Q3**Q*:: QUU? QU)**1a0AaC;;q!3DD &>6&>'  &> s9.B== CCN)T)__doc__ sympy.corerrr sympy.polysrrrsympy.utilities.iterablesr r5rPrYrQr4r_s*7((==1CLN)b?rQ