K i`TddlmZmZmZmZmZddlmZmZm Z ddl m Z ddl m Z ddlmZmZmZddlmZmZdZdefd Zd Zd Zdd Zd ZGddeZdZdZddZ dZ!dZ"dZ#dZ$dZ%y))AddExprMulSsympify)_mexpand count_ops expand_mul)default_sort_key)Dummy)rootsignsqrt)PolyPolynomialErrorc|jxr=|jjxr%t|jtj uS)z/Return True if expr is a sqrt, otherwise False.)is_Powexp is_RationalabsrHalf)exprs _/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/simplify/sqrtdenest.pyis_sqrtr s3 ;; K488// KCMQVV4KKreturnc|tjury|jry|js |jrt d|j DSt|rt|jdzSy)aReturn the maximum depth of any square root argument of p. >>> from sympy.functions.elementary.miscellaneous import sqrt >>> from sympy.simplify.sqrtdenest import sqrt_depth Neither of these square roots contains any other square roots so the depth is 1: >>> sqrt_depth(1 + sqrt(2)*(1 + sqrt(3))) 1 The sqrt(3) is contained within a square root so the depth is 2: >>> sqrt_depth(1 + sqrt(2)*sqrt(1 + sqrt(3))) 2 rc32K|]}t|ywN) sqrt_depth.0xs r zsqrt_depth..&s1Q:a=1) r ImaginaryUnitis_Atomis_Addis_Mulmaxargsrr!baseps rr!r!s]$ AOOyyxx1881!&&111qz!&&!A%% rc$|jry|jryt|s"|jr+|jj rt |jS|js |jrtd|jDSy)aReturn True if p is comprised of only Rationals or square roots of Rationals and algebraic operations. Examples ======== >>> from sympy.functions.elementary.miscellaneous import sqrt >>> from sympy.simplify.sqrtdenest import is_algebraic >>> from sympy import cos >>> is_algebraic(sqrt(2)*(3/(sqrt(7) + sqrt(5)*sqrt(2)))) True >>> is_algebraic(sqrt(2)*(3/(sqrt(7) + sqrt(5)*cos(2)))) False TFc32K|]}t|ywr ) is_algebraicr"s rr%zis_algebraic..Cs3q<?3r&) rr(rrr is_Integerr2r-r)r*allr,r.s rr2r2,se  }}  qxxAEE$4$4AFF## QXX3AFF333rc |dk(rdgg}|S|dk(r ddgddgddgg}|S|dk(rgdgdgdgdgd gd gd g}|St|dz }|Dcgc]}|dgz }}|Dcgc]}|dgz }}|dg|dz zdgzgz|z}|Scc}wcc}w) ag Returns all possible subsets of the set (0, 1, ..., n-1) except the empty set, listed in reversed lexicographical order according to binary representation, so that the case of the fourth root is treated last. Examples ======== >>> from sympy.simplify.sqrtdenest import _subsets >>> _subsets(2) [[1, 0], [0, 1], [1, 1]] rr)rrr)rrr)rrr)rrr)rrr)rrr)rrr)_subsets)nabr$a0a1s rr8r8Hs AvSE H aVaVaV $ H a  9  9i 9 H QUO !!a1#g ! ! !!a1#g ! ! 1#q1u+#$ $r ) H" !s  B! B cht|}t|D]}t|}||k(r|cS|}|S)aDenests sqrts in an expression that contain other square roots if possible, otherwise returns the expr unchanged. This is based on the algorithms of [1]. Examples ======== >>> from sympy.simplify.sqrtdenest import sqrtdenest >>> from sympy import sqrt >>> sqrtdenest(sqrt(5 + 2 * sqrt(6))) sqrt(2) + sqrt(3) See Also ======== sympy.solvers.solvers.unrad References ========== .. [1] https://web.archive.org/web/20210806201615/https://researcher.watson.ibm.com/researcher/files/us-fagin/symb85.pdf .. [2] D. J. Jeffrey and A. D. Rich, 'Symplifying Square Roots of Square Roots by Denesting' (available at https://www.cybertester.com/data/denest.pdf) )r range _sqrtdenest0)rmax_iterizs r sqrtdenestrDesC6 d D 8_   19K  Krcddlm}t|}|jr,|tj tj f}t|S|j r=t|jt}|Dcgc]}|dz }}td|Dr||\}}}|||f}t|St|D cgc]\} }t||| f} } }t| t} | ddk(r g}t|S| \} } } |j| }| j| tj }|j"rpg}g}|jD]3}t|| kr|j%|#|j%|5t'j(|}t'j(|}g}|g}| D]}|d| kr|j%|d |d}||k(r|j%d<|j"rWt|j}||vr)|j+||j%t'||j%|d|j%|dt-|}t-|}|||dzf}t|S|j/\}}t1|r!tj ||dzf}t|Sg}t|Scc}wcc}} w)aReturn [a, b, r] for p.match(a + b*sqrt(r)) where, in addition to matching, sqrt(r) also has then maximal sqrt_depth among addends of p. Examples ======== >>> from sympy.functions.elementary.miscellaneous import sqrt >>> from sympy.simplify.sqrtdenest import _sqrt_match >>> _sqrt_match(1 + sqrt(2) + sqrt(2)*sqrt(3) + 2*sqrt(1+sqrt(5))) [1 + sqrt(2) + sqrt(6), 2, 1 + sqrt(5)] r) split_surdskeyr6c3PK|]}|jxr |j ywr )r is_positive)r#sqs rr%z_sqrt_match..s BRr~~0"..0Bs$&r)sympy.simplify.radsimprFr is_NumberrZeror)sortedr,r r4list enumerater!r+popOner*appendr _from_argsremover as_coeff_Mulr)r/rFrespargsr$sqargsrr;r:rBvnmaxdepth_bvrvr=b1x1x1argss r _sqrt_matchres3 A{{!&&!&&!x 9w qvv#34 %&1!Q$&& B6B B!!nGAq!Q'C9 09/? @tq!jmQ " @ @1*+ 7a<C\ 9WKE1a ! A EE!HAxx%A!!}u, !  ! % NN2&NN2&BB ,Q4%<IIadO1BQw ! 99%)"'']F F{ & a 0 " #v, 7 " !A$IIadO! ,"RARAaA,C 9 ~~1 1:661ad#C 9C 9s' As 6 K K%c eZdZy)SqrtdenestStopIterationN)__name__ __module__ __qualname__rrrgrgsrrgc t|r|j\}}|tjur|jj rt |jjt}t|dkDrtd|Dr t|Sttt|Dcgc] }t!|c}}t#|S||fDcgc] }t!|c}\}}||z St%|trzg}g}|jD]7}|j'\}} |j)||j)| 9td|Drtd|Dr t+||St%|t,r4|j}|r&|j.|D cgc] } t!| c} S|S#t$rY;wxYwcc}wcc}wcc} w)z+Returns expr after denesting its arguments.rGr6c3:K|]}|dzjyw)r6N)r3r"s rr%z_sqrtdenest0..s(Iq!Q$):):(Isc34K|]}|jywr )r)r#cs rr%z_sqrtdenest0..s)q}})c32K|]}t|ywr )r)r#args rr%z_sqrtdenest0..s1O3'#,1Or&)ras_numer_denomrrSr-r)rOr,r lenr4_sqrtdenest_recrgrrrr@ _sqrtdenest1 isinstancerWrT _sqrt_ratcombrfunc) rr9dr,r$rBcsrrror:s rr@r@st}""$1 :vv}}affkk/?@t9q=S(ID(I%I.q11HSD*Iq<?*I%JKL% %./V4LO4DAqQ3J$ 99 C##%DAq IIaL KKN  )b) )c1O$1O.O T* *$yy 499=1|A=> > K/3*I5">s$ G+GG/G! GGcfddlm}m}m}|js t |S|j dkr+tdtt|j zS||j \}}}|t|z}||kr||}}t|dz|dzz }t|jdkDr||\}}} |t|z}|| kr| |} }t|dz| dzz } tt| } tt|| z} || | \} }t| tdz | |tdzz z}ntt|}t|dkDrt||z}t|jt|jk\r't|t|j k\rtt t|}t|dkDrt|||\} }|tdz | |tdzz z}||}t|S)alHelper that denests the square root of three or more surds. Explanation =========== It returns the denested expression; if it cannot be denested it throws SqrtdenestStopIteration Algorithm: expr.base is in the extension Q_m = Q(sqrt(r_1),..,sqrt(r_k)); split expr.base = a + b*sqrt(r_k), where `a` and `b` are on Q_(m-1) = Q(sqrt(r_1),..,sqrt(r_(k-1))); then a**2 - b**2*r_k is on Q_(m-1); denest sqrt(a**2 - b**2*r_k) and so on. See [1], section 6. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.sqrtdenest import _sqrtdenest_rec >>> _sqrtdenest_rec(sqrt(-72*sqrt(2) + 158*sqrt(5) + 498)) -sqrt(10) + sqrt(2) + 9 + 9*sqrt(5) >>> w=-6*sqrt(55)-6*sqrt(35)-2*sqrt(22)-2*sqrt(14)+2*sqrt(77)+6*sqrt(10)+65 >>> _sqrtdenest_rec(sqrt(w)) -sqrt(11) - sqrt(7) + sqrt(2) + 3*sqrt(5) r)radsimprad_rationalizerFr6r)rLr}r~rFrrDr-rrurrtr,rvr!rgr )rr}r~rFgr:r;c2r=rbc2_1c_1d_1numdenroacrzr[s rrurus4ML ;;$ yy1}BxdiiZ(8999$))$GAq! $q' A1u!1 !Q$A+ B 277|aO 2r QZ 7BAA &d4j)d28n-"2s+S Sa[3DG #44 5 b "!}q%% QB 277|s499~% R=Idii0 0) )48A!}q%%q!$HC $q' CT!W%%A A A;rcddlm}t|s|S|j}|jr|St |}|s|S|\}}}t |dz|dz|zz }|jro|jrt||||}|d|St | |z} t| } | jr>$Q1b1A} B3q5/CcB~~(!A#1cB=T!QZ<' "!Q * =H <- !$1a 4C   aB-C747#$c1j.>?BA 1v~ } a=Jt, ,1 $1OK KrcVtt|||f\}}}t|}|sy|\}}}|rtdd} t |j t ||dz|z |z |}|jdk(r|j\} } } | |z } t| dzd| z| zz jdr]t | t || d| zz zdzz} | jr,ttj| j} | Syyy#t$rYywxYw)a4Given an expression, sqrt(a + b*sqrt(b)), return the denested expression or None. Explanation =========== If r = ra + rb*sqrt(rr), try replacing sqrt(rr) in ``a`` with (y**2 - ra)/rb, and if the result is a quadratic, ca*y**2 + cb*y + cc, and (cb + b)**2 - 4*ca*cc is 0, then sqrt(a + b*sqrt(r)) can be rewritten as sqrt(ca*(sqrt(r) + (cb + b)/(2*ca))**2). Examples ======== >>> from sympy.simplify.sqrtdenest import _sqrt_symbolic_denest, sqrtdenest >>> from sympy import sqrt, Symbol >>> from sympy.abc import x >>> a, b, r = 16 - 2*sqrt(29), 2, -10*sqrt(29) + 55 >>> _sqrt_symbolic_denest(a, b, r) sqrt(11 - 2*sqrt(29)) + sqrt(5) If the expression is numeric, it will be simplified: >>> w = sqrt(sqrt(sqrt(3) + 1) + 1) + 1 + sqrt(2) >>> sqrtdenest(sqrt((w**2).expand())) 1 + sqrt(2) + sqrt(1 + sqrt(1 + sqrt(3))) Otherwise, it will only be simplified if assumptions allow: >>> w = w.subs(sqrt(3), sqrt(x + 3)) >>> sqrtdenest(sqrt((w**2).expand())) sqrt((sqrt(sqrt(sqrt(x + 3) + 1) + 1) + 1 + sqrt(2))**2) Notice that the argument of the sqrt is a square. If x is made positive then the sqrt of the square is resolved: >>> _.subs(x, Symbol('x', positive=True)) sqrt(sqrt(sqrt(x + 3) + 1) + 1) + 1 + sqrt(2) NyT)positiver6rr)maprrer rsubsrrdegree all_coeffsrequals is_numberrrUas_content_primitive) r:r;r[rvalrarbrrrnewacacbccrCs rrr|s0T'Aq!9%GAq! q>D JBB # % tBx!Q$)R8! 0$ If it cannot be denested, it returns ``None``. rr6rN)rr!rrexpand) r:r;r[rrzss1s2rXs rrrs RA AA !}z!}q((QT,>,>a$q'B >r>KBDQK"tAE{"22d1g=Azz| -?rc Fddlm}m}|dks|dks|rt|jdkry|||fD]3}|j D]"}|dz} | j r | jr!y5ttt||} t| dkDry|dz | dz z|dz | dz z g\} } | | fD]g}tt|} t| dkDr&||td| z\}}||z }| |t|zz}|dkr| }t|cSy)adenest expr = sqrt(a + b*sqrt(r)) where a, b, r are linear combinations of square roots of positive rationals on the rationals (SQRR) and r > 0, b != 0, d2 = a**2 - b**2*r > 0 If it cannot denest it returns None. Explanation =========== Search for a solution A of type SQRR of the biquadratic equation 4*A**4 - 4*a*A**2 + b**2*r = 0 (1) sqd = sqrt(a**2 - b**2*r) Choosing the sqrt to be positive, the possible solutions are A = sqrt(a/2 +/- sqd/2) Since a, b, r are SQRR, then a**2 - b**2*r is a SQRR, so if sqd can be denested, it is done by _sqrtdenest_rec, and the result is a SQRR. Similarly for A. Examples of solutions (in both cases a and sqd are positive): Example of expr with solution sqrt(a/2 + sqd/2) but not solution sqrt(a/2 - sqd/2): expr = sqrt(-sqrt(15) - sqrt(2)*sqrt(-sqrt(5) + 5) - sqrt(3) + 8) a = -sqrt(15) - sqrt(3) + 8; sqd = -2*sqrt(5) - 2 + 4*sqrt(3) Example of expr with solution sqrt(a/2 - sqd/2) but not solution sqrt(a/2 + sqd/2): w = 2 + r2 + r3 + (1 + r3)*sqrt(2 + r2 + 5*r3) expr = sqrt((w**2).expand()) a = 4*sqrt(6) + 8*sqrt(2) + 47 + 28*sqrt(3) sqd = 29 + 20*sqrt(3) Define B = b/2*A; eq.(1) implies a = A**2 + B**2*r; then expr**2 = a + b*sqrt(r) = (A + B*sqrt(r))**2 Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.sqrtdenest import _sqrt_match, sqrt_biquadratic_denest >>> z = sqrt((2*sqrt(2) + 4)*sqrt(2 + sqrt(2)) + 5*sqrt(2) + 8) >>> a, b, r = _sqrt_match(z**2) >>> d2 = a**2 - b**2*r >>> sqrt_biquadratic_denest(z, a, b, r, d2) sqrt(2) + sqrt(sqrt(2) + 2) + 2 r)r}r~r6Nr) rLr}r~r!r-r,r3rJrrDr)rr:r;r[rr}r~r$ry2sqdrcx2ABnBdBrCs rrrs:`@AvaqJtyy$9A$=AY AAB==  :d72;/0 1C#cCEk1Q3Q; 'FB"X  tAw  a=1   HQqSM2B rE $q' M q5A{  rc ddlm}||kDry|dy|dtd|Drtt |D]ut t tt Dcgc] }|s ||c}}jddkDrdr| }t|}|jsq|fcSt|ddgt |zfSd}|d|ddg} |d}|d |g} d|d<nttd|D cgc] } t| c} } | D]} | ds ||| dk7sd|d<y| d}!|t|ddgt |zfS| D cgc](} t | ddzt || ddzzz *c} |gz} t| ||dz|\} sytfd tt |Ds'| d} t| dt | d| zzfSt tt |Dcgc] }|s ||c}}t|} dvrCj!dt |dz kr#t |dz r| d | d<| d | d<t |st | d| z}|dkrt|ddgt |zfSt#|t#|dzks|dzj$sd|d<yt't|d }t#|t#|dzksd|d<y|d|z }t |tdz | dt|z|ztdz z}|fSt | d|z| z}|dkrt|ddgt |zfSt)t |d t|}}t |td|zz | d|ztd|zz zfScc}wcc} wcc} wcc}w)aDenests a list of expressions that contain nested square roots. Explanation =========== Algorithm based on . It is assumed that all of the elements of 'nested' share the same bottom-level radicand. (This is stated in the paper, on page 177, in the paragraph immediately preceding the algorithm.) When evaluating all of the arguments in parallel, the bottom-level radicand only needs to be denested once. This means that calling _denester with x arguments results in a recursive invocation with x+1 arguments; hence _denester has polynomial complexity. However, if the arguments were evaluated separately, each call would result in two recursive invocations, and the algorithm would have exponential complexity. This is discussed in the paper in the middle paragraph of page 179. rr)NNrNc34K|]}|jywr )rM)r#r9s rr%z_denester..6s, ,rprr6r7c3(K|] }| ywr rk)r#rBfs rr%z_denester..Ys4A1Q44sF)rr)rr}r4r8rtrrr?countrrrPfilterreranyindexr!rMrvr )nestedrhmax_depth_levelr}rBr/sqpRvaluesnested2rr\rzvadsqvadsqvad1rXrFRrrs @rrrsB.0? 1v~ A ,V, ,#f+& A%A-HQ1Q4vayHIJAwwqzA~!B%Bq'CAv  F2J!S[00  q6 "1gYFAA1vqkGCF&f'Md D(9'MNOF !Q4}!9%)CF#-aD !yF2J'!S[884:14s6{!344r A!x!Q//0!3 3s6{);DAqtfQiDEAAAAv!''!*s6{Q61S[1_;M!u!!u!S[>qtax(!8r +aSV_<<!#*Q-!*;;Q))!CF%$T#Y?"5)Z]Q->>!CF% 5)uT!W}!T!W V0CDG0KLMAv ad1f%)7r +aSV_<<Xa[!,d2hA472:1b$q'!)1D DEqHHEI (N<Es$" O8-O8O=&-P P$Pc<ddlm}d}||}|(tt||Dcgc] \}}||z c}}S|\}}} |j | } |j | ||} ||xx|| |z| j z z cc<t ||Scc}}w)a#Denest rational combinations of radicals. Based on section 5 of [1]. Examples ======== >>> from sympy import sqrt >>> from sympy.simplify.sqrtdenest import sqrtdenest >>> z = sqrt(1+sqrt(3)) + sqrt(3+3*sqrt(3)) - sqrt(10+6*sqrt(3)) >>> sqrtdenest(z) 0 rrct|}t|dz D]m}t|dz|D]Y}||j}||j}t||z}t t |}|t |k7sR|||fccSoy)Nr)rtr?r-rrDr)r:r9rBjrrr/rs rfindz_sqrt_ratcomb..finds Fq1u #A1q5!_ #qTYYqTYYR"W%tAw'Q<a7N  # #r)rLr}rziprRr-rx) r{r,r}rindicesrorrri1i2rr=s rrxrx}s/ #4jG3r4=9CQW9::IAr2 BHHRL bBrFgb1frww&''F T "":sB N)r7)T)& sympy.corerrrrrsympy.core.functionrr r sympy.core.sortingr sympy.core.symbolr sympy.functionsr rr sympy.polysrrrintr!r2r8rDre StopIterationrgr@rurvrrrrrxrkrrrs11??/#,,-L  S :8 :!HL^ m "J=@8v<~(GTaIH)#r