polytools.py 190 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425
  1. """User-friendly public interface to polynomial functions. """
  2. from functools import wraps, reduce
  3. from operator import mul
  4. from typing import Optional
  5. from sympy.core import (
  6. S, Expr, Add, Tuple
  7. )
  8. from sympy.core.basic import Basic
  9. from sympy.core.decorators import _sympifyit
  10. from sympy.core.exprtools import Factors, factor_nc, factor_terms
  11. from sympy.core.evalf import (
  12. pure_complex, evalf, fastlog, _evalf_with_bounded_error, quad_to_mpmath)
  13. from sympy.core.function import Derivative
  14. from sympy.core.mul import Mul, _keep_coeff
  15. from sympy.core.numbers import ilcm, I, Integer, equal_valued
  16. from sympy.core.relational import Relational, Equality
  17. from sympy.core.sorting import ordered
  18. from sympy.core.symbol import Dummy, Symbol
  19. from sympy.core.sympify import sympify, _sympify
  20. from sympy.core.traversal import preorder_traversal, bottom_up
  21. from sympy.logic.boolalg import BooleanAtom
  22. from sympy.polys import polyoptions as options
  23. from sympy.polys.constructor import construct_domain
  24. from sympy.polys.domains import FF, QQ, ZZ
  25. from sympy.polys.domains.domainelement import DomainElement
  26. from sympy.polys.fglmtools import matrix_fglm
  27. from sympy.polys.groebnertools import groebner as _groebner
  28. from sympy.polys.monomials import Monomial
  29. from sympy.polys.orderings import monomial_key
  30. from sympy.polys.polyclasses import DMP, DMF, ANP
  31. from sympy.polys.polyerrors import (
  32. OperationNotSupported, DomainError,
  33. CoercionFailed, UnificationFailed,
  34. GeneratorsNeeded, PolynomialError,
  35. MultivariatePolynomialError,
  36. ExactQuotientFailed,
  37. PolificationFailed,
  38. ComputationFailed,
  39. GeneratorsError,
  40. )
  41. from sympy.polys.polyutils import (
  42. basic_from_dict,
  43. _sort_gens,
  44. _unify_gens,
  45. _dict_reorder,
  46. _dict_from_expr,
  47. _parallel_dict_from_expr,
  48. )
  49. from sympy.polys.rationaltools import together
  50. from sympy.polys.rootisolation import dup_isolate_real_roots_list
  51. from sympy.utilities import group, public, filldedent
  52. from sympy.utilities.exceptions import sympy_deprecation_warning
  53. from sympy.utilities.iterables import iterable, sift
  54. # Required to avoid errors
  55. import sympy.polys
  56. import mpmath
  57. from mpmath.libmp.libhyper import NoConvergence
  58. def _polifyit(func):
  59. @wraps(func)
  60. def wrapper(f, g):
  61. g = _sympify(g)
  62. if isinstance(g, Poly):
  63. return func(f, g)
  64. elif isinstance(g, Expr):
  65. try:
  66. g = f.from_expr(g, *f.gens)
  67. except PolynomialError:
  68. if g.is_Matrix:
  69. return NotImplemented
  70. expr_method = getattr(f.as_expr(), func.__name__)
  71. result = expr_method(g)
  72. if result is not NotImplemented:
  73. sympy_deprecation_warning(
  74. """
  75. Mixing Poly with non-polynomial expressions in binary
  76. operations is deprecated. Either explicitly convert
  77. the non-Poly operand to a Poly with as_poly() or
  78. convert the Poly to an Expr with as_expr().
  79. """,
  80. deprecated_since_version="1.6",
  81. active_deprecations_target="deprecated-poly-nonpoly-binary-operations",
  82. )
  83. return result
  84. else:
  85. return func(f, g)
  86. else:
  87. return NotImplemented
  88. return wrapper
  89. @public
  90. class Poly(Basic):
  91. """
  92. Generic class for representing and operating on polynomial expressions.
  93. See :ref:`polys-docs` for general documentation.
  94. Poly is a subclass of Basic rather than Expr but instances can be
  95. converted to Expr with the :py:meth:`~.Poly.as_expr` method.
  96. .. deprecated:: 1.6
  97. Combining Poly with non-Poly objects in binary operations is
  98. deprecated. Explicitly convert both objects to either Poly or Expr
  99. first. See :ref:`deprecated-poly-nonpoly-binary-operations`.
  100. Examples
  101. ========
  102. >>> from sympy import Poly
  103. >>> from sympy.abc import x, y
  104. Create a univariate polynomial:
  105. >>> Poly(x*(x**2 + x - 1)**2)
  106. Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')
  107. Create a univariate polynomial with specific domain:
  108. >>> from sympy import sqrt
  109. >>> Poly(x**2 + 2*x + sqrt(3), domain='R')
  110. Poly(1.0*x**2 + 2.0*x + 1.73205080756888, x, domain='RR')
  111. Create a multivariate polynomial:
  112. >>> Poly(y*x**2 + x*y + 1)
  113. Poly(x**2*y + x*y + 1, x, y, domain='ZZ')
  114. Create a univariate polynomial, where y is a constant:
  115. >>> Poly(y*x**2 + x*y + 1,x)
  116. Poly(y*x**2 + y*x + 1, x, domain='ZZ[y]')
  117. You can evaluate the above polynomial as a function of y:
  118. >>> Poly(y*x**2 + x*y + 1,x).eval(2)
  119. 6*y + 1
  120. See Also
  121. ========
  122. sympy.core.expr.Expr
  123. """
  124. __slots__ = ('rep', 'gens')
  125. is_commutative = True
  126. is_Poly = True
  127. _op_priority = 10.001
  128. def __new__(cls, rep, *gens, **args):
  129. """Create a new polynomial instance out of something useful. """
  130. opt = options.build_options(gens, args)
  131. if 'order' in opt:
  132. raise NotImplementedError("'order' keyword is not implemented yet")
  133. if isinstance(rep, (DMP, DMF, ANP, DomainElement)):
  134. return cls._from_domain_element(rep, opt)
  135. elif iterable(rep, exclude=str):
  136. if isinstance(rep, dict):
  137. return cls._from_dict(rep, opt)
  138. else:
  139. return cls._from_list(list(rep), opt)
  140. else:
  141. rep = sympify(rep)
  142. if rep.is_Poly:
  143. return cls._from_poly(rep, opt)
  144. else:
  145. return cls._from_expr(rep, opt)
  146. # Poly does not pass its args to Basic.__new__ to be stored in _args so we
  147. # have to emulate them here with an args property that derives from rep
  148. # and gens which are instance attributes. This also means we need to
  149. # define _hashable_content. The _hashable_content is rep and gens but args
  150. # uses expr instead of rep (expr is the Basic version of rep). Passing
  151. # expr in args means that Basic methods like subs should work. Using rep
  152. # otherwise means that Poly can remain more efficient than Basic by
  153. # avoiding creating a Basic instance just to be hashable.
  154. @classmethod
  155. def new(cls, rep, *gens):
  156. """Construct :class:`Poly` instance from raw representation. """
  157. if not isinstance(rep, DMP):
  158. raise PolynomialError(
  159. "invalid polynomial representation: %s" % rep)
  160. elif rep.lev != len(gens) - 1:
  161. raise PolynomialError("invalid arguments: %s, %s" % (rep, gens))
  162. obj = Basic.__new__(cls)
  163. obj.rep = rep
  164. obj.gens = gens
  165. return obj
  166. @property
  167. def expr(self):
  168. return basic_from_dict(self.rep.to_sympy_dict(), *self.gens)
  169. @property
  170. def args(self):
  171. return (self.expr,) + self.gens
  172. def _hashable_content(self):
  173. return (self.rep,) + self.gens
  174. @classmethod
  175. def from_dict(cls, rep, *gens, **args):
  176. """Construct a polynomial from a ``dict``. """
  177. opt = options.build_options(gens, args)
  178. return cls._from_dict(rep, opt)
  179. @classmethod
  180. def from_list(cls, rep, *gens, **args):
  181. """Construct a polynomial from a ``list``. """
  182. opt = options.build_options(gens, args)
  183. return cls._from_list(rep, opt)
  184. @classmethod
  185. def from_poly(cls, rep, *gens, **args):
  186. """Construct a polynomial from a polynomial. """
  187. opt = options.build_options(gens, args)
  188. return cls._from_poly(rep, opt)
  189. @classmethod
  190. def from_expr(cls, rep, *gens, **args):
  191. """Construct a polynomial from an expression. """
  192. opt = options.build_options(gens, args)
  193. return cls._from_expr(rep, opt)
  194. @classmethod
  195. def _from_dict(cls, rep, opt):
  196. """Construct a polynomial from a ``dict``. """
  197. gens = opt.gens
  198. if not gens:
  199. raise GeneratorsNeeded(
  200. "Cannot initialize from 'dict' without generators")
  201. level = len(gens) - 1
  202. domain = opt.domain
  203. if domain is None:
  204. domain, rep = construct_domain(rep, opt=opt)
  205. else:
  206. for monom, coeff in rep.items():
  207. rep[monom] = domain.convert(coeff)
  208. return cls.new(DMP.from_dict(rep, level, domain), *gens)
  209. @classmethod
  210. def _from_list(cls, rep, opt):
  211. """Construct a polynomial from a ``list``. """
  212. gens = opt.gens
  213. if not gens:
  214. raise GeneratorsNeeded(
  215. "Cannot initialize from 'list' without generators")
  216. elif len(gens) != 1:
  217. raise MultivariatePolynomialError(
  218. "'list' representation not supported")
  219. level = len(gens) - 1
  220. domain = opt.domain
  221. if domain is None:
  222. domain, rep = construct_domain(rep, opt=opt)
  223. else:
  224. rep = list(map(domain.convert, rep))
  225. return cls.new(DMP.from_list(rep, level, domain), *gens)
  226. @classmethod
  227. def _from_poly(cls, rep, opt):
  228. """Construct a polynomial from a polynomial. """
  229. if cls != rep.__class__:
  230. rep = cls.new(rep.rep, *rep.gens)
  231. gens = opt.gens
  232. field = opt.field
  233. domain = opt.domain
  234. if gens and rep.gens != gens:
  235. if set(rep.gens) != set(gens):
  236. return cls._from_expr(rep.as_expr(), opt)
  237. else:
  238. rep = rep.reorder(*gens)
  239. if 'domain' in opt and domain:
  240. rep = rep.set_domain(domain)
  241. elif field is True:
  242. rep = rep.to_field()
  243. return rep
  244. @classmethod
  245. def _from_expr(cls, rep, opt):
  246. """Construct a polynomial from an expression. """
  247. rep, opt = _dict_from_expr(rep, opt)
  248. return cls._from_dict(rep, opt)
  249. @classmethod
  250. def _from_domain_element(cls, rep, opt):
  251. gens = opt.gens
  252. domain = opt.domain
  253. level = len(gens) - 1
  254. rep = [domain.convert(rep)]
  255. return cls.new(DMP.from_list(rep, level, domain), *gens)
  256. def __hash__(self):
  257. return super().__hash__()
  258. @property
  259. def free_symbols(self):
  260. """
  261. Free symbols of a polynomial expression.
  262. Examples
  263. ========
  264. >>> from sympy import Poly
  265. >>> from sympy.abc import x, y, z
  266. >>> Poly(x**2 + 1).free_symbols
  267. {x}
  268. >>> Poly(x**2 + y).free_symbols
  269. {x, y}
  270. >>> Poly(x**2 + y, x).free_symbols
  271. {x, y}
  272. >>> Poly(x**2 + y, x, z).free_symbols
  273. {x, y}
  274. """
  275. symbols = set()
  276. gens = self.gens
  277. for i in range(len(gens)):
  278. for monom in self.monoms():
  279. if monom[i]:
  280. symbols |= gens[i].free_symbols
  281. break
  282. return symbols | self.free_symbols_in_domain
  283. @property
  284. def free_symbols_in_domain(self):
  285. """
  286. Free symbols of the domain of ``self``.
  287. Examples
  288. ========
  289. >>> from sympy import Poly
  290. >>> from sympy.abc import x, y
  291. >>> Poly(x**2 + 1).free_symbols_in_domain
  292. set()
  293. >>> Poly(x**2 + y).free_symbols_in_domain
  294. set()
  295. >>> Poly(x**2 + y, x).free_symbols_in_domain
  296. {y}
  297. """
  298. domain, symbols = self.rep.dom, set()
  299. if domain.is_Composite:
  300. for gen in domain.symbols:
  301. symbols |= gen.free_symbols
  302. elif domain.is_EX:
  303. for coeff in self.coeffs():
  304. symbols |= coeff.free_symbols
  305. return symbols
  306. @property
  307. def gen(self):
  308. """
  309. Return the principal generator.
  310. Examples
  311. ========
  312. >>> from sympy import Poly
  313. >>> from sympy.abc import x
  314. >>> Poly(x**2 + 1, x).gen
  315. x
  316. """
  317. return self.gens[0]
  318. @property
  319. def domain(self):
  320. """Get the ground domain of a :py:class:`~.Poly`
  321. Returns
  322. =======
  323. :py:class:`~.Domain`:
  324. Ground domain of the :py:class:`~.Poly`.
  325. Examples
  326. ========
  327. >>> from sympy import Poly, Symbol
  328. >>> x = Symbol('x')
  329. >>> p = Poly(x**2 + x)
  330. >>> p
  331. Poly(x**2 + x, x, domain='ZZ')
  332. >>> p.domain
  333. ZZ
  334. """
  335. return self.get_domain()
  336. @property
  337. def zero(self):
  338. """Return zero polynomial with ``self``'s properties. """
  339. return self.new(self.rep.zero(self.rep.lev, self.rep.dom), *self.gens)
  340. @property
  341. def one(self):
  342. """Return one polynomial with ``self``'s properties. """
  343. return self.new(self.rep.one(self.rep.lev, self.rep.dom), *self.gens)
  344. @property
  345. def unit(self):
  346. """Return unit polynomial with ``self``'s properties. """
  347. return self.new(self.rep.unit(self.rep.lev, self.rep.dom), *self.gens)
  348. def unify(f, g):
  349. """
  350. Make ``f`` and ``g`` belong to the same domain.
  351. Examples
  352. ========
  353. >>> from sympy import Poly
  354. >>> from sympy.abc import x
  355. >>> f, g = Poly(x/2 + 1), Poly(2*x + 1)
  356. >>> f
  357. Poly(1/2*x + 1, x, domain='QQ')
  358. >>> g
  359. Poly(2*x + 1, x, domain='ZZ')
  360. >>> F, G = f.unify(g)
  361. >>> F
  362. Poly(1/2*x + 1, x, domain='QQ')
  363. >>> G
  364. Poly(2*x + 1, x, domain='QQ')
  365. """
  366. _, per, F, G = f._unify(g)
  367. return per(F), per(G)
  368. def _unify(f, g):
  369. g = sympify(g)
  370. if not g.is_Poly:
  371. try:
  372. return f.rep.dom, f.per, f.rep, f.rep.per(f.rep.dom.from_sympy(g))
  373. except CoercionFailed:
  374. raise UnificationFailed("Cannot unify %s with %s" % (f, g))
  375. if isinstance(f.rep, DMP) and isinstance(g.rep, DMP):
  376. gens = _unify_gens(f.gens, g.gens)
  377. dom, lev = f.rep.dom.unify(g.rep.dom, gens), len(gens) - 1
  378. if f.gens != gens:
  379. f_monoms, f_coeffs = _dict_reorder(
  380. f.rep.to_dict(), f.gens, gens)
  381. if f.rep.dom != dom:
  382. f_coeffs = [dom.convert(c, f.rep.dom) for c in f_coeffs]
  383. F = DMP(dict(list(zip(f_monoms, f_coeffs))), dom, lev)
  384. else:
  385. F = f.rep.convert(dom)
  386. if g.gens != gens:
  387. g_monoms, g_coeffs = _dict_reorder(
  388. g.rep.to_dict(), g.gens, gens)
  389. if g.rep.dom != dom:
  390. g_coeffs = [dom.convert(c, g.rep.dom) for c in g_coeffs]
  391. G = DMP(dict(list(zip(g_monoms, g_coeffs))), dom, lev)
  392. else:
  393. G = g.rep.convert(dom)
  394. else:
  395. raise UnificationFailed("Cannot unify %s with %s" % (f, g))
  396. cls = f.__class__
  397. def per(rep, dom=dom, gens=gens, remove=None):
  398. if remove is not None:
  399. gens = gens[:remove] + gens[remove + 1:]
  400. if not gens:
  401. return dom.to_sympy(rep)
  402. return cls.new(rep, *gens)
  403. return dom, per, F, G
  404. def per(f, rep, gens=None, remove=None):
  405. """
  406. Create a Poly out of the given representation.
  407. Examples
  408. ========
  409. >>> from sympy import Poly, ZZ
  410. >>> from sympy.abc import x, y
  411. >>> from sympy.polys.polyclasses import DMP
  412. >>> a = Poly(x**2 + 1)
  413. >>> a.per(DMP([ZZ(1), ZZ(1)], ZZ), gens=[y])
  414. Poly(y + 1, y, domain='ZZ')
  415. """
  416. if gens is None:
  417. gens = f.gens
  418. if remove is not None:
  419. gens = gens[:remove] + gens[remove + 1:]
  420. if not gens:
  421. return f.rep.dom.to_sympy(rep)
  422. return f.__class__.new(rep, *gens)
  423. def set_domain(f, domain):
  424. """Set the ground domain of ``f``. """
  425. opt = options.build_options(f.gens, {'domain': domain})
  426. return f.per(f.rep.convert(opt.domain))
  427. def get_domain(f):
  428. """Get the ground domain of ``f``. """
  429. return f.rep.dom
  430. def set_modulus(f, modulus):
  431. """
  432. Set the modulus of ``f``.
  433. Examples
  434. ========
  435. >>> from sympy import Poly
  436. >>> from sympy.abc import x
  437. >>> Poly(5*x**2 + 2*x - 1, x).set_modulus(2)
  438. Poly(x**2 + 1, x, modulus=2)
  439. """
  440. modulus = options.Modulus.preprocess(modulus)
  441. return f.set_domain(FF(modulus))
  442. def get_modulus(f):
  443. """
  444. Get the modulus of ``f``.
  445. Examples
  446. ========
  447. >>> from sympy import Poly
  448. >>> from sympy.abc import x
  449. >>> Poly(x**2 + 1, modulus=2).get_modulus()
  450. 2
  451. """
  452. domain = f.get_domain()
  453. if domain.is_FiniteField:
  454. return Integer(domain.characteristic())
  455. else:
  456. raise PolynomialError("not a polynomial over a Galois field")
  457. def _eval_subs(f, old, new):
  458. """Internal implementation of :func:`subs`. """
  459. if old in f.gens:
  460. if new.is_number:
  461. return f.eval(old, new)
  462. else:
  463. try:
  464. return f.replace(old, new)
  465. except PolynomialError:
  466. pass
  467. return f.as_expr().subs(old, new)
  468. def exclude(f):
  469. """
  470. Remove unnecessary generators from ``f``.
  471. Examples
  472. ========
  473. >>> from sympy import Poly
  474. >>> from sympy.abc import a, b, c, d, x
  475. >>> Poly(a + x, a, b, c, d, x).exclude()
  476. Poly(a + x, a, x, domain='ZZ')
  477. """
  478. J, new = f.rep.exclude()
  479. gens = [gen for j, gen in enumerate(f.gens) if j not in J]
  480. return f.per(new, gens=gens)
  481. def replace(f, x, y=None, **_ignore):
  482. # XXX this does not match Basic's signature
  483. """
  484. Replace ``x`` with ``y`` in generators list.
  485. Examples
  486. ========
  487. >>> from sympy import Poly
  488. >>> from sympy.abc import x, y
  489. >>> Poly(x**2 + 1, x).replace(x, y)
  490. Poly(y**2 + 1, y, domain='ZZ')
  491. """
  492. if y is None:
  493. if f.is_univariate:
  494. x, y = f.gen, x
  495. else:
  496. raise PolynomialError(
  497. "syntax supported only in univariate case")
  498. if x == y or x not in f.gens:
  499. return f
  500. if x in f.gens and y not in f.gens:
  501. dom = f.get_domain()
  502. if not dom.is_Composite or y not in dom.symbols:
  503. gens = list(f.gens)
  504. gens[gens.index(x)] = y
  505. return f.per(f.rep, gens=gens)
  506. raise PolynomialError("Cannot replace %s with %s in %s" % (x, y, f))
  507. def match(f, *args, **kwargs):
  508. """Match expression from Poly. See Basic.match()"""
  509. return f.as_expr().match(*args, **kwargs)
  510. def reorder(f, *gens, **args):
  511. """
  512. Efficiently apply new order of generators.
  513. Examples
  514. ========
  515. >>> from sympy import Poly
  516. >>> from sympy.abc import x, y
  517. >>> Poly(x**2 + x*y**2, x, y).reorder(y, x)
  518. Poly(y**2*x + x**2, y, x, domain='ZZ')
  519. """
  520. opt = options.Options((), args)
  521. if not gens:
  522. gens = _sort_gens(f.gens, opt=opt)
  523. elif set(f.gens) != set(gens):
  524. raise PolynomialError(
  525. "generators list can differ only up to order of elements")
  526. rep = dict(list(zip(*_dict_reorder(f.rep.to_dict(), f.gens, gens))))
  527. return f.per(DMP(rep, f.rep.dom, len(gens) - 1), gens=gens)
  528. def ltrim(f, gen):
  529. """
  530. Remove dummy generators from ``f`` that are to the left of
  531. specified ``gen`` in the generators as ordered. When ``gen``
  532. is an integer, it refers to the generator located at that
  533. position within the tuple of generators of ``f``.
  534. Examples
  535. ========
  536. >>> from sympy import Poly
  537. >>> from sympy.abc import x, y, z
  538. >>> Poly(y**2 + y*z**2, x, y, z).ltrim(y)
  539. Poly(y**2 + y*z**2, y, z, domain='ZZ')
  540. >>> Poly(z, x, y, z).ltrim(-1)
  541. Poly(z, z, domain='ZZ')
  542. """
  543. rep = f.as_dict(native=True)
  544. j = f._gen_to_level(gen)
  545. terms = {}
  546. for monom, coeff in rep.items():
  547. if any(monom[:j]):
  548. # some generator is used in the portion to be trimmed
  549. raise PolynomialError("Cannot left trim %s" % f)
  550. terms[monom[j:]] = coeff
  551. gens = f.gens[j:]
  552. return f.new(DMP.from_dict(terms, len(gens) - 1, f.rep.dom), *gens)
  553. def has_only_gens(f, *gens):
  554. """
  555. Return ``True`` if ``Poly(f, *gens)`` retains ground domain.
  556. Examples
  557. ========
  558. >>> from sympy import Poly
  559. >>> from sympy.abc import x, y, z
  560. >>> Poly(x*y + 1, x, y, z).has_only_gens(x, y)
  561. True
  562. >>> Poly(x*y + z, x, y, z).has_only_gens(x, y)
  563. False
  564. """
  565. indices = set()
  566. for gen in gens:
  567. try:
  568. index = f.gens.index(gen)
  569. except ValueError:
  570. raise GeneratorsError(
  571. "%s doesn't have %s as generator" % (f, gen))
  572. else:
  573. indices.add(index)
  574. for monom in f.monoms():
  575. for i, elt in enumerate(monom):
  576. if i not in indices and elt:
  577. return False
  578. return True
  579. def to_ring(f):
  580. """
  581. Make the ground domain a ring.
  582. Examples
  583. ========
  584. >>> from sympy import Poly, QQ
  585. >>> from sympy.abc import x
  586. >>> Poly(x**2 + 1, domain=QQ).to_ring()
  587. Poly(x**2 + 1, x, domain='ZZ')
  588. """
  589. if hasattr(f.rep, 'to_ring'):
  590. result = f.rep.to_ring()
  591. else: # pragma: no cover
  592. raise OperationNotSupported(f, 'to_ring')
  593. return f.per(result)
  594. def to_field(f):
  595. """
  596. Make the ground domain a field.
  597. Examples
  598. ========
  599. >>> from sympy import Poly, ZZ
  600. >>> from sympy.abc import x
  601. >>> Poly(x**2 + 1, x, domain=ZZ).to_field()
  602. Poly(x**2 + 1, x, domain='QQ')
  603. """
  604. if hasattr(f.rep, 'to_field'):
  605. result = f.rep.to_field()
  606. else: # pragma: no cover
  607. raise OperationNotSupported(f, 'to_field')
  608. return f.per(result)
  609. def to_exact(f):
  610. """
  611. Make the ground domain exact.
  612. Examples
  613. ========
  614. >>> from sympy import Poly, RR
  615. >>> from sympy.abc import x
  616. >>> Poly(x**2 + 1.0, x, domain=RR).to_exact()
  617. Poly(x**2 + 1, x, domain='QQ')
  618. """
  619. if hasattr(f.rep, 'to_exact'):
  620. result = f.rep.to_exact()
  621. else: # pragma: no cover
  622. raise OperationNotSupported(f, 'to_exact')
  623. return f.per(result)
  624. def retract(f, field=None):
  625. """
  626. Recalculate the ground domain of a polynomial.
  627. Examples
  628. ========
  629. >>> from sympy import Poly
  630. >>> from sympy.abc import x
  631. >>> f = Poly(x**2 + 1, x, domain='QQ[y]')
  632. >>> f
  633. Poly(x**2 + 1, x, domain='QQ[y]')
  634. >>> f.retract()
  635. Poly(x**2 + 1, x, domain='ZZ')
  636. >>> f.retract(field=True)
  637. Poly(x**2 + 1, x, domain='QQ')
  638. """
  639. dom, rep = construct_domain(f.as_dict(zero=True),
  640. field=field, composite=f.domain.is_Composite or None)
  641. return f.from_dict(rep, f.gens, domain=dom)
  642. def slice(f, x, m, n=None):
  643. """Take a continuous subsequence of terms of ``f``. """
  644. if n is None:
  645. j, m, n = 0, x, m
  646. else:
  647. j = f._gen_to_level(x)
  648. m, n = int(m), int(n)
  649. if hasattr(f.rep, 'slice'):
  650. result = f.rep.slice(m, n, j)
  651. else: # pragma: no cover
  652. raise OperationNotSupported(f, 'slice')
  653. return f.per(result)
  654. def coeffs(f, order=None):
  655. """
  656. Returns all non-zero coefficients from ``f`` in lex order.
  657. Examples
  658. ========
  659. >>> from sympy import Poly
  660. >>> from sympy.abc import x
  661. >>> Poly(x**3 + 2*x + 3, x).coeffs()
  662. [1, 2, 3]
  663. See Also
  664. ========
  665. all_coeffs
  666. coeff_monomial
  667. nth
  668. """
  669. return [f.rep.dom.to_sympy(c) for c in f.rep.coeffs(order=order)]
  670. def monoms(f, order=None):
  671. """
  672. Returns all non-zero monomials from ``f`` in lex order.
  673. Examples
  674. ========
  675. >>> from sympy import Poly
  676. >>> from sympy.abc import x, y
  677. >>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).monoms()
  678. [(2, 0), (1, 2), (1, 1), (0, 1)]
  679. See Also
  680. ========
  681. all_monoms
  682. """
  683. return f.rep.monoms(order=order)
  684. def terms(f, order=None):
  685. """
  686. Returns all non-zero terms from ``f`` in lex order.
  687. Examples
  688. ========
  689. >>> from sympy import Poly
  690. >>> from sympy.abc import x, y
  691. >>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).terms()
  692. [((2, 0), 1), ((1, 2), 2), ((1, 1), 1), ((0, 1), 3)]
  693. See Also
  694. ========
  695. all_terms
  696. """
  697. return [(m, f.rep.dom.to_sympy(c)) for m, c in f.rep.terms(order=order)]
  698. def all_coeffs(f):
  699. """
  700. Returns all coefficients from a univariate polynomial ``f``.
  701. Examples
  702. ========
  703. >>> from sympy import Poly
  704. >>> from sympy.abc import x
  705. >>> Poly(x**3 + 2*x - 1, x).all_coeffs()
  706. [1, 0, 2, -1]
  707. """
  708. return [f.rep.dom.to_sympy(c) for c in f.rep.all_coeffs()]
  709. def all_monoms(f):
  710. """
  711. Returns all monomials from a univariate polynomial ``f``.
  712. Examples
  713. ========
  714. >>> from sympy import Poly
  715. >>> from sympy.abc import x
  716. >>> Poly(x**3 + 2*x - 1, x).all_monoms()
  717. [(3,), (2,), (1,), (0,)]
  718. See Also
  719. ========
  720. all_terms
  721. """
  722. return f.rep.all_monoms()
  723. def all_terms(f):
  724. """
  725. Returns all terms from a univariate polynomial ``f``.
  726. Examples
  727. ========
  728. >>> from sympy import Poly
  729. >>> from sympy.abc import x
  730. >>> Poly(x**3 + 2*x - 1, x).all_terms()
  731. [((3,), 1), ((2,), 0), ((1,), 2), ((0,), -1)]
  732. """
  733. return [(m, f.rep.dom.to_sympy(c)) for m, c in f.rep.all_terms()]
  734. def termwise(f, func, *gens, **args):
  735. """
  736. Apply a function to all terms of ``f``.
  737. Examples
  738. ========
  739. >>> from sympy import Poly
  740. >>> from sympy.abc import x
  741. >>> def func(k, coeff):
  742. ... k = k[0]
  743. ... return coeff//10**(2-k)
  744. >>> Poly(x**2 + 20*x + 400).termwise(func)
  745. Poly(x**2 + 2*x + 4, x, domain='ZZ')
  746. """
  747. terms = {}
  748. for monom, coeff in f.terms():
  749. result = func(monom, coeff)
  750. if isinstance(result, tuple):
  751. monom, coeff = result
  752. else:
  753. coeff = result
  754. if coeff:
  755. if monom not in terms:
  756. terms[monom] = coeff
  757. else:
  758. raise PolynomialError(
  759. "%s monomial was generated twice" % monom)
  760. return f.from_dict(terms, *(gens or f.gens), **args)
  761. def length(f):
  762. """
  763. Returns the number of non-zero terms in ``f``.
  764. Examples
  765. ========
  766. >>> from sympy import Poly
  767. >>> from sympy.abc import x
  768. >>> Poly(x**2 + 2*x - 1).length()
  769. 3
  770. """
  771. return len(f.as_dict())
  772. def as_dict(f, native=False, zero=False):
  773. """
  774. Switch to a ``dict`` representation.
  775. Examples
  776. ========
  777. >>> from sympy import Poly
  778. >>> from sympy.abc import x, y
  779. >>> Poly(x**2 + 2*x*y**2 - y, x, y).as_dict()
  780. {(0, 1): -1, (1, 2): 2, (2, 0): 1}
  781. """
  782. if native:
  783. return f.rep.to_dict(zero=zero)
  784. else:
  785. return f.rep.to_sympy_dict(zero=zero)
  786. def as_list(f, native=False):
  787. """Switch to a ``list`` representation. """
  788. if native:
  789. return f.rep.to_list()
  790. else:
  791. return f.rep.to_sympy_list()
  792. def as_expr(f, *gens):
  793. """
  794. Convert a Poly instance to an Expr instance.
  795. Examples
  796. ========
  797. >>> from sympy import Poly
  798. >>> from sympy.abc import x, y
  799. >>> f = Poly(x**2 + 2*x*y**2 - y, x, y)
  800. >>> f.as_expr()
  801. x**2 + 2*x*y**2 - y
  802. >>> f.as_expr({x: 5})
  803. 10*y**2 - y + 25
  804. >>> f.as_expr(5, 6)
  805. 379
  806. """
  807. if not gens:
  808. return f.expr
  809. if len(gens) == 1 and isinstance(gens[0], dict):
  810. mapping = gens[0]
  811. gens = list(f.gens)
  812. for gen, value in mapping.items():
  813. try:
  814. index = gens.index(gen)
  815. except ValueError:
  816. raise GeneratorsError(
  817. "%s doesn't have %s as generator" % (f, gen))
  818. else:
  819. gens[index] = value
  820. return basic_from_dict(f.rep.to_sympy_dict(), *gens)
  821. def as_poly(self, *gens, **args):
  822. """Converts ``self`` to a polynomial or returns ``None``.
  823. >>> from sympy import sin
  824. >>> from sympy.abc import x, y
  825. >>> print((x**2 + x*y).as_poly())
  826. Poly(x**2 + x*y, x, y, domain='ZZ')
  827. >>> print((x**2 + x*y).as_poly(x, y))
  828. Poly(x**2 + x*y, x, y, domain='ZZ')
  829. >>> print((x**2 + sin(y)).as_poly(x, y))
  830. None
  831. """
  832. try:
  833. poly = Poly(self, *gens, **args)
  834. if not poly.is_Poly:
  835. return None
  836. else:
  837. return poly
  838. except PolynomialError:
  839. return None
  840. def lift(f):
  841. """
  842. Convert algebraic coefficients to rationals.
  843. Examples
  844. ========
  845. >>> from sympy import Poly, I
  846. >>> from sympy.abc import x
  847. >>> Poly(x**2 + I*x + 1, x, extension=I).lift()
  848. Poly(x**4 + 3*x**2 + 1, x, domain='QQ')
  849. """
  850. if hasattr(f.rep, 'lift'):
  851. result = f.rep.lift()
  852. else: # pragma: no cover
  853. raise OperationNotSupported(f, 'lift')
  854. return f.per(result)
  855. def deflate(f):
  856. """
  857. Reduce degree of ``f`` by mapping ``x_i**m`` to ``y_i``.
  858. Examples
  859. ========
  860. >>> from sympy import Poly
  861. >>> from sympy.abc import x, y
  862. >>> Poly(x**6*y**2 + x**3 + 1, x, y).deflate()
  863. ((3, 2), Poly(x**2*y + x + 1, x, y, domain='ZZ'))
  864. """
  865. if hasattr(f.rep, 'deflate'):
  866. J, result = f.rep.deflate()
  867. else: # pragma: no cover
  868. raise OperationNotSupported(f, 'deflate')
  869. return J, f.per(result)
  870. def inject(f, front=False):
  871. """
  872. Inject ground domain generators into ``f``.
  873. Examples
  874. ========
  875. >>> from sympy import Poly
  876. >>> from sympy.abc import x, y
  877. >>> f = Poly(x**2*y + x*y**3 + x*y + 1, x)
  878. >>> f.inject()
  879. Poly(x**2*y + x*y**3 + x*y + 1, x, y, domain='ZZ')
  880. >>> f.inject(front=True)
  881. Poly(y**3*x + y*x**2 + y*x + 1, y, x, domain='ZZ')
  882. """
  883. dom = f.rep.dom
  884. if dom.is_Numerical:
  885. return f
  886. elif not dom.is_Poly:
  887. raise DomainError("Cannot inject generators over %s" % dom)
  888. if hasattr(f.rep, 'inject'):
  889. result = f.rep.inject(front=front)
  890. else: # pragma: no cover
  891. raise OperationNotSupported(f, 'inject')
  892. if front:
  893. gens = dom.symbols + f.gens
  894. else:
  895. gens = f.gens + dom.symbols
  896. return f.new(result, *gens)
  897. def eject(f, *gens):
  898. """
  899. Eject selected generators into the ground domain.
  900. Examples
  901. ========
  902. >>> from sympy import Poly
  903. >>> from sympy.abc import x, y
  904. >>> f = Poly(x**2*y + x*y**3 + x*y + 1, x, y)
  905. >>> f.eject(x)
  906. Poly(x*y**3 + (x**2 + x)*y + 1, y, domain='ZZ[x]')
  907. >>> f.eject(y)
  908. Poly(y*x**2 + (y**3 + y)*x + 1, x, domain='ZZ[y]')
  909. """
  910. dom = f.rep.dom
  911. if not dom.is_Numerical:
  912. raise DomainError("Cannot eject generators over %s" % dom)
  913. k = len(gens)
  914. if f.gens[:k] == gens:
  915. _gens, front = f.gens[k:], True
  916. elif f.gens[-k:] == gens:
  917. _gens, front = f.gens[:-k], False
  918. else:
  919. raise NotImplementedError(
  920. "can only eject front or back generators")
  921. dom = dom.inject(*gens)
  922. if hasattr(f.rep, 'eject'):
  923. result = f.rep.eject(dom, front=front)
  924. else: # pragma: no cover
  925. raise OperationNotSupported(f, 'eject')
  926. return f.new(result, *_gens)
  927. def terms_gcd(f):
  928. """
  929. Remove GCD of terms from the polynomial ``f``.
  930. Examples
  931. ========
  932. >>> from sympy import Poly
  933. >>> from sympy.abc import x, y
  934. >>> Poly(x**6*y**2 + x**3*y, x, y).terms_gcd()
  935. ((3, 1), Poly(x**3*y + 1, x, y, domain='ZZ'))
  936. """
  937. if hasattr(f.rep, 'terms_gcd'):
  938. J, result = f.rep.terms_gcd()
  939. else: # pragma: no cover
  940. raise OperationNotSupported(f, 'terms_gcd')
  941. return J, f.per(result)
  942. def add_ground(f, coeff):
  943. """
  944. Add an element of the ground domain to ``f``.
  945. Examples
  946. ========
  947. >>> from sympy import Poly
  948. >>> from sympy.abc import x
  949. >>> Poly(x + 1).add_ground(2)
  950. Poly(x + 3, x, domain='ZZ')
  951. """
  952. if hasattr(f.rep, 'add_ground'):
  953. result = f.rep.add_ground(coeff)
  954. else: # pragma: no cover
  955. raise OperationNotSupported(f, 'add_ground')
  956. return f.per(result)
  957. def sub_ground(f, coeff):
  958. """
  959. Subtract an element of the ground domain from ``f``.
  960. Examples
  961. ========
  962. >>> from sympy import Poly
  963. >>> from sympy.abc import x
  964. >>> Poly(x + 1).sub_ground(2)
  965. Poly(x - 1, x, domain='ZZ')
  966. """
  967. if hasattr(f.rep, 'sub_ground'):
  968. result = f.rep.sub_ground(coeff)
  969. else: # pragma: no cover
  970. raise OperationNotSupported(f, 'sub_ground')
  971. return f.per(result)
  972. def mul_ground(f, coeff):
  973. """
  974. Multiply ``f`` by a an element of the ground domain.
  975. Examples
  976. ========
  977. >>> from sympy import Poly
  978. >>> from sympy.abc import x
  979. >>> Poly(x + 1).mul_ground(2)
  980. Poly(2*x + 2, x, domain='ZZ')
  981. """
  982. if hasattr(f.rep, 'mul_ground'):
  983. result = f.rep.mul_ground(coeff)
  984. else: # pragma: no cover
  985. raise OperationNotSupported(f, 'mul_ground')
  986. return f.per(result)
  987. def quo_ground(f, coeff):
  988. """
  989. Quotient of ``f`` by a an element of the ground domain.
  990. Examples
  991. ========
  992. >>> from sympy import Poly
  993. >>> from sympy.abc import x
  994. >>> Poly(2*x + 4).quo_ground(2)
  995. Poly(x + 2, x, domain='ZZ')
  996. >>> Poly(2*x + 3).quo_ground(2)
  997. Poly(x + 1, x, domain='ZZ')
  998. """
  999. if hasattr(f.rep, 'quo_ground'):
  1000. result = f.rep.quo_ground(coeff)
  1001. else: # pragma: no cover
  1002. raise OperationNotSupported(f, 'quo_ground')
  1003. return f.per(result)
  1004. def exquo_ground(f, coeff):
  1005. """
  1006. Exact quotient of ``f`` by a an element of the ground domain.
  1007. Examples
  1008. ========
  1009. >>> from sympy import Poly
  1010. >>> from sympy.abc import x
  1011. >>> Poly(2*x + 4).exquo_ground(2)
  1012. Poly(x + 2, x, domain='ZZ')
  1013. >>> Poly(2*x + 3).exquo_ground(2)
  1014. Traceback (most recent call last):
  1015. ...
  1016. ExactQuotientFailed: 2 does not divide 3 in ZZ
  1017. """
  1018. if hasattr(f.rep, 'exquo_ground'):
  1019. result = f.rep.exquo_ground(coeff)
  1020. else: # pragma: no cover
  1021. raise OperationNotSupported(f, 'exquo_ground')
  1022. return f.per(result)
  1023. def abs(f):
  1024. """
  1025. Make all coefficients in ``f`` positive.
  1026. Examples
  1027. ========
  1028. >>> from sympy import Poly
  1029. >>> from sympy.abc import x
  1030. >>> Poly(x**2 - 1, x).abs()
  1031. Poly(x**2 + 1, x, domain='ZZ')
  1032. """
  1033. if hasattr(f.rep, 'abs'):
  1034. result = f.rep.abs()
  1035. else: # pragma: no cover
  1036. raise OperationNotSupported(f, 'abs')
  1037. return f.per(result)
  1038. def neg(f):
  1039. """
  1040. Negate all coefficients in ``f``.
  1041. Examples
  1042. ========
  1043. >>> from sympy import Poly
  1044. >>> from sympy.abc import x
  1045. >>> Poly(x**2 - 1, x).neg()
  1046. Poly(-x**2 + 1, x, domain='ZZ')
  1047. >>> -Poly(x**2 - 1, x)
  1048. Poly(-x**2 + 1, x, domain='ZZ')
  1049. """
  1050. if hasattr(f.rep, 'neg'):
  1051. result = f.rep.neg()
  1052. else: # pragma: no cover
  1053. raise OperationNotSupported(f, 'neg')
  1054. return f.per(result)
  1055. def add(f, g):
  1056. """
  1057. Add two polynomials ``f`` and ``g``.
  1058. Examples
  1059. ========
  1060. >>> from sympy import Poly
  1061. >>> from sympy.abc import x
  1062. >>> Poly(x**2 + 1, x).add(Poly(x - 2, x))
  1063. Poly(x**2 + x - 1, x, domain='ZZ')
  1064. >>> Poly(x**2 + 1, x) + Poly(x - 2, x)
  1065. Poly(x**2 + x - 1, x, domain='ZZ')
  1066. """
  1067. g = sympify(g)
  1068. if not g.is_Poly:
  1069. return f.add_ground(g)
  1070. _, per, F, G = f._unify(g)
  1071. if hasattr(f.rep, 'add'):
  1072. result = F.add(G)
  1073. else: # pragma: no cover
  1074. raise OperationNotSupported(f, 'add')
  1075. return per(result)
  1076. def sub(f, g):
  1077. """
  1078. Subtract two polynomials ``f`` and ``g``.
  1079. Examples
  1080. ========
  1081. >>> from sympy import Poly
  1082. >>> from sympy.abc import x
  1083. >>> Poly(x**2 + 1, x).sub(Poly(x - 2, x))
  1084. Poly(x**2 - x + 3, x, domain='ZZ')
  1085. >>> Poly(x**2 + 1, x) - Poly(x - 2, x)
  1086. Poly(x**2 - x + 3, x, domain='ZZ')
  1087. """
  1088. g = sympify(g)
  1089. if not g.is_Poly:
  1090. return f.sub_ground(g)
  1091. _, per, F, G = f._unify(g)
  1092. if hasattr(f.rep, 'sub'):
  1093. result = F.sub(G)
  1094. else: # pragma: no cover
  1095. raise OperationNotSupported(f, 'sub')
  1096. return per(result)
  1097. def mul(f, g):
  1098. """
  1099. Multiply two polynomials ``f`` and ``g``.
  1100. Examples
  1101. ========
  1102. >>> from sympy import Poly
  1103. >>> from sympy.abc import x
  1104. >>> Poly(x**2 + 1, x).mul(Poly(x - 2, x))
  1105. Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ')
  1106. >>> Poly(x**2 + 1, x)*Poly(x - 2, x)
  1107. Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ')
  1108. """
  1109. g = sympify(g)
  1110. if not g.is_Poly:
  1111. return f.mul_ground(g)
  1112. _, per, F, G = f._unify(g)
  1113. if hasattr(f.rep, 'mul'):
  1114. result = F.mul(G)
  1115. else: # pragma: no cover
  1116. raise OperationNotSupported(f, 'mul')
  1117. return per(result)
  1118. def sqr(f):
  1119. """
  1120. Square a polynomial ``f``.
  1121. Examples
  1122. ========
  1123. >>> from sympy import Poly
  1124. >>> from sympy.abc import x
  1125. >>> Poly(x - 2, x).sqr()
  1126. Poly(x**2 - 4*x + 4, x, domain='ZZ')
  1127. >>> Poly(x - 2, x)**2
  1128. Poly(x**2 - 4*x + 4, x, domain='ZZ')
  1129. """
  1130. if hasattr(f.rep, 'sqr'):
  1131. result = f.rep.sqr()
  1132. else: # pragma: no cover
  1133. raise OperationNotSupported(f, 'sqr')
  1134. return f.per(result)
  1135. def pow(f, n):
  1136. """
  1137. Raise ``f`` to a non-negative power ``n``.
  1138. Examples
  1139. ========
  1140. >>> from sympy import Poly
  1141. >>> from sympy.abc import x
  1142. >>> Poly(x - 2, x).pow(3)
  1143. Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ')
  1144. >>> Poly(x - 2, x)**3
  1145. Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ')
  1146. """
  1147. n = int(n)
  1148. if hasattr(f.rep, 'pow'):
  1149. result = f.rep.pow(n)
  1150. else: # pragma: no cover
  1151. raise OperationNotSupported(f, 'pow')
  1152. return f.per(result)
  1153. def pdiv(f, g):
  1154. """
  1155. Polynomial pseudo-division of ``f`` by ``g``.
  1156. Examples
  1157. ========
  1158. >>> from sympy import Poly
  1159. >>> from sympy.abc import x
  1160. >>> Poly(x**2 + 1, x).pdiv(Poly(2*x - 4, x))
  1161. (Poly(2*x + 4, x, domain='ZZ'), Poly(20, x, domain='ZZ'))
  1162. """
  1163. _, per, F, G = f._unify(g)
  1164. if hasattr(f.rep, 'pdiv'):
  1165. q, r = F.pdiv(G)
  1166. else: # pragma: no cover
  1167. raise OperationNotSupported(f, 'pdiv')
  1168. return per(q), per(r)
  1169. def prem(f, g):
  1170. """
  1171. Polynomial pseudo-remainder of ``f`` by ``g``.
  1172. Caveat: The function prem(f, g, x) can be safely used to compute
  1173. in Z[x] _only_ subresultant polynomial remainder sequences (prs's).
  1174. To safely compute Euclidean and Sturmian prs's in Z[x]
  1175. employ anyone of the corresponding functions found in
  1176. the module sympy.polys.subresultants_qq_zz. The functions
  1177. in the module with suffix _pg compute prs's in Z[x] employing
  1178. rem(f, g, x), whereas the functions with suffix _amv
  1179. compute prs's in Z[x] employing rem_z(f, g, x).
  1180. The function rem_z(f, g, x) differs from prem(f, g, x) in that
  1181. to compute the remainder polynomials in Z[x] it premultiplies
  1182. the divident times the absolute value of the leading coefficient
  1183. of the divisor raised to the power degree(f, x) - degree(g, x) + 1.
  1184. Examples
  1185. ========
  1186. >>> from sympy import Poly
  1187. >>> from sympy.abc import x
  1188. >>> Poly(x**2 + 1, x).prem(Poly(2*x - 4, x))
  1189. Poly(20, x, domain='ZZ')
  1190. """
  1191. _, per, F, G = f._unify(g)
  1192. if hasattr(f.rep, 'prem'):
  1193. result = F.prem(G)
  1194. else: # pragma: no cover
  1195. raise OperationNotSupported(f, 'prem')
  1196. return per(result)
  1197. def pquo(f, g):
  1198. """
  1199. Polynomial pseudo-quotient of ``f`` by ``g``.
  1200. See the Caveat note in the function prem(f, g).
  1201. Examples
  1202. ========
  1203. >>> from sympy import Poly
  1204. >>> from sympy.abc import x
  1205. >>> Poly(x**2 + 1, x).pquo(Poly(2*x - 4, x))
  1206. Poly(2*x + 4, x, domain='ZZ')
  1207. >>> Poly(x**2 - 1, x).pquo(Poly(2*x - 2, x))
  1208. Poly(2*x + 2, x, domain='ZZ')
  1209. """
  1210. _, per, F, G = f._unify(g)
  1211. if hasattr(f.rep, 'pquo'):
  1212. result = F.pquo(G)
  1213. else: # pragma: no cover
  1214. raise OperationNotSupported(f, 'pquo')
  1215. return per(result)
  1216. def pexquo(f, g):
  1217. """
  1218. Polynomial exact pseudo-quotient of ``f`` by ``g``.
  1219. Examples
  1220. ========
  1221. >>> from sympy import Poly
  1222. >>> from sympy.abc import x
  1223. >>> Poly(x**2 - 1, x).pexquo(Poly(2*x - 2, x))
  1224. Poly(2*x + 2, x, domain='ZZ')
  1225. >>> Poly(x**2 + 1, x).pexquo(Poly(2*x - 4, x))
  1226. Traceback (most recent call last):
  1227. ...
  1228. ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1
  1229. """
  1230. _, per, F, G = f._unify(g)
  1231. if hasattr(f.rep, 'pexquo'):
  1232. try:
  1233. result = F.pexquo(G)
  1234. except ExactQuotientFailed as exc:
  1235. raise exc.new(f.as_expr(), g.as_expr())
  1236. else: # pragma: no cover
  1237. raise OperationNotSupported(f, 'pexquo')
  1238. return per(result)
  1239. def div(f, g, auto=True):
  1240. """
  1241. Polynomial division with remainder of ``f`` by ``g``.
  1242. Examples
  1243. ========
  1244. >>> from sympy import Poly
  1245. >>> from sympy.abc import x
  1246. >>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x))
  1247. (Poly(1/2*x + 1, x, domain='QQ'), Poly(5, x, domain='QQ'))
  1248. >>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x), auto=False)
  1249. (Poly(0, x, domain='ZZ'), Poly(x**2 + 1, x, domain='ZZ'))
  1250. """
  1251. dom, per, F, G = f._unify(g)
  1252. retract = False
  1253. if auto and dom.is_Ring and not dom.is_Field:
  1254. F, G = F.to_field(), G.to_field()
  1255. retract = True
  1256. if hasattr(f.rep, 'div'):
  1257. q, r = F.div(G)
  1258. else: # pragma: no cover
  1259. raise OperationNotSupported(f, 'div')
  1260. if retract:
  1261. try:
  1262. Q, R = q.to_ring(), r.to_ring()
  1263. except CoercionFailed:
  1264. pass
  1265. else:
  1266. q, r = Q, R
  1267. return per(q), per(r)
  1268. def rem(f, g, auto=True):
  1269. """
  1270. Computes the polynomial remainder of ``f`` by ``g``.
  1271. Examples
  1272. ========
  1273. >>> from sympy import Poly
  1274. >>> from sympy.abc import x
  1275. >>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x))
  1276. Poly(5, x, domain='ZZ')
  1277. >>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x), auto=False)
  1278. Poly(x**2 + 1, x, domain='ZZ')
  1279. """
  1280. dom, per, F, G = f._unify(g)
  1281. retract = False
  1282. if auto and dom.is_Ring and not dom.is_Field:
  1283. F, G = F.to_field(), G.to_field()
  1284. retract = True
  1285. if hasattr(f.rep, 'rem'):
  1286. r = F.rem(G)
  1287. else: # pragma: no cover
  1288. raise OperationNotSupported(f, 'rem')
  1289. if retract:
  1290. try:
  1291. r = r.to_ring()
  1292. except CoercionFailed:
  1293. pass
  1294. return per(r)
  1295. def quo(f, g, auto=True):
  1296. """
  1297. Computes polynomial quotient of ``f`` by ``g``.
  1298. Examples
  1299. ========
  1300. >>> from sympy import Poly
  1301. >>> from sympy.abc import x
  1302. >>> Poly(x**2 + 1, x).quo(Poly(2*x - 4, x))
  1303. Poly(1/2*x + 1, x, domain='QQ')
  1304. >>> Poly(x**2 - 1, x).quo(Poly(x - 1, x))
  1305. Poly(x + 1, x, domain='ZZ')
  1306. """
  1307. dom, per, F, G = f._unify(g)
  1308. retract = False
  1309. if auto and dom.is_Ring and not dom.is_Field:
  1310. F, G = F.to_field(), G.to_field()
  1311. retract = True
  1312. if hasattr(f.rep, 'quo'):
  1313. q = F.quo(G)
  1314. else: # pragma: no cover
  1315. raise OperationNotSupported(f, 'quo')
  1316. if retract:
  1317. try:
  1318. q = q.to_ring()
  1319. except CoercionFailed:
  1320. pass
  1321. return per(q)
  1322. def exquo(f, g, auto=True):
  1323. """
  1324. Computes polynomial exact quotient of ``f`` by ``g``.
  1325. Examples
  1326. ========
  1327. >>> from sympy import Poly
  1328. >>> from sympy.abc import x
  1329. >>> Poly(x**2 - 1, x).exquo(Poly(x - 1, x))
  1330. Poly(x + 1, x, domain='ZZ')
  1331. >>> Poly(x**2 + 1, x).exquo(Poly(2*x - 4, x))
  1332. Traceback (most recent call last):
  1333. ...
  1334. ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1
  1335. """
  1336. dom, per, F, G = f._unify(g)
  1337. retract = False
  1338. if auto and dom.is_Ring and not dom.is_Field:
  1339. F, G = F.to_field(), G.to_field()
  1340. retract = True
  1341. if hasattr(f.rep, 'exquo'):
  1342. try:
  1343. q = F.exquo(G)
  1344. except ExactQuotientFailed as exc:
  1345. raise exc.new(f.as_expr(), g.as_expr())
  1346. else: # pragma: no cover
  1347. raise OperationNotSupported(f, 'exquo')
  1348. if retract:
  1349. try:
  1350. q = q.to_ring()
  1351. except CoercionFailed:
  1352. pass
  1353. return per(q)
  1354. def _gen_to_level(f, gen):
  1355. """Returns level associated with the given generator. """
  1356. if isinstance(gen, int):
  1357. length = len(f.gens)
  1358. if -length <= gen < length:
  1359. if gen < 0:
  1360. return length + gen
  1361. else:
  1362. return gen
  1363. else:
  1364. raise PolynomialError("-%s <= gen < %s expected, got %s" %
  1365. (length, length, gen))
  1366. else:
  1367. try:
  1368. return f.gens.index(sympify(gen))
  1369. except ValueError:
  1370. raise PolynomialError(
  1371. "a valid generator expected, got %s" % gen)
  1372. def degree(f, gen=0):
  1373. """
  1374. Returns degree of ``f`` in ``x_j``.
  1375. The degree of 0 is negative infinity.
  1376. Examples
  1377. ========
  1378. >>> from sympy import Poly
  1379. >>> from sympy.abc import x, y
  1380. >>> Poly(x**2 + y*x + 1, x, y).degree()
  1381. 2
  1382. >>> Poly(x**2 + y*x + y, x, y).degree(y)
  1383. 1
  1384. >>> Poly(0, x).degree()
  1385. -oo
  1386. """
  1387. j = f._gen_to_level(gen)
  1388. if hasattr(f.rep, 'degree'):
  1389. return f.rep.degree(j)
  1390. else: # pragma: no cover
  1391. raise OperationNotSupported(f, 'degree')
  1392. def degree_list(f):
  1393. """
  1394. Returns a list of degrees of ``f``.
  1395. Examples
  1396. ========
  1397. >>> from sympy import Poly
  1398. >>> from sympy.abc import x, y
  1399. >>> Poly(x**2 + y*x + 1, x, y).degree_list()
  1400. (2, 1)
  1401. """
  1402. if hasattr(f.rep, 'degree_list'):
  1403. return f.rep.degree_list()
  1404. else: # pragma: no cover
  1405. raise OperationNotSupported(f, 'degree_list')
  1406. def total_degree(f):
  1407. """
  1408. Returns the total degree of ``f``.
  1409. Examples
  1410. ========
  1411. >>> from sympy import Poly
  1412. >>> from sympy.abc import x, y
  1413. >>> Poly(x**2 + y*x + 1, x, y).total_degree()
  1414. 2
  1415. >>> Poly(x + y**5, x, y).total_degree()
  1416. 5
  1417. """
  1418. if hasattr(f.rep, 'total_degree'):
  1419. return f.rep.total_degree()
  1420. else: # pragma: no cover
  1421. raise OperationNotSupported(f, 'total_degree')
  1422. def homogenize(f, s):
  1423. """
  1424. Returns the homogeneous polynomial of ``f``.
  1425. A homogeneous polynomial is a polynomial whose all monomials with
  1426. non-zero coefficients have the same total degree. If you only
  1427. want to check if a polynomial is homogeneous, then use
  1428. :func:`Poly.is_homogeneous`. If you want not only to check if a
  1429. polynomial is homogeneous but also compute its homogeneous order,
  1430. then use :func:`Poly.homogeneous_order`.
  1431. Examples
  1432. ========
  1433. >>> from sympy import Poly
  1434. >>> from sympy.abc import x, y, z
  1435. >>> f = Poly(x**5 + 2*x**2*y**2 + 9*x*y**3)
  1436. >>> f.homogenize(z)
  1437. Poly(x**5 + 2*x**2*y**2*z + 9*x*y**3*z, x, y, z, domain='ZZ')
  1438. """
  1439. if not isinstance(s, Symbol):
  1440. raise TypeError("``Symbol`` expected, got %s" % type(s))
  1441. if s in f.gens:
  1442. i = f.gens.index(s)
  1443. gens = f.gens
  1444. else:
  1445. i = len(f.gens)
  1446. gens = f.gens + (s,)
  1447. if hasattr(f.rep, 'homogenize'):
  1448. return f.per(f.rep.homogenize(i), gens=gens)
  1449. raise OperationNotSupported(f, 'homogeneous_order')
  1450. def homogeneous_order(f):
  1451. """
  1452. Returns the homogeneous order of ``f``.
  1453. A homogeneous polynomial is a polynomial whose all monomials with
  1454. non-zero coefficients have the same total degree. This degree is
  1455. the homogeneous order of ``f``. If you only want to check if a
  1456. polynomial is homogeneous, then use :func:`Poly.is_homogeneous`.
  1457. Examples
  1458. ========
  1459. >>> from sympy import Poly
  1460. >>> from sympy.abc import x, y
  1461. >>> f = Poly(x**5 + 2*x**3*y**2 + 9*x*y**4)
  1462. >>> f.homogeneous_order()
  1463. 5
  1464. """
  1465. if hasattr(f.rep, 'homogeneous_order'):
  1466. return f.rep.homogeneous_order()
  1467. else: # pragma: no cover
  1468. raise OperationNotSupported(f, 'homogeneous_order')
  1469. def LC(f, order=None):
  1470. """
  1471. Returns the leading coefficient of ``f``.
  1472. Examples
  1473. ========
  1474. >>> from sympy import Poly
  1475. >>> from sympy.abc import x
  1476. >>> Poly(4*x**3 + 2*x**2 + 3*x, x).LC()
  1477. 4
  1478. """
  1479. if order is not None:
  1480. return f.coeffs(order)[0]
  1481. if hasattr(f.rep, 'LC'):
  1482. result = f.rep.LC()
  1483. else: # pragma: no cover
  1484. raise OperationNotSupported(f, 'LC')
  1485. return f.rep.dom.to_sympy(result)
  1486. def TC(f):
  1487. """
  1488. Returns the trailing coefficient of ``f``.
  1489. Examples
  1490. ========
  1491. >>> from sympy import Poly
  1492. >>> from sympy.abc import x
  1493. >>> Poly(x**3 + 2*x**2 + 3*x, x).TC()
  1494. 0
  1495. """
  1496. if hasattr(f.rep, 'TC'):
  1497. result = f.rep.TC()
  1498. else: # pragma: no cover
  1499. raise OperationNotSupported(f, 'TC')
  1500. return f.rep.dom.to_sympy(result)
  1501. def EC(f, order=None):
  1502. """
  1503. Returns the last non-zero coefficient of ``f``.
  1504. Examples
  1505. ========
  1506. >>> from sympy import Poly
  1507. >>> from sympy.abc import x
  1508. >>> Poly(x**3 + 2*x**2 + 3*x, x).EC()
  1509. 3
  1510. """
  1511. if hasattr(f.rep, 'coeffs'):
  1512. return f.coeffs(order)[-1]
  1513. else: # pragma: no cover
  1514. raise OperationNotSupported(f, 'EC')
  1515. def coeff_monomial(f, monom):
  1516. """
  1517. Returns the coefficient of ``monom`` in ``f`` if there, else None.
  1518. Examples
  1519. ========
  1520. >>> from sympy import Poly, exp
  1521. >>> from sympy.abc import x, y
  1522. >>> p = Poly(24*x*y*exp(8) + 23*x, x, y)
  1523. >>> p.coeff_monomial(x)
  1524. 23
  1525. >>> p.coeff_monomial(y)
  1526. 0
  1527. >>> p.coeff_monomial(x*y)
  1528. 24*exp(8)
  1529. Note that ``Expr.coeff()`` behaves differently, collecting terms
  1530. if possible; the Poly must be converted to an Expr to use that
  1531. method, however:
  1532. >>> p.as_expr().coeff(x)
  1533. 24*y*exp(8) + 23
  1534. >>> p.as_expr().coeff(y)
  1535. 24*x*exp(8)
  1536. >>> p.as_expr().coeff(x*y)
  1537. 24*exp(8)
  1538. See Also
  1539. ========
  1540. nth: more efficient query using exponents of the monomial's generators
  1541. """
  1542. return f.nth(*Monomial(monom, f.gens).exponents)
  1543. def nth(f, *N):
  1544. """
  1545. Returns the ``n``-th coefficient of ``f`` where ``N`` are the
  1546. exponents of the generators in the term of interest.
  1547. Examples
  1548. ========
  1549. >>> from sympy import Poly, sqrt
  1550. >>> from sympy.abc import x, y
  1551. >>> Poly(x**3 + 2*x**2 + 3*x, x).nth(2)
  1552. 2
  1553. >>> Poly(x**3 + 2*x*y**2 + y**2, x, y).nth(1, 2)
  1554. 2
  1555. >>> Poly(4*sqrt(x)*y)
  1556. Poly(4*y*(sqrt(x)), y, sqrt(x), domain='ZZ')
  1557. >>> _.nth(1, 1)
  1558. 4
  1559. See Also
  1560. ========
  1561. coeff_monomial
  1562. """
  1563. if hasattr(f.rep, 'nth'):
  1564. if len(N) != len(f.gens):
  1565. raise ValueError('exponent of each generator must be specified')
  1566. result = f.rep.nth(*list(map(int, N)))
  1567. else: # pragma: no cover
  1568. raise OperationNotSupported(f, 'nth')
  1569. return f.rep.dom.to_sympy(result)
  1570. def coeff(f, x, n=1, right=False):
  1571. # the semantics of coeff_monomial and Expr.coeff are different;
  1572. # if someone is working with a Poly, they should be aware of the
  1573. # differences and chose the method best suited for the query.
  1574. # Alternatively, a pure-polys method could be written here but
  1575. # at this time the ``right`` keyword would be ignored because Poly
  1576. # doesn't work with non-commutatives.
  1577. raise NotImplementedError(
  1578. 'Either convert to Expr with `as_expr` method '
  1579. 'to use Expr\'s coeff method or else use the '
  1580. '`coeff_monomial` method of Polys.')
  1581. def LM(f, order=None):
  1582. """
  1583. Returns the leading monomial of ``f``.
  1584. The Leading monomial signifies the monomial having
  1585. the highest power of the principal generator in the
  1586. expression f.
  1587. Examples
  1588. ========
  1589. >>> from sympy import Poly
  1590. >>> from sympy.abc import x, y
  1591. >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LM()
  1592. x**2*y**0
  1593. """
  1594. return Monomial(f.monoms(order)[0], f.gens)
  1595. def EM(f, order=None):
  1596. """
  1597. Returns the last non-zero monomial of ``f``.
  1598. Examples
  1599. ========
  1600. >>> from sympy import Poly
  1601. >>> from sympy.abc import x, y
  1602. >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).EM()
  1603. x**0*y**1
  1604. """
  1605. return Monomial(f.monoms(order)[-1], f.gens)
  1606. def LT(f, order=None):
  1607. """
  1608. Returns the leading term of ``f``.
  1609. The Leading term signifies the term having
  1610. the highest power of the principal generator in the
  1611. expression f along with its coefficient.
  1612. Examples
  1613. ========
  1614. >>> from sympy import Poly
  1615. >>> from sympy.abc import x, y
  1616. >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LT()
  1617. (x**2*y**0, 4)
  1618. """
  1619. monom, coeff = f.terms(order)[0]
  1620. return Monomial(monom, f.gens), coeff
  1621. def ET(f, order=None):
  1622. """
  1623. Returns the last non-zero term of ``f``.
  1624. Examples
  1625. ========
  1626. >>> from sympy import Poly
  1627. >>> from sympy.abc import x, y
  1628. >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).ET()
  1629. (x**0*y**1, 3)
  1630. """
  1631. monom, coeff = f.terms(order)[-1]
  1632. return Monomial(monom, f.gens), coeff
  1633. def max_norm(f):
  1634. """
  1635. Returns maximum norm of ``f``.
  1636. Examples
  1637. ========
  1638. >>> from sympy import Poly
  1639. >>> from sympy.abc import x
  1640. >>> Poly(-x**2 + 2*x - 3, x).max_norm()
  1641. 3
  1642. """
  1643. if hasattr(f.rep, 'max_norm'):
  1644. result = f.rep.max_norm()
  1645. else: # pragma: no cover
  1646. raise OperationNotSupported(f, 'max_norm')
  1647. return f.rep.dom.to_sympy(result)
  1648. def l1_norm(f):
  1649. """
  1650. Returns l1 norm of ``f``.
  1651. Examples
  1652. ========
  1653. >>> from sympy import Poly
  1654. >>> from sympy.abc import x
  1655. >>> Poly(-x**2 + 2*x - 3, x).l1_norm()
  1656. 6
  1657. """
  1658. if hasattr(f.rep, 'l1_norm'):
  1659. result = f.rep.l1_norm()
  1660. else: # pragma: no cover
  1661. raise OperationNotSupported(f, 'l1_norm')
  1662. return f.rep.dom.to_sympy(result)
  1663. def clear_denoms(self, convert=False):
  1664. """
  1665. Clear denominators, but keep the ground domain.
  1666. Examples
  1667. ========
  1668. >>> from sympy import Poly, S, QQ
  1669. >>> from sympy.abc import x
  1670. >>> f = Poly(x/2 + S(1)/3, x, domain=QQ)
  1671. >>> f.clear_denoms()
  1672. (6, Poly(3*x + 2, x, domain='QQ'))
  1673. >>> f.clear_denoms(convert=True)
  1674. (6, Poly(3*x + 2, x, domain='ZZ'))
  1675. """
  1676. f = self
  1677. if not f.rep.dom.is_Field:
  1678. return S.One, f
  1679. dom = f.get_domain()
  1680. if dom.has_assoc_Ring:
  1681. dom = f.rep.dom.get_ring()
  1682. if hasattr(f.rep, 'clear_denoms'):
  1683. coeff, result = f.rep.clear_denoms()
  1684. else: # pragma: no cover
  1685. raise OperationNotSupported(f, 'clear_denoms')
  1686. coeff, f = dom.to_sympy(coeff), f.per(result)
  1687. if not convert or not dom.has_assoc_Ring:
  1688. return coeff, f
  1689. else:
  1690. return coeff, f.to_ring()
  1691. def rat_clear_denoms(self, g):
  1692. """
  1693. Clear denominators in a rational function ``f/g``.
  1694. Examples
  1695. ========
  1696. >>> from sympy import Poly
  1697. >>> from sympy.abc import x, y
  1698. >>> f = Poly(x**2/y + 1, x)
  1699. >>> g = Poly(x**3 + y, x)
  1700. >>> p, q = f.rat_clear_denoms(g)
  1701. >>> p
  1702. Poly(x**2 + y, x, domain='ZZ[y]')
  1703. >>> q
  1704. Poly(y*x**3 + y**2, x, domain='ZZ[y]')
  1705. """
  1706. f = self
  1707. dom, per, f, g = f._unify(g)
  1708. f = per(f)
  1709. g = per(g)
  1710. if not (dom.is_Field and dom.has_assoc_Ring):
  1711. return f, g
  1712. a, f = f.clear_denoms(convert=True)
  1713. b, g = g.clear_denoms(convert=True)
  1714. f = f.mul_ground(b)
  1715. g = g.mul_ground(a)
  1716. return f, g
  1717. def integrate(self, *specs, **args):
  1718. """
  1719. Computes indefinite integral of ``f``.
  1720. Examples
  1721. ========
  1722. >>> from sympy import Poly
  1723. >>> from sympy.abc import x, y
  1724. >>> Poly(x**2 + 2*x + 1, x).integrate()
  1725. Poly(1/3*x**3 + x**2 + x, x, domain='QQ')
  1726. >>> Poly(x*y**2 + x, x, y).integrate((0, 1), (1, 0))
  1727. Poly(1/2*x**2*y**2 + 1/2*x**2, x, y, domain='QQ')
  1728. """
  1729. f = self
  1730. if args.get('auto', True) and f.rep.dom.is_Ring:
  1731. f = f.to_field()
  1732. if hasattr(f.rep, 'integrate'):
  1733. if not specs:
  1734. return f.per(f.rep.integrate(m=1))
  1735. rep = f.rep
  1736. for spec in specs:
  1737. if isinstance(spec, tuple):
  1738. gen, m = spec
  1739. else:
  1740. gen, m = spec, 1
  1741. rep = rep.integrate(int(m), f._gen_to_level(gen))
  1742. return f.per(rep)
  1743. else: # pragma: no cover
  1744. raise OperationNotSupported(f, 'integrate')
  1745. def diff(f, *specs, **kwargs):
  1746. """
  1747. Computes partial derivative of ``f``.
  1748. Examples
  1749. ========
  1750. >>> from sympy import Poly
  1751. >>> from sympy.abc import x, y
  1752. >>> Poly(x**2 + 2*x + 1, x).diff()
  1753. Poly(2*x + 2, x, domain='ZZ')
  1754. >>> Poly(x*y**2 + x, x, y).diff((0, 0), (1, 1))
  1755. Poly(2*x*y, x, y, domain='ZZ')
  1756. """
  1757. if not kwargs.get('evaluate', True):
  1758. return Derivative(f, *specs, **kwargs)
  1759. if hasattr(f.rep, 'diff'):
  1760. if not specs:
  1761. return f.per(f.rep.diff(m=1))
  1762. rep = f.rep
  1763. for spec in specs:
  1764. if isinstance(spec, tuple):
  1765. gen, m = spec
  1766. else:
  1767. gen, m = spec, 1
  1768. rep = rep.diff(int(m), f._gen_to_level(gen))
  1769. return f.per(rep)
  1770. else: # pragma: no cover
  1771. raise OperationNotSupported(f, 'diff')
  1772. _eval_derivative = diff
  1773. def eval(self, x, a=None, auto=True):
  1774. """
  1775. Evaluate ``f`` at ``a`` in the given variable.
  1776. Examples
  1777. ========
  1778. >>> from sympy import Poly
  1779. >>> from sympy.abc import x, y, z
  1780. >>> Poly(x**2 + 2*x + 3, x).eval(2)
  1781. 11
  1782. >>> Poly(2*x*y + 3*x + y + 2, x, y).eval(x, 2)
  1783. Poly(5*y + 8, y, domain='ZZ')
  1784. >>> f = Poly(2*x*y + 3*x + y + 2*z, x, y, z)
  1785. >>> f.eval({x: 2})
  1786. Poly(5*y + 2*z + 6, y, z, domain='ZZ')
  1787. >>> f.eval({x: 2, y: 5})
  1788. Poly(2*z + 31, z, domain='ZZ')
  1789. >>> f.eval({x: 2, y: 5, z: 7})
  1790. 45
  1791. >>> f.eval((2, 5))
  1792. Poly(2*z + 31, z, domain='ZZ')
  1793. >>> f(2, 5)
  1794. Poly(2*z + 31, z, domain='ZZ')
  1795. """
  1796. f = self
  1797. if a is None:
  1798. if isinstance(x, dict):
  1799. mapping = x
  1800. for gen, value in mapping.items():
  1801. f = f.eval(gen, value)
  1802. return f
  1803. elif isinstance(x, (tuple, list)):
  1804. values = x
  1805. if len(values) > len(f.gens):
  1806. raise ValueError("too many values provided")
  1807. for gen, value in zip(f.gens, values):
  1808. f = f.eval(gen, value)
  1809. return f
  1810. else:
  1811. j, a = 0, x
  1812. else:
  1813. j = f._gen_to_level(x)
  1814. if not hasattr(f.rep, 'eval'): # pragma: no cover
  1815. raise OperationNotSupported(f, 'eval')
  1816. try:
  1817. result = f.rep.eval(a, j)
  1818. except CoercionFailed:
  1819. if not auto:
  1820. raise DomainError("Cannot evaluate at %s in %s" % (a, f.rep.dom))
  1821. else:
  1822. a_domain, [a] = construct_domain([a])
  1823. new_domain = f.get_domain().unify_with_symbols(a_domain, f.gens)
  1824. f = f.set_domain(new_domain)
  1825. a = new_domain.convert(a, a_domain)
  1826. result = f.rep.eval(a, j)
  1827. return f.per(result, remove=j)
  1828. def __call__(f, *values):
  1829. """
  1830. Evaluate ``f`` at the give values.
  1831. Examples
  1832. ========
  1833. >>> from sympy import Poly
  1834. >>> from sympy.abc import x, y, z
  1835. >>> f = Poly(2*x*y + 3*x + y + 2*z, x, y, z)
  1836. >>> f(2)
  1837. Poly(5*y + 2*z + 6, y, z, domain='ZZ')
  1838. >>> f(2, 5)
  1839. Poly(2*z + 31, z, domain='ZZ')
  1840. >>> f(2, 5, 7)
  1841. 45
  1842. """
  1843. return f.eval(values)
  1844. def half_gcdex(f, g, auto=True):
  1845. """
  1846. Half extended Euclidean algorithm of ``f`` and ``g``.
  1847. Returns ``(s, h)`` such that ``h = gcd(f, g)`` and ``s*f = h (mod g)``.
  1848. Examples
  1849. ========
  1850. >>> from sympy import Poly
  1851. >>> from sympy.abc import x
  1852. >>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
  1853. >>> g = x**3 + x**2 - 4*x - 4
  1854. >>> Poly(f).half_gcdex(Poly(g))
  1855. (Poly(-1/5*x + 3/5, x, domain='QQ'), Poly(x + 1, x, domain='QQ'))
  1856. """
  1857. dom, per, F, G = f._unify(g)
  1858. if auto and dom.is_Ring:
  1859. F, G = F.to_field(), G.to_field()
  1860. if hasattr(f.rep, 'half_gcdex'):
  1861. s, h = F.half_gcdex(G)
  1862. else: # pragma: no cover
  1863. raise OperationNotSupported(f, 'half_gcdex')
  1864. return per(s), per(h)
  1865. def gcdex(f, g, auto=True):
  1866. """
  1867. Extended Euclidean algorithm of ``f`` and ``g``.
  1868. Returns ``(s, t, h)`` such that ``h = gcd(f, g)`` and ``s*f + t*g = h``.
  1869. Examples
  1870. ========
  1871. >>> from sympy import Poly
  1872. >>> from sympy.abc import x
  1873. >>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
  1874. >>> g = x**3 + x**2 - 4*x - 4
  1875. >>> Poly(f).gcdex(Poly(g))
  1876. (Poly(-1/5*x + 3/5, x, domain='QQ'),
  1877. Poly(1/5*x**2 - 6/5*x + 2, x, domain='QQ'),
  1878. Poly(x + 1, x, domain='QQ'))
  1879. """
  1880. dom, per, F, G = f._unify(g)
  1881. if auto and dom.is_Ring:
  1882. F, G = F.to_field(), G.to_field()
  1883. if hasattr(f.rep, 'gcdex'):
  1884. s, t, h = F.gcdex(G)
  1885. else: # pragma: no cover
  1886. raise OperationNotSupported(f, 'gcdex')
  1887. return per(s), per(t), per(h)
  1888. def invert(f, g, auto=True):
  1889. """
  1890. Invert ``f`` modulo ``g`` when possible.
  1891. Examples
  1892. ========
  1893. >>> from sympy import Poly
  1894. >>> from sympy.abc import x
  1895. >>> Poly(x**2 - 1, x).invert(Poly(2*x - 1, x))
  1896. Poly(-4/3, x, domain='QQ')
  1897. >>> Poly(x**2 - 1, x).invert(Poly(x - 1, x))
  1898. Traceback (most recent call last):
  1899. ...
  1900. NotInvertible: zero divisor
  1901. """
  1902. dom, per, F, G = f._unify(g)
  1903. if auto and dom.is_Ring:
  1904. F, G = F.to_field(), G.to_field()
  1905. if hasattr(f.rep, 'invert'):
  1906. result = F.invert(G)
  1907. else: # pragma: no cover
  1908. raise OperationNotSupported(f, 'invert')
  1909. return per(result)
  1910. def revert(f, n):
  1911. """
  1912. Compute ``f**(-1)`` mod ``x**n``.
  1913. Examples
  1914. ========
  1915. >>> from sympy import Poly
  1916. >>> from sympy.abc import x
  1917. >>> Poly(1, x).revert(2)
  1918. Poly(1, x, domain='ZZ')
  1919. >>> Poly(1 + x, x).revert(1)
  1920. Poly(1, x, domain='ZZ')
  1921. >>> Poly(x**2 - 2, x).revert(2)
  1922. Traceback (most recent call last):
  1923. ...
  1924. NotReversible: only units are reversible in a ring
  1925. >>> Poly(1/x, x).revert(1)
  1926. Traceback (most recent call last):
  1927. ...
  1928. PolynomialError: 1/x contains an element of the generators set
  1929. """
  1930. if hasattr(f.rep, 'revert'):
  1931. result = f.rep.revert(int(n))
  1932. else: # pragma: no cover
  1933. raise OperationNotSupported(f, 'revert')
  1934. return f.per(result)
  1935. def subresultants(f, g):
  1936. """
  1937. Computes the subresultant PRS of ``f`` and ``g``.
  1938. Examples
  1939. ========
  1940. >>> from sympy import Poly
  1941. >>> from sympy.abc import x
  1942. >>> Poly(x**2 + 1, x).subresultants(Poly(x**2 - 1, x))
  1943. [Poly(x**2 + 1, x, domain='ZZ'),
  1944. Poly(x**2 - 1, x, domain='ZZ'),
  1945. Poly(-2, x, domain='ZZ')]
  1946. """
  1947. _, per, F, G = f._unify(g)
  1948. if hasattr(f.rep, 'subresultants'):
  1949. result = F.subresultants(G)
  1950. else: # pragma: no cover
  1951. raise OperationNotSupported(f, 'subresultants')
  1952. return list(map(per, result))
  1953. def resultant(f, g, includePRS=False):
  1954. """
  1955. Computes the resultant of ``f`` and ``g`` via PRS.
  1956. If includePRS=True, it includes the subresultant PRS in the result.
  1957. Because the PRS is used to calculate the resultant, this is more
  1958. efficient than calling :func:`subresultants` separately.
  1959. Examples
  1960. ========
  1961. >>> from sympy import Poly
  1962. >>> from sympy.abc import x
  1963. >>> f = Poly(x**2 + 1, x)
  1964. >>> f.resultant(Poly(x**2 - 1, x))
  1965. 4
  1966. >>> f.resultant(Poly(x**2 - 1, x), includePRS=True)
  1967. (4, [Poly(x**2 + 1, x, domain='ZZ'), Poly(x**2 - 1, x, domain='ZZ'),
  1968. Poly(-2, x, domain='ZZ')])
  1969. """
  1970. _, per, F, G = f._unify(g)
  1971. if hasattr(f.rep, 'resultant'):
  1972. if includePRS:
  1973. result, R = F.resultant(G, includePRS=includePRS)
  1974. else:
  1975. result = F.resultant(G)
  1976. else: # pragma: no cover
  1977. raise OperationNotSupported(f, 'resultant')
  1978. if includePRS:
  1979. return (per(result, remove=0), list(map(per, R)))
  1980. return per(result, remove=0)
  1981. def discriminant(f):
  1982. """
  1983. Computes the discriminant of ``f``.
  1984. Examples
  1985. ========
  1986. >>> from sympy import Poly
  1987. >>> from sympy.abc import x
  1988. >>> Poly(x**2 + 2*x + 3, x).discriminant()
  1989. -8
  1990. """
  1991. if hasattr(f.rep, 'discriminant'):
  1992. result = f.rep.discriminant()
  1993. else: # pragma: no cover
  1994. raise OperationNotSupported(f, 'discriminant')
  1995. return f.per(result, remove=0)
  1996. def dispersionset(f, g=None):
  1997. r"""Compute the *dispersion set* of two polynomials.
  1998. For two polynomials `f(x)` and `g(x)` with `\deg f > 0`
  1999. and `\deg g > 0` the dispersion set `\operatorname{J}(f, g)` is defined as:
  2000. .. math::
  2001. \operatorname{J}(f, g)
  2002. & := \{a \in \mathbb{N}_0 | \gcd(f(x), g(x+a)) \neq 1\} \\
  2003. & = \{a \in \mathbb{N}_0 | \deg \gcd(f(x), g(x+a)) \geq 1\}
  2004. For a single polynomial one defines `\operatorname{J}(f) := \operatorname{J}(f, f)`.
  2005. Examples
  2006. ========
  2007. >>> from sympy import poly
  2008. >>> from sympy.polys.dispersion import dispersion, dispersionset
  2009. >>> from sympy.abc import x
  2010. Dispersion set and dispersion of a simple polynomial:
  2011. >>> fp = poly((x - 3)*(x + 3), x)
  2012. >>> sorted(dispersionset(fp))
  2013. [0, 6]
  2014. >>> dispersion(fp)
  2015. 6
  2016. Note that the definition of the dispersion is not symmetric:
  2017. >>> fp = poly(x**4 - 3*x**2 + 1, x)
  2018. >>> gp = fp.shift(-3)
  2019. >>> sorted(dispersionset(fp, gp))
  2020. [2, 3, 4]
  2021. >>> dispersion(fp, gp)
  2022. 4
  2023. >>> sorted(dispersionset(gp, fp))
  2024. []
  2025. >>> dispersion(gp, fp)
  2026. -oo
  2027. Computing the dispersion also works over field extensions:
  2028. >>> from sympy import sqrt
  2029. >>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
  2030. >>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
  2031. >>> sorted(dispersionset(fp, gp))
  2032. [2]
  2033. >>> sorted(dispersionset(gp, fp))
  2034. [1, 4]
  2035. We can even perform the computations for polynomials
  2036. having symbolic coefficients:
  2037. >>> from sympy.abc import a
  2038. >>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
  2039. >>> sorted(dispersionset(fp))
  2040. [0, 1]
  2041. See Also
  2042. ========
  2043. dispersion
  2044. References
  2045. ==========
  2046. 1. [ManWright94]_
  2047. 2. [Koepf98]_
  2048. 3. [Abramov71]_
  2049. 4. [Man93]_
  2050. """
  2051. from sympy.polys.dispersion import dispersionset
  2052. return dispersionset(f, g)
  2053. def dispersion(f, g=None):
  2054. r"""Compute the *dispersion* of polynomials.
  2055. For two polynomials `f(x)` and `g(x)` with `\deg f > 0`
  2056. and `\deg g > 0` the dispersion `\operatorname{dis}(f, g)` is defined as:
  2057. .. math::
  2058. \operatorname{dis}(f, g)
  2059. & := \max\{ J(f,g) \cup \{0\} \} \\
  2060. & = \max\{ \{a \in \mathbb{N} | \gcd(f(x), g(x+a)) \neq 1\} \cup \{0\} \}
  2061. and for a single polynomial `\operatorname{dis}(f) := \operatorname{dis}(f, f)`.
  2062. Examples
  2063. ========
  2064. >>> from sympy import poly
  2065. >>> from sympy.polys.dispersion import dispersion, dispersionset
  2066. >>> from sympy.abc import x
  2067. Dispersion set and dispersion of a simple polynomial:
  2068. >>> fp = poly((x - 3)*(x + 3), x)
  2069. >>> sorted(dispersionset(fp))
  2070. [0, 6]
  2071. >>> dispersion(fp)
  2072. 6
  2073. Note that the definition of the dispersion is not symmetric:
  2074. >>> fp = poly(x**4 - 3*x**2 + 1, x)
  2075. >>> gp = fp.shift(-3)
  2076. >>> sorted(dispersionset(fp, gp))
  2077. [2, 3, 4]
  2078. >>> dispersion(fp, gp)
  2079. 4
  2080. >>> sorted(dispersionset(gp, fp))
  2081. []
  2082. >>> dispersion(gp, fp)
  2083. -oo
  2084. Computing the dispersion also works over field extensions:
  2085. >>> from sympy import sqrt
  2086. >>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
  2087. >>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
  2088. >>> sorted(dispersionset(fp, gp))
  2089. [2]
  2090. >>> sorted(dispersionset(gp, fp))
  2091. [1, 4]
  2092. We can even perform the computations for polynomials
  2093. having symbolic coefficients:
  2094. >>> from sympy.abc import a
  2095. >>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
  2096. >>> sorted(dispersionset(fp))
  2097. [0, 1]
  2098. See Also
  2099. ========
  2100. dispersionset
  2101. References
  2102. ==========
  2103. 1. [ManWright94]_
  2104. 2. [Koepf98]_
  2105. 3. [Abramov71]_
  2106. 4. [Man93]_
  2107. """
  2108. from sympy.polys.dispersion import dispersion
  2109. return dispersion(f, g)
  2110. def cofactors(f, g):
  2111. """
  2112. Returns the GCD of ``f`` and ``g`` and their cofactors.
  2113. Returns polynomials ``(h, cff, cfg)`` such that ``h = gcd(f, g)``, and
  2114. ``cff = quo(f, h)`` and ``cfg = quo(g, h)`` are, so called, cofactors
  2115. of ``f`` and ``g``.
  2116. Examples
  2117. ========
  2118. >>> from sympy import Poly
  2119. >>> from sympy.abc import x
  2120. >>> Poly(x**2 - 1, x).cofactors(Poly(x**2 - 3*x + 2, x))
  2121. (Poly(x - 1, x, domain='ZZ'),
  2122. Poly(x + 1, x, domain='ZZ'),
  2123. Poly(x - 2, x, domain='ZZ'))
  2124. """
  2125. _, per, F, G = f._unify(g)
  2126. if hasattr(f.rep, 'cofactors'):
  2127. h, cff, cfg = F.cofactors(G)
  2128. else: # pragma: no cover
  2129. raise OperationNotSupported(f, 'cofactors')
  2130. return per(h), per(cff), per(cfg)
  2131. def gcd(f, g):
  2132. """
  2133. Returns the polynomial GCD of ``f`` and ``g``.
  2134. Examples
  2135. ========
  2136. >>> from sympy import Poly
  2137. >>> from sympy.abc import x
  2138. >>> Poly(x**2 - 1, x).gcd(Poly(x**2 - 3*x + 2, x))
  2139. Poly(x - 1, x, domain='ZZ')
  2140. """
  2141. _, per, F, G = f._unify(g)
  2142. if hasattr(f.rep, 'gcd'):
  2143. result = F.gcd(G)
  2144. else: # pragma: no cover
  2145. raise OperationNotSupported(f, 'gcd')
  2146. return per(result)
  2147. def lcm(f, g):
  2148. """
  2149. Returns polynomial LCM of ``f`` and ``g``.
  2150. Examples
  2151. ========
  2152. >>> from sympy import Poly
  2153. >>> from sympy.abc import x
  2154. >>> Poly(x**2 - 1, x).lcm(Poly(x**2 - 3*x + 2, x))
  2155. Poly(x**3 - 2*x**2 - x + 2, x, domain='ZZ')
  2156. """
  2157. _, per, F, G = f._unify(g)
  2158. if hasattr(f.rep, 'lcm'):
  2159. result = F.lcm(G)
  2160. else: # pragma: no cover
  2161. raise OperationNotSupported(f, 'lcm')
  2162. return per(result)
  2163. def trunc(f, p):
  2164. """
  2165. Reduce ``f`` modulo a constant ``p``.
  2166. Examples
  2167. ========
  2168. >>> from sympy import Poly
  2169. >>> from sympy.abc import x
  2170. >>> Poly(2*x**3 + 3*x**2 + 5*x + 7, x).trunc(3)
  2171. Poly(-x**3 - x + 1, x, domain='ZZ')
  2172. """
  2173. p = f.rep.dom.convert(p)
  2174. if hasattr(f.rep, 'trunc'):
  2175. result = f.rep.trunc(p)
  2176. else: # pragma: no cover
  2177. raise OperationNotSupported(f, 'trunc')
  2178. return f.per(result)
  2179. def monic(self, auto=True):
  2180. """
  2181. Divides all coefficients by ``LC(f)``.
  2182. Examples
  2183. ========
  2184. >>> from sympy import Poly, ZZ
  2185. >>> from sympy.abc import x
  2186. >>> Poly(3*x**2 + 6*x + 9, x, domain=ZZ).monic()
  2187. Poly(x**2 + 2*x + 3, x, domain='QQ')
  2188. >>> Poly(3*x**2 + 4*x + 2, x, domain=ZZ).monic()
  2189. Poly(x**2 + 4/3*x + 2/3, x, domain='QQ')
  2190. """
  2191. f = self
  2192. if auto and f.rep.dom.is_Ring:
  2193. f = f.to_field()
  2194. if hasattr(f.rep, 'monic'):
  2195. result = f.rep.monic()
  2196. else: # pragma: no cover
  2197. raise OperationNotSupported(f, 'monic')
  2198. return f.per(result)
  2199. def content(f):
  2200. """
  2201. Returns the GCD of polynomial coefficients.
  2202. Examples
  2203. ========
  2204. >>> from sympy import Poly
  2205. >>> from sympy.abc import x
  2206. >>> Poly(6*x**2 + 8*x + 12, x).content()
  2207. 2
  2208. """
  2209. if hasattr(f.rep, 'content'):
  2210. result = f.rep.content()
  2211. else: # pragma: no cover
  2212. raise OperationNotSupported(f, 'content')
  2213. return f.rep.dom.to_sympy(result)
  2214. def primitive(f):
  2215. """
  2216. Returns the content and a primitive form of ``f``.
  2217. Examples
  2218. ========
  2219. >>> from sympy import Poly
  2220. >>> from sympy.abc import x
  2221. >>> Poly(2*x**2 + 8*x + 12, x).primitive()
  2222. (2, Poly(x**2 + 4*x + 6, x, domain='ZZ'))
  2223. """
  2224. if hasattr(f.rep, 'primitive'):
  2225. cont, result = f.rep.primitive()
  2226. else: # pragma: no cover
  2227. raise OperationNotSupported(f, 'primitive')
  2228. return f.rep.dom.to_sympy(cont), f.per(result)
  2229. def compose(f, g):
  2230. """
  2231. Computes the functional composition of ``f`` and ``g``.
  2232. Examples
  2233. ========
  2234. >>> from sympy import Poly
  2235. >>> from sympy.abc import x
  2236. >>> Poly(x**2 + x, x).compose(Poly(x - 1, x))
  2237. Poly(x**2 - x, x, domain='ZZ')
  2238. """
  2239. _, per, F, G = f._unify(g)
  2240. if hasattr(f.rep, 'compose'):
  2241. result = F.compose(G)
  2242. else: # pragma: no cover
  2243. raise OperationNotSupported(f, 'compose')
  2244. return per(result)
  2245. def decompose(f):
  2246. """
  2247. Computes a functional decomposition of ``f``.
  2248. Examples
  2249. ========
  2250. >>> from sympy import Poly
  2251. >>> from sympy.abc import x
  2252. >>> Poly(x**4 + 2*x**3 - x - 1, x, domain='ZZ').decompose()
  2253. [Poly(x**2 - x - 1, x, domain='ZZ'), Poly(x**2 + x, x, domain='ZZ')]
  2254. """
  2255. if hasattr(f.rep, 'decompose'):
  2256. result = f.rep.decompose()
  2257. else: # pragma: no cover
  2258. raise OperationNotSupported(f, 'decompose')
  2259. return list(map(f.per, result))
  2260. def shift(f, a):
  2261. """
  2262. Efficiently compute Taylor shift ``f(x + a)``.
  2263. Examples
  2264. ========
  2265. >>> from sympy import Poly
  2266. >>> from sympy.abc import x
  2267. >>> Poly(x**2 - 2*x + 1, x).shift(2)
  2268. Poly(x**2 + 2*x + 1, x, domain='ZZ')
  2269. """
  2270. if hasattr(f.rep, 'shift'):
  2271. result = f.rep.shift(a)
  2272. else: # pragma: no cover
  2273. raise OperationNotSupported(f, 'shift')
  2274. return f.per(result)
  2275. def transform(f, p, q):
  2276. """
  2277. Efficiently evaluate the functional transformation ``q**n * f(p/q)``.
  2278. Examples
  2279. ========
  2280. >>> from sympy import Poly
  2281. >>> from sympy.abc import x
  2282. >>> Poly(x**2 - 2*x + 1, x).transform(Poly(x + 1, x), Poly(x - 1, x))
  2283. Poly(4, x, domain='ZZ')
  2284. """
  2285. P, Q = p.unify(q)
  2286. F, P = f.unify(P)
  2287. F, Q = F.unify(Q)
  2288. if hasattr(F.rep, 'transform'):
  2289. result = F.rep.transform(P.rep, Q.rep)
  2290. else: # pragma: no cover
  2291. raise OperationNotSupported(F, 'transform')
  2292. return F.per(result)
  2293. def sturm(self, auto=True):
  2294. """
  2295. Computes the Sturm sequence of ``f``.
  2296. Examples
  2297. ========
  2298. >>> from sympy import Poly
  2299. >>> from sympy.abc import x
  2300. >>> Poly(x**3 - 2*x**2 + x - 3, x).sturm()
  2301. [Poly(x**3 - 2*x**2 + x - 3, x, domain='QQ'),
  2302. Poly(3*x**2 - 4*x + 1, x, domain='QQ'),
  2303. Poly(2/9*x + 25/9, x, domain='QQ'),
  2304. Poly(-2079/4, x, domain='QQ')]
  2305. """
  2306. f = self
  2307. if auto and f.rep.dom.is_Ring:
  2308. f = f.to_field()
  2309. if hasattr(f.rep, 'sturm'):
  2310. result = f.rep.sturm()
  2311. else: # pragma: no cover
  2312. raise OperationNotSupported(f, 'sturm')
  2313. return list(map(f.per, result))
  2314. def gff_list(f):
  2315. """
  2316. Computes greatest factorial factorization of ``f``.
  2317. Examples
  2318. ========
  2319. >>> from sympy import Poly
  2320. >>> from sympy.abc import x
  2321. >>> f = x**5 + 2*x**4 - x**3 - 2*x**2
  2322. >>> Poly(f).gff_list()
  2323. [(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)]
  2324. """
  2325. if hasattr(f.rep, 'gff_list'):
  2326. result = f.rep.gff_list()
  2327. else: # pragma: no cover
  2328. raise OperationNotSupported(f, 'gff_list')
  2329. return [(f.per(g), k) for g, k in result]
  2330. def norm(f):
  2331. """
  2332. Computes the product, ``Norm(f)``, of the conjugates of
  2333. a polynomial ``f`` defined over a number field ``K``.
  2334. Examples
  2335. ========
  2336. >>> from sympy import Poly, sqrt
  2337. >>> from sympy.abc import x
  2338. >>> a, b = sqrt(2), sqrt(3)
  2339. A polynomial over a quadratic extension.
  2340. Two conjugates x - a and x + a.
  2341. >>> f = Poly(x - a, x, extension=a)
  2342. >>> f.norm()
  2343. Poly(x**2 - 2, x, domain='QQ')
  2344. A polynomial over a quartic extension.
  2345. Four conjugates x - a, x - a, x + a and x + a.
  2346. >>> f = Poly(x - a, x, extension=(a, b))
  2347. >>> f.norm()
  2348. Poly(x**4 - 4*x**2 + 4, x, domain='QQ')
  2349. """
  2350. if hasattr(f.rep, 'norm'):
  2351. r = f.rep.norm()
  2352. else: # pragma: no cover
  2353. raise OperationNotSupported(f, 'norm')
  2354. return f.per(r)
  2355. def sqf_norm(f):
  2356. """
  2357. Computes square-free norm of ``f``.
  2358. Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and
  2359. ``r(x) = Norm(g(x))`` is a square-free polynomial over ``K``,
  2360. where ``a`` is the algebraic extension of the ground domain.
  2361. Examples
  2362. ========
  2363. >>> from sympy import Poly, sqrt
  2364. >>> from sympy.abc import x
  2365. >>> s, f, r = Poly(x**2 + 1, x, extension=[sqrt(3)]).sqf_norm()
  2366. >>> s
  2367. 1
  2368. >>> f
  2369. Poly(x**2 - 2*sqrt(3)*x + 4, x, domain='QQ<sqrt(3)>')
  2370. >>> r
  2371. Poly(x**4 - 4*x**2 + 16, x, domain='QQ')
  2372. """
  2373. if hasattr(f.rep, 'sqf_norm'):
  2374. s, g, r = f.rep.sqf_norm()
  2375. else: # pragma: no cover
  2376. raise OperationNotSupported(f, 'sqf_norm')
  2377. return s, f.per(g), f.per(r)
  2378. def sqf_part(f):
  2379. """
  2380. Computes square-free part of ``f``.
  2381. Examples
  2382. ========
  2383. >>> from sympy import Poly
  2384. >>> from sympy.abc import x
  2385. >>> Poly(x**3 - 3*x - 2, x).sqf_part()
  2386. Poly(x**2 - x - 2, x, domain='ZZ')
  2387. """
  2388. if hasattr(f.rep, 'sqf_part'):
  2389. result = f.rep.sqf_part()
  2390. else: # pragma: no cover
  2391. raise OperationNotSupported(f, 'sqf_part')
  2392. return f.per(result)
  2393. def sqf_list(f, all=False):
  2394. """
  2395. Returns a list of square-free factors of ``f``.
  2396. Examples
  2397. ========
  2398. >>> from sympy import Poly
  2399. >>> from sympy.abc import x
  2400. >>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16
  2401. >>> Poly(f).sqf_list()
  2402. (2, [(Poly(x + 1, x, domain='ZZ'), 2),
  2403. (Poly(x + 2, x, domain='ZZ'), 3)])
  2404. >>> Poly(f).sqf_list(all=True)
  2405. (2, [(Poly(1, x, domain='ZZ'), 1),
  2406. (Poly(x + 1, x, domain='ZZ'), 2),
  2407. (Poly(x + 2, x, domain='ZZ'), 3)])
  2408. """
  2409. if hasattr(f.rep, 'sqf_list'):
  2410. coeff, factors = f.rep.sqf_list(all)
  2411. else: # pragma: no cover
  2412. raise OperationNotSupported(f, 'sqf_list')
  2413. return f.rep.dom.to_sympy(coeff), [(f.per(g), k) for g, k in factors]
  2414. def sqf_list_include(f, all=False):
  2415. """
  2416. Returns a list of square-free factors of ``f``.
  2417. Examples
  2418. ========
  2419. >>> from sympy import Poly, expand
  2420. >>> from sympy.abc import x
  2421. >>> f = expand(2*(x + 1)**3*x**4)
  2422. >>> f
  2423. 2*x**7 + 6*x**6 + 6*x**5 + 2*x**4
  2424. >>> Poly(f).sqf_list_include()
  2425. [(Poly(2, x, domain='ZZ'), 1),
  2426. (Poly(x + 1, x, domain='ZZ'), 3),
  2427. (Poly(x, x, domain='ZZ'), 4)]
  2428. >>> Poly(f).sqf_list_include(all=True)
  2429. [(Poly(2, x, domain='ZZ'), 1),
  2430. (Poly(1, x, domain='ZZ'), 2),
  2431. (Poly(x + 1, x, domain='ZZ'), 3),
  2432. (Poly(x, x, domain='ZZ'), 4)]
  2433. """
  2434. if hasattr(f.rep, 'sqf_list_include'):
  2435. factors = f.rep.sqf_list_include(all)
  2436. else: # pragma: no cover
  2437. raise OperationNotSupported(f, 'sqf_list_include')
  2438. return [(f.per(g), k) for g, k in factors]
  2439. def factor_list(f):
  2440. """
  2441. Returns a list of irreducible factors of ``f``.
  2442. Examples
  2443. ========
  2444. >>> from sympy import Poly
  2445. >>> from sympy.abc import x, y
  2446. >>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y
  2447. >>> Poly(f).factor_list()
  2448. (2, [(Poly(x + y, x, y, domain='ZZ'), 1),
  2449. (Poly(x**2 + 1, x, y, domain='ZZ'), 2)])
  2450. """
  2451. if hasattr(f.rep, 'factor_list'):
  2452. try:
  2453. coeff, factors = f.rep.factor_list()
  2454. except DomainError:
  2455. return S.One, [(f, 1)]
  2456. else: # pragma: no cover
  2457. raise OperationNotSupported(f, 'factor_list')
  2458. return f.rep.dom.to_sympy(coeff), [(f.per(g), k) for g, k in factors]
  2459. def factor_list_include(f):
  2460. """
  2461. Returns a list of irreducible factors of ``f``.
  2462. Examples
  2463. ========
  2464. >>> from sympy import Poly
  2465. >>> from sympy.abc import x, y
  2466. >>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y
  2467. >>> Poly(f).factor_list_include()
  2468. [(Poly(2*x + 2*y, x, y, domain='ZZ'), 1),
  2469. (Poly(x**2 + 1, x, y, domain='ZZ'), 2)]
  2470. """
  2471. if hasattr(f.rep, 'factor_list_include'):
  2472. try:
  2473. factors = f.rep.factor_list_include()
  2474. except DomainError:
  2475. return [(f, 1)]
  2476. else: # pragma: no cover
  2477. raise OperationNotSupported(f, 'factor_list_include')
  2478. return [(f.per(g), k) for g, k in factors]
  2479. def intervals(f, all=False, eps=None, inf=None, sup=None, fast=False, sqf=False):
  2480. """
  2481. Compute isolating intervals for roots of ``f``.
  2482. For real roots the Vincent-Akritas-Strzebonski (VAS) continued fractions method is used.
  2483. References
  2484. ==========
  2485. .. [#] Alkiviadis G. Akritas and Adam W. Strzebonski: A Comparative Study of Two Real Root
  2486. Isolation Methods . Nonlinear Analysis: Modelling and Control, Vol. 10, No. 4, 297-304, 2005.
  2487. .. [#] Alkiviadis G. Akritas, Adam W. Strzebonski and Panagiotis S. Vigklas: Improving the
  2488. Performance of the Continued Fractions Method Using new Bounds of Positive Roots. Nonlinear
  2489. Analysis: Modelling and Control, Vol. 13, No. 3, 265-279, 2008.
  2490. Examples
  2491. ========
  2492. >>> from sympy import Poly
  2493. >>> from sympy.abc import x
  2494. >>> Poly(x**2 - 3, x).intervals()
  2495. [((-2, -1), 1), ((1, 2), 1)]
  2496. >>> Poly(x**2 - 3, x).intervals(eps=1e-2)
  2497. [((-26/15, -19/11), 1), ((19/11, 26/15), 1)]
  2498. """
  2499. if eps is not None:
  2500. eps = QQ.convert(eps)
  2501. if eps <= 0:
  2502. raise ValueError("'eps' must be a positive rational")
  2503. if inf is not None:
  2504. inf = QQ.convert(inf)
  2505. if sup is not None:
  2506. sup = QQ.convert(sup)
  2507. if hasattr(f.rep, 'intervals'):
  2508. result = f.rep.intervals(
  2509. all=all, eps=eps, inf=inf, sup=sup, fast=fast, sqf=sqf)
  2510. else: # pragma: no cover
  2511. raise OperationNotSupported(f, 'intervals')
  2512. if sqf:
  2513. def _real(interval):
  2514. s, t = interval
  2515. return (QQ.to_sympy(s), QQ.to_sympy(t))
  2516. if not all:
  2517. return list(map(_real, result))
  2518. def _complex(rectangle):
  2519. (u, v), (s, t) = rectangle
  2520. return (QQ.to_sympy(u) + I*QQ.to_sympy(v),
  2521. QQ.to_sympy(s) + I*QQ.to_sympy(t))
  2522. real_part, complex_part = result
  2523. return list(map(_real, real_part)), list(map(_complex, complex_part))
  2524. else:
  2525. def _real(interval):
  2526. (s, t), k = interval
  2527. return ((QQ.to_sympy(s), QQ.to_sympy(t)), k)
  2528. if not all:
  2529. return list(map(_real, result))
  2530. def _complex(rectangle):
  2531. ((u, v), (s, t)), k = rectangle
  2532. return ((QQ.to_sympy(u) + I*QQ.to_sympy(v),
  2533. QQ.to_sympy(s) + I*QQ.to_sympy(t)), k)
  2534. real_part, complex_part = result
  2535. return list(map(_real, real_part)), list(map(_complex, complex_part))
  2536. def refine_root(f, s, t, eps=None, steps=None, fast=False, check_sqf=False):
  2537. """
  2538. Refine an isolating interval of a root to the given precision.
  2539. Examples
  2540. ========
  2541. >>> from sympy import Poly
  2542. >>> from sympy.abc import x
  2543. >>> Poly(x**2 - 3, x).refine_root(1, 2, eps=1e-2)
  2544. (19/11, 26/15)
  2545. """
  2546. if check_sqf and not f.is_sqf:
  2547. raise PolynomialError("only square-free polynomials supported")
  2548. s, t = QQ.convert(s), QQ.convert(t)
  2549. if eps is not None:
  2550. eps = QQ.convert(eps)
  2551. if eps <= 0:
  2552. raise ValueError("'eps' must be a positive rational")
  2553. if steps is not None:
  2554. steps = int(steps)
  2555. elif eps is None:
  2556. steps = 1
  2557. if hasattr(f.rep, 'refine_root'):
  2558. S, T = f.rep.refine_root(s, t, eps=eps, steps=steps, fast=fast)
  2559. else: # pragma: no cover
  2560. raise OperationNotSupported(f, 'refine_root')
  2561. return QQ.to_sympy(S), QQ.to_sympy(T)
  2562. def count_roots(f, inf=None, sup=None):
  2563. """
  2564. Return the number of roots of ``f`` in ``[inf, sup]`` interval.
  2565. Examples
  2566. ========
  2567. >>> from sympy import Poly, I
  2568. >>> from sympy.abc import x
  2569. >>> Poly(x**4 - 4, x).count_roots(-3, 3)
  2570. 2
  2571. >>> Poly(x**4 - 4, x).count_roots(0, 1 + 3*I)
  2572. 1
  2573. """
  2574. inf_real, sup_real = True, True
  2575. if inf is not None:
  2576. inf = sympify(inf)
  2577. if inf is S.NegativeInfinity:
  2578. inf = None
  2579. else:
  2580. re, im = inf.as_real_imag()
  2581. if not im:
  2582. inf = QQ.convert(inf)
  2583. else:
  2584. inf, inf_real = list(map(QQ.convert, (re, im))), False
  2585. if sup is not None:
  2586. sup = sympify(sup)
  2587. if sup is S.Infinity:
  2588. sup = None
  2589. else:
  2590. re, im = sup.as_real_imag()
  2591. if not im:
  2592. sup = QQ.convert(sup)
  2593. else:
  2594. sup, sup_real = list(map(QQ.convert, (re, im))), False
  2595. if inf_real and sup_real:
  2596. if hasattr(f.rep, 'count_real_roots'):
  2597. count = f.rep.count_real_roots(inf=inf, sup=sup)
  2598. else: # pragma: no cover
  2599. raise OperationNotSupported(f, 'count_real_roots')
  2600. else:
  2601. if inf_real and inf is not None:
  2602. inf = (inf, QQ.zero)
  2603. if sup_real and sup is not None:
  2604. sup = (sup, QQ.zero)
  2605. if hasattr(f.rep, 'count_complex_roots'):
  2606. count = f.rep.count_complex_roots(inf=inf, sup=sup)
  2607. else: # pragma: no cover
  2608. raise OperationNotSupported(f, 'count_complex_roots')
  2609. return Integer(count)
  2610. def root(f, index, radicals=True):
  2611. """
  2612. Get an indexed root of a polynomial.
  2613. Examples
  2614. ========
  2615. >>> from sympy import Poly
  2616. >>> from sympy.abc import x
  2617. >>> f = Poly(2*x**3 - 7*x**2 + 4*x + 4)
  2618. >>> f.root(0)
  2619. -1/2
  2620. >>> f.root(1)
  2621. 2
  2622. >>> f.root(2)
  2623. 2
  2624. >>> f.root(3)
  2625. Traceback (most recent call last):
  2626. ...
  2627. IndexError: root index out of [-3, 2] range, got 3
  2628. >>> Poly(x**5 + x + 1).root(0)
  2629. CRootOf(x**3 - x**2 + 1, 0)
  2630. """
  2631. return sympy.polys.rootoftools.rootof(f, index, radicals=radicals)
  2632. def real_roots(f, multiple=True, radicals=True):
  2633. """
  2634. Return a list of real roots with multiplicities.
  2635. Examples
  2636. ========
  2637. >>> from sympy import Poly
  2638. >>> from sympy.abc import x
  2639. >>> Poly(2*x**3 - 7*x**2 + 4*x + 4).real_roots()
  2640. [-1/2, 2, 2]
  2641. >>> Poly(x**3 + x + 1).real_roots()
  2642. [CRootOf(x**3 + x + 1, 0)]
  2643. """
  2644. reals = sympy.polys.rootoftools.CRootOf.real_roots(f, radicals=radicals)
  2645. if multiple:
  2646. return reals
  2647. else:
  2648. return group(reals, multiple=False)
  2649. def all_roots(f, multiple=True, radicals=True):
  2650. """
  2651. Return a list of real and complex roots with multiplicities.
  2652. Examples
  2653. ========
  2654. >>> from sympy import Poly
  2655. >>> from sympy.abc import x
  2656. >>> Poly(2*x**3 - 7*x**2 + 4*x + 4).all_roots()
  2657. [-1/2, 2, 2]
  2658. >>> Poly(x**3 + x + 1).all_roots()
  2659. [CRootOf(x**3 + x + 1, 0),
  2660. CRootOf(x**3 + x + 1, 1),
  2661. CRootOf(x**3 + x + 1, 2)]
  2662. """
  2663. roots = sympy.polys.rootoftools.CRootOf.all_roots(f, radicals=radicals)
  2664. if multiple:
  2665. return roots
  2666. else:
  2667. return group(roots, multiple=False)
  2668. def nroots(f, n=15, maxsteps=50, cleanup=True):
  2669. """
  2670. Compute numerical approximations of roots of ``f``.
  2671. Parameters
  2672. ==========
  2673. n ... the number of digits to calculate
  2674. maxsteps ... the maximum number of iterations to do
  2675. If the accuracy `n` cannot be reached in `maxsteps`, it will raise an
  2676. exception. You need to rerun with higher maxsteps.
  2677. Examples
  2678. ========
  2679. >>> from sympy import Poly
  2680. >>> from sympy.abc import x
  2681. >>> Poly(x**2 - 3).nroots(n=15)
  2682. [-1.73205080756888, 1.73205080756888]
  2683. >>> Poly(x**2 - 3).nroots(n=30)
  2684. [-1.73205080756887729352744634151, 1.73205080756887729352744634151]
  2685. """
  2686. if f.is_multivariate:
  2687. raise MultivariatePolynomialError(
  2688. "Cannot compute numerical roots of %s" % f)
  2689. if f.degree() <= 0:
  2690. return []
  2691. # For integer and rational coefficients, convert them to integers only
  2692. # (for accuracy). Otherwise just try to convert the coefficients to
  2693. # mpmath.mpc and raise an exception if the conversion fails.
  2694. if f.rep.dom is ZZ:
  2695. coeffs = [int(coeff) for coeff in f.all_coeffs()]
  2696. elif f.rep.dom is QQ:
  2697. denoms = [coeff.q for coeff in f.all_coeffs()]
  2698. fac = ilcm(*denoms)
  2699. coeffs = [int(coeff*fac) for coeff in f.all_coeffs()]
  2700. else:
  2701. coeffs = [coeff.evalf(n=n).as_real_imag()
  2702. for coeff in f.all_coeffs()]
  2703. try:
  2704. coeffs = [mpmath.mpc(*coeff) for coeff in coeffs]
  2705. except TypeError:
  2706. raise DomainError("Numerical domain expected, got %s" % \
  2707. f.rep.dom)
  2708. dps = mpmath.mp.dps
  2709. mpmath.mp.dps = n
  2710. from sympy.functions.elementary.complexes import sign
  2711. try:
  2712. # We need to add extra precision to guard against losing accuracy.
  2713. # 10 times the degree of the polynomial seems to work well.
  2714. roots = mpmath.polyroots(coeffs, maxsteps=maxsteps,
  2715. cleanup=cleanup, error=False, extraprec=f.degree()*10)
  2716. # Mpmath puts real roots first, then complex ones (as does all_roots)
  2717. # so we make sure this convention holds here, too.
  2718. roots = list(map(sympify,
  2719. sorted(roots, key=lambda r: (1 if r.imag else 0, r.real, abs(r.imag), sign(r.imag)))))
  2720. except NoConvergence:
  2721. try:
  2722. # If roots did not converge try again with more extra precision.
  2723. roots = mpmath.polyroots(coeffs, maxsteps=maxsteps,
  2724. cleanup=cleanup, error=False, extraprec=f.degree()*15)
  2725. roots = list(map(sympify,
  2726. sorted(roots, key=lambda r: (1 if r.imag else 0, r.real, abs(r.imag), sign(r.imag)))))
  2727. except NoConvergence:
  2728. raise NoConvergence(
  2729. 'convergence to root failed; try n < %s or maxsteps > %s' % (
  2730. n, maxsteps))
  2731. finally:
  2732. mpmath.mp.dps = dps
  2733. return roots
  2734. def ground_roots(f):
  2735. """
  2736. Compute roots of ``f`` by factorization in the ground domain.
  2737. Examples
  2738. ========
  2739. >>> from sympy import Poly
  2740. >>> from sympy.abc import x
  2741. >>> Poly(x**6 - 4*x**4 + 4*x**3 - x**2).ground_roots()
  2742. {0: 2, 1: 2}
  2743. """
  2744. if f.is_multivariate:
  2745. raise MultivariatePolynomialError(
  2746. "Cannot compute ground roots of %s" % f)
  2747. roots = {}
  2748. for factor, k in f.factor_list()[1]:
  2749. if factor.is_linear:
  2750. a, b = factor.all_coeffs()
  2751. roots[-b/a] = k
  2752. return roots
  2753. def nth_power_roots_poly(f, n):
  2754. """
  2755. Construct a polynomial with n-th powers of roots of ``f``.
  2756. Examples
  2757. ========
  2758. >>> from sympy import Poly
  2759. >>> from sympy.abc import x
  2760. >>> f = Poly(x**4 - x**2 + 1)
  2761. >>> f.nth_power_roots_poly(2)
  2762. Poly(x**4 - 2*x**3 + 3*x**2 - 2*x + 1, x, domain='ZZ')
  2763. >>> f.nth_power_roots_poly(3)
  2764. Poly(x**4 + 2*x**2 + 1, x, domain='ZZ')
  2765. >>> f.nth_power_roots_poly(4)
  2766. Poly(x**4 + 2*x**3 + 3*x**2 + 2*x + 1, x, domain='ZZ')
  2767. >>> f.nth_power_roots_poly(12)
  2768. Poly(x**4 - 4*x**3 + 6*x**2 - 4*x + 1, x, domain='ZZ')
  2769. """
  2770. if f.is_multivariate:
  2771. raise MultivariatePolynomialError(
  2772. "must be a univariate polynomial")
  2773. N = sympify(n)
  2774. if N.is_Integer and N >= 1:
  2775. n = int(N)
  2776. else:
  2777. raise ValueError("'n' must an integer and n >= 1, got %s" % n)
  2778. x = f.gen
  2779. t = Dummy('t')
  2780. r = f.resultant(f.__class__.from_expr(x**n - t, x, t))
  2781. return r.replace(t, x)
  2782. def same_root(f, a, b):
  2783. """
  2784. Decide whether two roots of this polynomial are equal.
  2785. Examples
  2786. ========
  2787. >>> from sympy import Poly, cyclotomic_poly, exp, I, pi
  2788. >>> f = Poly(cyclotomic_poly(5))
  2789. >>> r0 = exp(2*I*pi/5)
  2790. >>> indices = [i for i, r in enumerate(f.all_roots()) if f.same_root(r, r0)]
  2791. >>> print(indices)
  2792. [3]
  2793. Raises
  2794. ======
  2795. DomainError
  2796. If the domain of the polynomial is not :ref:`ZZ`, :ref:`QQ`,
  2797. :ref:`RR`, or :ref:`CC`.
  2798. MultivariatePolynomialError
  2799. If the polynomial is not univariate.
  2800. PolynomialError
  2801. If the polynomial is of degree < 2.
  2802. """
  2803. if f.is_multivariate:
  2804. raise MultivariatePolynomialError(
  2805. "Must be a univariate polynomial")
  2806. dom_delta_sq = f.rep.mignotte_sep_bound_squared()
  2807. delta_sq = f.domain.get_field().to_sympy(dom_delta_sq)
  2808. # We have delta_sq = delta**2, where delta is a lower bound on the
  2809. # minimum separation between any two roots of this polynomial.
  2810. # Let eps = delta/3, and define eps_sq = eps**2 = delta**2/9.
  2811. eps_sq = delta_sq / 9
  2812. r, _, _, _ = evalf(1/eps_sq, 1, {})
  2813. n = fastlog(r)
  2814. # Then 2^n > 1/eps**2.
  2815. m = (n // 2) + (n % 2)
  2816. # Then 2^(-m) < eps.
  2817. ev = lambda x: quad_to_mpmath(_evalf_with_bounded_error(x, m=m))
  2818. # Then for any complex numbers a, b we will have
  2819. # |a - ev(a)| < eps and |b - ev(b)| < eps.
  2820. # So if |ev(a) - ev(b)|**2 < eps**2, then
  2821. # |ev(a) - ev(b)| < eps, hence |a - b| < 3*eps = delta.
  2822. A, B = ev(a), ev(b)
  2823. return (A.real - B.real)**2 + (A.imag - B.imag)**2 < eps_sq
  2824. def cancel(f, g, include=False):
  2825. """
  2826. Cancel common factors in a rational function ``f/g``.
  2827. Examples
  2828. ========
  2829. >>> from sympy import Poly
  2830. >>> from sympy.abc import x
  2831. >>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x))
  2832. (1, Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))
  2833. >>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x), include=True)
  2834. (Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))
  2835. """
  2836. dom, per, F, G = f._unify(g)
  2837. if hasattr(F, 'cancel'):
  2838. result = F.cancel(G, include=include)
  2839. else: # pragma: no cover
  2840. raise OperationNotSupported(f, 'cancel')
  2841. if not include:
  2842. if dom.has_assoc_Ring:
  2843. dom = dom.get_ring()
  2844. cp, cq, p, q = result
  2845. cp = dom.to_sympy(cp)
  2846. cq = dom.to_sympy(cq)
  2847. return cp/cq, per(p), per(q)
  2848. else:
  2849. return tuple(map(per, result))
  2850. def make_monic_over_integers_by_scaling_roots(f):
  2851. """
  2852. Turn any univariate polynomial over :ref:`QQ` or :ref:`ZZ` into a monic
  2853. polynomial over :ref:`ZZ`, by scaling the roots as necessary.
  2854. Explanation
  2855. ===========
  2856. This operation can be performed whether or not *f* is irreducible; when
  2857. it is, this can be understood as determining an algebraic integer
  2858. generating the same field as a root of *f*.
  2859. Examples
  2860. ========
  2861. >>> from sympy import Poly, S
  2862. >>> from sympy.abc import x
  2863. >>> f = Poly(x**2/2 + S(1)/4 * x + S(1)/8, x, domain='QQ')
  2864. >>> f.make_monic_over_integers_by_scaling_roots()
  2865. (Poly(x**2 + 2*x + 4, x, domain='ZZ'), 4)
  2866. Returns
  2867. =======
  2868. Pair ``(g, c)``
  2869. g is the polynomial
  2870. c is the integer by which the roots had to be scaled
  2871. """
  2872. if not f.is_univariate or f.domain not in [ZZ, QQ]:
  2873. raise ValueError('Polynomial must be univariate over ZZ or QQ.')
  2874. if f.is_monic and f.domain == ZZ:
  2875. return f, ZZ.one
  2876. else:
  2877. fm = f.monic()
  2878. c, _ = fm.clear_denoms()
  2879. return fm.transform(Poly(fm.gen), c).to_ring(), c
  2880. def galois_group(f, by_name=False, max_tries=30, randomize=False):
  2881. """
  2882. Compute the Galois group of this polynomial.
  2883. Examples
  2884. ========
  2885. >>> from sympy import Poly
  2886. >>> from sympy.abc import x
  2887. >>> f = Poly(x**4 - 2)
  2888. >>> G, _ = f.galois_group(by_name=True)
  2889. >>> print(G)
  2890. S4TransitiveSubgroups.D4
  2891. See Also
  2892. ========
  2893. sympy.polys.numberfields.galoisgroups.galois_group
  2894. """
  2895. from sympy.polys.numberfields.galoisgroups import (
  2896. _galois_group_degree_3, _galois_group_degree_4_lookup,
  2897. _galois_group_degree_5_lookup_ext_factor,
  2898. _galois_group_degree_6_lookup,
  2899. )
  2900. if (not f.is_univariate
  2901. or not f.is_irreducible
  2902. or f.domain not in [ZZ, QQ]
  2903. ):
  2904. raise ValueError('Polynomial must be irreducible and univariate over ZZ or QQ.')
  2905. gg = {
  2906. 3: _galois_group_degree_3,
  2907. 4: _galois_group_degree_4_lookup,
  2908. 5: _galois_group_degree_5_lookup_ext_factor,
  2909. 6: _galois_group_degree_6_lookup,
  2910. }
  2911. max_supported = max(gg.keys())
  2912. n = f.degree()
  2913. if n > max_supported:
  2914. raise ValueError(f"Only polynomials up to degree {max_supported} are supported.")
  2915. elif n < 1:
  2916. raise ValueError("Constant polynomial has no Galois group.")
  2917. elif n == 1:
  2918. from sympy.combinatorics.galois import S1TransitiveSubgroups
  2919. name, alt = S1TransitiveSubgroups.S1, True
  2920. elif n == 2:
  2921. from sympy.combinatorics.galois import S2TransitiveSubgroups
  2922. name, alt = S2TransitiveSubgroups.S2, False
  2923. else:
  2924. g, _ = f.make_monic_over_integers_by_scaling_roots()
  2925. name, alt = gg[n](g, max_tries=max_tries, randomize=randomize)
  2926. G = name if by_name else name.get_perm_group()
  2927. return G, alt
  2928. @property
  2929. def is_zero(f):
  2930. """
  2931. Returns ``True`` if ``f`` is a zero polynomial.
  2932. Examples
  2933. ========
  2934. >>> from sympy import Poly
  2935. >>> from sympy.abc import x
  2936. >>> Poly(0, x).is_zero
  2937. True
  2938. >>> Poly(1, x).is_zero
  2939. False
  2940. """
  2941. return f.rep.is_zero
  2942. @property
  2943. def is_one(f):
  2944. """
  2945. Returns ``True`` if ``f`` is a unit polynomial.
  2946. Examples
  2947. ========
  2948. >>> from sympy import Poly
  2949. >>> from sympy.abc import x
  2950. >>> Poly(0, x).is_one
  2951. False
  2952. >>> Poly(1, x).is_one
  2953. True
  2954. """
  2955. return f.rep.is_one
  2956. @property
  2957. def is_sqf(f):
  2958. """
  2959. Returns ``True`` if ``f`` is a square-free polynomial.
  2960. Examples
  2961. ========
  2962. >>> from sympy import Poly
  2963. >>> from sympy.abc import x
  2964. >>> Poly(x**2 - 2*x + 1, x).is_sqf
  2965. False
  2966. >>> Poly(x**2 - 1, x).is_sqf
  2967. True
  2968. """
  2969. return f.rep.is_sqf
  2970. @property
  2971. def is_monic(f):
  2972. """
  2973. Returns ``True`` if the leading coefficient of ``f`` is one.
  2974. Examples
  2975. ========
  2976. >>> from sympy import Poly
  2977. >>> from sympy.abc import x
  2978. >>> Poly(x + 2, x).is_monic
  2979. True
  2980. >>> Poly(2*x + 2, x).is_monic
  2981. False
  2982. """
  2983. return f.rep.is_monic
  2984. @property
  2985. def is_primitive(f):
  2986. """
  2987. Returns ``True`` if GCD of the coefficients of ``f`` is one.
  2988. Examples
  2989. ========
  2990. >>> from sympy import Poly
  2991. >>> from sympy.abc import x
  2992. >>> Poly(2*x**2 + 6*x + 12, x).is_primitive
  2993. False
  2994. >>> Poly(x**2 + 3*x + 6, x).is_primitive
  2995. True
  2996. """
  2997. return f.rep.is_primitive
  2998. @property
  2999. def is_ground(f):
  3000. """
  3001. Returns ``True`` if ``f`` is an element of the ground domain.
  3002. Examples
  3003. ========
  3004. >>> from sympy import Poly
  3005. >>> from sympy.abc import x, y
  3006. >>> Poly(x, x).is_ground
  3007. False
  3008. >>> Poly(2, x).is_ground
  3009. True
  3010. >>> Poly(y, x).is_ground
  3011. True
  3012. """
  3013. return f.rep.is_ground
  3014. @property
  3015. def is_linear(f):
  3016. """
  3017. Returns ``True`` if ``f`` is linear in all its variables.
  3018. Examples
  3019. ========
  3020. >>> from sympy import Poly
  3021. >>> from sympy.abc import x, y
  3022. >>> Poly(x + y + 2, x, y).is_linear
  3023. True
  3024. >>> Poly(x*y + 2, x, y).is_linear
  3025. False
  3026. """
  3027. return f.rep.is_linear
  3028. @property
  3029. def is_quadratic(f):
  3030. """
  3031. Returns ``True`` if ``f`` is quadratic in all its variables.
  3032. Examples
  3033. ========
  3034. >>> from sympy import Poly
  3035. >>> from sympy.abc import x, y
  3036. >>> Poly(x*y + 2, x, y).is_quadratic
  3037. True
  3038. >>> Poly(x*y**2 + 2, x, y).is_quadratic
  3039. False
  3040. """
  3041. return f.rep.is_quadratic
  3042. @property
  3043. def is_monomial(f):
  3044. """
  3045. Returns ``True`` if ``f`` is zero or has only one term.
  3046. Examples
  3047. ========
  3048. >>> from sympy import Poly
  3049. >>> from sympy.abc import x
  3050. >>> Poly(3*x**2, x).is_monomial
  3051. True
  3052. >>> Poly(3*x**2 + 1, x).is_monomial
  3053. False
  3054. """
  3055. return f.rep.is_monomial
  3056. @property
  3057. def is_homogeneous(f):
  3058. """
  3059. Returns ``True`` if ``f`` is a homogeneous polynomial.
  3060. A homogeneous polynomial is a polynomial whose all monomials with
  3061. non-zero coefficients have the same total degree. If you want not
  3062. only to check if a polynomial is homogeneous but also compute its
  3063. homogeneous order, then use :func:`Poly.homogeneous_order`.
  3064. Examples
  3065. ========
  3066. >>> from sympy import Poly
  3067. >>> from sympy.abc import x, y
  3068. >>> Poly(x**2 + x*y, x, y).is_homogeneous
  3069. True
  3070. >>> Poly(x**3 + x*y, x, y).is_homogeneous
  3071. False
  3072. """
  3073. return f.rep.is_homogeneous
  3074. @property
  3075. def is_irreducible(f):
  3076. """
  3077. Returns ``True`` if ``f`` has no factors over its domain.
  3078. Examples
  3079. ========
  3080. >>> from sympy import Poly
  3081. >>> from sympy.abc import x
  3082. >>> Poly(x**2 + x + 1, x, modulus=2).is_irreducible
  3083. True
  3084. >>> Poly(x**2 + 1, x, modulus=2).is_irreducible
  3085. False
  3086. """
  3087. return f.rep.is_irreducible
  3088. @property
  3089. def is_univariate(f):
  3090. """
  3091. Returns ``True`` if ``f`` is a univariate polynomial.
  3092. Examples
  3093. ========
  3094. >>> from sympy import Poly
  3095. >>> from sympy.abc import x, y
  3096. >>> Poly(x**2 + x + 1, x).is_univariate
  3097. True
  3098. >>> Poly(x*y**2 + x*y + 1, x, y).is_univariate
  3099. False
  3100. >>> Poly(x*y**2 + x*y + 1, x).is_univariate
  3101. True
  3102. >>> Poly(x**2 + x + 1, x, y).is_univariate
  3103. False
  3104. """
  3105. return len(f.gens) == 1
  3106. @property
  3107. def is_multivariate(f):
  3108. """
  3109. Returns ``True`` if ``f`` is a multivariate polynomial.
  3110. Examples
  3111. ========
  3112. >>> from sympy import Poly
  3113. >>> from sympy.abc import x, y
  3114. >>> Poly(x**2 + x + 1, x).is_multivariate
  3115. False
  3116. >>> Poly(x*y**2 + x*y + 1, x, y).is_multivariate
  3117. True
  3118. >>> Poly(x*y**2 + x*y + 1, x).is_multivariate
  3119. False
  3120. >>> Poly(x**2 + x + 1, x, y).is_multivariate
  3121. True
  3122. """
  3123. return len(f.gens) != 1
  3124. @property
  3125. def is_cyclotomic(f):
  3126. """
  3127. Returns ``True`` if ``f`` is a cyclotomic polnomial.
  3128. Examples
  3129. ========
  3130. >>> from sympy import Poly
  3131. >>> from sympy.abc import x
  3132. >>> f = x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1
  3133. >>> Poly(f).is_cyclotomic
  3134. False
  3135. >>> g = x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1
  3136. >>> Poly(g).is_cyclotomic
  3137. True
  3138. """
  3139. return f.rep.is_cyclotomic
  3140. def __abs__(f):
  3141. return f.abs()
  3142. def __neg__(f):
  3143. return f.neg()
  3144. @_polifyit
  3145. def __add__(f, g):
  3146. return f.add(g)
  3147. @_polifyit
  3148. def __radd__(f, g):
  3149. return g.add(f)
  3150. @_polifyit
  3151. def __sub__(f, g):
  3152. return f.sub(g)
  3153. @_polifyit
  3154. def __rsub__(f, g):
  3155. return g.sub(f)
  3156. @_polifyit
  3157. def __mul__(f, g):
  3158. return f.mul(g)
  3159. @_polifyit
  3160. def __rmul__(f, g):
  3161. return g.mul(f)
  3162. @_sympifyit('n', NotImplemented)
  3163. def __pow__(f, n):
  3164. if n.is_Integer and n >= 0:
  3165. return f.pow(n)
  3166. else:
  3167. return NotImplemented
  3168. @_polifyit
  3169. def __divmod__(f, g):
  3170. return f.div(g)
  3171. @_polifyit
  3172. def __rdivmod__(f, g):
  3173. return g.div(f)
  3174. @_polifyit
  3175. def __mod__(f, g):
  3176. return f.rem(g)
  3177. @_polifyit
  3178. def __rmod__(f, g):
  3179. return g.rem(f)
  3180. @_polifyit
  3181. def __floordiv__(f, g):
  3182. return f.quo(g)
  3183. @_polifyit
  3184. def __rfloordiv__(f, g):
  3185. return g.quo(f)
  3186. @_sympifyit('g', NotImplemented)
  3187. def __truediv__(f, g):
  3188. return f.as_expr()/g.as_expr()
  3189. @_sympifyit('g', NotImplemented)
  3190. def __rtruediv__(f, g):
  3191. return g.as_expr()/f.as_expr()
  3192. @_sympifyit('other', NotImplemented)
  3193. def __eq__(self, other):
  3194. f, g = self, other
  3195. if not g.is_Poly:
  3196. try:
  3197. g = f.__class__(g, f.gens, domain=f.get_domain())
  3198. except (PolynomialError, DomainError, CoercionFailed):
  3199. return False
  3200. if f.gens != g.gens:
  3201. return False
  3202. if f.rep.dom != g.rep.dom:
  3203. return False
  3204. return f.rep == g.rep
  3205. @_sympifyit('g', NotImplemented)
  3206. def __ne__(f, g):
  3207. return not f == g
  3208. def __bool__(f):
  3209. return not f.is_zero
  3210. def eq(f, g, strict=False):
  3211. if not strict:
  3212. return f == g
  3213. else:
  3214. return f._strict_eq(sympify(g))
  3215. def ne(f, g, strict=False):
  3216. return not f.eq(g, strict=strict)
  3217. def _strict_eq(f, g):
  3218. return isinstance(g, f.__class__) and f.gens == g.gens and f.rep.eq(g.rep, strict=True)
  3219. @public
  3220. class PurePoly(Poly):
  3221. """Class for representing pure polynomials. """
  3222. def _hashable_content(self):
  3223. """Allow SymPy to hash Poly instances. """
  3224. return (self.rep,)
  3225. def __hash__(self):
  3226. return super().__hash__()
  3227. @property
  3228. def free_symbols(self):
  3229. """
  3230. Free symbols of a polynomial.
  3231. Examples
  3232. ========
  3233. >>> from sympy import PurePoly
  3234. >>> from sympy.abc import x, y
  3235. >>> PurePoly(x**2 + 1).free_symbols
  3236. set()
  3237. >>> PurePoly(x**2 + y).free_symbols
  3238. set()
  3239. >>> PurePoly(x**2 + y, x).free_symbols
  3240. {y}
  3241. """
  3242. return self.free_symbols_in_domain
  3243. @_sympifyit('other', NotImplemented)
  3244. def __eq__(self, other):
  3245. f, g = self, other
  3246. if not g.is_Poly:
  3247. try:
  3248. g = f.__class__(g, f.gens, domain=f.get_domain())
  3249. except (PolynomialError, DomainError, CoercionFailed):
  3250. return False
  3251. if len(f.gens) != len(g.gens):
  3252. return False
  3253. if f.rep.dom != g.rep.dom:
  3254. try:
  3255. dom = f.rep.dom.unify(g.rep.dom, f.gens)
  3256. except UnificationFailed:
  3257. return False
  3258. f = f.set_domain(dom)
  3259. g = g.set_domain(dom)
  3260. return f.rep == g.rep
  3261. def _strict_eq(f, g):
  3262. return isinstance(g, f.__class__) and f.rep.eq(g.rep, strict=True)
  3263. def _unify(f, g):
  3264. g = sympify(g)
  3265. if not g.is_Poly:
  3266. try:
  3267. return f.rep.dom, f.per, f.rep, f.rep.per(f.rep.dom.from_sympy(g))
  3268. except CoercionFailed:
  3269. raise UnificationFailed("Cannot unify %s with %s" % (f, g))
  3270. if len(f.gens) != len(g.gens):
  3271. raise UnificationFailed("Cannot unify %s with %s" % (f, g))
  3272. if not (isinstance(f.rep, DMP) and isinstance(g.rep, DMP)):
  3273. raise UnificationFailed("Cannot unify %s with %s" % (f, g))
  3274. cls = f.__class__
  3275. gens = f.gens
  3276. dom = f.rep.dom.unify(g.rep.dom, gens)
  3277. F = f.rep.convert(dom)
  3278. G = g.rep.convert(dom)
  3279. def per(rep, dom=dom, gens=gens, remove=None):
  3280. if remove is not None:
  3281. gens = gens[:remove] + gens[remove + 1:]
  3282. if not gens:
  3283. return dom.to_sympy(rep)
  3284. return cls.new(rep, *gens)
  3285. return dom, per, F, G
  3286. @public
  3287. def poly_from_expr(expr, *gens, **args):
  3288. """Construct a polynomial from an expression. """
  3289. opt = options.build_options(gens, args)
  3290. return _poly_from_expr(expr, opt)
  3291. def _poly_from_expr(expr, opt):
  3292. """Construct a polynomial from an expression. """
  3293. orig, expr = expr, sympify(expr)
  3294. if not isinstance(expr, Basic):
  3295. raise PolificationFailed(opt, orig, expr)
  3296. elif expr.is_Poly:
  3297. poly = expr.__class__._from_poly(expr, opt)
  3298. opt.gens = poly.gens
  3299. opt.domain = poly.domain
  3300. if opt.polys is None:
  3301. opt.polys = True
  3302. return poly, opt
  3303. elif opt.expand:
  3304. expr = expr.expand()
  3305. rep, opt = _dict_from_expr(expr, opt)
  3306. if not opt.gens:
  3307. raise PolificationFailed(opt, orig, expr)
  3308. monoms, coeffs = list(zip(*list(rep.items())))
  3309. domain = opt.domain
  3310. if domain is None:
  3311. opt.domain, coeffs = construct_domain(coeffs, opt=opt)
  3312. else:
  3313. coeffs = list(map(domain.from_sympy, coeffs))
  3314. rep = dict(list(zip(monoms, coeffs)))
  3315. poly = Poly._from_dict(rep, opt)
  3316. if opt.polys is None:
  3317. opt.polys = False
  3318. return poly, opt
  3319. @public
  3320. def parallel_poly_from_expr(exprs, *gens, **args):
  3321. """Construct polynomials from expressions. """
  3322. opt = options.build_options(gens, args)
  3323. return _parallel_poly_from_expr(exprs, opt)
  3324. def _parallel_poly_from_expr(exprs, opt):
  3325. """Construct polynomials from expressions. """
  3326. if len(exprs) == 2:
  3327. f, g = exprs
  3328. if isinstance(f, Poly) and isinstance(g, Poly):
  3329. f = f.__class__._from_poly(f, opt)
  3330. g = g.__class__._from_poly(g, opt)
  3331. f, g = f.unify(g)
  3332. opt.gens = f.gens
  3333. opt.domain = f.domain
  3334. if opt.polys is None:
  3335. opt.polys = True
  3336. return [f, g], opt
  3337. origs, exprs = list(exprs), []
  3338. _exprs, _polys = [], []
  3339. failed = False
  3340. for i, expr in enumerate(origs):
  3341. expr = sympify(expr)
  3342. if isinstance(expr, Basic):
  3343. if expr.is_Poly:
  3344. _polys.append(i)
  3345. else:
  3346. _exprs.append(i)
  3347. if opt.expand:
  3348. expr = expr.expand()
  3349. else:
  3350. failed = True
  3351. exprs.append(expr)
  3352. if failed:
  3353. raise PolificationFailed(opt, origs, exprs, True)
  3354. if _polys:
  3355. # XXX: this is a temporary solution
  3356. for i in _polys:
  3357. exprs[i] = exprs[i].as_expr()
  3358. reps, opt = _parallel_dict_from_expr(exprs, opt)
  3359. if not opt.gens:
  3360. raise PolificationFailed(opt, origs, exprs, True)
  3361. from sympy.functions.elementary.piecewise import Piecewise
  3362. for k in opt.gens:
  3363. if isinstance(k, Piecewise):
  3364. raise PolynomialError("Piecewise generators do not make sense")
  3365. coeffs_list, lengths = [], []
  3366. all_monoms = []
  3367. all_coeffs = []
  3368. for rep in reps:
  3369. monoms, coeffs = list(zip(*list(rep.items())))
  3370. coeffs_list.extend(coeffs)
  3371. all_monoms.append(monoms)
  3372. lengths.append(len(coeffs))
  3373. domain = opt.domain
  3374. if domain is None:
  3375. opt.domain, coeffs_list = construct_domain(coeffs_list, opt=opt)
  3376. else:
  3377. coeffs_list = list(map(domain.from_sympy, coeffs_list))
  3378. for k in lengths:
  3379. all_coeffs.append(coeffs_list[:k])
  3380. coeffs_list = coeffs_list[k:]
  3381. polys = []
  3382. for monoms, coeffs in zip(all_monoms, all_coeffs):
  3383. rep = dict(list(zip(monoms, coeffs)))
  3384. poly = Poly._from_dict(rep, opt)
  3385. polys.append(poly)
  3386. if opt.polys is None:
  3387. opt.polys = bool(_polys)
  3388. return polys, opt
  3389. def _update_args(args, key, value):
  3390. """Add a new ``(key, value)`` pair to arguments ``dict``. """
  3391. args = dict(args)
  3392. if key not in args:
  3393. args[key] = value
  3394. return args
  3395. @public
  3396. def degree(f, gen=0):
  3397. """
  3398. Return the degree of ``f`` in the given variable.
  3399. The degree of 0 is negative infinity.
  3400. Examples
  3401. ========
  3402. >>> from sympy import degree
  3403. >>> from sympy.abc import x, y
  3404. >>> degree(x**2 + y*x + 1, gen=x)
  3405. 2
  3406. >>> degree(x**2 + y*x + 1, gen=y)
  3407. 1
  3408. >>> degree(0, x)
  3409. -oo
  3410. See also
  3411. ========
  3412. sympy.polys.polytools.Poly.total_degree
  3413. degree_list
  3414. """
  3415. f = sympify(f, strict=True)
  3416. gen_is_Num = sympify(gen, strict=True).is_Number
  3417. if f.is_Poly:
  3418. p = f
  3419. isNum = p.as_expr().is_Number
  3420. else:
  3421. isNum = f.is_Number
  3422. if not isNum:
  3423. if gen_is_Num:
  3424. p, _ = poly_from_expr(f)
  3425. else:
  3426. p, _ = poly_from_expr(f, gen)
  3427. if isNum:
  3428. return S.Zero if f else S.NegativeInfinity
  3429. if not gen_is_Num:
  3430. if f.is_Poly and gen not in p.gens:
  3431. # try recast without explicit gens
  3432. p, _ = poly_from_expr(f.as_expr())
  3433. if gen not in p.gens:
  3434. return S.Zero
  3435. elif not f.is_Poly and len(f.free_symbols) > 1:
  3436. raise TypeError(filldedent('''
  3437. A symbolic generator of interest is required for a multivariate
  3438. expression like func = %s, e.g. degree(func, gen = %s) instead of
  3439. degree(func, gen = %s).
  3440. ''' % (f, next(ordered(f.free_symbols)), gen)))
  3441. result = p.degree(gen)
  3442. return Integer(result) if isinstance(result, int) else S.NegativeInfinity
  3443. @public
  3444. def total_degree(f, *gens):
  3445. """
  3446. Return the total_degree of ``f`` in the given variables.
  3447. Examples
  3448. ========
  3449. >>> from sympy import total_degree, Poly
  3450. >>> from sympy.abc import x, y
  3451. >>> total_degree(1)
  3452. 0
  3453. >>> total_degree(x + x*y)
  3454. 2
  3455. >>> total_degree(x + x*y, x)
  3456. 1
  3457. If the expression is a Poly and no variables are given
  3458. then the generators of the Poly will be used:
  3459. >>> p = Poly(x + x*y, y)
  3460. >>> total_degree(p)
  3461. 1
  3462. To deal with the underlying expression of the Poly, convert
  3463. it to an Expr:
  3464. >>> total_degree(p.as_expr())
  3465. 2
  3466. This is done automatically if any variables are given:
  3467. >>> total_degree(p, x)
  3468. 1
  3469. See also
  3470. ========
  3471. degree
  3472. """
  3473. p = sympify(f)
  3474. if p.is_Poly:
  3475. p = p.as_expr()
  3476. if p.is_Number:
  3477. rv = 0
  3478. else:
  3479. if f.is_Poly:
  3480. gens = gens or f.gens
  3481. rv = Poly(p, gens).total_degree()
  3482. return Integer(rv)
  3483. @public
  3484. def degree_list(f, *gens, **args):
  3485. """
  3486. Return a list of degrees of ``f`` in all variables.
  3487. Examples
  3488. ========
  3489. >>> from sympy import degree_list
  3490. >>> from sympy.abc import x, y
  3491. >>> degree_list(x**2 + y*x + 1)
  3492. (2, 1)
  3493. """
  3494. options.allowed_flags(args, ['polys'])
  3495. try:
  3496. F, opt = poly_from_expr(f, *gens, **args)
  3497. except PolificationFailed as exc:
  3498. raise ComputationFailed('degree_list', 1, exc)
  3499. degrees = F.degree_list()
  3500. return tuple(map(Integer, degrees))
  3501. @public
  3502. def LC(f, *gens, **args):
  3503. """
  3504. Return the leading coefficient of ``f``.
  3505. Examples
  3506. ========
  3507. >>> from sympy import LC
  3508. >>> from sympy.abc import x, y
  3509. >>> LC(4*x**2 + 2*x*y**2 + x*y + 3*y)
  3510. 4
  3511. """
  3512. options.allowed_flags(args, ['polys'])
  3513. try:
  3514. F, opt = poly_from_expr(f, *gens, **args)
  3515. except PolificationFailed as exc:
  3516. raise ComputationFailed('LC', 1, exc)
  3517. return F.LC(order=opt.order)
  3518. @public
  3519. def LM(f, *gens, **args):
  3520. """
  3521. Return the leading monomial of ``f``.
  3522. Examples
  3523. ========
  3524. >>> from sympy import LM
  3525. >>> from sympy.abc import x, y
  3526. >>> LM(4*x**2 + 2*x*y**2 + x*y + 3*y)
  3527. x**2
  3528. """
  3529. options.allowed_flags(args, ['polys'])
  3530. try:
  3531. F, opt = poly_from_expr(f, *gens, **args)
  3532. except PolificationFailed as exc:
  3533. raise ComputationFailed('LM', 1, exc)
  3534. monom = F.LM(order=opt.order)
  3535. return monom.as_expr()
  3536. @public
  3537. def LT(f, *gens, **args):
  3538. """
  3539. Return the leading term of ``f``.
  3540. Examples
  3541. ========
  3542. >>> from sympy import LT
  3543. >>> from sympy.abc import x, y
  3544. >>> LT(4*x**2 + 2*x*y**2 + x*y + 3*y)
  3545. 4*x**2
  3546. """
  3547. options.allowed_flags(args, ['polys'])
  3548. try:
  3549. F, opt = poly_from_expr(f, *gens, **args)
  3550. except PolificationFailed as exc:
  3551. raise ComputationFailed('LT', 1, exc)
  3552. monom, coeff = F.LT(order=opt.order)
  3553. return coeff*monom.as_expr()
  3554. @public
  3555. def pdiv(f, g, *gens, **args):
  3556. """
  3557. Compute polynomial pseudo-division of ``f`` and ``g``.
  3558. Examples
  3559. ========
  3560. >>> from sympy import pdiv
  3561. >>> from sympy.abc import x
  3562. >>> pdiv(x**2 + 1, 2*x - 4)
  3563. (2*x + 4, 20)
  3564. """
  3565. options.allowed_flags(args, ['polys'])
  3566. try:
  3567. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3568. except PolificationFailed as exc:
  3569. raise ComputationFailed('pdiv', 2, exc)
  3570. q, r = F.pdiv(G)
  3571. if not opt.polys:
  3572. return q.as_expr(), r.as_expr()
  3573. else:
  3574. return q, r
  3575. @public
  3576. def prem(f, g, *gens, **args):
  3577. """
  3578. Compute polynomial pseudo-remainder of ``f`` and ``g``.
  3579. Examples
  3580. ========
  3581. >>> from sympy import prem
  3582. >>> from sympy.abc import x
  3583. >>> prem(x**2 + 1, 2*x - 4)
  3584. 20
  3585. """
  3586. options.allowed_flags(args, ['polys'])
  3587. try:
  3588. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3589. except PolificationFailed as exc:
  3590. raise ComputationFailed('prem', 2, exc)
  3591. r = F.prem(G)
  3592. if not opt.polys:
  3593. return r.as_expr()
  3594. else:
  3595. return r
  3596. @public
  3597. def pquo(f, g, *gens, **args):
  3598. """
  3599. Compute polynomial pseudo-quotient of ``f`` and ``g``.
  3600. Examples
  3601. ========
  3602. >>> from sympy import pquo
  3603. >>> from sympy.abc import x
  3604. >>> pquo(x**2 + 1, 2*x - 4)
  3605. 2*x + 4
  3606. >>> pquo(x**2 - 1, 2*x - 1)
  3607. 2*x + 1
  3608. """
  3609. options.allowed_flags(args, ['polys'])
  3610. try:
  3611. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3612. except PolificationFailed as exc:
  3613. raise ComputationFailed('pquo', 2, exc)
  3614. try:
  3615. q = F.pquo(G)
  3616. except ExactQuotientFailed:
  3617. raise ExactQuotientFailed(f, g)
  3618. if not opt.polys:
  3619. return q.as_expr()
  3620. else:
  3621. return q
  3622. @public
  3623. def pexquo(f, g, *gens, **args):
  3624. """
  3625. Compute polynomial exact pseudo-quotient of ``f`` and ``g``.
  3626. Examples
  3627. ========
  3628. >>> from sympy import pexquo
  3629. >>> from sympy.abc import x
  3630. >>> pexquo(x**2 - 1, 2*x - 2)
  3631. 2*x + 2
  3632. >>> pexquo(x**2 + 1, 2*x - 4)
  3633. Traceback (most recent call last):
  3634. ...
  3635. ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1
  3636. """
  3637. options.allowed_flags(args, ['polys'])
  3638. try:
  3639. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3640. except PolificationFailed as exc:
  3641. raise ComputationFailed('pexquo', 2, exc)
  3642. q = F.pexquo(G)
  3643. if not opt.polys:
  3644. return q.as_expr()
  3645. else:
  3646. return q
  3647. @public
  3648. def div(f, g, *gens, **args):
  3649. """
  3650. Compute polynomial division of ``f`` and ``g``.
  3651. Examples
  3652. ========
  3653. >>> from sympy import div, ZZ, QQ
  3654. >>> from sympy.abc import x
  3655. >>> div(x**2 + 1, 2*x - 4, domain=ZZ)
  3656. (0, x**2 + 1)
  3657. >>> div(x**2 + 1, 2*x - 4, domain=QQ)
  3658. (x/2 + 1, 5)
  3659. """
  3660. options.allowed_flags(args, ['auto', 'polys'])
  3661. try:
  3662. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3663. except PolificationFailed as exc:
  3664. raise ComputationFailed('div', 2, exc)
  3665. q, r = F.div(G, auto=opt.auto)
  3666. if not opt.polys:
  3667. return q.as_expr(), r.as_expr()
  3668. else:
  3669. return q, r
  3670. @public
  3671. def rem(f, g, *gens, **args):
  3672. """
  3673. Compute polynomial remainder of ``f`` and ``g``.
  3674. Examples
  3675. ========
  3676. >>> from sympy import rem, ZZ, QQ
  3677. >>> from sympy.abc import x
  3678. >>> rem(x**2 + 1, 2*x - 4, domain=ZZ)
  3679. x**2 + 1
  3680. >>> rem(x**2 + 1, 2*x - 4, domain=QQ)
  3681. 5
  3682. """
  3683. options.allowed_flags(args, ['auto', 'polys'])
  3684. try:
  3685. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3686. except PolificationFailed as exc:
  3687. raise ComputationFailed('rem', 2, exc)
  3688. r = F.rem(G, auto=opt.auto)
  3689. if not opt.polys:
  3690. return r.as_expr()
  3691. else:
  3692. return r
  3693. @public
  3694. def quo(f, g, *gens, **args):
  3695. """
  3696. Compute polynomial quotient of ``f`` and ``g``.
  3697. Examples
  3698. ========
  3699. >>> from sympy import quo
  3700. >>> from sympy.abc import x
  3701. >>> quo(x**2 + 1, 2*x - 4)
  3702. x/2 + 1
  3703. >>> quo(x**2 - 1, x - 1)
  3704. x + 1
  3705. """
  3706. options.allowed_flags(args, ['auto', 'polys'])
  3707. try:
  3708. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3709. except PolificationFailed as exc:
  3710. raise ComputationFailed('quo', 2, exc)
  3711. q = F.quo(G, auto=opt.auto)
  3712. if not opt.polys:
  3713. return q.as_expr()
  3714. else:
  3715. return q
  3716. @public
  3717. def exquo(f, g, *gens, **args):
  3718. """
  3719. Compute polynomial exact quotient of ``f`` and ``g``.
  3720. Examples
  3721. ========
  3722. >>> from sympy import exquo
  3723. >>> from sympy.abc import x
  3724. >>> exquo(x**2 - 1, x - 1)
  3725. x + 1
  3726. >>> exquo(x**2 + 1, 2*x - 4)
  3727. Traceback (most recent call last):
  3728. ...
  3729. ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1
  3730. """
  3731. options.allowed_flags(args, ['auto', 'polys'])
  3732. try:
  3733. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3734. except PolificationFailed as exc:
  3735. raise ComputationFailed('exquo', 2, exc)
  3736. q = F.exquo(G, auto=opt.auto)
  3737. if not opt.polys:
  3738. return q.as_expr()
  3739. else:
  3740. return q
  3741. @public
  3742. def half_gcdex(f, g, *gens, **args):
  3743. """
  3744. Half extended Euclidean algorithm of ``f`` and ``g``.
  3745. Returns ``(s, h)`` such that ``h = gcd(f, g)`` and ``s*f = h (mod g)``.
  3746. Examples
  3747. ========
  3748. >>> from sympy import half_gcdex
  3749. >>> from sympy.abc import x
  3750. >>> half_gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
  3751. (3/5 - x/5, x + 1)
  3752. """
  3753. options.allowed_flags(args, ['auto', 'polys'])
  3754. try:
  3755. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3756. except PolificationFailed as exc:
  3757. domain, (a, b) = construct_domain(exc.exprs)
  3758. try:
  3759. s, h = domain.half_gcdex(a, b)
  3760. except NotImplementedError:
  3761. raise ComputationFailed('half_gcdex', 2, exc)
  3762. else:
  3763. return domain.to_sympy(s), domain.to_sympy(h)
  3764. s, h = F.half_gcdex(G, auto=opt.auto)
  3765. if not opt.polys:
  3766. return s.as_expr(), h.as_expr()
  3767. else:
  3768. return s, h
  3769. @public
  3770. def gcdex(f, g, *gens, **args):
  3771. """
  3772. Extended Euclidean algorithm of ``f`` and ``g``.
  3773. Returns ``(s, t, h)`` such that ``h = gcd(f, g)`` and ``s*f + t*g = h``.
  3774. Examples
  3775. ========
  3776. >>> from sympy import gcdex
  3777. >>> from sympy.abc import x
  3778. >>> gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
  3779. (3/5 - x/5, x**2/5 - 6*x/5 + 2, x + 1)
  3780. """
  3781. options.allowed_flags(args, ['auto', 'polys'])
  3782. try:
  3783. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3784. except PolificationFailed as exc:
  3785. domain, (a, b) = construct_domain(exc.exprs)
  3786. try:
  3787. s, t, h = domain.gcdex(a, b)
  3788. except NotImplementedError:
  3789. raise ComputationFailed('gcdex', 2, exc)
  3790. else:
  3791. return domain.to_sympy(s), domain.to_sympy(t), domain.to_sympy(h)
  3792. s, t, h = F.gcdex(G, auto=opt.auto)
  3793. if not opt.polys:
  3794. return s.as_expr(), t.as_expr(), h.as_expr()
  3795. else:
  3796. return s, t, h
  3797. @public
  3798. def invert(f, g, *gens, **args):
  3799. """
  3800. Invert ``f`` modulo ``g`` when possible.
  3801. Examples
  3802. ========
  3803. >>> from sympy import invert, S, mod_inverse
  3804. >>> from sympy.abc import x
  3805. >>> invert(x**2 - 1, 2*x - 1)
  3806. -4/3
  3807. >>> invert(x**2 - 1, x - 1)
  3808. Traceback (most recent call last):
  3809. ...
  3810. NotInvertible: zero divisor
  3811. For more efficient inversion of Rationals,
  3812. use the :obj:`~.mod_inverse` function:
  3813. >>> mod_inverse(3, 5)
  3814. 2
  3815. >>> (S(2)/5).invert(S(7)/3)
  3816. 5/2
  3817. See Also
  3818. ========
  3819. sympy.core.numbers.mod_inverse
  3820. """
  3821. options.allowed_flags(args, ['auto', 'polys'])
  3822. try:
  3823. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3824. except PolificationFailed as exc:
  3825. domain, (a, b) = construct_domain(exc.exprs)
  3826. try:
  3827. return domain.to_sympy(domain.invert(a, b))
  3828. except NotImplementedError:
  3829. raise ComputationFailed('invert', 2, exc)
  3830. h = F.invert(G, auto=opt.auto)
  3831. if not opt.polys:
  3832. return h.as_expr()
  3833. else:
  3834. return h
  3835. @public
  3836. def subresultants(f, g, *gens, **args):
  3837. """
  3838. Compute subresultant PRS of ``f`` and ``g``.
  3839. Examples
  3840. ========
  3841. >>> from sympy import subresultants
  3842. >>> from sympy.abc import x
  3843. >>> subresultants(x**2 + 1, x**2 - 1)
  3844. [x**2 + 1, x**2 - 1, -2]
  3845. """
  3846. options.allowed_flags(args, ['polys'])
  3847. try:
  3848. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3849. except PolificationFailed as exc:
  3850. raise ComputationFailed('subresultants', 2, exc)
  3851. result = F.subresultants(G)
  3852. if not opt.polys:
  3853. return [r.as_expr() for r in result]
  3854. else:
  3855. return result
  3856. @public
  3857. def resultant(f, g, *gens, includePRS=False, **args):
  3858. """
  3859. Compute resultant of ``f`` and ``g``.
  3860. Examples
  3861. ========
  3862. >>> from sympy import resultant
  3863. >>> from sympy.abc import x
  3864. >>> resultant(x**2 + 1, x**2 - 1)
  3865. 4
  3866. """
  3867. options.allowed_flags(args, ['polys'])
  3868. try:
  3869. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3870. except PolificationFailed as exc:
  3871. raise ComputationFailed('resultant', 2, exc)
  3872. if includePRS:
  3873. result, R = F.resultant(G, includePRS=includePRS)
  3874. else:
  3875. result = F.resultant(G)
  3876. if not opt.polys:
  3877. if includePRS:
  3878. return result.as_expr(), [r.as_expr() for r in R]
  3879. return result.as_expr()
  3880. else:
  3881. if includePRS:
  3882. return result, R
  3883. return result
  3884. @public
  3885. def discriminant(f, *gens, **args):
  3886. """
  3887. Compute discriminant of ``f``.
  3888. Examples
  3889. ========
  3890. >>> from sympy import discriminant
  3891. >>> from sympy.abc import x
  3892. >>> discriminant(x**2 + 2*x + 3)
  3893. -8
  3894. """
  3895. options.allowed_flags(args, ['polys'])
  3896. try:
  3897. F, opt = poly_from_expr(f, *gens, **args)
  3898. except PolificationFailed as exc:
  3899. raise ComputationFailed('discriminant', 1, exc)
  3900. result = F.discriminant()
  3901. if not opt.polys:
  3902. return result.as_expr()
  3903. else:
  3904. return result
  3905. @public
  3906. def cofactors(f, g, *gens, **args):
  3907. """
  3908. Compute GCD and cofactors of ``f`` and ``g``.
  3909. Returns polynomials ``(h, cff, cfg)`` such that ``h = gcd(f, g)``, and
  3910. ``cff = quo(f, h)`` and ``cfg = quo(g, h)`` are, so called, cofactors
  3911. of ``f`` and ``g``.
  3912. Examples
  3913. ========
  3914. >>> from sympy import cofactors
  3915. >>> from sympy.abc import x
  3916. >>> cofactors(x**2 - 1, x**2 - 3*x + 2)
  3917. (x - 1, x + 1, x - 2)
  3918. """
  3919. options.allowed_flags(args, ['polys'])
  3920. try:
  3921. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  3922. except PolificationFailed as exc:
  3923. domain, (a, b) = construct_domain(exc.exprs)
  3924. try:
  3925. h, cff, cfg = domain.cofactors(a, b)
  3926. except NotImplementedError:
  3927. raise ComputationFailed('cofactors', 2, exc)
  3928. else:
  3929. return domain.to_sympy(h), domain.to_sympy(cff), domain.to_sympy(cfg)
  3930. h, cff, cfg = F.cofactors(G)
  3931. if not opt.polys:
  3932. return h.as_expr(), cff.as_expr(), cfg.as_expr()
  3933. else:
  3934. return h, cff, cfg
  3935. @public
  3936. def gcd_list(seq, *gens, **args):
  3937. """
  3938. Compute GCD of a list of polynomials.
  3939. Examples
  3940. ========
  3941. >>> from sympy import gcd_list
  3942. >>> from sympy.abc import x
  3943. >>> gcd_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
  3944. x - 1
  3945. """
  3946. seq = sympify(seq)
  3947. def try_non_polynomial_gcd(seq):
  3948. if not gens and not args:
  3949. domain, numbers = construct_domain(seq)
  3950. if not numbers:
  3951. return domain.zero
  3952. elif domain.is_Numerical:
  3953. result, numbers = numbers[0], numbers[1:]
  3954. for number in numbers:
  3955. result = domain.gcd(result, number)
  3956. if domain.is_one(result):
  3957. break
  3958. return domain.to_sympy(result)
  3959. return None
  3960. result = try_non_polynomial_gcd(seq)
  3961. if result is not None:
  3962. return result
  3963. options.allowed_flags(args, ['polys'])
  3964. try:
  3965. polys, opt = parallel_poly_from_expr(seq, *gens, **args)
  3966. # gcd for domain Q[irrational] (purely algebraic irrational)
  3967. if len(seq) > 1 and all(elt.is_algebraic and elt.is_irrational for elt in seq):
  3968. a = seq[-1]
  3969. lst = [ (a/elt).ratsimp() for elt in seq[:-1] ]
  3970. if all(frc.is_rational for frc in lst):
  3971. lc = 1
  3972. for frc in lst:
  3973. lc = lcm(lc, frc.as_numer_denom()[0])
  3974. # abs ensures that the gcd is always non-negative
  3975. return abs(a/lc)
  3976. except PolificationFailed as exc:
  3977. result = try_non_polynomial_gcd(exc.exprs)
  3978. if result is not None:
  3979. return result
  3980. else:
  3981. raise ComputationFailed('gcd_list', len(seq), exc)
  3982. if not polys:
  3983. if not opt.polys:
  3984. return S.Zero
  3985. else:
  3986. return Poly(0, opt=opt)
  3987. result, polys = polys[0], polys[1:]
  3988. for poly in polys:
  3989. result = result.gcd(poly)
  3990. if result.is_one:
  3991. break
  3992. if not opt.polys:
  3993. return result.as_expr()
  3994. else:
  3995. return result
  3996. @public
  3997. def gcd(f, g=None, *gens, **args):
  3998. """
  3999. Compute GCD of ``f`` and ``g``.
  4000. Examples
  4001. ========
  4002. >>> from sympy import gcd
  4003. >>> from sympy.abc import x
  4004. >>> gcd(x**2 - 1, x**2 - 3*x + 2)
  4005. x - 1
  4006. """
  4007. if hasattr(f, '__iter__'):
  4008. if g is not None:
  4009. gens = (g,) + gens
  4010. return gcd_list(f, *gens, **args)
  4011. elif g is None:
  4012. raise TypeError("gcd() takes 2 arguments or a sequence of arguments")
  4013. options.allowed_flags(args, ['polys'])
  4014. try:
  4015. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  4016. # gcd for domain Q[irrational] (purely algebraic irrational)
  4017. a, b = map(sympify, (f, g))
  4018. if a.is_algebraic and a.is_irrational and b.is_algebraic and b.is_irrational:
  4019. frc = (a/b).ratsimp()
  4020. if frc.is_rational:
  4021. # abs ensures that the returned gcd is always non-negative
  4022. return abs(a/frc.as_numer_denom()[0])
  4023. except PolificationFailed as exc:
  4024. domain, (a, b) = construct_domain(exc.exprs)
  4025. try:
  4026. return domain.to_sympy(domain.gcd(a, b))
  4027. except NotImplementedError:
  4028. raise ComputationFailed('gcd', 2, exc)
  4029. result = F.gcd(G)
  4030. if not opt.polys:
  4031. return result.as_expr()
  4032. else:
  4033. return result
  4034. @public
  4035. def lcm_list(seq, *gens, **args):
  4036. """
  4037. Compute LCM of a list of polynomials.
  4038. Examples
  4039. ========
  4040. >>> from sympy import lcm_list
  4041. >>> from sympy.abc import x
  4042. >>> lcm_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
  4043. x**5 - x**4 - 2*x**3 - x**2 + x + 2
  4044. """
  4045. seq = sympify(seq)
  4046. def try_non_polynomial_lcm(seq) -> Optional[Expr]:
  4047. if not gens and not args:
  4048. domain, numbers = construct_domain(seq)
  4049. if not numbers:
  4050. return domain.to_sympy(domain.one)
  4051. elif domain.is_Numerical:
  4052. result, numbers = numbers[0], numbers[1:]
  4053. for number in numbers:
  4054. result = domain.lcm(result, number)
  4055. return domain.to_sympy(result)
  4056. return None
  4057. result = try_non_polynomial_lcm(seq)
  4058. if result is not None:
  4059. return result
  4060. options.allowed_flags(args, ['polys'])
  4061. try:
  4062. polys, opt = parallel_poly_from_expr(seq, *gens, **args)
  4063. # lcm for domain Q[irrational] (purely algebraic irrational)
  4064. if len(seq) > 1 and all(elt.is_algebraic and elt.is_irrational for elt in seq):
  4065. a = seq[-1]
  4066. lst = [ (a/elt).ratsimp() for elt in seq[:-1] ]
  4067. if all(frc.is_rational for frc in lst):
  4068. lc = 1
  4069. for frc in lst:
  4070. lc = lcm(lc, frc.as_numer_denom()[1])
  4071. return a*lc
  4072. except PolificationFailed as exc:
  4073. result = try_non_polynomial_lcm(exc.exprs)
  4074. if result is not None:
  4075. return result
  4076. else:
  4077. raise ComputationFailed('lcm_list', len(seq), exc)
  4078. if not polys:
  4079. if not opt.polys:
  4080. return S.One
  4081. else:
  4082. return Poly(1, opt=opt)
  4083. result, polys = polys[0], polys[1:]
  4084. for poly in polys:
  4085. result = result.lcm(poly)
  4086. if not opt.polys:
  4087. return result.as_expr()
  4088. else:
  4089. return result
  4090. @public
  4091. def lcm(f, g=None, *gens, **args):
  4092. """
  4093. Compute LCM of ``f`` and ``g``.
  4094. Examples
  4095. ========
  4096. >>> from sympy import lcm
  4097. >>> from sympy.abc import x
  4098. >>> lcm(x**2 - 1, x**2 - 3*x + 2)
  4099. x**3 - 2*x**2 - x + 2
  4100. """
  4101. if hasattr(f, '__iter__'):
  4102. if g is not None:
  4103. gens = (g,) + gens
  4104. return lcm_list(f, *gens, **args)
  4105. elif g is None:
  4106. raise TypeError("lcm() takes 2 arguments or a sequence of arguments")
  4107. options.allowed_flags(args, ['polys'])
  4108. try:
  4109. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  4110. # lcm for domain Q[irrational] (purely algebraic irrational)
  4111. a, b = map(sympify, (f, g))
  4112. if a.is_algebraic and a.is_irrational and b.is_algebraic and b.is_irrational:
  4113. frc = (a/b).ratsimp()
  4114. if frc.is_rational:
  4115. return a*frc.as_numer_denom()[1]
  4116. except PolificationFailed as exc:
  4117. domain, (a, b) = construct_domain(exc.exprs)
  4118. try:
  4119. return domain.to_sympy(domain.lcm(a, b))
  4120. except NotImplementedError:
  4121. raise ComputationFailed('lcm', 2, exc)
  4122. result = F.lcm(G)
  4123. if not opt.polys:
  4124. return result.as_expr()
  4125. else:
  4126. return result
  4127. @public
  4128. def terms_gcd(f, *gens, **args):
  4129. """
  4130. Remove GCD of terms from ``f``.
  4131. If the ``deep`` flag is True, then the arguments of ``f`` will have
  4132. terms_gcd applied to them.
  4133. If a fraction is factored out of ``f`` and ``f`` is an Add, then
  4134. an unevaluated Mul will be returned so that automatic simplification
  4135. does not redistribute it. The hint ``clear``, when set to False, can be
  4136. used to prevent such factoring when all coefficients are not fractions.
  4137. Examples
  4138. ========
  4139. >>> from sympy import terms_gcd, cos
  4140. >>> from sympy.abc import x, y
  4141. >>> terms_gcd(x**6*y**2 + x**3*y, x, y)
  4142. x**3*y*(x**3*y + 1)
  4143. The default action of polys routines is to expand the expression
  4144. given to them. terms_gcd follows this behavior:
  4145. >>> terms_gcd((3+3*x)*(x+x*y))
  4146. 3*x*(x*y + x + y + 1)
  4147. If this is not desired then the hint ``expand`` can be set to False.
  4148. In this case the expression will be treated as though it were comprised
  4149. of one or more terms:
  4150. >>> terms_gcd((3+3*x)*(x+x*y), expand=False)
  4151. (3*x + 3)*(x*y + x)
  4152. In order to traverse factors of a Mul or the arguments of other
  4153. functions, the ``deep`` hint can be used:
  4154. >>> terms_gcd((3 + 3*x)*(x + x*y), expand=False, deep=True)
  4155. 3*x*(x + 1)*(y + 1)
  4156. >>> terms_gcd(cos(x + x*y), deep=True)
  4157. cos(x*(y + 1))
  4158. Rationals are factored out by default:
  4159. >>> terms_gcd(x + y/2)
  4160. (2*x + y)/2
  4161. Only the y-term had a coefficient that was a fraction; if one
  4162. does not want to factor out the 1/2 in cases like this, the
  4163. flag ``clear`` can be set to False:
  4164. >>> terms_gcd(x + y/2, clear=False)
  4165. x + y/2
  4166. >>> terms_gcd(x*y/2 + y**2, clear=False)
  4167. y*(x/2 + y)
  4168. The ``clear`` flag is ignored if all coefficients are fractions:
  4169. >>> terms_gcd(x/3 + y/2, clear=False)
  4170. (2*x + 3*y)/6
  4171. See Also
  4172. ========
  4173. sympy.core.exprtools.gcd_terms, sympy.core.exprtools.factor_terms
  4174. """
  4175. orig = sympify(f)
  4176. if isinstance(f, Equality):
  4177. return Equality(*(terms_gcd(s, *gens, **args) for s in [f.lhs, f.rhs]))
  4178. elif isinstance(f, Relational):
  4179. raise TypeError("Inequalities cannot be used with terms_gcd. Found: %s" %(f,))
  4180. if not isinstance(f, Expr) or f.is_Atom:
  4181. return orig
  4182. if args.get('deep', False):
  4183. new = f.func(*[terms_gcd(a, *gens, **args) for a in f.args])
  4184. args.pop('deep')
  4185. args['expand'] = False
  4186. return terms_gcd(new, *gens, **args)
  4187. clear = args.pop('clear', True)
  4188. options.allowed_flags(args, ['polys'])
  4189. try:
  4190. F, opt = poly_from_expr(f, *gens, **args)
  4191. except PolificationFailed as exc:
  4192. return exc.expr
  4193. J, f = F.terms_gcd()
  4194. if opt.domain.is_Ring:
  4195. if opt.domain.is_Field:
  4196. denom, f = f.clear_denoms(convert=True)
  4197. coeff, f = f.primitive()
  4198. if opt.domain.is_Field:
  4199. coeff /= denom
  4200. else:
  4201. coeff = S.One
  4202. term = Mul(*[x**j for x, j in zip(f.gens, J)])
  4203. if equal_valued(coeff, 1):
  4204. coeff = S.One
  4205. if term == 1:
  4206. return orig
  4207. if clear:
  4208. return _keep_coeff(coeff, term*f.as_expr())
  4209. # base the clearing on the form of the original expression, not
  4210. # the (perhaps) Mul that we have now
  4211. coeff, f = _keep_coeff(coeff, f.as_expr(), clear=False).as_coeff_Mul()
  4212. return _keep_coeff(coeff, term*f, clear=False)
  4213. @public
  4214. def trunc(f, p, *gens, **args):
  4215. """
  4216. Reduce ``f`` modulo a constant ``p``.
  4217. Examples
  4218. ========
  4219. >>> from sympy import trunc
  4220. >>> from sympy.abc import x
  4221. >>> trunc(2*x**3 + 3*x**2 + 5*x + 7, 3)
  4222. -x**3 - x + 1
  4223. """
  4224. options.allowed_flags(args, ['auto', 'polys'])
  4225. try:
  4226. F, opt = poly_from_expr(f, *gens, **args)
  4227. except PolificationFailed as exc:
  4228. raise ComputationFailed('trunc', 1, exc)
  4229. result = F.trunc(sympify(p))
  4230. if not opt.polys:
  4231. return result.as_expr()
  4232. else:
  4233. return result
  4234. @public
  4235. def monic(f, *gens, **args):
  4236. """
  4237. Divide all coefficients of ``f`` by ``LC(f)``.
  4238. Examples
  4239. ========
  4240. >>> from sympy import monic
  4241. >>> from sympy.abc import x
  4242. >>> monic(3*x**2 + 4*x + 2)
  4243. x**2 + 4*x/3 + 2/3
  4244. """
  4245. options.allowed_flags(args, ['auto', 'polys'])
  4246. try:
  4247. F, opt = poly_from_expr(f, *gens, **args)
  4248. except PolificationFailed as exc:
  4249. raise ComputationFailed('monic', 1, exc)
  4250. result = F.monic(auto=opt.auto)
  4251. if not opt.polys:
  4252. return result.as_expr()
  4253. else:
  4254. return result
  4255. @public
  4256. def content(f, *gens, **args):
  4257. """
  4258. Compute GCD of coefficients of ``f``.
  4259. Examples
  4260. ========
  4261. >>> from sympy import content
  4262. >>> from sympy.abc import x
  4263. >>> content(6*x**2 + 8*x + 12)
  4264. 2
  4265. """
  4266. options.allowed_flags(args, ['polys'])
  4267. try:
  4268. F, opt = poly_from_expr(f, *gens, **args)
  4269. except PolificationFailed as exc:
  4270. raise ComputationFailed('content', 1, exc)
  4271. return F.content()
  4272. @public
  4273. def primitive(f, *gens, **args):
  4274. """
  4275. Compute content and the primitive form of ``f``.
  4276. Examples
  4277. ========
  4278. >>> from sympy.polys.polytools import primitive
  4279. >>> from sympy.abc import x
  4280. >>> primitive(6*x**2 + 8*x + 12)
  4281. (2, 3*x**2 + 4*x + 6)
  4282. >>> eq = (2 + 2*x)*x + 2
  4283. Expansion is performed by default:
  4284. >>> primitive(eq)
  4285. (2, x**2 + x + 1)
  4286. Set ``expand`` to False to shut this off. Note that the
  4287. extraction will not be recursive; use the as_content_primitive method
  4288. for recursive, non-destructive Rational extraction.
  4289. >>> primitive(eq, expand=False)
  4290. (1, x*(2*x + 2) + 2)
  4291. >>> eq.as_content_primitive()
  4292. (2, x*(x + 1) + 1)
  4293. """
  4294. options.allowed_flags(args, ['polys'])
  4295. try:
  4296. F, opt = poly_from_expr(f, *gens, **args)
  4297. except PolificationFailed as exc:
  4298. raise ComputationFailed('primitive', 1, exc)
  4299. cont, result = F.primitive()
  4300. if not opt.polys:
  4301. return cont, result.as_expr()
  4302. else:
  4303. return cont, result
  4304. @public
  4305. def compose(f, g, *gens, **args):
  4306. """
  4307. Compute functional composition ``f(g)``.
  4308. Examples
  4309. ========
  4310. >>> from sympy import compose
  4311. >>> from sympy.abc import x
  4312. >>> compose(x**2 + x, x - 1)
  4313. x**2 - x
  4314. """
  4315. options.allowed_flags(args, ['polys'])
  4316. try:
  4317. (F, G), opt = parallel_poly_from_expr((f, g), *gens, **args)
  4318. except PolificationFailed as exc:
  4319. raise ComputationFailed('compose', 2, exc)
  4320. result = F.compose(G)
  4321. if not opt.polys:
  4322. return result.as_expr()
  4323. else:
  4324. return result
  4325. @public
  4326. def decompose(f, *gens, **args):
  4327. """
  4328. Compute functional decomposition of ``f``.
  4329. Examples
  4330. ========
  4331. >>> from sympy import decompose
  4332. >>> from sympy.abc import x
  4333. >>> decompose(x**4 + 2*x**3 - x - 1)
  4334. [x**2 - x - 1, x**2 + x]
  4335. """
  4336. options.allowed_flags(args, ['polys'])
  4337. try:
  4338. F, opt = poly_from_expr(f, *gens, **args)
  4339. except PolificationFailed as exc:
  4340. raise ComputationFailed('decompose', 1, exc)
  4341. result = F.decompose()
  4342. if not opt.polys:
  4343. return [r.as_expr() for r in result]
  4344. else:
  4345. return result
  4346. @public
  4347. def sturm(f, *gens, **args):
  4348. """
  4349. Compute Sturm sequence of ``f``.
  4350. Examples
  4351. ========
  4352. >>> from sympy import sturm
  4353. >>> from sympy.abc import x
  4354. >>> sturm(x**3 - 2*x**2 + x - 3)
  4355. [x**3 - 2*x**2 + x - 3, 3*x**2 - 4*x + 1, 2*x/9 + 25/9, -2079/4]
  4356. """
  4357. options.allowed_flags(args, ['auto', 'polys'])
  4358. try:
  4359. F, opt = poly_from_expr(f, *gens, **args)
  4360. except PolificationFailed as exc:
  4361. raise ComputationFailed('sturm', 1, exc)
  4362. result = F.sturm(auto=opt.auto)
  4363. if not opt.polys:
  4364. return [r.as_expr() for r in result]
  4365. else:
  4366. return result
  4367. @public
  4368. def gff_list(f, *gens, **args):
  4369. """
  4370. Compute a list of greatest factorial factors of ``f``.
  4371. Note that the input to ff() and rf() should be Poly instances to use the
  4372. definitions here.
  4373. Examples
  4374. ========
  4375. >>> from sympy import gff_list, ff, Poly
  4376. >>> from sympy.abc import x
  4377. >>> f = Poly(x**5 + 2*x**4 - x**3 - 2*x**2, x)
  4378. >>> gff_list(f)
  4379. [(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)]
  4380. >>> (ff(Poly(x), 1)*ff(Poly(x + 2), 4)) == f
  4381. True
  4382. >>> f = Poly(x**12 + 6*x**11 - 11*x**10 - 56*x**9 + 220*x**8 + 208*x**7 - \
  4383. 1401*x**6 + 1090*x**5 + 2715*x**4 - 6720*x**3 - 1092*x**2 + 5040*x, x)
  4384. >>> gff_list(f)
  4385. [(Poly(x**3 + 7, x, domain='ZZ'), 2), (Poly(x**2 + 5*x, x, domain='ZZ'), 3)]
  4386. >>> ff(Poly(x**3 + 7, x), 2)*ff(Poly(x**2 + 5*x, x), 3) == f
  4387. True
  4388. """
  4389. options.allowed_flags(args, ['polys'])
  4390. try:
  4391. F, opt = poly_from_expr(f, *gens, **args)
  4392. except PolificationFailed as exc:
  4393. raise ComputationFailed('gff_list', 1, exc)
  4394. factors = F.gff_list()
  4395. if not opt.polys:
  4396. return [(g.as_expr(), k) for g, k in factors]
  4397. else:
  4398. return factors
  4399. @public
  4400. def gff(f, *gens, **args):
  4401. """Compute greatest factorial factorization of ``f``. """
  4402. raise NotImplementedError('symbolic falling factorial')
  4403. @public
  4404. def sqf_norm(f, *gens, **args):
  4405. """
  4406. Compute square-free norm of ``f``.
  4407. Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and
  4408. ``r(x) = Norm(g(x))`` is a square-free polynomial over ``K``,
  4409. where ``a`` is the algebraic extension of the ground domain.
  4410. Examples
  4411. ========
  4412. >>> from sympy import sqf_norm, sqrt
  4413. >>> from sympy.abc import x
  4414. >>> sqf_norm(x**2 + 1, extension=[sqrt(3)])
  4415. (1, x**2 - 2*sqrt(3)*x + 4, x**4 - 4*x**2 + 16)
  4416. """
  4417. options.allowed_flags(args, ['polys'])
  4418. try:
  4419. F, opt = poly_from_expr(f, *gens, **args)
  4420. except PolificationFailed as exc:
  4421. raise ComputationFailed('sqf_norm', 1, exc)
  4422. s, g, r = F.sqf_norm()
  4423. if not opt.polys:
  4424. return Integer(s), g.as_expr(), r.as_expr()
  4425. else:
  4426. return Integer(s), g, r
  4427. @public
  4428. def sqf_part(f, *gens, **args):
  4429. """
  4430. Compute square-free part of ``f``.
  4431. Examples
  4432. ========
  4433. >>> from sympy import sqf_part
  4434. >>> from sympy.abc import x
  4435. >>> sqf_part(x**3 - 3*x - 2)
  4436. x**2 - x - 2
  4437. """
  4438. options.allowed_flags(args, ['polys'])
  4439. try:
  4440. F, opt = poly_from_expr(f, *gens, **args)
  4441. except PolificationFailed as exc:
  4442. raise ComputationFailed('sqf_part', 1, exc)
  4443. result = F.sqf_part()
  4444. if not opt.polys:
  4445. return result.as_expr()
  4446. else:
  4447. return result
  4448. def _sorted_factors(factors, method):
  4449. """Sort a list of ``(expr, exp)`` pairs. """
  4450. if method == 'sqf':
  4451. def key(obj):
  4452. poly, exp = obj
  4453. rep = poly.rep.rep
  4454. return (exp, len(rep), len(poly.gens), str(poly.domain), rep)
  4455. else:
  4456. def key(obj):
  4457. poly, exp = obj
  4458. rep = poly.rep.rep
  4459. return (len(rep), len(poly.gens), exp, str(poly.domain), rep)
  4460. return sorted(factors, key=key)
  4461. def _factors_product(factors):
  4462. """Multiply a list of ``(expr, exp)`` pairs. """
  4463. return Mul(*[f.as_expr()**k for f, k in factors])
  4464. def _symbolic_factor_list(expr, opt, method):
  4465. """Helper function for :func:`_symbolic_factor`. """
  4466. coeff, factors = S.One, []
  4467. args = [i._eval_factor() if hasattr(i, '_eval_factor') else i
  4468. for i in Mul.make_args(expr)]
  4469. for arg in args:
  4470. if arg.is_Number or (isinstance(arg, Expr) and pure_complex(arg)):
  4471. coeff *= arg
  4472. continue
  4473. elif arg.is_Pow and arg.base != S.Exp1:
  4474. base, exp = arg.args
  4475. if base.is_Number and exp.is_Number:
  4476. coeff *= arg
  4477. continue
  4478. if base.is_Number:
  4479. factors.append((base, exp))
  4480. continue
  4481. else:
  4482. base, exp = arg, S.One
  4483. try:
  4484. poly, _ = _poly_from_expr(base, opt)
  4485. except PolificationFailed as exc:
  4486. factors.append((exc.expr, exp))
  4487. else:
  4488. func = getattr(poly, method + '_list')
  4489. _coeff, _factors = func()
  4490. if _coeff is not S.One:
  4491. if exp.is_Integer:
  4492. coeff *= _coeff**exp
  4493. elif _coeff.is_positive:
  4494. factors.append((_coeff, exp))
  4495. else:
  4496. _factors.append((_coeff, S.One))
  4497. if exp is S.One:
  4498. factors.extend(_factors)
  4499. elif exp.is_integer:
  4500. factors.extend([(f, k*exp) for f, k in _factors])
  4501. else:
  4502. other = []
  4503. for f, k in _factors:
  4504. if f.as_expr().is_positive:
  4505. factors.append((f, k*exp))
  4506. else:
  4507. other.append((f, k))
  4508. factors.append((_factors_product(other), exp))
  4509. if method == 'sqf':
  4510. factors = [(reduce(mul, (f for f, _ in factors if _ == k)), k)
  4511. for k in {i for _, i in factors}]
  4512. return coeff, factors
  4513. def _symbolic_factor(expr, opt, method):
  4514. """Helper function for :func:`_factor`. """
  4515. if isinstance(expr, Expr):
  4516. if hasattr(expr,'_eval_factor'):
  4517. return expr._eval_factor()
  4518. coeff, factors = _symbolic_factor_list(together(expr, fraction=opt['fraction']), opt, method)
  4519. return _keep_coeff(coeff, _factors_product(factors))
  4520. elif hasattr(expr, 'args'):
  4521. return expr.func(*[_symbolic_factor(arg, opt, method) for arg in expr.args])
  4522. elif hasattr(expr, '__iter__'):
  4523. return expr.__class__([_symbolic_factor(arg, opt, method) for arg in expr])
  4524. else:
  4525. return expr
  4526. def _generic_factor_list(expr, gens, args, method):
  4527. """Helper function for :func:`sqf_list` and :func:`factor_list`. """
  4528. options.allowed_flags(args, ['frac', 'polys'])
  4529. opt = options.build_options(gens, args)
  4530. expr = sympify(expr)
  4531. if isinstance(expr, (Expr, Poly)):
  4532. if isinstance(expr, Poly):
  4533. numer, denom = expr, 1
  4534. else:
  4535. numer, denom = together(expr).as_numer_denom()
  4536. cp, fp = _symbolic_factor_list(numer, opt, method)
  4537. cq, fq = _symbolic_factor_list(denom, opt, method)
  4538. if fq and not opt.frac:
  4539. raise PolynomialError("a polynomial expected, got %s" % expr)
  4540. _opt = opt.clone({"expand": True})
  4541. for factors in (fp, fq):
  4542. for i, (f, k) in enumerate(factors):
  4543. if not f.is_Poly:
  4544. f, _ = _poly_from_expr(f, _opt)
  4545. factors[i] = (f, k)
  4546. fp = _sorted_factors(fp, method)
  4547. fq = _sorted_factors(fq, method)
  4548. if not opt.polys:
  4549. fp = [(f.as_expr(), k) for f, k in fp]
  4550. fq = [(f.as_expr(), k) for f, k in fq]
  4551. coeff = cp/cq
  4552. if not opt.frac:
  4553. return coeff, fp
  4554. else:
  4555. return coeff, fp, fq
  4556. else:
  4557. raise PolynomialError("a polynomial expected, got %s" % expr)
  4558. def _generic_factor(expr, gens, args, method):
  4559. """Helper function for :func:`sqf` and :func:`factor`. """
  4560. fraction = args.pop('fraction', True)
  4561. options.allowed_flags(args, [])
  4562. opt = options.build_options(gens, args)
  4563. opt['fraction'] = fraction
  4564. return _symbolic_factor(sympify(expr), opt, method)
  4565. def to_rational_coeffs(f):
  4566. """
  4567. try to transform a polynomial to have rational coefficients
  4568. try to find a transformation ``x = alpha*y``
  4569. ``f(x) = lc*alpha**n * g(y)`` where ``g`` is a polynomial with
  4570. rational coefficients, ``lc`` the leading coefficient.
  4571. If this fails, try ``x = y + beta``
  4572. ``f(x) = g(y)``
  4573. Returns ``None`` if ``g`` not found;
  4574. ``(lc, alpha, None, g)`` in case of rescaling
  4575. ``(None, None, beta, g)`` in case of translation
  4576. Notes
  4577. =====
  4578. Currently it transforms only polynomials without roots larger than 2.
  4579. Examples
  4580. ========
  4581. >>> from sympy import sqrt, Poly, simplify
  4582. >>> from sympy.polys.polytools import to_rational_coeffs
  4583. >>> from sympy.abc import x
  4584. >>> p = Poly(((x**2-1)*(x-2)).subs({x:x*(1 + sqrt(2))}), x, domain='EX')
  4585. >>> lc, r, _, g = to_rational_coeffs(p)
  4586. >>> lc, r
  4587. (7 + 5*sqrt(2), 2 - 2*sqrt(2))
  4588. >>> g
  4589. Poly(x**3 + x**2 - 1/4*x - 1/4, x, domain='QQ')
  4590. >>> r1 = simplify(1/r)
  4591. >>> Poly(lc*r**3*(g.as_expr()).subs({x:x*r1}), x, domain='EX') == p
  4592. True
  4593. """
  4594. from sympy.simplify.simplify import simplify
  4595. def _try_rescale(f, f1=None):
  4596. """
  4597. try rescaling ``x -> alpha*x`` to convert f to a polynomial
  4598. with rational coefficients.
  4599. Returns ``alpha, f``; if the rescaling is successful,
  4600. ``alpha`` is the rescaling factor, and ``f`` is the rescaled
  4601. polynomial; else ``alpha`` is ``None``.
  4602. """
  4603. if not len(f.gens) == 1 or not (f.gens[0]).is_Atom:
  4604. return None, f
  4605. n = f.degree()
  4606. lc = f.LC()
  4607. f1 = f1 or f1.monic()
  4608. coeffs = f1.all_coeffs()[1:]
  4609. coeffs = [simplify(coeffx) for coeffx in coeffs]
  4610. if len(coeffs) > 1 and coeffs[-2]:
  4611. rescale1_x = simplify(coeffs[-2]/coeffs[-1])
  4612. coeffs1 = []
  4613. for i in range(len(coeffs)):
  4614. coeffx = simplify(coeffs[i]*rescale1_x**(i + 1))
  4615. if not coeffx.is_rational:
  4616. break
  4617. coeffs1.append(coeffx)
  4618. else:
  4619. rescale_x = simplify(1/rescale1_x)
  4620. x = f.gens[0]
  4621. v = [x**n]
  4622. for i in range(1, n + 1):
  4623. v.append(coeffs1[i - 1]*x**(n - i))
  4624. f = Add(*v)
  4625. f = Poly(f)
  4626. return lc, rescale_x, f
  4627. return None
  4628. def _try_translate(f, f1=None):
  4629. """
  4630. try translating ``x -> x + alpha`` to convert f to a polynomial
  4631. with rational coefficients.
  4632. Returns ``alpha, f``; if the translating is successful,
  4633. ``alpha`` is the translating factor, and ``f`` is the shifted
  4634. polynomial; else ``alpha`` is ``None``.
  4635. """
  4636. if not len(f.gens) == 1 or not (f.gens[0]).is_Atom:
  4637. return None, f
  4638. n = f.degree()
  4639. f1 = f1 or f1.monic()
  4640. coeffs = f1.all_coeffs()[1:]
  4641. c = simplify(coeffs[0])
  4642. if c.is_Add and not c.is_rational:
  4643. rat, nonrat = sift(c.args,
  4644. lambda z: z.is_rational is True, binary=True)
  4645. alpha = -c.func(*nonrat)/n
  4646. f2 = f1.shift(alpha)
  4647. return alpha, f2
  4648. return None
  4649. def _has_square_roots(p):
  4650. """
  4651. Return True if ``f`` is a sum with square roots but no other root
  4652. """
  4653. coeffs = p.coeffs()
  4654. has_sq = False
  4655. for y in coeffs:
  4656. for x in Add.make_args(y):
  4657. f = Factors(x).factors
  4658. r = [wx.q for b, wx in f.items() if
  4659. b.is_number and wx.is_Rational and wx.q >= 2]
  4660. if not r:
  4661. continue
  4662. if min(r) == 2:
  4663. has_sq = True
  4664. if max(r) > 2:
  4665. return False
  4666. return has_sq
  4667. if f.get_domain().is_EX and _has_square_roots(f):
  4668. f1 = f.monic()
  4669. r = _try_rescale(f, f1)
  4670. if r:
  4671. return r[0], r[1], None, r[2]
  4672. else:
  4673. r = _try_translate(f, f1)
  4674. if r:
  4675. return None, None, r[0], r[1]
  4676. return None
  4677. def _torational_factor_list(p, x):
  4678. """
  4679. helper function to factor polynomial using to_rational_coeffs
  4680. Examples
  4681. ========
  4682. >>> from sympy.polys.polytools import _torational_factor_list
  4683. >>> from sympy.abc import x
  4684. >>> from sympy import sqrt, expand, Mul
  4685. >>> p = expand(((x**2-1)*(x-2)).subs({x:x*(1 + sqrt(2))}))
  4686. >>> factors = _torational_factor_list(p, x); factors
  4687. (-2, [(-x*(1 + sqrt(2))/2 + 1, 1), (-x*(1 + sqrt(2)) - 1, 1), (-x*(1 + sqrt(2)) + 1, 1)])
  4688. >>> expand(factors[0]*Mul(*[z[0] for z in factors[1]])) == p
  4689. True
  4690. >>> p = expand(((x**2-1)*(x-2)).subs({x:x + sqrt(2)}))
  4691. >>> factors = _torational_factor_list(p, x); factors
  4692. (1, [(x - 2 + sqrt(2), 1), (x - 1 + sqrt(2), 1), (x + 1 + sqrt(2), 1)])
  4693. >>> expand(factors[0]*Mul(*[z[0] for z in factors[1]])) == p
  4694. True
  4695. """
  4696. from sympy.simplify.simplify import simplify
  4697. p1 = Poly(p, x, domain='EX')
  4698. n = p1.degree()
  4699. res = to_rational_coeffs(p1)
  4700. if not res:
  4701. return None
  4702. lc, r, t, g = res
  4703. factors = factor_list(g.as_expr())
  4704. if lc:
  4705. c = simplify(factors[0]*lc*r**n)
  4706. r1 = simplify(1/r)
  4707. a = []
  4708. for z in factors[1:][0]:
  4709. a.append((simplify(z[0].subs({x: x*r1})), z[1]))
  4710. else:
  4711. c = factors[0]
  4712. a = []
  4713. for z in factors[1:][0]:
  4714. a.append((z[0].subs({x: x - t}), z[1]))
  4715. return (c, a)
  4716. @public
  4717. def sqf_list(f, *gens, **args):
  4718. """
  4719. Compute a list of square-free factors of ``f``.
  4720. Examples
  4721. ========
  4722. >>> from sympy import sqf_list
  4723. >>> from sympy.abc import x
  4724. >>> sqf_list(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
  4725. (2, [(x + 1, 2), (x + 2, 3)])
  4726. """
  4727. return _generic_factor_list(f, gens, args, method='sqf')
  4728. @public
  4729. def sqf(f, *gens, **args):
  4730. """
  4731. Compute square-free factorization of ``f``.
  4732. Examples
  4733. ========
  4734. >>> from sympy import sqf
  4735. >>> from sympy.abc import x
  4736. >>> sqf(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
  4737. 2*(x + 1)**2*(x + 2)**3
  4738. """
  4739. return _generic_factor(f, gens, args, method='sqf')
  4740. @public
  4741. def factor_list(f, *gens, **args):
  4742. """
  4743. Compute a list of irreducible factors of ``f``.
  4744. Examples
  4745. ========
  4746. >>> from sympy import factor_list
  4747. >>> from sympy.abc import x, y
  4748. >>> factor_list(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y)
  4749. (2, [(x + y, 1), (x**2 + 1, 2)])
  4750. """
  4751. return _generic_factor_list(f, gens, args, method='factor')
  4752. @public
  4753. def factor(f, *gens, deep=False, **args):
  4754. """
  4755. Compute the factorization of expression, ``f``, into irreducibles. (To
  4756. factor an integer into primes, use ``factorint``.)
  4757. There two modes implemented: symbolic and formal. If ``f`` is not an
  4758. instance of :class:`Poly` and generators are not specified, then the
  4759. former mode is used. Otherwise, the formal mode is used.
  4760. In symbolic mode, :func:`factor` will traverse the expression tree and
  4761. factor its components without any prior expansion, unless an instance
  4762. of :class:`~.Add` is encountered (in this case formal factorization is
  4763. used). This way :func:`factor` can handle large or symbolic exponents.
  4764. By default, the factorization is computed over the rationals. To factor
  4765. over other domain, e.g. an algebraic or finite field, use appropriate
  4766. options: ``extension``, ``modulus`` or ``domain``.
  4767. Examples
  4768. ========
  4769. >>> from sympy import factor, sqrt, exp
  4770. >>> from sympy.abc import x, y
  4771. >>> factor(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y)
  4772. 2*(x + y)*(x**2 + 1)**2
  4773. >>> factor(x**2 + 1)
  4774. x**2 + 1
  4775. >>> factor(x**2 + 1, modulus=2)
  4776. (x + 1)**2
  4777. >>> factor(x**2 + 1, gaussian=True)
  4778. (x - I)*(x + I)
  4779. >>> factor(x**2 - 2, extension=sqrt(2))
  4780. (x - sqrt(2))*(x + sqrt(2))
  4781. >>> factor((x**2 - 1)/(x**2 + 4*x + 4))
  4782. (x - 1)*(x + 1)/(x + 2)**2
  4783. >>> factor((x**2 + 4*x + 4)**10000000*(x**2 + 1))
  4784. (x + 2)**20000000*(x**2 + 1)
  4785. By default, factor deals with an expression as a whole:
  4786. >>> eq = 2**(x**2 + 2*x + 1)
  4787. >>> factor(eq)
  4788. 2**(x**2 + 2*x + 1)
  4789. If the ``deep`` flag is True then subexpressions will
  4790. be factored:
  4791. >>> factor(eq, deep=True)
  4792. 2**((x + 1)**2)
  4793. If the ``fraction`` flag is False then rational expressions
  4794. will not be combined. By default it is True.
  4795. >>> factor(5*x + 3*exp(2 - 7*x), deep=True)
  4796. (5*x*exp(7*x) + 3*exp(2))*exp(-7*x)
  4797. >>> factor(5*x + 3*exp(2 - 7*x), deep=True, fraction=False)
  4798. 5*x + 3*exp(2)*exp(-7*x)
  4799. See Also
  4800. ========
  4801. sympy.ntheory.factor_.factorint
  4802. """
  4803. f = sympify(f)
  4804. if deep:
  4805. def _try_factor(expr):
  4806. """
  4807. Factor, but avoid changing the expression when unable to.
  4808. """
  4809. fac = factor(expr, *gens, **args)
  4810. if fac.is_Mul or fac.is_Pow:
  4811. return fac
  4812. return expr
  4813. f = bottom_up(f, _try_factor)
  4814. # clean up any subexpressions that may have been expanded
  4815. # while factoring out a larger expression
  4816. partials = {}
  4817. muladd = f.atoms(Mul, Add)
  4818. for p in muladd:
  4819. fac = factor(p, *gens, **args)
  4820. if (fac.is_Mul or fac.is_Pow) and fac != p:
  4821. partials[p] = fac
  4822. return f.xreplace(partials)
  4823. try:
  4824. return _generic_factor(f, gens, args, method='factor')
  4825. except PolynomialError as msg:
  4826. if not f.is_commutative:
  4827. return factor_nc(f)
  4828. else:
  4829. raise PolynomialError(msg)
  4830. @public
  4831. def intervals(F, all=False, eps=None, inf=None, sup=None, strict=False, fast=False, sqf=False):
  4832. """
  4833. Compute isolating intervals for roots of ``f``.
  4834. Examples
  4835. ========
  4836. >>> from sympy import intervals
  4837. >>> from sympy.abc import x
  4838. >>> intervals(x**2 - 3)
  4839. [((-2, -1), 1), ((1, 2), 1)]
  4840. >>> intervals(x**2 - 3, eps=1e-2)
  4841. [((-26/15, -19/11), 1), ((19/11, 26/15), 1)]
  4842. """
  4843. if not hasattr(F, '__iter__'):
  4844. try:
  4845. F = Poly(F)
  4846. except GeneratorsNeeded:
  4847. return []
  4848. return F.intervals(all=all, eps=eps, inf=inf, sup=sup, fast=fast, sqf=sqf)
  4849. else:
  4850. polys, opt = parallel_poly_from_expr(F, domain='QQ')
  4851. if len(opt.gens) > 1:
  4852. raise MultivariatePolynomialError
  4853. for i, poly in enumerate(polys):
  4854. polys[i] = poly.rep.rep
  4855. if eps is not None:
  4856. eps = opt.domain.convert(eps)
  4857. if eps <= 0:
  4858. raise ValueError("'eps' must be a positive rational")
  4859. if inf is not None:
  4860. inf = opt.domain.convert(inf)
  4861. if sup is not None:
  4862. sup = opt.domain.convert(sup)
  4863. intervals = dup_isolate_real_roots_list(polys, opt.domain,
  4864. eps=eps, inf=inf, sup=sup, strict=strict, fast=fast)
  4865. result = []
  4866. for (s, t), indices in intervals:
  4867. s, t = opt.domain.to_sympy(s), opt.domain.to_sympy(t)
  4868. result.append(((s, t), indices))
  4869. return result
  4870. @public
  4871. def refine_root(f, s, t, eps=None, steps=None, fast=False, check_sqf=False):
  4872. """
  4873. Refine an isolating interval of a root to the given precision.
  4874. Examples
  4875. ========
  4876. >>> from sympy import refine_root
  4877. >>> from sympy.abc import x
  4878. >>> refine_root(x**2 - 3, 1, 2, eps=1e-2)
  4879. (19/11, 26/15)
  4880. """
  4881. try:
  4882. F = Poly(f)
  4883. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  4884. # root of sin(x) + 1 is -1 but when someone
  4885. # passes an Expr instead of Poly they may not expect
  4886. # that the generator will be sin(x), not x
  4887. raise PolynomialError("generator must be a Symbol")
  4888. except GeneratorsNeeded:
  4889. raise PolynomialError(
  4890. "Cannot refine a root of %s, not a polynomial" % f)
  4891. return F.refine_root(s, t, eps=eps, steps=steps, fast=fast, check_sqf=check_sqf)
  4892. @public
  4893. def count_roots(f, inf=None, sup=None):
  4894. """
  4895. Return the number of roots of ``f`` in ``[inf, sup]`` interval.
  4896. If one of ``inf`` or ``sup`` is complex, it will return the number of roots
  4897. in the complex rectangle with corners at ``inf`` and ``sup``.
  4898. Examples
  4899. ========
  4900. >>> from sympy import count_roots, I
  4901. >>> from sympy.abc import x
  4902. >>> count_roots(x**4 - 4, -3, 3)
  4903. 2
  4904. >>> count_roots(x**4 - 4, 0, 1 + 3*I)
  4905. 1
  4906. """
  4907. try:
  4908. F = Poly(f, greedy=False)
  4909. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  4910. # root of sin(x) + 1 is -1 but when someone
  4911. # passes an Expr instead of Poly they may not expect
  4912. # that the generator will be sin(x), not x
  4913. raise PolynomialError("generator must be a Symbol")
  4914. except GeneratorsNeeded:
  4915. raise PolynomialError("Cannot count roots of %s, not a polynomial" % f)
  4916. return F.count_roots(inf=inf, sup=sup)
  4917. @public
  4918. def real_roots(f, multiple=True):
  4919. """
  4920. Return a list of real roots with multiplicities of ``f``.
  4921. Examples
  4922. ========
  4923. >>> from sympy import real_roots
  4924. >>> from sympy.abc import x
  4925. >>> real_roots(2*x**3 - 7*x**2 + 4*x + 4)
  4926. [-1/2, 2, 2]
  4927. """
  4928. try:
  4929. F = Poly(f, greedy=False)
  4930. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  4931. # root of sin(x) + 1 is -1 but when someone
  4932. # passes an Expr instead of Poly they may not expect
  4933. # that the generator will be sin(x), not x
  4934. raise PolynomialError("generator must be a Symbol")
  4935. except GeneratorsNeeded:
  4936. raise PolynomialError(
  4937. "Cannot compute real roots of %s, not a polynomial" % f)
  4938. return F.real_roots(multiple=multiple)
  4939. @public
  4940. def nroots(f, n=15, maxsteps=50, cleanup=True):
  4941. """
  4942. Compute numerical approximations of roots of ``f``.
  4943. Examples
  4944. ========
  4945. >>> from sympy import nroots
  4946. >>> from sympy.abc import x
  4947. >>> nroots(x**2 - 3, n=15)
  4948. [-1.73205080756888, 1.73205080756888]
  4949. >>> nroots(x**2 - 3, n=30)
  4950. [-1.73205080756887729352744634151, 1.73205080756887729352744634151]
  4951. """
  4952. try:
  4953. F = Poly(f, greedy=False)
  4954. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  4955. # root of sin(x) + 1 is -1 but when someone
  4956. # passes an Expr instead of Poly they may not expect
  4957. # that the generator will be sin(x), not x
  4958. raise PolynomialError("generator must be a Symbol")
  4959. except GeneratorsNeeded:
  4960. raise PolynomialError(
  4961. "Cannot compute numerical roots of %s, not a polynomial" % f)
  4962. return F.nroots(n=n, maxsteps=maxsteps, cleanup=cleanup)
  4963. @public
  4964. def ground_roots(f, *gens, **args):
  4965. """
  4966. Compute roots of ``f`` by factorization in the ground domain.
  4967. Examples
  4968. ========
  4969. >>> from sympy import ground_roots
  4970. >>> from sympy.abc import x
  4971. >>> ground_roots(x**6 - 4*x**4 + 4*x**3 - x**2)
  4972. {0: 2, 1: 2}
  4973. """
  4974. options.allowed_flags(args, [])
  4975. try:
  4976. F, opt = poly_from_expr(f, *gens, **args)
  4977. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  4978. # root of sin(x) + 1 is -1 but when someone
  4979. # passes an Expr instead of Poly they may not expect
  4980. # that the generator will be sin(x), not x
  4981. raise PolynomialError("generator must be a Symbol")
  4982. except PolificationFailed as exc:
  4983. raise ComputationFailed('ground_roots', 1, exc)
  4984. return F.ground_roots()
  4985. @public
  4986. def nth_power_roots_poly(f, n, *gens, **args):
  4987. """
  4988. Construct a polynomial with n-th powers of roots of ``f``.
  4989. Examples
  4990. ========
  4991. >>> from sympy import nth_power_roots_poly, factor, roots
  4992. >>> from sympy.abc import x
  4993. >>> f = x**4 - x**2 + 1
  4994. >>> g = factor(nth_power_roots_poly(f, 2))
  4995. >>> g
  4996. (x**2 - x + 1)**2
  4997. >>> R_f = [ (r**2).expand() for r in roots(f) ]
  4998. >>> R_g = roots(g).keys()
  4999. >>> set(R_f) == set(R_g)
  5000. True
  5001. """
  5002. options.allowed_flags(args, [])
  5003. try:
  5004. F, opt = poly_from_expr(f, *gens, **args)
  5005. if not isinstance(f, Poly) and not F.gen.is_Symbol:
  5006. # root of sin(x) + 1 is -1 but when someone
  5007. # passes an Expr instead of Poly they may not expect
  5008. # that the generator will be sin(x), not x
  5009. raise PolynomialError("generator must be a Symbol")
  5010. except PolificationFailed as exc:
  5011. raise ComputationFailed('nth_power_roots_poly', 1, exc)
  5012. result = F.nth_power_roots_poly(n)
  5013. if not opt.polys:
  5014. return result.as_expr()
  5015. else:
  5016. return result
  5017. @public
  5018. def cancel(f, *gens, _signsimp=True, **args):
  5019. """
  5020. Cancel common factors in a rational function ``f``.
  5021. Examples
  5022. ========
  5023. >>> from sympy import cancel, sqrt, Symbol, together
  5024. >>> from sympy.abc import x
  5025. >>> A = Symbol('A', commutative=False)
  5026. >>> cancel((2*x**2 - 2)/(x**2 - 2*x + 1))
  5027. (2*x + 2)/(x - 1)
  5028. >>> cancel((sqrt(3) + sqrt(15)*A)/(sqrt(2) + sqrt(10)*A))
  5029. sqrt(6)/2
  5030. Note: due to automatic distribution of Rationals, a sum divided by an integer
  5031. will appear as a sum. To recover a rational form use `together` on the result:
  5032. >>> cancel(x/2 + 1)
  5033. x/2 + 1
  5034. >>> together(_)
  5035. (x + 2)/2
  5036. """
  5037. from sympy.simplify.simplify import signsimp
  5038. from sympy.polys.rings import sring
  5039. options.allowed_flags(args, ['polys'])
  5040. f = sympify(f)
  5041. if _signsimp:
  5042. f = signsimp(f)
  5043. opt = {}
  5044. if 'polys' in args:
  5045. opt['polys'] = args['polys']
  5046. if not isinstance(f, (tuple, Tuple)):
  5047. if f.is_Number or isinstance(f, Relational) or not isinstance(f, Expr):
  5048. return f
  5049. f = factor_terms(f, radical=True)
  5050. p, q = f.as_numer_denom()
  5051. elif len(f) == 2:
  5052. p, q = f
  5053. if isinstance(p, Poly) and isinstance(q, Poly):
  5054. opt['gens'] = p.gens
  5055. opt['domain'] = p.domain
  5056. opt['polys'] = opt.get('polys', True)
  5057. p, q = p.as_expr(), q.as_expr()
  5058. elif isinstance(f, Tuple):
  5059. return factor_terms(f)
  5060. else:
  5061. raise ValueError('unexpected argument: %s' % f)
  5062. from sympy.functions.elementary.piecewise import Piecewise
  5063. try:
  5064. if f.has(Piecewise):
  5065. raise PolynomialError()
  5066. R, (F, G) = sring((p, q), *gens, **args)
  5067. if not R.ngens:
  5068. if not isinstance(f, (tuple, Tuple)):
  5069. return f.expand()
  5070. else:
  5071. return S.One, p, q
  5072. except PolynomialError as msg:
  5073. if f.is_commutative and not f.has(Piecewise):
  5074. raise PolynomialError(msg)
  5075. # Handling of noncommutative and/or piecewise expressions
  5076. if f.is_Add or f.is_Mul:
  5077. c, nc = sift(f.args, lambda x:
  5078. x.is_commutative is True and not x.has(Piecewise),
  5079. binary=True)
  5080. nc = [cancel(i) for i in nc]
  5081. return f.func(cancel(f.func(*c)), *nc)
  5082. else:
  5083. reps = []
  5084. pot = preorder_traversal(f)
  5085. next(pot)
  5086. for e in pot:
  5087. # XXX: This should really skip anything that's not Expr.
  5088. if isinstance(e, (tuple, Tuple, BooleanAtom)):
  5089. continue
  5090. try:
  5091. reps.append((e, cancel(e)))
  5092. pot.skip() # this was handled successfully
  5093. except NotImplementedError:
  5094. pass
  5095. return f.xreplace(dict(reps))
  5096. c, (P, Q) = 1, F.cancel(G)
  5097. if opt.get('polys', False) and 'gens' not in opt:
  5098. opt['gens'] = R.symbols
  5099. if not isinstance(f, (tuple, Tuple)):
  5100. return c*(P.as_expr()/Q.as_expr())
  5101. else:
  5102. P, Q = P.as_expr(), Q.as_expr()
  5103. if not opt.get('polys', False):
  5104. return c, P, Q
  5105. else:
  5106. return c, Poly(P, *gens, **opt), Poly(Q, *gens, **opt)
  5107. @public
  5108. def reduced(f, G, *gens, **args):
  5109. """
  5110. Reduces a polynomial ``f`` modulo a set of polynomials ``G``.
  5111. Given a polynomial ``f`` and a set of polynomials ``G = (g_1, ..., g_n)``,
  5112. computes a set of quotients ``q = (q_1, ..., q_n)`` and the remainder ``r``
  5113. such that ``f = q_1*g_1 + ... + q_n*g_n + r``, where ``r`` vanishes or ``r``
  5114. is a completely reduced polynomial with respect to ``G``.
  5115. Examples
  5116. ========
  5117. >>> from sympy import reduced
  5118. >>> from sympy.abc import x, y
  5119. >>> reduced(2*x**4 + y**2 - x**2 + y**3, [x**3 - x, y**3 - y])
  5120. ([2*x, 1], x**2 + y**2 + y)
  5121. """
  5122. options.allowed_flags(args, ['polys', 'auto'])
  5123. try:
  5124. polys, opt = parallel_poly_from_expr([f] + list(G), *gens, **args)
  5125. except PolificationFailed as exc:
  5126. raise ComputationFailed('reduced', 0, exc)
  5127. domain = opt.domain
  5128. retract = False
  5129. if opt.auto and domain.is_Ring and not domain.is_Field:
  5130. opt = opt.clone({"domain": domain.get_field()})
  5131. retract = True
  5132. from sympy.polys.rings import xring
  5133. _ring, _ = xring(opt.gens, opt.domain, opt.order)
  5134. for i, poly in enumerate(polys):
  5135. poly = poly.set_domain(opt.domain).rep.to_dict()
  5136. polys[i] = _ring.from_dict(poly)
  5137. Q, r = polys[0].div(polys[1:])
  5138. Q = [Poly._from_dict(dict(q), opt) for q in Q]
  5139. r = Poly._from_dict(dict(r), opt)
  5140. if retract:
  5141. try:
  5142. _Q, _r = [q.to_ring() for q in Q], r.to_ring()
  5143. except CoercionFailed:
  5144. pass
  5145. else:
  5146. Q, r = _Q, _r
  5147. if not opt.polys:
  5148. return [q.as_expr() for q in Q], r.as_expr()
  5149. else:
  5150. return Q, r
  5151. @public
  5152. def groebner(F, *gens, **args):
  5153. """
  5154. Computes the reduced Groebner basis for a set of polynomials.
  5155. Use the ``order`` argument to set the monomial ordering that will be
  5156. used to compute the basis. Allowed orders are ``lex``, ``grlex`` and
  5157. ``grevlex``. If no order is specified, it defaults to ``lex``.
  5158. For more information on Groebner bases, see the references and the docstring
  5159. of :func:`~.solve_poly_system`.
  5160. Examples
  5161. ========
  5162. Example taken from [1].
  5163. >>> from sympy import groebner
  5164. >>> from sympy.abc import x, y
  5165. >>> F = [x*y - 2*y, 2*y**2 - x**2]
  5166. >>> groebner(F, x, y, order='lex')
  5167. GroebnerBasis([x**2 - 2*y**2, x*y - 2*y, y**3 - 2*y], x, y,
  5168. domain='ZZ', order='lex')
  5169. >>> groebner(F, x, y, order='grlex')
  5170. GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
  5171. domain='ZZ', order='grlex')
  5172. >>> groebner(F, x, y, order='grevlex')
  5173. GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
  5174. domain='ZZ', order='grevlex')
  5175. By default, an improved implementation of the Buchberger algorithm is
  5176. used. Optionally, an implementation of the F5B algorithm can be used. The
  5177. algorithm can be set using the ``method`` flag or with the
  5178. :func:`sympy.polys.polyconfig.setup` function.
  5179. >>> F = [x**2 - x - 1, (2*x - 1) * y - (x**10 - (1 - x)**10)]
  5180. >>> groebner(F, x, y, method='buchberger')
  5181. GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex')
  5182. >>> groebner(F, x, y, method='f5b')
  5183. GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex')
  5184. References
  5185. ==========
  5186. 1. [Buchberger01]_
  5187. 2. [Cox97]_
  5188. """
  5189. return GroebnerBasis(F, *gens, **args)
  5190. @public
  5191. def is_zero_dimensional(F, *gens, **args):
  5192. """
  5193. Checks if the ideal generated by a Groebner basis is zero-dimensional.
  5194. The algorithm checks if the set of monomials not divisible by the
  5195. leading monomial of any element of ``F`` is bounded.
  5196. References
  5197. ==========
  5198. David A. Cox, John B. Little, Donal O'Shea. Ideals, Varieties and
  5199. Algorithms, 3rd edition, p. 230
  5200. """
  5201. return GroebnerBasis(F, *gens, **args).is_zero_dimensional
  5202. @public
  5203. class GroebnerBasis(Basic):
  5204. """Represents a reduced Groebner basis. """
  5205. def __new__(cls, F, *gens, **args):
  5206. """Compute a reduced Groebner basis for a system of polynomials. """
  5207. options.allowed_flags(args, ['polys', 'method'])
  5208. try:
  5209. polys, opt = parallel_poly_from_expr(F, *gens, **args)
  5210. except PolificationFailed as exc:
  5211. raise ComputationFailed('groebner', len(F), exc)
  5212. from sympy.polys.rings import PolyRing
  5213. ring = PolyRing(opt.gens, opt.domain, opt.order)
  5214. polys = [ring.from_dict(poly.rep.to_dict()) for poly in polys if poly]
  5215. G = _groebner(polys, ring, method=opt.method)
  5216. G = [Poly._from_dict(g, opt) for g in G]
  5217. return cls._new(G, opt)
  5218. @classmethod
  5219. def _new(cls, basis, options):
  5220. obj = Basic.__new__(cls)
  5221. obj._basis = tuple(basis)
  5222. obj._options = options
  5223. return obj
  5224. @property
  5225. def args(self):
  5226. basis = (p.as_expr() for p in self._basis)
  5227. return (Tuple(*basis), Tuple(*self._options.gens))
  5228. @property
  5229. def exprs(self):
  5230. return [poly.as_expr() for poly in self._basis]
  5231. @property
  5232. def polys(self):
  5233. return list(self._basis)
  5234. @property
  5235. def gens(self):
  5236. return self._options.gens
  5237. @property
  5238. def domain(self):
  5239. return self._options.domain
  5240. @property
  5241. def order(self):
  5242. return self._options.order
  5243. def __len__(self):
  5244. return len(self._basis)
  5245. def __iter__(self):
  5246. if self._options.polys:
  5247. return iter(self.polys)
  5248. else:
  5249. return iter(self.exprs)
  5250. def __getitem__(self, item):
  5251. if self._options.polys:
  5252. basis = self.polys
  5253. else:
  5254. basis = self.exprs
  5255. return basis[item]
  5256. def __hash__(self):
  5257. return hash((self._basis, tuple(self._options.items())))
  5258. def __eq__(self, other):
  5259. if isinstance(other, self.__class__):
  5260. return self._basis == other._basis and self._options == other._options
  5261. elif iterable(other):
  5262. return self.polys == list(other) or self.exprs == list(other)
  5263. else:
  5264. return False
  5265. def __ne__(self, other):
  5266. return not self == other
  5267. @property
  5268. def is_zero_dimensional(self):
  5269. """
  5270. Checks if the ideal generated by a Groebner basis is zero-dimensional.
  5271. The algorithm checks if the set of monomials not divisible by the
  5272. leading monomial of any element of ``F`` is bounded.
  5273. References
  5274. ==========
  5275. David A. Cox, John B. Little, Donal O'Shea. Ideals, Varieties and
  5276. Algorithms, 3rd edition, p. 230
  5277. """
  5278. def single_var(monomial):
  5279. return sum(map(bool, monomial)) == 1
  5280. exponents = Monomial([0]*len(self.gens))
  5281. order = self._options.order
  5282. for poly in self.polys:
  5283. monomial = poly.LM(order=order)
  5284. if single_var(monomial):
  5285. exponents *= monomial
  5286. # If any element of the exponents vector is zero, then there's
  5287. # a variable for which there's no degree bound and the ideal
  5288. # generated by this Groebner basis isn't zero-dimensional.
  5289. return all(exponents)
  5290. def fglm(self, order):
  5291. """
  5292. Convert a Groebner basis from one ordering to another.
  5293. The FGLM algorithm converts reduced Groebner bases of zero-dimensional
  5294. ideals from one ordering to another. This method is often used when it
  5295. is infeasible to compute a Groebner basis with respect to a particular
  5296. ordering directly.
  5297. Examples
  5298. ========
  5299. >>> from sympy.abc import x, y
  5300. >>> from sympy import groebner
  5301. >>> F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1]
  5302. >>> G = groebner(F, x, y, order='grlex')
  5303. >>> list(G.fglm('lex'))
  5304. [2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7]
  5305. >>> list(groebner(F, x, y, order='lex'))
  5306. [2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7]
  5307. References
  5308. ==========
  5309. .. [1] J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient
  5310. Computation of Zero-dimensional Groebner Bases by Change of
  5311. Ordering
  5312. """
  5313. opt = self._options
  5314. src_order = opt.order
  5315. dst_order = monomial_key(order)
  5316. if src_order == dst_order:
  5317. return self
  5318. if not self.is_zero_dimensional:
  5319. raise NotImplementedError("Cannot convert Groebner bases of ideals with positive dimension")
  5320. polys = list(self._basis)
  5321. domain = opt.domain
  5322. opt = opt.clone({
  5323. "domain": domain.get_field(),
  5324. "order": dst_order,
  5325. })
  5326. from sympy.polys.rings import xring
  5327. _ring, _ = xring(opt.gens, opt.domain, src_order)
  5328. for i, poly in enumerate(polys):
  5329. poly = poly.set_domain(opt.domain).rep.to_dict()
  5330. polys[i] = _ring.from_dict(poly)
  5331. G = matrix_fglm(polys, _ring, dst_order)
  5332. G = [Poly._from_dict(dict(g), opt) for g in G]
  5333. if not domain.is_Field:
  5334. G = [g.clear_denoms(convert=True)[1] for g in G]
  5335. opt.domain = domain
  5336. return self._new(G, opt)
  5337. def reduce(self, expr, auto=True):
  5338. """
  5339. Reduces a polynomial modulo a Groebner basis.
  5340. Given a polynomial ``f`` and a set of polynomials ``G = (g_1, ..., g_n)``,
  5341. computes a set of quotients ``q = (q_1, ..., q_n)`` and the remainder ``r``
  5342. such that ``f = q_1*f_1 + ... + q_n*f_n + r``, where ``r`` vanishes or ``r``
  5343. is a completely reduced polynomial with respect to ``G``.
  5344. Examples
  5345. ========
  5346. >>> from sympy import groebner, expand
  5347. >>> from sympy.abc import x, y
  5348. >>> f = 2*x**4 - x**2 + y**3 + y**2
  5349. >>> G = groebner([x**3 - x, y**3 - y])
  5350. >>> G.reduce(f)
  5351. ([2*x, 1], x**2 + y**2 + y)
  5352. >>> Q, r = _
  5353. >>> expand(sum(q*g for q, g in zip(Q, G)) + r)
  5354. 2*x**4 - x**2 + y**3 + y**2
  5355. >>> _ == f
  5356. True
  5357. """
  5358. poly = Poly._from_expr(expr, self._options)
  5359. polys = [poly] + list(self._basis)
  5360. opt = self._options
  5361. domain = opt.domain
  5362. retract = False
  5363. if auto and domain.is_Ring and not domain.is_Field:
  5364. opt = opt.clone({"domain": domain.get_field()})
  5365. retract = True
  5366. from sympy.polys.rings import xring
  5367. _ring, _ = xring(opt.gens, opt.domain, opt.order)
  5368. for i, poly in enumerate(polys):
  5369. poly = poly.set_domain(opt.domain).rep.to_dict()
  5370. polys[i] = _ring.from_dict(poly)
  5371. Q, r = polys[0].div(polys[1:])
  5372. Q = [Poly._from_dict(dict(q), opt) for q in Q]
  5373. r = Poly._from_dict(dict(r), opt)
  5374. if retract:
  5375. try:
  5376. _Q, _r = [q.to_ring() for q in Q], r.to_ring()
  5377. except CoercionFailed:
  5378. pass
  5379. else:
  5380. Q, r = _Q, _r
  5381. if not opt.polys:
  5382. return [q.as_expr() for q in Q], r.as_expr()
  5383. else:
  5384. return Q, r
  5385. def contains(self, poly):
  5386. """
  5387. Check if ``poly`` belongs the ideal generated by ``self``.
  5388. Examples
  5389. ========
  5390. >>> from sympy import groebner
  5391. >>> from sympy.abc import x, y
  5392. >>> f = 2*x**3 + y**3 + 3*y
  5393. >>> G = groebner([x**2 + y**2 - 1, x*y - 2])
  5394. >>> G.contains(f)
  5395. True
  5396. >>> G.contains(f + 1)
  5397. False
  5398. """
  5399. return self.reduce(poly)[1] == 0
  5400. @public
  5401. def poly(expr, *gens, **args):
  5402. """
  5403. Efficiently transform an expression into a polynomial.
  5404. Examples
  5405. ========
  5406. >>> from sympy import poly
  5407. >>> from sympy.abc import x
  5408. >>> poly(x*(x**2 + x - 1)**2)
  5409. Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')
  5410. """
  5411. options.allowed_flags(args, [])
  5412. def _poly(expr, opt):
  5413. terms, poly_terms = [], []
  5414. for term in Add.make_args(expr):
  5415. factors, poly_factors = [], []
  5416. for factor in Mul.make_args(term):
  5417. if factor.is_Add:
  5418. poly_factors.append(_poly(factor, opt))
  5419. elif factor.is_Pow and factor.base.is_Add and \
  5420. factor.exp.is_Integer and factor.exp >= 0:
  5421. poly_factors.append(
  5422. _poly(factor.base, opt).pow(factor.exp))
  5423. else:
  5424. factors.append(factor)
  5425. if not poly_factors:
  5426. terms.append(term)
  5427. else:
  5428. product = poly_factors[0]
  5429. for factor in poly_factors[1:]:
  5430. product = product.mul(factor)
  5431. if factors:
  5432. factor = Mul(*factors)
  5433. if factor.is_Number:
  5434. product = product.mul(factor)
  5435. else:
  5436. product = product.mul(Poly._from_expr(factor, opt))
  5437. poly_terms.append(product)
  5438. if not poly_terms:
  5439. result = Poly._from_expr(expr, opt)
  5440. else:
  5441. result = poly_terms[0]
  5442. for term in poly_terms[1:]:
  5443. result = result.add(term)
  5444. if terms:
  5445. term = Add(*terms)
  5446. if term.is_Number:
  5447. result = result.add(term)
  5448. else:
  5449. result = result.add(Poly._from_expr(term, opt))
  5450. return result.reorder(*opt.get('gens', ()), **args)
  5451. expr = sympify(expr)
  5452. if expr.is_Poly:
  5453. return Poly(expr, *gens, **args)
  5454. if 'expand' not in args:
  5455. args['expand'] = False
  5456. opt = options.build_options(gens, args)
  5457. return _poly(expr, opt)
  5458. def named_poly(n, f, K, name, x, polys):
  5459. r"""Common interface to the low-level polynomial generating functions
  5460. in orthopolys and appellseqs.
  5461. Parameters
  5462. ==========
  5463. n : int
  5464. Index of the polynomial, which may or may not equal its degree.
  5465. f : callable
  5466. Low-level generating function to use.
  5467. K : Domain or None
  5468. Domain in which to perform the computations. If None, use the smallest
  5469. field containing the rationals and the extra parameters of x (see below).
  5470. name : str
  5471. Name of an arbitrary individual polynomial in the sequence generated
  5472. by f, only used in the error message for invalid n.
  5473. x : seq
  5474. The first element of this argument is the main variable of all
  5475. polynomials in this sequence. Any further elements are extra
  5476. parameters required by f.
  5477. polys : bool, optional
  5478. If True, return a Poly, otherwise (default) return an expression.
  5479. """
  5480. if n < 0:
  5481. raise ValueError("Cannot generate %s of index %s" % (name, n))
  5482. head, tail = x[0], x[1:]
  5483. if K is None:
  5484. K, tail = construct_domain(tail, field=True)
  5485. poly = DMP(f(int(n), *tail, K), K)
  5486. if head is None:
  5487. poly = PurePoly.new(poly, Dummy('x'))
  5488. else:
  5489. poly = Poly.new(poly, head)
  5490. return poly if polys else poly.as_expr()