Navigation

Source code for sympy.polys.constructor

"""Tools for constructing domains for expressions. """fromsympy.polys.polyutilsimportparallel_dict_from_basicfromsympy.polys.polyoptionsimportbuild_optionsfromsympy.polys.polyerrorsimportGeneratorsNeededfromsympy.polys.domainsimportZZ,QQ,RR,EXfromsympy.assumptionsimportask,Qfromsympy.coreimportsympifydef_construct_simple(coeffs,opt):"""Handle simple domains, e.g.: ZZ, QQ, RR and algebraic domains. """result,rationals,reals,algebraics={},False,False,Falseifopt.extensionisTrue:is_algebraic=lambdacoeff:ask(Q.algebraic(coeff))else:is_algebraic=lambdacoeff:False# XXX: add support for a + b*I coefficientsforcoeffincoeffs:ifcoeff.is_Rational:ifnotcoeff.is_Integer:rationals=Trueelifcoeff.is_Float:ifnotalgebraics:reals=Trueelse:# there are both reals and algebraics -> EXreturnFalseelifis_algebraic(coeff):ifnotreals:algebraics=Trueelse:# there are both algebraics and reals -> EXreturnFalseelse:# this is a composite domain, e.g. ZZ[X], EXreturnNoneifalgebraics:domain,result=_construct_algebraic(coeffs,opt)else:ifreals:domain=RRelse:ifopt.fieldorrationals:domain=QQelse:domain=ZZresult=[]forcoeffincoeffs:result.append(domain.from_sympy(coeff))returndomain,resultdef_construct_algebraic(coeffs,opt):"""We know that coefficients are algebraic so construct the extension. """fromsympy.polys.numberfieldsimportprimitive_elementresult,exts=[],set([])forcoeffincoeffs:ifcoeff.is_Rational:coeff=(None,0,QQ.from_sympy(coeff))else:a=coeff.as_coeff_add()[0]coeff-=ab=coeff.as_coeff_mul()[0]coeff/=bexts.add(coeff)a=QQ.from_sympy(a)b=QQ.from_sympy(b)coeff=(coeff,b,a)result.append(coeff)exts=list(exts)g,span,H=primitive_element(exts,ex=True,polys=True)root=sum([s*extfors,extinzip(span,exts)])domain,g=QQ.algebraic_field((g,root)),g.rep.repfori,(coeff,a,b)inenumerate(result):ifcoeffisnotNone:coeff=a*domain.dtype.from_list(H[exts.index(coeff)],g,QQ)+belse:coeff=domain.dtype.from_list([b],g,QQ)result[i]=coeffreturndomain,resultdef_construct_composite(coeffs,opt):"""Handle composite domains, e.g.: ZZ[X], QQ[X], ZZ(X), QQ(X). """numers,denoms=[],[]forcoeffincoeffs:numer,denom=coeff.as_numer_denom()numers.append(numer)denoms.append(denom)try:polys,gens=parallel_dict_from_basic(numers+denoms)# XXX: sortingexceptGeneratorsNeeded:returnNoneifany(gen.is_numberforgeningens):returnNone# generators are number-like so lets better use EXn=len(gens)k=len(polys)//2numers=polys[:k]denoms=polys[k:]ifopt.field:fractions=Trueelse:fractions,zeros=False,(0,)*nfordenomindenoms:iflen(denom)>1orzerosnotindenom:fractions=Truebreakcoeffs=set([])ifnotfractions:fornumer,denominzip(numers,denoms):denom=denom[zeros]formonom,coeffinnumer.iteritems():coeff/=denomcoeffs.add(coeff)numer[monom]=coeffelse:fornumer,denominzip(numers,denoms):coeffs.update(numer.values())coeffs.update(denom.values())rationals,reals=False,Falseforcoeffincoeffs:ifcoeff.is_Rational:ifnotcoeff.is_Integer:rationals=Trueelifcoeff.is_Float:reals=Truebreakifreals:ground=RRelifrationals:ground=QQelse:ground=ZZresult=[]ifnotfractions:domain=ground.poly_ring(*gens)fornumerinnumers:formonom,coeffinnumer.iteritems():numer[monom]=ground.from_sympy(coeff)result.append(domain(numer))else:domain=ground.frac_field(*gens)fornumer,denominzip(numers,denoms):formonom,coeffinnumer.iteritems():numer[monom]=ground.from_sympy(coeff)formonom,coeffindenom.iteritems():denom[monom]=ground.from_sympy(coeff)result.append(domain((numer,denom)))returndomain,resultdef_construct_expression(coeffs,opt):"""The last resort case, i.e. use the expression domain. """domain,result=EX,[]forcoeffincoeffs:result.append(domain.from_sympy(coeff))returndomain,result

[docs]defconstruct_domain(obj,**args):"""Construct a minimal domain for the list of coefficients. """opt=build_options(args)ifhasattr(obj,'__iter__'):ifisinstance(obj,dict):monoms,coeffs=zip(*obj.items())else:coeffs=objelse:coeffs=[obj]coeffs=map(sympify,coeffs)result=_construct_simple(coeffs,opt)ifresultisnotNone:ifresultisnotFalse:domain,coeffs=resultelse:domain,coeffs=_construct_expression(coeffs,opt)else:ifopt.composite:result=_construct_composite(coeffs,opt)else:result=NoneifresultisnotNone:domain,coeffs=resultelse:domain,coeffs=_construct_expression(coeffs,opt)ifhasattr(obj,'__iter__'):ifisinstance(obj,dict):returndomain,dict(zip(monoms,coeffs))else:returndomain,coeffselse:returndomain,coeffs[0]