K ikdZddlmZddlmZddlmZddlmZddl m Z m Z m Z m Z ddlmZmZddlmZdd lmZmZmZmZmZmZmZd Zd Zdd ZdZddZddZ dZ!dZ"dZ#dZ$dZ%dZ&ddZ'dZ(y )a Algorithms for solving the Risch differential equation. Given a differential field K of characteristic 0 that is a simple monomial extension of a base field k and f, g in K, the Risch Differential Equation problem is to decide if there exist y in K such that Dy + f*y == g and to find one if there are some. If t is a monomial over k and the coefficients of f and g are in k(t), then y is in k(t), and the outline of the algorithm here is given as: 1. Compute the normal part n of the denominator of y. The problem is then reduced to finding y' in k, where y == y'/n. 2. Compute the special part s of the denominator of y. The problem is then reduced to finding y'' in k[t], where y == y''/(n*s) 3. Bound the degree of y''. 4. Reduce the equation Dy + f*y == g to a similar equation with f, g in k[t]. 5. Find the solutions in k[t] of bounded degree of the reduced equation. See Chapter 6 of "Symbolic Integration I: Transcendental Functions" by Manuel Bronstein. See also the docstring of risch.py. )mul)reduce)oo)Dummy)PolygcdZZcancel)imre)sqrt)gcdex_diophantinefrac_in derivation splitfactorNonElementaryIntegralExceptionDecrementLevelrecognize_log_derivativec"|jrtS|t||k(r%|j|j ddSg}|}|j |}d}|jr;|j ||f||z}|dz}|j |}|jr;d}td|}t|dk7rN|j} || dz} |j | }|jr || dz }| }t|dk7rN|S)aY Computes the order of a at p, with respect to t. Explanation =========== For a, p in k[t], the order of a at p is defined as nu_p(a) = max({n in Z+ such that p**n|a}), where a != 0. If a == 0, nu_p(a) = +oo. To compute the order at a rational function, a/b, use the fact that nu_p(a/b) == nu_p(a) - nu_p(b). r) is_zerorras_polyETremappendlenpop) apt power_listp1r tracks_powernproductfinalproductfs Y/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/integrals/rde.pyorder_atr+)s yy DAJyy| #A&& J B b AL ))2l+, U EE"I )) A1ajG j/Q  58# EE(O 99 qMAG j/Q  Hcl|jrtS|j||j|z S)z Computes the order of a/d at oo (infinity), with respect to t. For f in k(t), the order or f at oo is defined as deg(d) - deg(a), where f == a/d. )rrdegree)rdr!s r* order_at_oor0Ts+ yy 88A;! $$r,Nc|xs td}t||\}}t||j|j}|j |}|j t||}t |j |j|j|j|j|j|j\} } |t||jt||zz j|jj|j|j} t| |} | jj|std|j||ffS| jD cgc]} | tvs | dkDs| } } tt | Dcgc]2}t|t||jt||zz |4c}td|j}t||}||z||zz }||z}|j#|d\}}|||ffScc} wcc}w)a Weak normalization. Explanation =========== Given a derivation D on k[t] and f == a/d in k(t), return q in k[t] such that f - Dq/q is weakly normalized with respect to t. f in k(t) is said to be "weakly normalized" with respect to t if residue_p(f) is not a positive integer for any normal irreducible p in k[t] such that f is in R_p (Definition 6.1.1). If f has an elementary integral, this is equivalent to no logarithm of integral(f) whose argument depends on t has a positive integer coefficient, where the arguments of the logarithms not in k(t) are in k[t]. Returns (q, f - Dq/q) zrrTinclude)rrrdiffr!quorrrr resultantexprhas real_rootsr rrr )rr/DEr2dndsg d_sqf_partd1a1br$iNr&qdqsnsds r*weak_normalizerrI`s( U3ZA B FB B AJ J* +B aeeBi//5rzz"$$7G "$$ EB T!RTT]:b"- - -66rtt<FF 244 A Q A 66::a=Q 1v&&LLN8qa2g!a%8A8sANqST!RTT]:b"+===rBN Q  A Ar B 1qtB 1B YYr4Y (FB Bx= 9Ns I"I(I<7I ct||\}}t||\}}|j|} |j|j|jj | j| j|j} || z} | | z} | j |drt | |z} | j|d\} }| |z|t| |z|zz }|j|d\}}| ||f| |f| fS)a Normal part of the denominator. Explanation =========== Given a derivation D on k[t] and f, g in k(t) with f weakly normalized with respect to t, either raise NonElementaryIntegralException, in which case the equation Dy + f*y == g has no solution in k(t), or the quadruplet (a, b, c, h) such that a, h in k[t], b, c in k, and for any solution y in k(t) of Dy + f*y == g, q = y*h in k satisfies a*Dq + b*q == c. This constitutes step 1 in the outline given in the rde.py docstring. rTr3) rrr5r!r6divrr r)fafdgagdr;r<r=enesr hrccacdbabds r* normal_denomrXs R FB R FB r A rwwrtt}!!!%%rtt "56A 1A !AuuRy|,, 2B YYr4Y (FB 2:a$$R' 'B YYr4Y (FB Bx"b1 %%r,c 6 |dk(r |j}|dk(r!t|j|j}n|dk(r't|jdzdz|j}nj|dvrX|jj |}|jj |} ||| td|jfSt d|zt |||jt |||jz } t |||jt |||jz } td| td| z } | sdd lm } |dk(r|jj t|j|j}t|5t|jd |jdz |jdz |j\}}t||j\}}| |||||}||\}}}|dk(r t| |} d d d n|dk(r|jj t|jdzdz|j}t|5tt|jtd  |jtd z |jtd z |j\}}tt!|jtd  |jtd z |jtd z |j\}}t||j\}}t#td|j|z||rQ| |ttd |jz|z||zz||z|||}||\}}}|dk(r t| |} d d d t%d| | | z }||z}|| z}||z}||j |zt| |j|zt'||j |z|zz}||z|zj |} |}||| |fS#1swYxYw#1swYxYw) a Special part of the denominator. Explanation =========== case is one of {'exp', 'tan', 'primitive'} for the hyperexponential, hypertangent, and primitive cases, respectively. For the hyperexponential (resp. hypertangent) case, given a derivation D on k[t] and a in k[t], b, c, in k with Dt/t in k (resp. Dt/(t**2 + 1) in k, sqrt(-1) not in k), a != 0, and gcd(a, t) == 1 (resp. gcd(a, t**2 + 1) == 1), return the quadruplet (A, B, C, 1/h) such that A, B, C, h in k[t] and for any solution q in k of a*Dq + b*q == c, r = qh in k[t] satisfies A*Dr + B*r == C. For ``case == 'primitive'``, k == k[t], so it returns (a, b, c, 1) in this case. This constitutes step 2 of the outline given in the rde.py docstring. autoexptanrr) primitivebasez@case must be one of {'exp', 'tan', 'primitive', 'base'}, not %s.rparametric_log_derivN)caserr!to_fieldr6 ValueErrorr+minprder`r/rrevalr r r rmaxr)rrVrWrTrUr;rbr BCnbncr&r`dcoeffalphaaalphadetaaetadAQmr2betaabetadrDpNpnrRs r* special_denomrys. v~ww u} rtt   q1bdd # & & KKM  b ! KKM  b !1aa''!%&' ' "a "a!6 6B "a "a!6 6B ArC2JA . 5=TTXXd244./F# &!("''!*RWWQZ)?q )I244!P$VRTT2 d(tRH=GAq!Av1I & &U]TTXXd244719bdd34F# *!(RWWT"X->,>rwwtBx?P,PQRQWQWX\]_X`Qa,a)bdfdhdh!i&r27748+<*zbound_degree..(s,A"$$,s%(r^rrr])limited_integratezLength of m should be 1!is_log_deriv_k_t_radical_in_fieldNr[r_)r\other_nonlinearzScase must be one of {'exp', 'tan', 'primitive', 'other_nonlinear', 'base'}, not %s.)rbr.r!rhr rLCas_expr is_Integerrr/Tlevelrrfrrrdrrrr`r6r)rrBcQr;rb parametricdadbdcalphar&rprqt1rnrorzazdrtrrraar2betarurvr`deltalams ` r* bound_degreer s( v~ww "$$B "$$B ,, , YYrtt_ AIIbddO&&(0022 "$$$$&' (E v~ 2BQ' ( a! !A% 7F H- &, Hsa2(R7R/C R7=R'6R7%?S R$ R7#R$$R7' R40R73R44R77SSctd|j}td|j}td|j} |jr||d||fS|dkdurt|j |}|j |jst|j ||j ||j |}}}|j|jdk(rE|jj |}|jj |}|||||fSt|||\} } |t||z }| t| |z }||j|jz}||| zz }||z}C)a Rothstein's Special Polynomial Differential Equation algorithm. Explanation =========== Given a derivation D on k[t], an integer n and ``a``,``b``,``c`` in k[t] with ``a != 0``, either raise NonElementaryIntegralException, in which case the equation a*Dq + b*q == c has no solution of degree at most ``n`` in k[t], or return the tuple (B, C, m, alpha, beta) such that B, C, alpha, beta in k[t], m in ZZ, and any solution q in k[t] of degree at most n of a*Dq + b*q == c must be of the form q == alpha*h + beta, where h in k[t], deg(h) <= m, and Dh + B*h == C. This constitutes step 4 of the outline given in the rde.py docstring. rrT) rr!rrrrr6r.rcrr) rrBrSr&r;zerorrr>r$r2s r*spders]" 244=D BDDME 244=D  99$4. . Ed?0 0 EE!HuuQx0 0%%(AEE!HaeeAha1 88BDD>Q    #A   #Aq!UD) ) Aq)1 Z2  1b! ! QXXbdd^    / r,c2td|j}|js|j|j|j|jz }d|cxkr |ks ttt|j |jj |j |jj z |j|zz|jd}||z}|dz }|t||z ||zz }|js|S)a Poly Risch Differential Equation - No cancellation: deg(b) large enough. Explanation =========== Given a derivation D on k[t], ``n`` either an integer or +oo, and ``b``,``c`` in k[t] with ``b != 0`` and either D == d/dt or deg(b) > max(0, deg(D) - 1), either raise NonElementaryIntegralException, in which case the equation ``Dq + b*q == c`` has no solution of degree at most n in k[t], or a solution q in k[t] of this equation with ``deg(q) < n``. rFexpandr)rr!rr.rrrrrBrSr&r;rErtr s r*no_cancel_b_largers Q Aii HHRTTNQXXbdd^ +A{{0 00 0 244##%aiio&8&8&::2447BBDD  E E 1b! !AaC 'ii Hr,ctd|j}|js9|dk(rd}nD|j|j|jj|jz dz}d|cxkr |ks t t |dkDrt|j |jj||jj |jjzz |j|zz|jd}n|j|j|j|jk7rt |j|jdk(rW||j |j|jdz |j |j|jdz fSt|j |jj|j |jjz |jd}||z}|dz }|t||z ||zz }|js9|S)a Poly Risch Differential Equation - No cancellation: deg(b) small enough. Explanation =========== Given a derivation D on k[t], ``n`` either an integer or +oo, and ``b``,``c`` in k[t] with deg(b) < deg(D) - 1 and either D == d/dt or deg(D) >= 2, either raise NonElementaryIntegralException, in which case the equation Dq + b*q == c has no solution of degree at most n in k[t], or a solution q in k[t] of this equation with deg(q) <= n, or the tuple (h, b0, c0) such that h in k[t], b0, c0, in k, and for any solution q in k[t] of degree at most n of Dq + bq == c, y == q - h is a solution in k of Dy + b0*y == c0. rrFr) rr!rr.r/rrrrrrrs r*no_cancel_b_smallrs Q Aii 6ARTT!22Q6AA{{0 00 0 q5QYYrtt_'')1RTT\\"$$-?-B-B-D+DEbddAgMU$Axx~"$$/44xx~"199RTT"((Q,%78IIbdd288a<0133QYYrtt_'')!))BDD/*<*<*>>A E E 1b! !AaC '/ii2 Hr,cXtd|j}t|j|jj |j j|jj z }|j r|jr|}nd}|jst||j|j|j j|jz dz}d|cxkr |ks ttt||j j|jj z|j|jj z}|jr|||fS|dkDrSt|j|jj |z |j|zz|jd} n|j|j|j j|jdz k7rt|j|jj |j|jj z } || z}|dz }|t| |z || zz }|js|S)a Poly Risch Differential Equation - No cancellation: deg(b) == deg(D) - 1 Explanation =========== Given a derivation D on k[t] with deg(D) >= 2, n either an integer or +oo, and b, c in k[t] with deg(b) == deg(D) - 1, either raise NonElementaryIntegralException, in which case the equation Dq + b*q == c has no solution of degree at most n in k[t], or a solution q in k[t] of this equation with deg(q) <= n, or the tuple (h, m, C) such that h in k[t], m in ZZ, and C in k[t], and for any solution q in k[t] of degree at most n of Dq + b*q == c, y == q - h is a solution in k[t] of degree at most m of Dy + b*y == C. rrarFr) rr!r rrr/r is_positiverrhr.rr) rBrSr&r;rElcMrtur s r*no_cancel_equalrs Q A 244##%%bddll244&8&;&;&== >B }}  ii 188BDD>BDDKK$559 :A{{0 00 0 1RTT\\"$$'**,,qyy/A/A/CC D 99q!9  q5QYYrtt_'')!+BDD!G3RTT%HAxx~RTT!2Q!6644IIbddO&&(244););)== E E 1b! !AaC ''ii* Hr,cTddlm}t|5t||j\}}||||}||\}}|dk(r t dddd|j r|S||j|jkrttd|j} |j s|j|j} || krtt|5t|j|j\} } t| | |\} }dddt jjz |j| zz|jd}| |z } | dz }|||zt||zz}|j s| S#1swYFxYw#1swYxYw)a Poly Risch Differential Equation - Cancellation: Primitive case. Explanation =========== Given a derivation D on k[t], n either an integer or +oo, ``b`` in k, and ``c`` in k[t] with Dt in k and ``b != 0``, either raise NonElementaryIntegralException, in which case the equation Dq + b*q == c has no solution of degree at most n in k[t], or a solution q in k[t] of this equation with deg(q) <= n. rrNz7is_deriv_in_field() is required to solve this problem.rFr)rfrrrr!NotImplementedErrorrr.rrrrischDErr)rBrSr&r;rrVrWrrr2rErta2aa2dsarHstms r*cancel_primitiver.s8  ,BDD!B -b"b 9 =DAqAv)++,, , yy188BDD>,, Q Aii HHRTTN q50 0 B  3qttvrtt,HCRS#r2FB 32::< ,RTT1W4bdd5I S E QsUZR( ((ii HA,,0 3 3s;F:FFF'cddlm}|jjt |j |j j }t|5t||j \}}t||j \}} ||| |||} | | \} } } | dk(r tdddd|jr|S||j|j krtt d|j }|js7|j|j } || krt|j }t|5t||j \}}|z|zt | |j zz}||z}t|j|j \}}t|||||\}}dddt j j z |j | zz|j d}||z }| dz }|||zt||zz}|js7|S#1swYxYw#1swYxYw)a Poly Risch Differential Equation - Cancellation: Hyperexponential case. Explanation =========== Given a derivation D on k[t], n either an integer or +oo, ``b`` in k, and ``c`` in k[t] with Dt/t in k and ``b != 0``, either raise NonElementaryIntegralException, in which case the equation Dq + b*q == c has no solution of degree at most n in k[t], or a solution q in k[t] of this equation with deg(q) <= n. rr_Nz6is_deriv_in_field() is required to solve this problem.rFr)rfr`r/r6rr!rrrrrr.rrrr)rBrSr&r;r`etarprqrVrWrrrrtr2rErAa1aa1drrrrHrs r* cancel_expr`s+ $$((4bdd# $ , , .C  +S"$$' dBDD!B RtR 8 =GAq!Av)+*+++ yy188BDD>,, Q Aii HHRTTN q50 0 YY[ B  5r244(HCd(T#Xd1bddm33Cd(Cqttvrtt,HCS#sC4FB 52::< ,RTT1W4bdd5I S E QsUZR( ((%ii& HS++8 5 5sAIA:IIIc|js~|jdk(sN|j|jt d|j j|jdz kDr!|rddlm}|||||St||||S|jsE|j|j|j j|jdz kr|jdk(s(|j j|jdk\r|rddlm }|||||St||||}t|tr|S|\}} } t|5| j|j| j|j} } | td| td t!| | ||j|j} ddd|| zS|j j|jdk\r)|j|j|j j|jdz k(r||j|jj# |j j|jj#z kDr|j|jj#j$s t'd |r t)d t+||||}t|tr|S|\}} } t!|| | |} || zS|jr t)d |jd k(r|r t)dt-||||S|jdk(r|r t)dt/||||St)d|jz#1swY| zSxYw)a  Solve a Polynomial Risch Differential Equation with degree bound ``n``. This constitutes step 4 of the outline given in the rde.py docstring. For parametric=False, cQ is c, a Poly; for parametric=True, cQ is Q == [q1, ..., qm], a list of Polys. r^rr)prde_no_cancel_b_larger)prde_no_cancel_b_smallNzb0 should be a non-Null valuezc0 should be a non-Null valuezResult should be a numberz0prde_no_cancel_b_equal() is not yet implemented.zWRemaining cases for Poly (P)RDE are not yet implemented (is_deriv_in_field() required).r[zIParametric RDE cancellation hyperexponential case is not yet implemented.r]zBParametric RDE cancellation primitive case is not yet implemented.zBOther Poly (P)RDE cancellation cases are not yet implemented (%s).)rrbr.r!rhr/rfrrrr isinstancerrrrdsolve_poly_rder is_number TypeErrorrrrr)rBrr&r;rrrRrRb0c0yrtrjs r*rrsP 99"''V+ HHRTTNSBDDKK$5$9: :  4)!RB7 7 B2.. ))qxx~ BDD(9A(== WW "$$++bdd"3q"8  4)!RB7 7 aQ + a HIAr2# @BDD)2::bdd+;B:$%DEE;$%DEE"2r1b199"$$?  @q5L RTT a AHHRTTNbddkk"$$6G!6K$K 244##%%bddll244&8&;&;&== =yy!!#--78 8 %'   Ar1b ) a HGAq!q!Q+Aq5L 99%'BC Cww%-/HII!!RB//K'-/ABB'2q"55*+:<>GG+DEEe @q5Ls A8N11N>cLt|||\}\}}t|||||\}\}}\} } } t|||| | |\} } }} t| | ||}t | | |||\} }}}}|jr|}nt| |||}||z|z| |zfS#t$r t }YPwxYw)a  Solve a Risch Differential Equation: Dy + f*y == g. Explanation =========== See the outline in the docstring of rde.py for more information about the procedure used. Either raise NonElementaryIntegralException, in which case there is no solution y in the given differential field, or return y in k(t) satisfying Dy + f*y == g, or raise NotImplementedError, in which case, the algorithms necessary to solve the given Risch Differential Equation have not yet been implemented. ) rIrXryrrrrrr)rLrMrNrOr;_rrVrWrTrUhnrrrirjhsr&rtrrrs r*rrs""b"-KAxB ,RRR @AxB"b22r2r26KAq!R  Aq" % 1aB/Aq!UDyy  1aB ' !GdNBrE ""   sBB#"B#r|)rZ)rZF)F))__doc__operatorr functoolsr sympy.corersympy.core.symbolr sympy.polysrrr r $sympy.functions.elementary.complexesr r (sympy.functions.elementary.miscellaneousr sympy.integrals.rischrrrrrrrr+r0rIrXryrrrrrrrrrr,r*rs.#--99[[[ ( V %0f"&JQht n-^ <+ ^, ^/ d9 xZz'#r,