K i jdZddlmZddlmZddlmZmZddlZddl m Z ddl m Z ddl mZdd lmZdd lmZdd lmZdd lmZmZmZdd lmZddlmZddlmZmZddl m!Z!m"Z"m#Z#m$Z$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-ddlm.Z.m/Z/ddl0m1Z1Gdde2Z3dddZ4dZ5d*dZ6dZ7d+d,dZ8d-d Z9d+d.d!Z:d+d,d"Z; d/d#Zd1d&Z?d2d'Z@d(ZAd)ZBy)3z,Solvers of systems of polynomial equations. ) annotations)Any)SequenceIterableN)Dummy)S)Expr) factor_terms)default_sort_key)Boolean)Polygroebnerroots)ZZ) build_options)parallel_poly_from_exprsqf_part)ComputationFailedPolificationFailedCoercionFailedGeneratorsNeeded DomainError)rcollect) postfixes)cartes) filldedent)OrAnd)EqceZdZdZy) SolveFailedz.Raised when solver's conditions were not met. N)__name__ __module__ __qualname____doc__[/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/solvers/polysys.pyr!r!#s8r'r!Fstrictc t|g|i|\}}t|t|jcxk(rdk(rGnnD|\}}t d|j |j zDr t|||St|||S#t$r}tdt||d}~wwxYw#t$rY@wxYw)a Return a list of solutions for the system of polynomial equations or else None. Parameters ========== seq: a list/tuple/set Listing all the equations that are needed to be solved gens: generators generators of the equations in seq for which we want the solutions strict: a boolean (default is False) if strict is True, NotImplementedError will be raised if the solution is known to be incomplete (which can occur if not all solutions are expressible in radicals) args: Keyword arguments Special options for solving the equations. Returns ======= List[Tuple] a list of tuples with elements being solutions for the symbols in the order they were passed as gens None None is returned when the computed basis contains only the ground. Examples ======== >>> from sympy import solve_poly_system >>> from sympy.abc import x, y >>> solve_poly_system([x*y - 2*y, 2*y**2 - x**2], x, y) [(0, 0), (2, -sqrt(2)), (2, sqrt(2))] >>> solve_poly_system([x**5 - x + y**3, y**2 - 1], x, y, strict=True) Traceback (most recent call last): ... UnsolvableFactorError solve_poly_systemNc3&K|] }|dk yw)r-Nr&).0is r( z$solve_poly_system..\sA!qAvAr)) rrrlengensall degree_listsolve_biquadraticr! solve_generic) seqr*r4argspolysoptexcfgs r(r,r,'sZD,S@4@4@ s 5zS]'a'1 Aq}}@A A (As33 F 33 D 3SXsCCD  s)B5 B7 B4B//B47 CCcxt||g}t|dk(r|djryt|dk7rt|j\}}|\}}|j |jstt ||d}t|jDcgc]}t||} }|jd}tt|j} tj| | D cgc]\} } | j|| | f} } } t| t Scc}wcc} } w) aSolve a system of two bivariate quadratic polynomial equations. Parameters ========== f: a single Expr or Poly First equation g: a single Expr or Poly Second Equation opt: an Options object For specifying keyword arguments and generators Returns ======= List[Tuple] a list of tuples with elements being solutions for the symbols in the order they were passed as gens None None is returned when the computed basis contains only the ground. Examples ======== >>> from sympy import Options, Poly >>> from sympy.abc import x, y >>> from sympy.solvers.polysys import solve_biquadratic >>> NewOption = Options((x, y), {'domain': 'ZZ'}) >>> a = Poly(y**2 - 4 + x, y, x, domain='ZZ') >>> b = Poly(y*2 + 3*x - 7, y, x, domain='ZZ') >>> solve_biquadratic(a, b, NewOption) [(1/3, 3), (41/27, 11/9)] >>> a = Poly(y + x**2 - 3, y, x, domain='ZZ') >>> b = Poly(-y + x - 4, y, x, domain='ZZ') >>> solve_biquadratic(a, b, NewOption) [(7/2 - sqrt(29)/2, -sqrt(29)/2 - 1/2), (sqrt(29)/2 + 7/2, -1/2 + sqrt(29)/2)] rNr-F)expandkey)rr3 is_groundr!r4gcdr rkeysrltrimlist itertoolsproductsubssortedr )r>r?r<Gxypqexprp_rootsq_rootsq_rootp_root solutionss r(r7r7esR !QA 1v{qt~~ 1v{ 88DAq DAq 558   Q% A-21X]]_=Txa =G=  A58==?#G""7G46nff&++a(&16I6 )!1 22> 6s D1?D6cdddfd  ||jd}|t|tSy#t$rtwxYw) a Solve a generic system of polynomial equations. Returns all possible solutions over C[x_1, x_2, ..., x_m] of a set F = { f_1, f_2, ..., f_n } of polynomial equations, using Groebner basis approach. For now only zero-dimensional systems are supported, which means F can have at most a finite number of solutions. If the basis contains only the ground, None is returned. The algorithm works by the fact that, supposing G is the basis of F with respect to an elimination order (here lexicographic order is used), G and F generate the same ideal, they have the same set of solutions. By the elimination property, if G is a reduced, zero-dimensional Groebner basis, then there exists an univariate polynomial in G (in its last variable). This can be solved by computing its roots. Substituting all computed roots for the last (eliminated) variable in other elements of G, new polynomial system is generated. Applying the above procedure recursively, a finite number of solutions can be found. The ability of finding all solutions by this procedure depends on the root finding algorithms. If no solutions were found, it means only that roots() failed, but the system is solvable. To overcome this difficulty use numerical algorithms instead. Parameters ========== polys: a list/tuple/set Listing all the polynomial equations that are needed to be solved opt: an Options object For specifying keyword arguments and generators strict: a boolean If strict is True, NotImplementedError will be raised if the solution is known to be incomplete Returns ======= List[Tuple] a list of tuples with elements being solutions for the symbols in the order they were passed as gens None None is returned when the computed basis contains only the ground. References ========== .. [Buchberger01] B. Buchberger, Groebner Bases: A Short Introduction for Systems Theorists, In: R. Moreno-Diaz, B. Buchberger, J.L. Freire, Proceedings of EUROCAST'01, February, 2001 .. [Cox97] D. Cox, J. Little, D. O'Shea, Ideals, Varieties and Algorithms, Springer, Second Edition, 1997, pp. 112 Raises ======== NotImplementedError If the system is not zero-dimensional (does not have a finite number of solutions) UnsolvableFactorError If ``strict`` is True and not all solution components are expressible in radicals Examples ======== >>> from sympy import Poly, Options >>> from sympy.solvers.polysys import solve_generic >>> from sympy.abc import x, y >>> NewOption = Options((x, y), {'domain': 'ZZ'}) >>> a = Poly(x - y + 5, x, y, domain='ZZ') >>> b = Poly(x + y - 3, x, y, domain='ZZ') >>> solve_generic([a, b], NewOption) [(-1, 4)] >>> a = Poly(x - 2*y + 5, x, y, domain='ZZ') >>> b = Poly(2*x - y - 3, x, y, domain='ZZ') >>> solve_generic([a, b], NewOption) [(11/3, 13/3)] >>> a = Poly(x**2 + y, x, y, domain='ZZ') >>> b = Poly(x + y*4, x, y, domain='ZZ') >>> solve_generic([a, b], NewOption) [(0, 0), (1/4, -1/16)] >>> a = Poly(x**5 - x + y**3, x, y, domain='ZZ') >>> b = Poly(y**2 - 1, x, y, domain='ZZ') >>> solve_generic([a, b], NewOption, strict=True) Traceback (most recent call last): ... UnsolvableFactorError cN|jD]}t|ddsyy)z8Returns True if 'f' is univariate in its last variable. NrCFT)monomsany)r>monoms r(_is_univariatez%solve_generic.._is_univariate s,XXZ E5": r'cx|j||i}|j|dk\r|jd}|S)z:Replace generator with a root so that the result is nice. r-F)deep)as_exprdegreerB)r>genzerorRs r( _subs_rootz!solve_generic.._subs_roots9 IIsDk " 88C=A e$Ar'ct|t|cxk(rdk(r?nnrdrY new_systemnew_gensbeqsolutionr__solve_reduced_systemrfr*s r(rxz,solve_generic.._solve_reduced_systems  v;#d) (q (vay$r(6BGGIJE(-.TG. .T2 u:?uQx11 &78 u:D !%j2'  z?a  A%j2'  vv2hU1773<7<<>?I u:?(-.TG. .  5DJCRyH3BZ *3-QVV#%%b)  * 2*hG 5  TG!34 5 5 Yq\*c$i7%j2' w/J/s  H H T)roNrDF)r4rrjrNr )r;r<r*resultr_rxrfs ` @@@r(r8r8sdHAAF"&uchhdCf"233 "!!"s >Ac t||}t||d}tt|}|j dd}|rd}n=|j d}|'t |D]\}} | j |||<d}|d jd |d d}} | j} || } |r"| D chc]} | f| j| f}} n| D chc]} | f| f }} t|dd }t|d d}t||D]<\}}t}|D]$\}} gtt||}}|D]} |f|z}| j|s| j|d k7s.|r*| j | jj!| } | j|j#t%|}| j||jk(s|j'|t)|d }||} | D]1} | | vr| j| }n| }|j+| f|z|f3'|}?t-d|Dt. Scc} wcc} w)aB Solve a polynomial system using Gianni-Kalkbrenner algorithm. The algorithm proceeds by computing one Groebner basis in the ground domain and then by iteratively computing polynomial factorizations in appropriately constructed algebraic extensions of the ground domain. Parameters ========== polys: a list/tuple/set Listing all the equations that are needed to be solved gens: generators generators of the equations in polys for which we want the solutions args: Keyword arguments Special options for solving the equations Returns ======= List[Tuple] A List of tuples. Solutions for symbols that satisfy the equations listed in polys Examples ======== >>> from sympy import solve_triangulated >>> from sympy.abc import x, y, z >>> F = [x**2 + y + z - 1, x + y**2 + z - 1, x + y + z**2 - 1] >>> solve_triangulated(F, x, y, z) [(0, 0, 1), (0, 1, 0), (1, 0, 0)] Using extension for algebraic solutions. >>> solve_triangulated(F, x, y, z, extension=True) #doctest: +NORMALIZE_WHITESPACE [(0, 0, 1), (0, 1, 0), (1, 0, 0), (CRootOf(x**2 + 2*x - 1, 0), CRootOf(x**2 + 2*x - 1, 0), CRootOf(x**2 + 2*x - 1, 0)), (CRootOf(x**2 + 2*x - 1, 1), CRootOf(x**2 + 2*x - 1, 1), CRootOf(x**2 + 2*x - 1, 1))] References ========== 1. Patrizia Gianni, Teo Mora, Algebraic Solution of System of Polynomial Equations using Groebner Bases, AAECC-5 on Applied Algebra, Algebraic Algorithms and Error-Correcting Codes, LNCS 356 247--257, 1989 Trh extensionFcZ|jddDcgc]\}}| c}}Scc}}w)NF)multipleradicals) all_roots)r>r_s r(_solve_univariatez-solve_triangulated.._solve_univariates'"#++uu+"MN$!QAN NNs 'domainNcPt|jjSN)rJ ground_rootsrH)r>s r(rz-solve_triangulated.._solve_univariates(--/0 0r'rrCrAc"|jSr)rc)hs r(z$solve_triangulated..s QXXZr'rDc3&K|] \}}| ywrr&)r/srs r(r1z%solve_triangulated..s+A1+r2)rrrJreversedget enumerate set_domainrI get_domainalgebraic_fieldrzipset has_only_gensrcrunifyevaldictrmminaddrNr )r;r4r:r<rOr|rrr0r?r>domrprerYvar_seqvars_seqvarvars _solutionsvaluesHmapping_varsrrRdom_zeros r(solve_triangulatedris{h d #CD)A Xa[A U+I O"  !!  ,1||F+! , 1 Q4::b>1QR5qA ,,.C a EFKLdtgs22489L L056tgs^6 6tCRy!Gab"H(+ TU $ =KFCT#dF"34wA $ "1??E*qxx}/A LL)<= ))$w-8Axx} 2  $A/0A%a(E = "2248H"H& 0(;<  =# =2 9: ++1A BBIM6s ;I+ I0c t||fi|}|Dcgc]}t|r|}}|Dcgc] }|Dcgc]}|jc}"}}}|Scc}wcc}wcc}}w)ak Factorizes a system of polynomial equations into irreducible subsystems. Parameters ========== eqs : list List of expressions to be factored. Each expression is assumed to be equal to zero. gens : list, optional Generator(s) of the polynomial ring. If not provided, all free symbols will be used. **kwargs : dict, optional Same optional arguments taken by ``factor`` Returns ======= list[list[Expr]] A list of lists of expressions, where each sublist represents an irreducible subsystem. When solved, each subsystem gives one component of the solution. Only generic solutions are returned (cases not requiring parameters to be zero). Examples ======== >>> from sympy.solvers.polysys import factor_system, factor_system_cond >>> from sympy.abc import x, y, a, b, c A simple system with multiple solutions: >>> factor_system([x**2 - 1, y - 1]) [[x + 1, y - 1], [x - 1, y - 1]] A system with no solution: >>> factor_system([x, 1]) [] A system where any value of the symbol(s) is a solution: >>> factor_system([x - x, (x + 1)**2 - (x**2 + 2*x + 1)]) [[]] A system with no generic solution: >>> factor_system([a*x*(x-1), b*y, c], [x, y]) [] If c is added to the unknowns then the system has a generic solution: >>> factor_system([a*x*(x-1), b*y, c], [x, y, c]) [[x - 1, y, c], [x, y, c]] Alternatively :func:`factor_system_cond` can be used to get degenerate cases as well: >>> factor_system_cond([a*x*(x-1), b*y, c], [x, y]) [[x - 1, y, c], [x, y, c], [x - 1, b, c], [x, b, c], [y, a, c], [a, b, c]] Each of the above cases is only satisfiable in the degenerate case `c = 0`. The solution set of the original system represented by eqs is the union of the solution sets of the factorized systems. An empty list [] means no generic solution exists. A list containing an empty list [[]] means any value of the symbol(s) is a solution. See Also ======== factor_system_cond : Returns both generic and degenerate solutions factor_system_bool : Returns a Boolean combination representing all solutions sympy.polys.polytools.factor : Factors a polynomial into irreducible factors over the rational numbers )_factor_system_poly_from_expr_is_degeneraterb) eqsr4kwargssystemssyssystems_genericrnrR systems_exprs r( factor_systemrsfh,C@@G&-Is^C5HsIOI@OPf&1QQYY[1PLP J1Ps AA A"A A"A"c&td|DS)z2Helper function to check if a system is degeneratec34K|]}|jywr)rFr/rRs r(r1z!_is_degenerate..9s+qq{{+s)r])rns r(rr7s +F+ ++r'c t||fi|}t|Dcgc]"}t|Dcgc]}t|dc}$c}}Scc}wcc}}w)aV Factorizes a system of polynomial equations into irreducible DNF. The system of expressions(eqs) is taken and a Boolean combination of equations is returned that represents the same solution set. The result is in disjunctive normal form (OR of ANDs). Parameters ========== eqs : list List of expressions to be factored. Each expression is assumed to be equal to zero. gens : list, optional Generator(s) of the polynomial ring. If not provided, all free symbols will be used. **kwargs : dict, optional Optional keyword arguments Returns ======= Boolean: A Boolean combination of equations. The result is typically in the form of a conjunction (AND) of a disjunctive normal form with additional conditions. Examples ======== >>> from sympy.solvers.polysys import factor_system_bool >>> from sympy.abc import x, y, a, b, c >>> factor_system_bool([x**2 - 1]) Eq(x - 1, 0) | Eq(x + 1, 0) >>> factor_system_bool([x**2 - 1, y - 1]) (Eq(x - 1, 0) & Eq(y - 1, 0)) | (Eq(x + 1, 0) & Eq(y - 1, 0)) >>> eqs = [a * (x - 1), b] >>> factor_system_bool([a*(x - 1), b]) (Eq(a, 0) & Eq(b, 0)) | (Eq(b, 0) & Eq(x - 1, 0)) >>> factor_system_bool([a*x**2 - a, b*(x + 1), c], [x]) (Eq(c, 0) & Eq(x + 1, 0)) | (Eq(a, 0) & Eq(b, 0) & Eq(c, 0)) | (Eq(b, 0) & Eq(c, 0) & Eq(x - 1, 0)) >>> factor_system_bool([x**2 + 2*x + 1 - (x + 1)**2]) True The result is logically equivalent to the system of equations i.e. eqs. The function returns ``True`` when all values of the symbol(s) is a solution and ``False`` when the system cannot be solved. See Also ======== factor_system : Returns factors and solvability condition separately factor_system_cond : Returns both factors and conditions r)factor_system_condrrr)rr4rrrrvs r(factor_system_boolr<sHB!d5f5G 7CC#.BbQi./C DD.CsA AA A c t||fi|}|Dcgc] }|Dcgc]}|jc}"}}}|Scc}wcc}}w)a Factorizes a polynomial system into irreducible components and returns both generic and degenerate solutions. Parameters ========== eqs : list List of expressions to be factored. Each expression is assumed to be equal to zero. gens : list, optional Generator(s) of the polynomial ring. If not provided, all free symbols will be used. **kwargs : dict, optional Optional keyword arguments. Returns ======= list[list[Expr]] A list of lists of expressions, where each sublist represents an irreducible subsystem. Includes both generic solutions and degenerate cases requiring equality conditions on parameters. Examples ======== >>> from sympy.solvers.polysys import factor_system_cond >>> from sympy.abc import x, y, a, b, c >>> factor_system_cond([x**2 - 4, a*y, b], [x, y]) [[x + 2, y, b], [x - 2, y, b], [x + 2, a, b], [x - 2, a, b]] >>> factor_system_cond([a*x*(x-1), b*y, c], [x, y]) [[x - 1, y, c], [x, y, c], [x - 1, b, c], [x, b, c], [y, a, c], [a, b, c]] An empty list [] means no solution exists. A list containing an empty list [[]] means any value of the symbol(s) is a solution. See Also ======== factor_system : Returns only generic solutions factor_system_bool : Returns a Boolean combination representing all solutions sympy.polys.polytools.factor : Factors a polynomial into irreducible factors over the rational numbers )rrb)rr4r systems_polyrnrRrs r(rrsGf1dEfEL;GHV, ,HGH N-Hs A= AAc  t|g|i|\}}d}|rt d|DrggSgSt |S#ttf$r2td}t||gfi|\}}|djsJd}YdwxYw)z Convert expressions to polynomials and factor the system. Takes a sequence of expressions, converts them to polynomials, and factors the resulting system. Handles both regular polynomial systems and purely numerical cases. FurTc3&K|] }|dk( yw)rNr&rs r(r1z0_factor_system_poly_from_expr..s1a161r2)rrrr is_Numericalr5factor_system_poly)rr4rr;opts only_numbers_us r(rrs-cCDCFC t 1511t9r9 e $$ 0 1 3Z-cB4B6B tH~**** s:>A;:A;c  td|Ds td|sggS|dj |dj t fd|ddDs t dg}|D]}|j \}}|j dur%|j d ur+|sgcS|j|Dcgc]\}}| c}}^tt|jd}t| }|Dcgc]\}}| }}}|j||j||sggSt|} t| Scc}}wcc}}w) a Factors a system of polynomial equations into irreducible subsystems Core implementation that works directly with Poly instances. Parameters ========== polys : list[Poly] A list of Poly instances to be factored. Returns ======= list[list[Poly]] A list of lists of polynomials, where each sublist represents an irreducible component of the solution. Includes both generic and degenerate cases. Examples ======== >>> from sympy import symbols, Poly, ZZ >>> from sympy.solvers.polysys import factor_system_poly >>> a, b, c, x = symbols('a b c x') >>> p1 = Poly((a - 1)*(x - 2), x, domain=ZZ[a,b,c]) >>> p2 = Poly((b - 3)*(x - 2), x, domain=ZZ[a,b,c]) >>> p3 = Poly(c, x, domain=ZZ[a,b,c]) The equation to be solved for x is ``x - 2 = 0`` provided either of the two conditions on the parameters ``a`` and ``b`` is nonzero and the constant parameter ``c`` should be zero. >>> sys1, sys2 = factor_system_poly([p1, p2, p3]) >>> sys1 [Poly(x - 2, x, domain='ZZ[a,b,c]'), Poly(c, x, domain='ZZ[a,b,c]')] >>> sys2 [Poly(a - 1, x, domain='ZZ[a,b,c]'), Poly(b - 3, x, domain='ZZ[a,b,c]'), Poly(c, x, domain='ZZ[a,b,c]')] An empty list [] when returned means no solution exists. Whereas a list containing an empty list [[]] means any value is a solution. See Also ======== factor_system : Returns only generic solutions factor_system_bool : Returns a Boolean combination representing the solutions factor_system_cond : Returns both generic and degenerate solutions sympy.polys.polytools.factor : Factors a polynomial into irreducible factors over the rational numbers c3<K|]}t|tywr) isinstancer )r/polys r(r1z%factor_system_poly.. s8$z$%8sz(polys should be a list of Poly instancesrc3^K|]$}|jk(xr|jk(&ywr)rr4)r/r base_domain base_genss r(r1z%factor_system_poly..s+[t{{k)Ddii9.DD[s*-rANz8All polynomials must have the same domain and generatorsTF)r)r5 TypeErrorrr4r factor_listis_zerormrr as_coeff_Mulr _factor_sets _sort_systems) r; factor_setsrconstant factors_multr>rconstpfactorsrzrrs @@r(rrsZn 8%8 8BCC t (//Ka I [QVWXWYQZ[ [TUUK(!%!1!1!3,   t #     &   l;da; < X 6 C C Ea HIH(IkBF%12TQq2G2 NN6 "   w '( t + &F    <3s 3 E Ec|s thSt|Dchc] }t|}}|Dchc]tfd|Drc}Scc}wcc}w)z Helper to find the minimal set of factorised subsystems that is equivalent to the original system. The result is in DNF. c3(K|] }|kD ywrr&r/s2s1s r(r1z$_factor_sets_slow..5s/NBR/N) frozensetrr])rr systems_setrs `r(_factor_sets_slowr+sS  }-3S\:c9S>:K:$ O2C/N+/N,NB OO; OsAA Ac v|s thSt|t}|Dcgc] }||us| }}|Dcgc]}||Dcgc] }||vs| c}|hf}}}t}|r|j \}}}|s|j t|3t|t} |Dcgc] }|| us| } }| D]0} | Dcgc] }| |vs| } }|| hz} |j | | | f2|r|Dchc]tfd|Drc}Scc}wcc}wcc}}wcc}wcc}wcc}w)z1 Helper that builds factor combinations. rDc3(K|] }|kD ywrr&rs r(r1z_factor_sets..Vs*Dr27*Dr)rrr3rrkrrmr])r current_setr other_setsfactorstackrzremaining_setscurrent_solutionnext_setnext_remaining next_factorvalid_remaining new_solutionrs `r(rr8s\  }cs#K 9A[$8!9J9' (*@Qaq@6( K (E (UF 3899;0 0 JJy!12 3 ~3/%3Iq7H!II# GK*8QQKq {{r"    txx//1 11r'c@tttt|S)z!Sort key for lists of polynomials)rJrmapr)rs r(rrfs S-. //r'ry)r&)rSequence[Expr | complex]r4Sequence[Expr]rrreturnzlist[list[Expr]])rn list[Poly]rbool)rrr4rrrrr )rrr4rrrrlist[list[Poly]])r;rrr)rz list[list]rzset[frozenset])rzIterable[Iterable[Poly]]rr)Cr% __future__rtypingrcollections.abcrrrKsympyr sympy.corersympy.core.exprr sympy.core.exprtoolsr sympy.core.sortingr sympy.logic.boolalgr sympy.polysr rrsympy.polys.domainsrsympy.polys.polyoptionsrsympy.polys.polytoolsrrsympy.polys.polyerrorsrrrrrsympy.simplifyrsympy.utilitiesrsympy.utilities.iterablesrsympy.utilities.miscrrrsympy.core.relationalr Exceptionr!r,r7r8rrrrrrrrrrrrr&r'r(rs2". -/'--"1C$%,+'$9)9*/;4|@3F~4BqChWt, BEJ5p% %%-;%GJ%%2V!r PFBA 20r'