polytools.py 208 KB

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