solvers.py 127 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528
  1. """
  2. This module contain solvers for all kinds of equations:
  3. - algebraic or transcendental, use solve()
  4. - recurrence, use rsolve()
  5. - differential, use dsolve()
  6. - nonlinear (numerically), use nsolve()
  7. (you will need a good starting point)
  8. """
  9. from sympy.core import (S, Add, Symbol, Dummy, Expr, Mul)
  10. from sympy.core.assumptions import check_assumptions
  11. from sympy.core.exprtools import factor_terms
  12. from sympy.core.function import (expand_mul, expand_log, Derivative,
  13. AppliedUndef, UndefinedFunction, nfloat,
  14. Function, expand_power_exp, _mexpand, expand,
  15. expand_func)
  16. from sympy.core.logic import fuzzy_not
  17. from sympy.core.numbers import ilcm, Float, Rational
  18. from sympy.core.power import integer_log, Pow
  19. from sympy.core.relational import Relational, Eq, Ne
  20. from sympy.core.sorting import ordered, default_sort_key
  21. from sympy.core.sympify import sympify
  22. from sympy.core.traversal import preorder_traversal
  23. from sympy.logic.boolalg import And, Or, BooleanAtom
  24. from sympy.functions import (log, exp, LambertW, cos, sin, tan, acos, asin, atan,
  25. Abs, re, im, arg, sqrt, atan2)
  26. from sympy.functions.combinatorial.factorials import binomial
  27. from sympy.functions.elementary.trigonometric import (TrigonometricFunction,
  28. HyperbolicFunction)
  29. from sympy.functions.elementary.piecewise import piecewise_fold, Piecewise
  30. from sympy.ntheory.factor_ import divisors
  31. from sympy.simplify import (simplify, collect, powsimp, posify, # type: ignore
  32. powdenest, nsimplify, denom, logcombine, sqrtdenest, fraction,
  33. separatevars)
  34. from sympy.simplify.sqrtdenest import sqrt_depth
  35. from sympy.simplify.fu import TR1, TR2i
  36. from sympy.matrices.common import NonInvertibleMatrixError
  37. from sympy.matrices import Matrix, zeros
  38. from sympy.polys import roots, cancel, factor, Poly
  39. from sympy.polys.polyerrors import GeneratorsNeeded, PolynomialError
  40. from sympy.polys.solvers import sympy_eqs_to_ring, solve_lin_sys
  41. from sympy.utilities.lambdify import lambdify
  42. from sympy.utilities.misc import filldedent, debug
  43. from sympy.utilities.iterables import (connected_components,
  44. generate_bell, uniq, iterable, is_sequence, subsets)
  45. from sympy.utilities.decorator import conserve_mpmath_dps
  46. from mpmath import findroot
  47. from sympy.solvers.polysys import solve_poly_system
  48. from types import GeneratorType
  49. from collections import defaultdict
  50. from itertools import product
  51. import warnings
  52. def recast_to_symbols(eqs, symbols):
  53. """
  54. Return (e, s, d) where e and s are versions of *eqs* and
  55. *symbols* in which any non-Symbol objects in *symbols* have
  56. been replaced with generic Dummy symbols and d is a dictionary
  57. that can be used to restore the original expressions.
  58. Examples
  59. ========
  60. >>> from sympy.solvers.solvers import recast_to_symbols
  61. >>> from sympy import symbols, Function
  62. >>> x, y = symbols('x y')
  63. >>> fx = Function('f')(x)
  64. >>> eqs, syms = [fx + 1, x, y], [fx, y]
  65. >>> e, s, d = recast_to_symbols(eqs, syms); (e, s, d)
  66. ([_X0 + 1, x, y], [_X0, y], {_X0: f(x)})
  67. The original equations and symbols can be restored using d:
  68. >>> assert [i.xreplace(d) for i in eqs] == eqs
  69. >>> assert [d.get(i, i) for i in s] == syms
  70. """
  71. if not iterable(eqs) and iterable(symbols):
  72. raise ValueError('Both eqs and symbols must be iterable')
  73. new_symbols = list(symbols)
  74. swap_sym = {}
  75. for i, s in enumerate(symbols):
  76. if not isinstance(s, Symbol) and s not in swap_sym:
  77. swap_sym[s] = Dummy('X%d' % i)
  78. new_symbols[i] = swap_sym[s]
  79. new_f = []
  80. for i in eqs:
  81. isubs = getattr(i, 'subs', None)
  82. if isubs is not None:
  83. new_f.append(isubs(swap_sym))
  84. else:
  85. new_f.append(i)
  86. swap_sym = {v: k for k, v in swap_sym.items()}
  87. return new_f, new_symbols, swap_sym
  88. def _ispow(e):
  89. """Return True if e is a Pow or is exp."""
  90. return isinstance(e, Expr) and (e.is_Pow or isinstance(e, exp))
  91. def _simple_dens(f, symbols):
  92. # when checking if a denominator is zero, we can just check the
  93. # base of powers with nonzero exponents since if the base is zero
  94. # the power will be zero, too. To keep it simple and fast, we
  95. # limit simplification to exponents that are Numbers
  96. dens = set()
  97. for d in denoms(f, symbols):
  98. if d.is_Pow and d.exp.is_Number:
  99. if d.exp.is_zero:
  100. continue # foo**0 is never 0
  101. d = d.base
  102. dens.add(d)
  103. return dens
  104. def denoms(eq, *symbols):
  105. """
  106. Return (recursively) set of all denominators that appear in *eq*
  107. that contain any symbol in *symbols*; if *symbols* are not
  108. provided then all denominators will be returned.
  109. Examples
  110. ========
  111. >>> from sympy.solvers.solvers import denoms
  112. >>> from sympy.abc import x, y, z
  113. >>> denoms(x/y)
  114. {y}
  115. >>> denoms(x/(y*z))
  116. {y, z}
  117. >>> denoms(3/x + y/z)
  118. {x, z}
  119. >>> denoms(x/2 + y/z)
  120. {2, z}
  121. If *symbols* are provided then only denominators containing
  122. those symbols will be returned:
  123. >>> denoms(1/x + 1/y + 1/z, y, z)
  124. {y, z}
  125. """
  126. pot = preorder_traversal(eq)
  127. dens = set()
  128. for p in pot:
  129. # Here p might be Tuple or Relational
  130. # Expr subtrees (e.g. lhs and rhs) will be traversed after by pot
  131. if not isinstance(p, Expr):
  132. continue
  133. den = denom(p)
  134. if den is S.One:
  135. continue
  136. for d in Mul.make_args(den):
  137. dens.add(d)
  138. if not symbols:
  139. return dens
  140. elif len(symbols) == 1:
  141. if iterable(symbols[0]):
  142. symbols = symbols[0]
  143. rv = []
  144. for d in dens:
  145. free = d.free_symbols
  146. if any(s in free for s in symbols):
  147. rv.append(d)
  148. return set(rv)
  149. def checksol(f, symbol, sol=None, **flags):
  150. """
  151. Checks whether sol is a solution of equation f == 0.
  152. Explanation
  153. ===========
  154. Input can be either a single symbol and corresponding value
  155. or a dictionary of symbols and values. When given as a dictionary
  156. and flag ``simplify=True``, the values in the dictionary will be
  157. simplified. *f* can be a single equation or an iterable of equations.
  158. A solution must satisfy all equations in *f* to be considered valid;
  159. if a solution does not satisfy any equation, False is returned; if one or
  160. more checks are inconclusive (and none are False) then None is returned.
  161. Examples
  162. ========
  163. >>> from sympy import checksol, symbols
  164. >>> x, y = symbols('x,y')
  165. >>> checksol(x**4 - 1, x, 1)
  166. True
  167. >>> checksol(x**4 - 1, x, 0)
  168. False
  169. >>> checksol(x**2 + y**2 - 5**2, {x: 3, y: 4})
  170. True
  171. To check if an expression is zero using ``checksol()``, pass it
  172. as *f* and send an empty dictionary for *symbol*:
  173. >>> checksol(x**2 + x - x*(x + 1), {})
  174. True
  175. None is returned if ``checksol()`` could not conclude.
  176. flags:
  177. 'numerical=True (default)'
  178. do a fast numerical check if ``f`` has only one symbol.
  179. 'minimal=True (default is False)'
  180. a very fast, minimal testing.
  181. 'warn=True (default is False)'
  182. show a warning if checksol() could not conclude.
  183. 'simplify=True (default)'
  184. simplify solution before substituting into function and
  185. simplify the function before trying specific simplifications
  186. 'force=True (default is False)'
  187. make positive all symbols without assumptions regarding sign.
  188. """
  189. from sympy.physics.units import Unit
  190. minimal = flags.get('minimal', False)
  191. if sol is not None:
  192. sol = {symbol: sol}
  193. elif isinstance(symbol, dict):
  194. sol = symbol
  195. else:
  196. msg = 'Expecting (sym, val) or ({sym: val}, None) but got (%s, %s)'
  197. raise ValueError(msg % (symbol, sol))
  198. if iterable(f):
  199. if not f:
  200. raise ValueError('no functions to check')
  201. rv = True
  202. for fi in f:
  203. check = checksol(fi, sol, **flags)
  204. if check:
  205. continue
  206. if check is False:
  207. return False
  208. rv = None # don't return, wait to see if there's a False
  209. return rv
  210. if isinstance(f, Poly):
  211. f = f.as_expr()
  212. elif isinstance(f, (Eq, Ne)):
  213. if f.rhs in (S.true, S.false):
  214. f = f.reversed
  215. B, E = f.args
  216. if isinstance(B, BooleanAtom):
  217. f = f.subs(sol)
  218. if not f.is_Boolean:
  219. return
  220. else:
  221. f = f.rewrite(Add, evaluate=False)
  222. if isinstance(f, BooleanAtom):
  223. return bool(f)
  224. elif not f.is_Relational and not f:
  225. return True
  226. if sol and not f.free_symbols & set(sol.keys()):
  227. # if f(y) == 0, x=3 does not set f(y) to zero...nor does it not
  228. return None
  229. illegal = {S.NaN,
  230. S.ComplexInfinity,
  231. S.Infinity,
  232. S.NegativeInfinity}
  233. if any(sympify(v).atoms() & illegal for k, v in sol.items()):
  234. return False
  235. was = f
  236. attempt = -1
  237. numerical = flags.get('numerical', True)
  238. while 1:
  239. attempt += 1
  240. if attempt == 0:
  241. val = f.subs(sol)
  242. if isinstance(val, Mul):
  243. val = val.as_independent(Unit)[0]
  244. if val.atoms() & illegal:
  245. return False
  246. elif attempt == 1:
  247. if not val.is_number:
  248. if not val.is_constant(*list(sol.keys()), simplify=not minimal):
  249. return False
  250. # there are free symbols -- simple expansion might work
  251. _, val = val.as_content_primitive()
  252. val = _mexpand(val.as_numer_denom()[0], recursive=True)
  253. elif attempt == 2:
  254. if minimal:
  255. return
  256. if flags.get('simplify', True):
  257. for k in sol:
  258. sol[k] = simplify(sol[k])
  259. # start over without the failed expanded form, possibly
  260. # with a simplified solution
  261. val = simplify(f.subs(sol))
  262. if flags.get('force', True):
  263. val, reps = posify(val)
  264. # expansion may work now, so try again and check
  265. exval = _mexpand(val, recursive=True)
  266. if exval.is_number:
  267. # we can decide now
  268. val = exval
  269. else:
  270. # if there are no radicals and no functions then this can't be
  271. # zero anymore -- can it?
  272. pot = preorder_traversal(expand_mul(val))
  273. seen = set()
  274. saw_pow_func = False
  275. for p in pot:
  276. if p in seen:
  277. continue
  278. seen.add(p)
  279. if p.is_Pow and not p.exp.is_Integer:
  280. saw_pow_func = True
  281. elif p.is_Function:
  282. saw_pow_func = True
  283. elif isinstance(p, UndefinedFunction):
  284. saw_pow_func = True
  285. if saw_pow_func:
  286. break
  287. if saw_pow_func is False:
  288. return False
  289. if flags.get('force', True):
  290. # don't do a zero check with the positive assumptions in place
  291. val = val.subs(reps)
  292. nz = fuzzy_not(val.is_zero)
  293. if nz is not None:
  294. # issue 5673: nz may be True even when False
  295. # so these are just hacks to keep a false positive
  296. # from being returned
  297. # HACK 1: LambertW (issue 5673)
  298. if val.is_number and val.has(LambertW):
  299. # don't eval this to verify solution since if we got here,
  300. # numerical must be False
  301. return None
  302. # add other HACKs here if necessary, otherwise we assume
  303. # the nz value is correct
  304. return not nz
  305. break
  306. if val == was:
  307. continue
  308. elif val.is_Rational:
  309. return val == 0
  310. if numerical and val.is_number:
  311. return (abs(val.n(18).n(12, chop=True)) < 1e-9) is S.true
  312. was = val
  313. if flags.get('warn', False):
  314. warnings.warn("\n\tWarning: could not verify solution %s." % sol)
  315. # returns None if it can't conclude
  316. # TODO: improve solution testing
  317. def solve(f, *symbols, **flags):
  318. r"""
  319. Algebraically solves equations and systems of equations.
  320. Explanation
  321. ===========
  322. Currently supported:
  323. - polynomial
  324. - transcendental
  325. - piecewise combinations of the above
  326. - systems of linear and polynomial equations
  327. - systems containing relational expressions
  328. Examples
  329. ========
  330. The output varies according to the input and can be seen by example:
  331. >>> from sympy import solve, Poly, Eq, Function, exp
  332. >>> from sympy.abc import x, y, z, a, b
  333. >>> f = Function('f')
  334. Boolean or univariate Relational:
  335. >>> solve(x < 3)
  336. (-oo < x) & (x < 3)
  337. To always get a list of solution mappings, use flag dict=True:
  338. >>> solve(x - 3, dict=True)
  339. [{x: 3}]
  340. >>> sol = solve([x - 3, y - 1], dict=True)
  341. >>> sol
  342. [{x: 3, y: 1}]
  343. >>> sol[0][x]
  344. 3
  345. >>> sol[0][y]
  346. 1
  347. To get a list of *symbols* and set of solution(s) use flag set=True:
  348. >>> solve([x**2 - 3, y - 1], set=True)
  349. ([x, y], {(-sqrt(3), 1), (sqrt(3), 1)})
  350. Single expression and single symbol that is in the expression:
  351. >>> solve(x - y, x)
  352. [y]
  353. >>> solve(x - 3, x)
  354. [3]
  355. >>> solve(Eq(x, 3), x)
  356. [3]
  357. >>> solve(Poly(x - 3), x)
  358. [3]
  359. >>> solve(x**2 - y**2, x, set=True)
  360. ([x], {(-y,), (y,)})
  361. >>> solve(x**4 - 1, x, set=True)
  362. ([x], {(-1,), (1,), (-I,), (I,)})
  363. Single expression with no symbol that is in the expression:
  364. >>> solve(3, x)
  365. []
  366. >>> solve(x - 3, y)
  367. []
  368. Single expression with no symbol given. In this case, all free *symbols*
  369. will be selected as potential *symbols* to solve for. If the equation is
  370. univariate then a list of solutions is returned; otherwise - as is the case
  371. when *symbols* are given as an iterable of length greater than 1 - a list of
  372. mappings will be returned:
  373. >>> solve(x - 3)
  374. [3]
  375. >>> solve(x**2 - y**2)
  376. [{x: -y}, {x: y}]
  377. >>> solve(z**2*x**2 - z**2*y**2)
  378. [{x: -y}, {x: y}, {z: 0}]
  379. >>> solve(z**2*x - z**2*y**2)
  380. [{x: y**2}, {z: 0}]
  381. When an object other than a Symbol is given as a symbol, it is
  382. isolated algebraically and an implicit solution may be obtained.
  383. This is mostly provided as a convenience to save you from replacing
  384. the object with a Symbol and solving for that Symbol. It will only
  385. work if the specified object can be replaced with a Symbol using the
  386. subs method:
  387. >>> solve(f(x) - x, f(x))
  388. [x]
  389. >>> solve(f(x).diff(x) - f(x) - x, f(x).diff(x))
  390. [x + f(x)]
  391. >>> solve(f(x).diff(x) - f(x) - x, f(x))
  392. [-x + Derivative(f(x), x)]
  393. >>> solve(x + exp(x)**2, exp(x), set=True)
  394. ([exp(x)], {(-sqrt(-x),), (sqrt(-x),)})
  395. >>> from sympy import Indexed, IndexedBase, Tuple, sqrt
  396. >>> A = IndexedBase('A')
  397. >>> eqs = Tuple(A[1] + A[2] - 3, A[1] - A[2] + 1)
  398. >>> solve(eqs, eqs.atoms(Indexed))
  399. {A[1]: 1, A[2]: 2}
  400. * To solve for a symbol implicitly, use implicit=True:
  401. >>> solve(x + exp(x), x)
  402. [-LambertW(1)]
  403. >>> solve(x + exp(x), x, implicit=True)
  404. [-exp(x)]
  405. * It is possible to solve for anything that can be targeted with
  406. subs:
  407. >>> solve(x + 2 + sqrt(3), x + 2)
  408. [-sqrt(3)]
  409. >>> solve((x + 2 + sqrt(3), x + 4 + y), y, x + 2)
  410. {y: -2 + sqrt(3), x + 2: -sqrt(3)}
  411. * Nothing heroic is done in this implicit solving so you may end up
  412. with a symbol still in the solution:
  413. >>> eqs = (x*y + 3*y + sqrt(3), x + 4 + y)
  414. >>> solve(eqs, y, x + 2)
  415. {y: -sqrt(3)/(x + 3), x + 2: -2*x/(x + 3) - 6/(x + 3) + sqrt(3)/(x + 3)}
  416. >>> solve(eqs, y*x, x)
  417. {x: -y - 4, x*y: -3*y - sqrt(3)}
  418. * If you attempt to solve for a number remember that the number
  419. you have obtained does not necessarily mean that the value is
  420. equivalent to the expression obtained:
  421. >>> solve(sqrt(2) - 1, 1)
  422. [sqrt(2)]
  423. >>> solve(x - y + 1, 1) # /!\ -1 is targeted, too
  424. [x/(y - 1)]
  425. >>> [_.subs(z, -1) for _ in solve((x - y + 1).subs(-1, z), 1)]
  426. [-x + y]
  427. * To solve for a function within a derivative, use ``dsolve``.
  428. Single expression and more than one symbol:
  429. * When there is a linear solution:
  430. >>> solve(x - y**2, x, y)
  431. [(y**2, y)]
  432. >>> solve(x**2 - y, x, y)
  433. [(x, x**2)]
  434. >>> solve(x**2 - y, x, y, dict=True)
  435. [{y: x**2}]
  436. * When undetermined coefficients are identified:
  437. * That are linear:
  438. >>> solve((a + b)*x - b + 2, a, b)
  439. {a: -2, b: 2}
  440. * That are nonlinear:
  441. >>> solve((a + b)*x - b**2 + 2, a, b, set=True)
  442. ([a, b], {(-sqrt(2), sqrt(2)), (sqrt(2), -sqrt(2))})
  443. * If there is no linear solution, then the first successful
  444. attempt for a nonlinear solution will be returned:
  445. >>> solve(x**2 - y**2, x, y, dict=True)
  446. [{x: -y}, {x: y}]
  447. >>> solve(x**2 - y**2/exp(x), x, y, dict=True)
  448. [{x: 2*LambertW(-y/2)}, {x: 2*LambertW(y/2)}]
  449. >>> solve(x**2 - y**2/exp(x), y, x)
  450. [(-x*sqrt(exp(x)), x), (x*sqrt(exp(x)), x)]
  451. Iterable of one or more of the above:
  452. * Involving relationals or bools:
  453. >>> solve([x < 3, x - 2])
  454. Eq(x, 2)
  455. >>> solve([x > 3, x - 2])
  456. False
  457. * When the system is linear:
  458. * With a solution:
  459. >>> solve([x - 3], x)
  460. {x: 3}
  461. >>> solve((x + 5*y - 2, -3*x + 6*y - 15), x, y)
  462. {x: -3, y: 1}
  463. >>> solve((x + 5*y - 2, -3*x + 6*y - 15), x, y, z)
  464. {x: -3, y: 1}
  465. >>> solve((x + 5*y - 2, -3*x + 6*y - z), z, x, y)
  466. {x: 2 - 5*y, z: 21*y - 6}
  467. * Without a solution:
  468. >>> solve([x + 3, x - 3])
  469. []
  470. * When the system is not linear:
  471. >>> solve([x**2 + y -2, y**2 - 4], x, y, set=True)
  472. ([x, y], {(-2, -2), (0, 2), (2, -2)})
  473. * If no *symbols* are given, all free *symbols* will be selected and a
  474. list of mappings returned:
  475. >>> solve([x - 2, x**2 + y])
  476. [{x: 2, y: -4}]
  477. >>> solve([x - 2, x**2 + f(x)], {f(x), x})
  478. [{x: 2, f(x): -4}]
  479. * If any equation does not depend on the symbol(s) given, it will be
  480. eliminated from the equation set and an answer may be given
  481. implicitly in terms of variables that were not of interest:
  482. >>> solve([x - y, y - 3], x)
  483. {x: y}
  484. **Additional Examples**
  485. ``solve()`` with check=True (default) will run through the symbol tags to
  486. elimate unwanted solutions. If no assumptions are included, all possible
  487. solutions will be returned:
  488. >>> from sympy import Symbol, solve
  489. >>> x = Symbol("x")
  490. >>> solve(x**2 - 1)
  491. [-1, 1]
  492. By using the positive tag, only one solution will be returned:
  493. >>> pos = Symbol("pos", positive=True)
  494. >>> solve(pos**2 - 1)
  495. [1]
  496. Assumptions are not checked when ``solve()`` input involves
  497. relationals or bools.
  498. When the solutions are checked, those that make any denominator zero
  499. are automatically excluded. If you do not want to exclude such solutions,
  500. then use the check=False option:
  501. >>> from sympy import sin, limit
  502. >>> solve(sin(x)/x) # 0 is excluded
  503. [pi]
  504. If check=False, then a solution to the numerator being zero is found: x = 0.
  505. In this case, this is a spurious solution since $\sin(x)/x$ has the well
  506. known limit (without dicontinuity) of 1 at x = 0:
  507. >>> solve(sin(x)/x, check=False)
  508. [0, pi]
  509. In the following case, however, the limit exists and is equal to the
  510. value of x = 0 that is excluded when check=True:
  511. >>> eq = x**2*(1/x - z**2/x)
  512. >>> solve(eq, x)
  513. []
  514. >>> solve(eq, x, check=False)
  515. [0]
  516. >>> limit(eq, x, 0, '-')
  517. 0
  518. >>> limit(eq, x, 0, '+')
  519. 0
  520. **Disabling High-Order Explicit Solutions**
  521. When solving polynomial expressions, you might not want explicit solutions
  522. (which can be quite long). If the expression is univariate, ``CRootOf``
  523. instances will be returned instead:
  524. >>> solve(x**3 - x + 1)
  525. [-1/((-1/2 - sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)) -
  526. (-1/2 - sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)/3,
  527. -(-1/2 + sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)/3 -
  528. 1/((-1/2 + sqrt(3)*I/2)*(3*sqrt(69)/2 + 27/2)**(1/3)),
  529. -(3*sqrt(69)/2 + 27/2)**(1/3)/3 -
  530. 1/(3*sqrt(69)/2 + 27/2)**(1/3)]
  531. >>> solve(x**3 - x + 1, cubics=False)
  532. [CRootOf(x**3 - x + 1, 0),
  533. CRootOf(x**3 - x + 1, 1),
  534. CRootOf(x**3 - x + 1, 2)]
  535. If the expression is multivariate, no solution might be returned:
  536. >>> solve(x**3 - x + a, x, cubics=False)
  537. []
  538. Sometimes solutions will be obtained even when a flag is False because the
  539. expression could be factored. In the following example, the equation can
  540. be factored as the product of a linear and a quadratic factor so explicit
  541. solutions (which did not require solving a cubic expression) are obtained:
  542. >>> eq = x**3 + 3*x**2 + x - 1
  543. >>> solve(eq, cubics=False)
  544. [-1, -1 + sqrt(2), -sqrt(2) - 1]
  545. **Solving Equations Involving Radicals**
  546. Because of SymPy's use of the principle root, some solutions
  547. to radical equations will be missed unless check=False:
  548. >>> from sympy import root
  549. >>> eq = root(x**3 - 3*x**2, 3) + 1 - x
  550. >>> solve(eq)
  551. []
  552. >>> solve(eq, check=False)
  553. [1/3]
  554. In the above example, there is only a single solution to the
  555. equation. Other expressions will yield spurious roots which
  556. must be checked manually; roots which give a negative argument
  557. to odd-powered radicals will also need special checking:
  558. >>> from sympy import real_root, S
  559. >>> eq = root(x, 3) - root(x, 5) + S(1)/7
  560. >>> solve(eq) # this gives 2 solutions but misses a 3rd
  561. [CRootOf(7*x**5 - 7*x**3 + 1, 1)**15,
  562. CRootOf(7*x**5 - 7*x**3 + 1, 2)**15]
  563. >>> sol = solve(eq, check=False)
  564. >>> [abs(eq.subs(x,i).n(2)) for i in sol]
  565. [0.48, 0.e-110, 0.e-110, 0.052, 0.052]
  566. The first solution is negative so ``real_root`` must be used to see that it
  567. satisfies the expression:
  568. >>> abs(real_root(eq.subs(x, sol[0])).n(2))
  569. 0.e-110
  570. If the roots of the equation are not real then more care will be
  571. necessary to find the roots, especially for higher order equations.
  572. Consider the following expression:
  573. >>> expr = root(x, 3) - root(x, 5)
  574. We will construct a known value for this expression at x = 3 by selecting
  575. the 1-th root for each radical:
  576. >>> expr1 = root(x, 3, 1) - root(x, 5, 1)
  577. >>> v = expr1.subs(x, -3)
  578. The ``solve`` function is unable to find any exact roots to this equation:
  579. >>> eq = Eq(expr, v); eq1 = Eq(expr1, v)
  580. >>> solve(eq, check=False), solve(eq1, check=False)
  581. ([], [])
  582. The function ``unrad``, however, can be used to get a form of the equation
  583. for which numerical roots can be found:
  584. >>> from sympy.solvers.solvers import unrad
  585. >>> from sympy import nroots
  586. >>> e, (p, cov) = unrad(eq)
  587. >>> pvals = nroots(e)
  588. >>> inversion = solve(cov, x)[0]
  589. >>> xvals = [inversion.subs(p, i) for i in pvals]
  590. Although ``eq`` or ``eq1`` could have been used to find ``xvals``, the
  591. solution can only be verified with ``expr1``:
  592. >>> z = expr - v
  593. >>> [xi.n(chop=1e-9) for xi in xvals if abs(z.subs(x, xi).n()) < 1e-9]
  594. []
  595. >>> z1 = expr1 - v
  596. >>> [xi.n(chop=1e-9) for xi in xvals if abs(z1.subs(x, xi).n()) < 1e-9]
  597. [-3.0]
  598. Parameters
  599. ==========
  600. f :
  601. - a single Expr or Poly that must be zero
  602. - an Equality
  603. - a Relational expression
  604. - a Boolean
  605. - iterable of one or more of the above
  606. symbols : (object(s) to solve for) specified as
  607. - none given (other non-numeric objects will be used)
  608. - single symbol
  609. - denested list of symbols
  610. (e.g., ``solve(f, x, y)``)
  611. - ordered iterable of symbols
  612. (e.g., ``solve(f, [x, y])``)
  613. flags :
  614. dict=True (default is False)
  615. Return list (perhaps empty) of solution mappings.
  616. set=True (default is False)
  617. Return list of symbols and set of tuple(s) of solution(s).
  618. exclude=[] (default)
  619. Do not try to solve for any of the free symbols in exclude;
  620. if expressions are given, the free symbols in them will
  621. be extracted automatically.
  622. check=True (default)
  623. If False, do not do any testing of solutions. This can be
  624. useful if you want to include solutions that make any
  625. denominator zero.
  626. numerical=True (default)
  627. Do a fast numerical check if *f* has only one symbol.
  628. minimal=True (default is False)
  629. A very fast, minimal testing.
  630. warn=True (default is False)
  631. Show a warning if ``checksol()`` could not conclude.
  632. simplify=True (default)
  633. Simplify all but polynomials of order 3 or greater before
  634. returning them and (if check is not False) use the
  635. general simplify function on the solutions and the
  636. expression obtained when they are substituted into the
  637. function which should be zero.
  638. force=True (default is False)
  639. Make positive all symbols without assumptions regarding sign.
  640. rational=True (default)
  641. Recast Floats as Rational; if this option is not used, the
  642. system containing Floats may fail to solve because of issues
  643. with polys. If rational=None, Floats will be recast as
  644. rationals but the answer will be recast as Floats. If the
  645. flag is False then nothing will be done to the Floats.
  646. manual=True (default is False)
  647. Do not use the polys/matrix method to solve a system of
  648. equations, solve them one at a time as you might "manually."
  649. implicit=True (default is False)
  650. Allows ``solve`` to return a solution for a pattern in terms of
  651. other functions that contain that pattern; this is only
  652. needed if the pattern is inside of some invertible function
  653. like cos, exp, ect.
  654. particular=True (default is False)
  655. Instructs ``solve`` to try to find a particular solution to a linear
  656. system with as many zeros as possible; this is very expensive.
  657. quick=True (default is False)
  658. When using particular=True, use a fast heuristic to find a
  659. solution with many zeros (instead of using the very slow method
  660. guaranteed to find the largest number of zeros possible).
  661. cubics=True (default)
  662. Return explicit solutions when cubic expressions are encountered.
  663. When False, quartics and quintics are disabled, too.
  664. quartics=True (default)
  665. Return explicit solutions when quartic expressions are encountered.
  666. When False, quintics are disabled, too.
  667. quintics=True (default)
  668. Return explicit solutions (if possible) when quintic expressions
  669. are encountered.
  670. See Also
  671. ========
  672. rsolve: For solving recurrence relationships
  673. dsolve: For solving differential equations
  674. """
  675. from .inequalities import reduce_inequalities
  676. # set solver types explicitly; as soon as one is False
  677. # all the rest will be False
  678. ###########################################################################
  679. hints = ('cubics', 'quartics', 'quintics')
  680. default = True
  681. for k in hints:
  682. default = flags.setdefault(k, bool(flags.get(k, default)))
  683. # keeping track of how f was passed since if it is a list
  684. # a dictionary of results will be returned.
  685. ###########################################################################
  686. def _sympified_list(w):
  687. return list(map(sympify, w if iterable(w) else [w]))
  688. bare_f = not iterable(f)
  689. ordered_symbols = (symbols and
  690. symbols[0] and
  691. (isinstance(symbols[0], Symbol) or
  692. is_sequence(symbols[0],
  693. include=GeneratorType)
  694. )
  695. )
  696. f, symbols = (_sympified_list(w) for w in [f, symbols])
  697. if isinstance(f, list):
  698. f = [s for s in f if s is not S.true and s is not True]
  699. implicit = flags.get('implicit', False)
  700. # preprocess symbol(s)
  701. ###########################################################################
  702. if not symbols:
  703. # get symbols from equations
  704. symbols = set().union(*[fi.free_symbols for fi in f])
  705. if len(symbols) < len(f):
  706. for fi in f:
  707. pot = preorder_traversal(fi)
  708. for p in pot:
  709. if isinstance(p, AppliedUndef):
  710. flags['dict'] = True # better show symbols
  711. symbols.add(p)
  712. pot.skip() # don't go any deeper
  713. symbols = list(symbols)
  714. ordered_symbols = False
  715. elif len(symbols) == 1 and iterable(symbols[0]):
  716. symbols = symbols[0]
  717. # remove symbols the user is not interested in
  718. exclude = flags.pop('exclude', set())
  719. if exclude:
  720. if isinstance(exclude, Expr):
  721. exclude = [exclude]
  722. exclude = set().union(*[e.free_symbols for e in sympify(exclude)])
  723. symbols = [s for s in symbols if s not in exclude]
  724. # preprocess equation(s)
  725. ###########################################################################
  726. for i, fi in enumerate(f):
  727. if isinstance(fi, (Eq, Ne)):
  728. if 'ImmutableDenseMatrix' in [type(a).__name__ for a in fi.args]:
  729. fi = fi.lhs - fi.rhs
  730. else:
  731. L, R = fi.args
  732. if isinstance(R, BooleanAtom):
  733. L, R = R, L
  734. if isinstance(L, BooleanAtom):
  735. if isinstance(fi, Ne):
  736. L = ~L
  737. if R.is_Relational:
  738. fi = ~R if L is S.false else R
  739. elif R.is_Symbol:
  740. return L
  741. elif R.is_Boolean and (~R).is_Symbol:
  742. return ~L
  743. else:
  744. raise NotImplementedError(filldedent('''
  745. Unanticipated argument of Eq when other arg
  746. is True or False.
  747. '''))
  748. else:
  749. fi = fi.rewrite(Add, evaluate=False)
  750. f[i] = fi
  751. if fi.is_Relational:
  752. return reduce_inequalities(f, symbols=symbols)
  753. if isinstance(fi, Poly):
  754. f[i] = fi.as_expr()
  755. # rewrite hyperbolics in terms of exp
  756. f[i] = f[i].replace(lambda w: isinstance(w, HyperbolicFunction) and \
  757. (len(w.free_symbols & set(symbols)) > 0), lambda w: w.rewrite(exp))
  758. # if we have a Matrix, we need to iterate over its elements again
  759. if f[i].is_Matrix:
  760. bare_f = False
  761. f.extend(list(f[i]))
  762. f[i] = S.Zero
  763. # if we can split it into real and imaginary parts then do so
  764. freei = f[i].free_symbols
  765. if freei and all(s.is_extended_real or s.is_imaginary for s in freei):
  766. fr, fi = f[i].as_real_imag()
  767. # accept as long as new re, im, arg or atan2 are not introduced
  768. had = f[i].atoms(re, im, arg, atan2)
  769. if fr and fi and fr != fi and not any(
  770. i.atoms(re, im, arg, atan2) - had for i in (fr, fi)):
  771. if bare_f:
  772. bare_f = False
  773. f[i: i + 1] = [fr, fi]
  774. # real/imag handling -----------------------------
  775. if any(isinstance(fi, (bool, BooleanAtom)) for fi in f):
  776. if flags.get('set', False):
  777. return [], set()
  778. return []
  779. for i, fi in enumerate(f):
  780. # Abs
  781. while True:
  782. was = fi
  783. fi = fi.replace(Abs, lambda arg:
  784. separatevars(Abs(arg)).rewrite(Piecewise) if arg.has(*symbols)
  785. else Abs(arg))
  786. if was == fi:
  787. break
  788. for e in fi.find(Abs):
  789. if e.has(*symbols):
  790. raise NotImplementedError('solving %s when the argument '
  791. 'is not real or imaginary.' % e)
  792. # arg
  793. fi = fi.replace(arg, lambda a: arg(a).rewrite(atan2).rewrite(atan))
  794. # save changes
  795. f[i] = fi
  796. # see if re(s) or im(s) appear
  797. freim = [fi for fi in f if fi.has(re, im)]
  798. if freim:
  799. irf = []
  800. for s in symbols:
  801. if s.is_real or s.is_imaginary:
  802. continue # neither re(x) nor im(x) will appear
  803. # if re(s) or im(s) appear, the auxiliary equation must be present
  804. if any(fi.has(re(s), im(s)) for fi in freim):
  805. irf.append((s, re(s) + S.ImaginaryUnit*im(s)))
  806. if irf:
  807. for s, rhs in irf:
  808. for i, fi in enumerate(f):
  809. f[i] = fi.xreplace({s: rhs})
  810. f.append(s - rhs)
  811. symbols.extend([re(s), im(s)])
  812. if bare_f:
  813. bare_f = False
  814. flags['dict'] = True
  815. # end of real/imag handling -----------------------------
  816. symbols = list(uniq(symbols))
  817. if not ordered_symbols:
  818. # we do this to make the results returned canonical in case f
  819. # contains a system of nonlinear equations; all other cases should
  820. # be unambiguous
  821. symbols = sorted(symbols, key=default_sort_key)
  822. # we can solve for non-symbol entities by replacing them with Dummy symbols
  823. f, symbols, swap_sym = recast_to_symbols(f, symbols)
  824. # this is needed in the next two events
  825. symset = set(symbols)
  826. # get rid of equations that have no symbols of interest; we don't
  827. # try to solve them because the user didn't ask and they might be
  828. # hard to solve; this means that solutions may be given in terms
  829. # of the eliminated equations e.g. solve((x-y, y-3), x) -> {x: y}
  830. newf = []
  831. for fi in f:
  832. # let the solver handle equations that..
  833. # - have no symbols but are expressions
  834. # - have symbols of interest
  835. # - have no symbols of interest but are constant
  836. # but when an expression is not constant and has no symbols of
  837. # interest, it can't change what we obtain for a solution from
  838. # the remaining equations so we don't include it; and if it's
  839. # zero it can be removed and if it's not zero, there is no
  840. # solution for the equation set as a whole
  841. #
  842. # The reason for doing this filtering is to allow an answer
  843. # to be obtained to queries like solve((x - y, y), x); without
  844. # this mod the return value is []
  845. ok = False
  846. if fi.free_symbols & symset:
  847. ok = True
  848. else:
  849. if fi.is_number:
  850. if fi.is_Number:
  851. if fi.is_zero:
  852. continue
  853. return []
  854. ok = True
  855. else:
  856. if fi.is_constant():
  857. ok = True
  858. if ok:
  859. newf.append(fi)
  860. if not newf:
  861. return []
  862. f = newf
  863. del newf
  864. # mask off any Object that we aren't going to invert: Derivative,
  865. # Integral, etc... so that solving for anything that they contain will
  866. # give an implicit solution
  867. seen = set()
  868. non_inverts = set()
  869. for fi in f:
  870. pot = preorder_traversal(fi)
  871. for p in pot:
  872. if not isinstance(p, Expr) or isinstance(p, Piecewise):
  873. pass
  874. elif (isinstance(p, bool) or
  875. not p.args or
  876. p in symset or
  877. p.is_Add or p.is_Mul or
  878. p.is_Pow and not implicit or
  879. p.is_Function and not implicit) and p.func not in (re, im):
  880. continue
  881. elif p not in seen:
  882. seen.add(p)
  883. if p.free_symbols & symset:
  884. non_inverts.add(p)
  885. else:
  886. continue
  887. pot.skip()
  888. del seen
  889. non_inverts = dict(list(zip(non_inverts, [Dummy() for _ in non_inverts])))
  890. f = [fi.subs(non_inverts) for fi in f]
  891. # Both xreplace and subs are needed below: xreplace to force substitution
  892. # inside Derivative, subs to handle non-straightforward substitutions
  893. non_inverts = [(v, k.xreplace(swap_sym).subs(swap_sym)) for k, v in non_inverts.items()]
  894. # rationalize Floats
  895. floats = False
  896. if flags.get('rational', True) is not False:
  897. for i, fi in enumerate(f):
  898. if fi.has(Float):
  899. floats = True
  900. f[i] = nsimplify(fi, rational=True)
  901. # capture any denominators before rewriting since
  902. # they may disappear after the rewrite, e.g. issue 14779
  903. flags['_denominators'] = _simple_dens(f[0], symbols)
  904. # Any embedded piecewise functions need to be brought out to the
  905. # top level so that the appropriate strategy gets selected.
  906. # However, this is necessary only if one of the piecewise
  907. # functions depends on one of the symbols we are solving for.
  908. def _has_piecewise(e):
  909. if e.is_Piecewise:
  910. return e.has(*symbols)
  911. return any(_has_piecewise(a) for a in e.args)
  912. for i, fi in enumerate(f):
  913. if _has_piecewise(fi):
  914. f[i] = piecewise_fold(fi)
  915. #
  916. # try to get a solution
  917. ###########################################################################
  918. if bare_f:
  919. solution = _solve(f[0], *symbols, **flags)
  920. else:
  921. solution = _solve_system(f, symbols, **flags)
  922. #
  923. # postprocessing
  924. ###########################################################################
  925. # Restore masked-off objects
  926. if non_inverts:
  927. def _do_dict(solution):
  928. return {k: v.subs(non_inverts) for k, v in
  929. solution.items()}
  930. for i in range(1):
  931. if isinstance(solution, dict):
  932. solution = _do_dict(solution)
  933. break
  934. elif solution and isinstance(solution, list):
  935. if isinstance(solution[0], dict):
  936. solution = [_do_dict(s) for s in solution]
  937. break
  938. elif isinstance(solution[0], tuple):
  939. solution = [tuple([v.subs(non_inverts) for v in s]) for s
  940. in solution]
  941. break
  942. else:
  943. solution = [v.subs(non_inverts) for v in solution]
  944. break
  945. elif not solution:
  946. break
  947. else:
  948. raise NotImplementedError(filldedent('''
  949. no handling of %s was implemented''' % solution))
  950. # Restore original "symbols" if a dictionary is returned.
  951. # This is not necessary for
  952. # - the single univariate equation case
  953. # since the symbol will have been removed from the solution;
  954. # - the nonlinear poly_system since that only supports zero-dimensional
  955. # systems and those results come back as a list
  956. #
  957. # ** unless there were Derivatives with the symbols, but those were handled
  958. # above.
  959. if swap_sym:
  960. symbols = [swap_sym.get(k, k) for k in symbols]
  961. if isinstance(solution, dict):
  962. solution = {swap_sym.get(k, k): v.subs(swap_sym)
  963. for k, v in solution.items()}
  964. elif solution and isinstance(solution, list) and isinstance(solution[0], dict):
  965. for i, sol in enumerate(solution):
  966. solution[i] = {swap_sym.get(k, k): v.subs(swap_sym)
  967. for k, v in sol.items()}
  968. # undo the dictionary solutions returned when the system was only partially
  969. # solved with poly-system if all symbols are present
  970. if (
  971. not flags.get('dict', False) and
  972. solution and
  973. ordered_symbols and
  974. not isinstance(solution, dict) and
  975. all(isinstance(sol, dict) for sol in solution)
  976. ):
  977. solution = [tuple([r.get(s, s) for s in symbols]) for r in solution]
  978. # Get assumptions about symbols, to filter solutions.
  979. # Note that if assumptions about a solution can't be verified, it is still
  980. # returned.
  981. check = flags.get('check', True)
  982. # restore floats
  983. if floats and solution and flags.get('rational', None) is None:
  984. solution = nfloat(solution, exponent=False)
  985. if check and solution: # assumption checking
  986. warn = flags.get('warn', False)
  987. got_None = [] # solutions for which one or more symbols gave None
  988. no_False = [] # solutions for which no symbols gave False
  989. if isinstance(solution, tuple):
  990. # this has already been checked and is in as_set form
  991. return solution
  992. elif isinstance(solution, list):
  993. if isinstance(solution[0], tuple):
  994. for sol in solution:
  995. for symb, val in zip(symbols, sol):
  996. test = check_assumptions(val, **symb.assumptions0)
  997. if test is False:
  998. break
  999. if test is None:
  1000. got_None.append(sol)
  1001. else:
  1002. no_False.append(sol)
  1003. elif isinstance(solution[0], dict):
  1004. for sol in solution:
  1005. a_None = False
  1006. for symb, val in sol.items():
  1007. test = check_assumptions(val, **symb.assumptions0)
  1008. if test:
  1009. continue
  1010. if test is False:
  1011. break
  1012. a_None = True
  1013. else:
  1014. no_False.append(sol)
  1015. if a_None:
  1016. got_None.append(sol)
  1017. else: # list of expressions
  1018. for sol in solution:
  1019. test = check_assumptions(sol, **symbols[0].assumptions0)
  1020. if test is False:
  1021. continue
  1022. no_False.append(sol)
  1023. if test is None:
  1024. got_None.append(sol)
  1025. elif isinstance(solution, dict):
  1026. a_None = False
  1027. for symb, val in solution.items():
  1028. test = check_assumptions(val, **symb.assumptions0)
  1029. if test:
  1030. continue
  1031. if test is False:
  1032. no_False = None
  1033. break
  1034. a_None = True
  1035. else:
  1036. no_False = solution
  1037. if a_None:
  1038. got_None.append(solution)
  1039. elif isinstance(solution, (Relational, And, Or)):
  1040. if len(symbols) != 1:
  1041. raise ValueError("Length should be 1")
  1042. if warn and symbols[0].assumptions0:
  1043. warnings.warn(filldedent("""
  1044. \tWarning: assumptions about variable '%s' are
  1045. not handled currently.""" % symbols[0]))
  1046. # TODO: check also variable assumptions for inequalities
  1047. else:
  1048. raise TypeError('Unrecognized solution') # improve the checker
  1049. solution = no_False
  1050. if warn and got_None:
  1051. warnings.warn(filldedent("""
  1052. \tWarning: assumptions concerning following solution(s)
  1053. cannot be checked:""" + '\n\t' +
  1054. ', '.join(str(s) for s in got_None)))
  1055. #
  1056. # done
  1057. ###########################################################################
  1058. as_dict = flags.get('dict', False)
  1059. as_set = flags.get('set', False)
  1060. if not as_set and isinstance(solution, list):
  1061. # Make sure that a list of solutions is ordered in a canonical way.
  1062. solution.sort(key=default_sort_key)
  1063. if not as_dict and not as_set:
  1064. return solution or []
  1065. # return a list of mappings or []
  1066. if not solution:
  1067. solution = []
  1068. else:
  1069. if isinstance(solution, dict):
  1070. solution = [solution]
  1071. elif iterable(solution[0]):
  1072. solution = [dict(list(zip(symbols, s))) for s in solution]
  1073. elif isinstance(solution[0], dict):
  1074. pass
  1075. else:
  1076. if len(symbols) != 1:
  1077. raise ValueError("Length should be 1")
  1078. solution = [{symbols[0]: s} for s in solution]
  1079. if as_dict:
  1080. return solution
  1081. assert as_set
  1082. if not solution:
  1083. return [], set()
  1084. k = list(ordered(solution[0].keys()))
  1085. return k, {tuple([s[ki] for ki in k]) for s in solution}
  1086. def _solve(f, *symbols, **flags):
  1087. """
  1088. Return a checked solution for *f* in terms of one or more of the
  1089. symbols. A list should be returned except for the case when a linear
  1090. undetermined-coefficients equation is encountered (in which case
  1091. a dictionary is returned).
  1092. If no method is implemented to solve the equation, a NotImplementedError
  1093. will be raised. In the case that conversion of an expression to a Poly
  1094. gives None a ValueError will be raised.
  1095. """
  1096. not_impl_msg = "No algorithms are implemented to solve equation %s"
  1097. if len(symbols) != 1:
  1098. soln = None
  1099. free = f.free_symbols
  1100. ex = free - set(symbols)
  1101. if len(ex) != 1:
  1102. ind, dep = f.as_independent(*symbols)
  1103. ex = ind.free_symbols & dep.free_symbols
  1104. if len(ex) == 1:
  1105. ex = ex.pop()
  1106. try:
  1107. # soln may come back as dict, list of dicts or tuples, or
  1108. # tuple of symbol list and set of solution tuples
  1109. soln = solve_undetermined_coeffs(f, symbols, ex, **flags)
  1110. except NotImplementedError:
  1111. pass
  1112. if soln:
  1113. if flags.get('simplify', True):
  1114. if isinstance(soln, dict):
  1115. for k in soln:
  1116. soln[k] = simplify(soln[k])
  1117. elif isinstance(soln, list):
  1118. if isinstance(soln[0], dict):
  1119. for d in soln:
  1120. for k in d:
  1121. d[k] = simplify(d[k])
  1122. elif isinstance(soln[0], tuple):
  1123. soln = [tuple(simplify(i) for i in j) for j in soln]
  1124. else:
  1125. raise TypeError('unrecognized args in list')
  1126. elif isinstance(soln, tuple):
  1127. sym, sols = soln
  1128. soln = sym, {tuple(simplify(i) for i in j) for j in sols}
  1129. else:
  1130. raise TypeError('unrecognized solution type')
  1131. return soln
  1132. # find first successful solution
  1133. failed = []
  1134. got_s = set()
  1135. result = []
  1136. for s in symbols:
  1137. xi, v = solve_linear(f, symbols=[s])
  1138. if xi == s:
  1139. # no need to check but we should simplify if desired
  1140. if flags.get('simplify', True):
  1141. v = simplify(v)
  1142. vfree = v.free_symbols
  1143. if got_s and any(ss in vfree for ss in got_s):
  1144. # sol depends on previously solved symbols: discard it
  1145. continue
  1146. got_s.add(xi)
  1147. result.append({xi: v})
  1148. elif xi: # there might be a non-linear solution if xi is not 0
  1149. failed.append(s)
  1150. if not failed:
  1151. return result
  1152. for s in failed:
  1153. try:
  1154. soln = _solve(f, s, **flags)
  1155. for sol in soln:
  1156. if got_s and any(ss in sol.free_symbols for ss in got_s):
  1157. # sol depends on previously solved symbols: discard it
  1158. continue
  1159. got_s.add(s)
  1160. result.append({s: sol})
  1161. except NotImplementedError:
  1162. continue
  1163. if got_s:
  1164. return result
  1165. else:
  1166. raise NotImplementedError(not_impl_msg % f)
  1167. symbol = symbols[0]
  1168. #expand binomials only if it has the unknown symbol
  1169. f = f.replace(lambda e: isinstance(e, binomial) and e.has(symbol),
  1170. lambda e: expand_func(e))
  1171. # /!\ capture this flag then set it to False so that no checking in
  1172. # recursive calls will be done; only the final answer is checked
  1173. flags['check'] = checkdens = check = flags.pop('check', True)
  1174. # build up solutions if f is a Mul
  1175. if f.is_Mul:
  1176. result = set()
  1177. for m in f.args:
  1178. if m in {S.NegativeInfinity, S.ComplexInfinity, S.Infinity}:
  1179. result = set()
  1180. break
  1181. soln = _solve(m, symbol, **flags)
  1182. result.update(set(soln))
  1183. result = list(result)
  1184. if check:
  1185. # all solutions have been checked but now we must
  1186. # check that the solutions do not set denominators
  1187. # in any factor to zero
  1188. dens = flags.get('_denominators', _simple_dens(f, symbols))
  1189. result = [s for s in result if
  1190. not any(checksol(den, {symbol: s}, **flags) for den in
  1191. dens)]
  1192. # set flags for quick exit at end; solutions for each
  1193. # factor were already checked and simplified
  1194. check = False
  1195. flags['simplify'] = False
  1196. elif f.is_Piecewise:
  1197. result = set()
  1198. for i, (expr, cond) in enumerate(f.args):
  1199. if expr.is_zero:
  1200. raise NotImplementedError(
  1201. 'solve cannot represent interval solutions')
  1202. candidates = _solve(expr, symbol, **flags)
  1203. # the explicit condition for this expr is the current cond
  1204. # and none of the previous conditions
  1205. args = [~c for _, c in f.args[:i]] + [cond]
  1206. cond = And(*args)
  1207. for candidate in candidates:
  1208. if candidate in result:
  1209. # an unconditional value was already there
  1210. continue
  1211. try:
  1212. v = cond.subs(symbol, candidate)
  1213. _eval_simplify = getattr(v, '_eval_simplify', None)
  1214. if _eval_simplify is not None:
  1215. # unconditionally take the simpification of v
  1216. v = _eval_simplify(ratio=2, measure=lambda x: 1)
  1217. except TypeError:
  1218. # incompatible type with condition(s)
  1219. continue
  1220. if v == False:
  1221. continue
  1222. if v == True:
  1223. result.add(candidate)
  1224. else:
  1225. result.add(Piecewise(
  1226. (candidate, v),
  1227. (S.NaN, True)))
  1228. # set flags for quick exit at end; solutions for each
  1229. # piece were already checked and simplified
  1230. check = False
  1231. flags['simplify'] = False
  1232. else:
  1233. # first see if it really depends on symbol and whether there
  1234. # is only a linear solution
  1235. f_num, sol = solve_linear(f, symbols=symbols)
  1236. if f_num.is_zero or sol is S.NaN:
  1237. return []
  1238. elif f_num.is_Symbol:
  1239. # no need to check but simplify if desired
  1240. if flags.get('simplify', True):
  1241. sol = simplify(sol)
  1242. return [sol]
  1243. poly = None
  1244. # check for a single Add generator
  1245. if not f_num.is_Add:
  1246. add_args = [i for i in f_num.atoms(Add)
  1247. if symbol in i.free_symbols]
  1248. if len(add_args) == 1:
  1249. gen = add_args[0]
  1250. spart = gen.as_independent(symbol)[1].as_base_exp()[0]
  1251. if spart == symbol:
  1252. try:
  1253. poly = Poly(f_num, spart)
  1254. except PolynomialError:
  1255. pass
  1256. result = False # no solution was obtained
  1257. msg = '' # there is no failure message
  1258. # Poly is generally robust enough to convert anything to
  1259. # a polynomial and tell us the different generators that it
  1260. # contains, so we will inspect the generators identified by
  1261. # polys to figure out what to do.
  1262. # try to identify a single generator that will allow us to solve this
  1263. # as a polynomial, followed (perhaps) by a change of variables if the
  1264. # generator is not a symbol
  1265. try:
  1266. if poly is None:
  1267. poly = Poly(f_num)
  1268. if poly is None:
  1269. raise ValueError('could not convert %s to Poly' % f_num)
  1270. except GeneratorsNeeded:
  1271. simplified_f = simplify(f_num)
  1272. if simplified_f != f_num:
  1273. return _solve(simplified_f, symbol, **flags)
  1274. raise ValueError('expression appears to be a constant')
  1275. gens = [g for g in poly.gens if g.has(symbol)]
  1276. def _as_base_q(x):
  1277. """Return (b**e, q) for x = b**(p*e/q) where p/q is the leading
  1278. Rational of the exponent of x, e.g. exp(-2*x/3) -> (exp(x), 3)
  1279. """
  1280. b, e = x.as_base_exp()
  1281. if e.is_Rational:
  1282. return b, e.q
  1283. if not e.is_Mul:
  1284. return x, 1
  1285. c, ee = e.as_coeff_Mul()
  1286. if c.is_Rational and c is not S.One: # c could be a Float
  1287. return b**ee, c.q
  1288. return x, 1
  1289. if len(gens) > 1:
  1290. # If there is more than one generator, it could be that the
  1291. # generators have the same base but different powers, e.g.
  1292. # >>> Poly(exp(x) + 1/exp(x))
  1293. # Poly(exp(-x) + exp(x), exp(-x), exp(x), domain='ZZ')
  1294. #
  1295. # If unrad was not disabled then there should be no rational
  1296. # exponents appearing as in
  1297. # >>> Poly(sqrt(x) + sqrt(sqrt(x)))
  1298. # Poly(sqrt(x) + x**(1/4), sqrt(x), x**(1/4), domain='ZZ')
  1299. bases, qs = list(zip(*[_as_base_q(g) for g in gens]))
  1300. bases = set(bases)
  1301. if len(bases) > 1 or not all(q == 1 for q in qs):
  1302. funcs = {b for b in bases if b.is_Function}
  1303. trig = {_ for _ in funcs if
  1304. isinstance(_, TrigonometricFunction)}
  1305. other = funcs - trig
  1306. if not other and len(funcs.intersection(trig)) > 1:
  1307. newf = None
  1308. if f_num.is_Add and len(f_num.args) == 2:
  1309. # check for sin(x)**p = cos(x)**p
  1310. _args = f_num.args
  1311. t = a, b = [i.atoms(Function).intersection(
  1312. trig) for i in _args]
  1313. if all(len(i) == 1 for i in t):
  1314. a, b = [i.pop() for i in t]
  1315. if isinstance(a, cos):
  1316. a, b = b, a
  1317. _args = _args[::-1]
  1318. if isinstance(a, sin) and isinstance(b, cos
  1319. ) and a.args[0] == b.args[0]:
  1320. # sin(x) + cos(x) = 0 -> tan(x) + 1 = 0
  1321. newf, _d = (TR2i(_args[0]/_args[1]) + 1
  1322. ).as_numer_denom()
  1323. if not _d.is_Number:
  1324. newf = None
  1325. if newf is None:
  1326. newf = TR1(f_num).rewrite(tan)
  1327. if newf != f_num:
  1328. # don't check the rewritten form --check
  1329. # solutions in the un-rewritten form below
  1330. flags['check'] = False
  1331. result = _solve(newf, symbol, **flags)
  1332. flags['check'] = check
  1333. # just a simple case - see if replacement of single function
  1334. # clears all symbol-dependent functions, e.g.
  1335. # log(x) - log(log(x) - 1) - 3 can be solved even though it has
  1336. # two generators.
  1337. if result is False and funcs:
  1338. funcs = list(ordered(funcs)) # put shallowest function first
  1339. f1 = funcs[0]
  1340. t = Dummy('t')
  1341. # perform the substitution
  1342. ftry = f_num.subs(f1, t)
  1343. # if no Functions left, we can proceed with usual solve
  1344. if not ftry.has(symbol):
  1345. cv_sols = _solve(ftry, t, **flags)
  1346. cv_inv = _solve(t - f1, symbol, **flags)[0]
  1347. sols = list()
  1348. for sol in cv_sols:
  1349. sols.append(cv_inv.subs(t, sol))
  1350. result = list(ordered(sols))
  1351. if result is False:
  1352. msg = 'multiple generators %s' % gens
  1353. else:
  1354. # e.g. case where gens are exp(x), exp(-x)
  1355. u = bases.pop()
  1356. t = Dummy('t')
  1357. inv = _solve(u - t, symbol, **flags)
  1358. if isinstance(u, (Pow, exp)):
  1359. # this will be resolved by factor in _tsolve but we might
  1360. # as well try a simple expansion here to get things in
  1361. # order so something like the following will work now without
  1362. # having to factor:
  1363. #
  1364. # >>> eq = (exp(I*(-x-2))+exp(I*(x+2)))
  1365. # >>> eq.subs(exp(x),y) # fails
  1366. # exp(I*(-x - 2)) + exp(I*(x + 2))
  1367. # >>> eq.expand().subs(exp(x),y) # works
  1368. # y**I*exp(2*I) + y**(-I)*exp(-2*I)
  1369. def _expand(p):
  1370. b, e = p.as_base_exp()
  1371. e = expand_mul(e)
  1372. return expand_power_exp(b**e)
  1373. ftry = f_num.replace(
  1374. lambda w: w.is_Pow or isinstance(w, exp),
  1375. _expand).subs(u, t)
  1376. if not ftry.has(symbol):
  1377. soln = _solve(ftry, t, **flags)
  1378. sols = list()
  1379. for sol in soln:
  1380. for i in inv:
  1381. sols.append(i.subs(t, sol))
  1382. result = list(ordered(sols))
  1383. elif len(gens) == 1:
  1384. # There is only one generator that we are interested in, but
  1385. # there may have been more than one generator identified by
  1386. # polys (e.g. for symbols other than the one we are interested
  1387. # in) so recast the poly in terms of our generator of interest.
  1388. # Also use composite=True with f_num since Poly won't update
  1389. # poly as documented in issue 8810.
  1390. poly = Poly(f_num, gens[0], composite=True)
  1391. # if we aren't on the tsolve-pass, use roots
  1392. if not flags.pop('tsolve', False):
  1393. soln = None
  1394. deg = poly.degree()
  1395. flags['tsolve'] = True
  1396. hints = ('cubics', 'quartics', 'quintics')
  1397. solvers = {h: flags.get(h) for h in hints}
  1398. soln = roots(poly, **solvers)
  1399. if sum(soln.values()) < deg:
  1400. # e.g. roots(32*x**5 + 400*x**4 + 2032*x**3 +
  1401. # 5000*x**2 + 6250*x + 3189) -> {}
  1402. # so all_roots is used and RootOf instances are
  1403. # returned *unless* the system is multivariate
  1404. # or high-order EX domain.
  1405. try:
  1406. soln = poly.all_roots()
  1407. except NotImplementedError:
  1408. if not flags.get('incomplete', True):
  1409. raise NotImplementedError(
  1410. filldedent('''
  1411. Neither high-order multivariate polynomials
  1412. nor sorting of EX-domain polynomials is supported.
  1413. If you want to see any results, pass keyword incomplete=True to
  1414. solve; to see numerical values of roots
  1415. for univariate expressions, use nroots.
  1416. '''))
  1417. else:
  1418. pass
  1419. else:
  1420. soln = list(soln.keys())
  1421. if soln is not None:
  1422. u = poly.gen
  1423. if u != symbol:
  1424. try:
  1425. t = Dummy('t')
  1426. iv = _solve(u - t, symbol, **flags)
  1427. soln = list(ordered({i.subs(t, s) for i in iv for s in soln}))
  1428. except NotImplementedError:
  1429. # perhaps _tsolve can handle f_num
  1430. soln = None
  1431. else:
  1432. check = False # only dens need to be checked
  1433. if soln is not None:
  1434. if len(soln) > 2:
  1435. # if the flag wasn't set then unset it since high-order
  1436. # results are quite long. Perhaps one could base this
  1437. # decision on a certain critical length of the
  1438. # roots. In addition, wester test M2 has an expression
  1439. # whose roots can be shown to be real with the
  1440. # unsimplified form of the solution whereas only one of
  1441. # the simplified forms appears to be real.
  1442. flags['simplify'] = flags.get('simplify', False)
  1443. result = soln
  1444. # fallback if above fails
  1445. # -----------------------
  1446. if result is False:
  1447. # try unrad
  1448. if flags.pop('_unrad', True):
  1449. try:
  1450. u = unrad(f_num, symbol)
  1451. except (ValueError, NotImplementedError):
  1452. u = False
  1453. if u:
  1454. eq, cov = u
  1455. if cov:
  1456. isym, ieq = cov
  1457. inv = _solve(ieq, symbol, **flags)[0]
  1458. rv = {inv.subs(isym, xi) for xi in _solve(eq, isym, **flags)}
  1459. else:
  1460. try:
  1461. rv = set(_solve(eq, symbol, **flags))
  1462. except NotImplementedError:
  1463. rv = None
  1464. if rv is not None:
  1465. result = list(ordered(rv))
  1466. # if the flag wasn't set then unset it since unrad results
  1467. # can be quite long or of very high order
  1468. flags['simplify'] = flags.get('simplify', False)
  1469. else:
  1470. pass # for coverage
  1471. # try _tsolve
  1472. if result is False:
  1473. flags.pop('tsolve', None) # allow tsolve to be used on next pass
  1474. try:
  1475. soln = _tsolve(f_num, symbol, **flags)
  1476. if soln is not None:
  1477. result = soln
  1478. except PolynomialError:
  1479. pass
  1480. # ----------- end of fallback ----------------------------
  1481. if result is False:
  1482. raise NotImplementedError('\n'.join([msg, not_impl_msg % f]))
  1483. if flags.get('simplify', True):
  1484. result = list(map(simplify, result))
  1485. # we just simplified the solution so we now set the flag to
  1486. # False so the simplification doesn't happen again in checksol()
  1487. flags['simplify'] = False
  1488. if checkdens:
  1489. # reject any result that makes any denom. affirmatively 0;
  1490. # if in doubt, keep it
  1491. dens = _simple_dens(f, symbols)
  1492. result = [s for s in result if
  1493. not any(checksol(d, {symbol: s}, **flags)
  1494. for d in dens)]
  1495. if check:
  1496. # keep only results if the check is not False
  1497. result = [r for r in result if
  1498. checksol(f_num, {symbol: r}, **flags) is not False]
  1499. return result
  1500. def _solve_system(exprs, symbols, **flags):
  1501. if not exprs:
  1502. return []
  1503. if flags.pop('_split', True):
  1504. # Split the system into connected components
  1505. V = exprs
  1506. symsset = set(symbols)
  1507. exprsyms = {e: e.free_symbols & symsset for e in exprs}
  1508. E = []
  1509. sym_indices = {sym: i for i, sym in enumerate(symbols)}
  1510. for n, e1 in enumerate(exprs):
  1511. for e2 in exprs[:n]:
  1512. # Equations are connected if they share a symbol
  1513. if exprsyms[e1] & exprsyms[e2]:
  1514. E.append((e1, e2))
  1515. G = V, E
  1516. subexprs = connected_components(G)
  1517. if len(subexprs) > 1:
  1518. subsols = []
  1519. for subexpr in subexprs:
  1520. subsyms = set()
  1521. for e in subexpr:
  1522. subsyms |= exprsyms[e]
  1523. subsyms = list(sorted(subsyms, key = lambda x: sym_indices[x]))
  1524. flags['_split'] = False # skip split step
  1525. subsol = _solve_system(subexpr, subsyms, **flags)
  1526. if not isinstance(subsol, list):
  1527. subsol = [subsol]
  1528. subsols.append(subsol)
  1529. # Full solution is cartesion product of subsystems
  1530. sols = []
  1531. for soldicts in product(*subsols):
  1532. sols.append(dict(item for sd in soldicts
  1533. for item in sd.items()))
  1534. # Return a list with one dict as just the dict
  1535. if len(sols) == 1:
  1536. return sols[0]
  1537. return sols
  1538. polys = []
  1539. dens = set()
  1540. failed = []
  1541. result = False
  1542. linear = False
  1543. manual = flags.get('manual', False)
  1544. checkdens = check = flags.get('check', True)
  1545. for j, g in enumerate(exprs):
  1546. dens.update(_simple_dens(g, symbols))
  1547. i, d = _invert(g, *symbols)
  1548. g = d - i
  1549. g = g.as_numer_denom()[0]
  1550. if manual:
  1551. failed.append(g)
  1552. continue
  1553. poly = g.as_poly(*symbols, extension=True)
  1554. if poly is not None:
  1555. polys.append(poly)
  1556. else:
  1557. failed.append(g)
  1558. if not polys:
  1559. solved_syms = []
  1560. else:
  1561. if all(p.is_linear for p in polys):
  1562. n, m = len(polys), len(symbols)
  1563. matrix = zeros(n, m + 1)
  1564. for i, poly in enumerate(polys):
  1565. for monom, coeff in poly.terms():
  1566. try:
  1567. j = monom.index(1)
  1568. matrix[i, j] = coeff
  1569. except ValueError:
  1570. matrix[i, m] = -coeff
  1571. # returns a dictionary ({symbols: values}) or None
  1572. if flags.pop('particular', False):
  1573. result = minsolve_linear_system(matrix, *symbols, **flags)
  1574. else:
  1575. result = solve_linear_system(matrix, *symbols, **flags)
  1576. if failed:
  1577. if result:
  1578. solved_syms = list(result.keys())
  1579. else:
  1580. solved_syms = []
  1581. else:
  1582. linear = True
  1583. else:
  1584. if len(symbols) > len(polys):
  1585. free = set().union(*[p.free_symbols for p in polys])
  1586. free = list(ordered(free.intersection(symbols)))
  1587. got_s = set()
  1588. result = []
  1589. for syms in subsets(free, len(polys)):
  1590. try:
  1591. # returns [] or list of tuples of solutions for syms
  1592. res = solve_poly_system(polys, *syms)
  1593. if res:
  1594. for r in res:
  1595. skip = False
  1596. for r1 in r:
  1597. if got_s and any(ss in r1.free_symbols
  1598. for ss in got_s):
  1599. # sol depends on previously
  1600. # solved symbols: discard it
  1601. skip = True
  1602. if not skip:
  1603. got_s.update(syms)
  1604. result.extend([dict(list(zip(syms, r)))])
  1605. except NotImplementedError:
  1606. pass
  1607. if got_s:
  1608. solved_syms = list(got_s)
  1609. else:
  1610. raise NotImplementedError('no valid subset found')
  1611. else:
  1612. try:
  1613. result = solve_poly_system(polys, *symbols)
  1614. if result:
  1615. solved_syms = symbols
  1616. # we don't know here if the symbols provided
  1617. # were given or not, so let solve resolve that.
  1618. # A list of dictionaries is going to always be
  1619. # returned from here.
  1620. result = [dict(list(zip(solved_syms, r))) for r in result]
  1621. except NotImplementedError:
  1622. failed.extend([g.as_expr() for g in polys])
  1623. solved_syms = []
  1624. result = None
  1625. if result:
  1626. if isinstance(result, dict):
  1627. result = [result]
  1628. else:
  1629. result = [{}]
  1630. if failed:
  1631. # For each failed equation, see if we can solve for one of the
  1632. # remaining symbols from that equation. If so, we update the
  1633. # solution set and continue with the next failed equation,
  1634. # repeating until we are done or we get an equation that can't
  1635. # be solved.
  1636. def _ok_syms(e, sort=False):
  1637. rv = (e.free_symbols - solved_syms) & legal
  1638. # Solve first for symbols that have lower degree in the equation.
  1639. # Ideally we want to solve firstly for symbols that appear linearly
  1640. # with rational coefficients e.g. if e = x*y + z then we should
  1641. # solve for z first.
  1642. def key(sym):
  1643. ep = e.as_poly(sym)
  1644. if ep is None:
  1645. complexity = (S.Infinity, S.Infinity, S.Infinity)
  1646. else:
  1647. coeff_syms = ep.LC().free_symbols
  1648. complexity = (ep.degree(), len(coeff_syms & rv), len(coeff_syms))
  1649. return complexity + (default_sort_key(sym),)
  1650. if sort:
  1651. rv = sorted(rv, key=key)
  1652. return rv
  1653. solved_syms = set(solved_syms) # set of symbols we have solved for
  1654. legal = set(symbols) # what we are interested in
  1655. # sort so equation with the fewest potential symbols is first
  1656. u = Dummy() # used in solution checking
  1657. for eq in ordered(failed, lambda _: len(_ok_syms(_))):
  1658. newresult = []
  1659. bad_results = []
  1660. got_s = set()
  1661. hit = False
  1662. for r in result:
  1663. # update eq with everything that is known so far
  1664. eq2 = eq.subs(r)
  1665. # if check is True then we see if it satisfies this
  1666. # equation, otherwise we just accept it
  1667. if check and r:
  1668. b = checksol(u, u, eq2, minimal=True)
  1669. if b is not None:
  1670. # this solution is sufficient to know whether
  1671. # it is valid or not so we either accept or
  1672. # reject it, then continue
  1673. if b:
  1674. newresult.append(r)
  1675. else:
  1676. bad_results.append(r)
  1677. continue
  1678. # search for a symbol amongst those available that
  1679. # can be solved for
  1680. ok_syms = _ok_syms(eq2, sort=True)
  1681. if not ok_syms:
  1682. if r:
  1683. newresult.append(r)
  1684. break # skip as it's independent of desired symbols
  1685. for s in ok_syms:
  1686. try:
  1687. soln = _solve(eq2, s, **flags)
  1688. except NotImplementedError:
  1689. continue
  1690. # put each solution in r and append the now-expanded
  1691. # result in the new result list; use copy since the
  1692. # solution for s in being added in-place
  1693. for sol in soln:
  1694. if got_s and any(ss in sol.free_symbols for ss in got_s):
  1695. # sol depends on previously solved symbols: discard it
  1696. continue
  1697. rnew = r.copy()
  1698. for k, v in r.items():
  1699. rnew[k] = v.subs(s, sol)
  1700. # and add this new solution
  1701. rnew[s] = sol
  1702. # check that it is independent of previous solutions
  1703. iset = set(rnew.items())
  1704. for i in newresult:
  1705. if len(i) < len(iset) and not set(i.items()) - iset:
  1706. # this is a superset of a known solution that
  1707. # is smaller
  1708. break
  1709. else:
  1710. # keep it
  1711. newresult.append(rnew)
  1712. hit = True
  1713. got_s.add(s)
  1714. if not hit:
  1715. raise NotImplementedError('could not solve %s' % eq2)
  1716. else:
  1717. result = newresult
  1718. for b in bad_results:
  1719. if b in result:
  1720. result.remove(b)
  1721. default_simplify = bool(failed) # rely on system-solvers to simplify
  1722. if flags.get('simplify', default_simplify):
  1723. for r in result:
  1724. for k in r:
  1725. r[k] = simplify(r[k])
  1726. flags['simplify'] = False # don't need to do so in checksol now
  1727. if checkdens:
  1728. result = [r for r in result
  1729. if not any(checksol(d, r, **flags) for d in dens)]
  1730. if check and not linear:
  1731. result = [r for r in result
  1732. if not any(checksol(e, r, **flags) is False for e in exprs)]
  1733. result = [r for r in result if r]
  1734. if linear and result:
  1735. result = result[0]
  1736. return result
  1737. def solve_linear(lhs, rhs=0, symbols=[], exclude=[]):
  1738. r"""
  1739. Return a tuple derived from ``f = lhs - rhs`` that is one of
  1740. the following: ``(0, 1)``, ``(0, 0)``, ``(symbol, solution)``, ``(n, d)``.
  1741. Explanation
  1742. ===========
  1743. ``(0, 1)`` meaning that ``f`` is independent of the symbols in *symbols*
  1744. that are not in *exclude*.
  1745. ``(0, 0)`` meaning that there is no solution to the equation amongst the
  1746. symbols given. If the first element of the tuple is not zero, then the
  1747. function is guaranteed to be dependent on a symbol in *symbols*.
  1748. ``(symbol, solution)`` where symbol appears linearly in the numerator of
  1749. ``f``, is in *symbols* (if given), and is not in *exclude* (if given). No
  1750. simplification is done to ``f`` other than a ``mul=True`` expansion, so the
  1751. solution will correspond strictly to a unique solution.
  1752. ``(n, d)`` where ``n`` and ``d`` are the numerator and denominator of ``f``
  1753. when the numerator was not linear in any symbol of interest; ``n`` will
  1754. never be a symbol unless a solution for that symbol was found (in which case
  1755. the second element is the solution, not the denominator).
  1756. Examples
  1757. ========
  1758. >>> from sympy import cancel, Pow
  1759. ``f`` is independent of the symbols in *symbols* that are not in
  1760. *exclude*:
  1761. >>> from sympy import cos, sin, solve_linear
  1762. >>> from sympy.abc import x, y, z
  1763. >>> eq = y*cos(x)**2 + y*sin(x)**2 - y # = y*(1 - 1) = 0
  1764. >>> solve_linear(eq)
  1765. (0, 1)
  1766. >>> eq = cos(x)**2 + sin(x)**2 # = 1
  1767. >>> solve_linear(eq)
  1768. (0, 1)
  1769. >>> solve_linear(x, exclude=[x])
  1770. (0, 1)
  1771. The variable ``x`` appears as a linear variable in each of the
  1772. following:
  1773. >>> solve_linear(x + y**2)
  1774. (x, -y**2)
  1775. >>> solve_linear(1/x - y**2)
  1776. (x, y**(-2))
  1777. When not linear in ``x`` or ``y`` then the numerator and denominator are
  1778. returned:
  1779. >>> solve_linear(x**2/y**2 - 3)
  1780. (x**2 - 3*y**2, y**2)
  1781. If the numerator of the expression is a symbol, then ``(0, 0)`` is
  1782. returned if the solution for that symbol would have set any
  1783. denominator to 0:
  1784. >>> eq = 1/(1/x - 2)
  1785. >>> eq.as_numer_denom()
  1786. (x, 1 - 2*x)
  1787. >>> solve_linear(eq)
  1788. (0, 0)
  1789. But automatic rewriting may cause a symbol in the denominator to
  1790. appear in the numerator so a solution will be returned:
  1791. >>> (1/x)**-1
  1792. x
  1793. >>> solve_linear((1/x)**-1)
  1794. (x, 0)
  1795. Use an unevaluated expression to avoid this:
  1796. >>> solve_linear(Pow(1/x, -1, evaluate=False))
  1797. (0, 0)
  1798. If ``x`` is allowed to cancel in the following expression, then it
  1799. appears to be linear in ``x``, but this sort of cancellation is not
  1800. done by ``solve_linear`` so the solution will always satisfy the
  1801. original expression without causing a division by zero error.
  1802. >>> eq = x**2*(1/x - z**2/x)
  1803. >>> solve_linear(cancel(eq))
  1804. (x, 0)
  1805. >>> solve_linear(eq)
  1806. (x**2*(1 - z**2), x)
  1807. A list of symbols for which a solution is desired may be given:
  1808. >>> solve_linear(x + y + z, symbols=[y])
  1809. (y, -x - z)
  1810. A list of symbols to ignore may also be given:
  1811. >>> solve_linear(x + y + z, exclude=[x])
  1812. (y, -x - z)
  1813. (A solution for ``y`` is obtained because it is the first variable
  1814. from the canonically sorted list of symbols that had a linear
  1815. solution.)
  1816. """
  1817. if isinstance(lhs, Eq):
  1818. if rhs:
  1819. raise ValueError(filldedent('''
  1820. If lhs is an Equality, rhs must be 0 but was %s''' % rhs))
  1821. rhs = lhs.rhs
  1822. lhs = lhs.lhs
  1823. dens = None
  1824. eq = lhs - rhs
  1825. n, d = eq.as_numer_denom()
  1826. if not n:
  1827. return S.Zero, S.One
  1828. free = n.free_symbols
  1829. if not symbols:
  1830. symbols = free
  1831. else:
  1832. bad = [s for s in symbols if not s.is_Symbol]
  1833. if bad:
  1834. if len(bad) == 1:
  1835. bad = bad[0]
  1836. if len(symbols) == 1:
  1837. eg = 'solve(%s, %s)' % (eq, symbols[0])
  1838. else:
  1839. eg = 'solve(%s, *%s)' % (eq, list(symbols))
  1840. raise ValueError(filldedent('''
  1841. solve_linear only handles symbols, not %s. To isolate
  1842. non-symbols use solve, e.g. >>> %s <<<.
  1843. ''' % (bad, eg)))
  1844. symbols = free.intersection(symbols)
  1845. symbols = symbols.difference(exclude)
  1846. if not symbols:
  1847. return S.Zero, S.One
  1848. from sympy.integrals.integrals import Integral
  1849. # derivatives are easy to do but tricky to analyze to see if they
  1850. # are going to disallow a linear solution, so for simplicity we
  1851. # just evaluate the ones that have the symbols of interest
  1852. derivs = defaultdict(list)
  1853. for der in n.atoms(Derivative):
  1854. csym = der.free_symbols & symbols
  1855. for c in csym:
  1856. derivs[c].append(der)
  1857. all_zero = True
  1858. for xi in sorted(symbols, key=default_sort_key): # canonical order
  1859. # if there are derivatives in this var, calculate them now
  1860. if isinstance(derivs[xi], list):
  1861. derivs[xi] = {der: der.doit() for der in derivs[xi]}
  1862. newn = n.subs(derivs[xi])
  1863. dnewn_dxi = newn.diff(xi)
  1864. # dnewn_dxi can be nonzero if it survives differentation by any
  1865. # of its free symbols
  1866. free = dnewn_dxi.free_symbols
  1867. if dnewn_dxi and (not free or any(dnewn_dxi.diff(s) for s in free) or free == symbols):
  1868. all_zero = False
  1869. if dnewn_dxi is S.NaN:
  1870. break
  1871. if xi not in dnewn_dxi.free_symbols:
  1872. vi = -1/dnewn_dxi*(newn.subs(xi, 0))
  1873. if dens is None:
  1874. dens = _simple_dens(eq, symbols)
  1875. if not any(checksol(di, {xi: vi}, minimal=True) is True
  1876. for di in dens):
  1877. # simplify any trivial integral
  1878. irep = [(i, i.doit()) for i in vi.atoms(Integral) if
  1879. i.function.is_number]
  1880. # do a slight bit of simplification
  1881. vi = expand_mul(vi.subs(irep))
  1882. return xi, vi
  1883. if all_zero:
  1884. return S.Zero, S.One
  1885. if n.is_Symbol: # no solution for this symbol was found
  1886. return S.Zero, S.Zero
  1887. return n, d
  1888. def minsolve_linear_system(system, *symbols, **flags):
  1889. r"""
  1890. Find a particular solution to a linear system.
  1891. Explanation
  1892. ===========
  1893. In particular, try to find a solution with the minimal possible number
  1894. of non-zero variables using a naive algorithm with exponential complexity.
  1895. If ``quick=True``, a heuristic is used.
  1896. """
  1897. quick = flags.get('quick', False)
  1898. # Check if there are any non-zero solutions at all
  1899. s0 = solve_linear_system(system, *symbols, **flags)
  1900. if not s0 or all(v == 0 for v in s0.values()):
  1901. return s0
  1902. if quick:
  1903. # We just solve the system and try to heuristically find a nice
  1904. # solution.
  1905. s = solve_linear_system(system, *symbols)
  1906. def update(determined, solution):
  1907. delete = []
  1908. for k, v in solution.items():
  1909. solution[k] = v.subs(determined)
  1910. if not solution[k].free_symbols:
  1911. delete.append(k)
  1912. determined[k] = solution[k]
  1913. for k in delete:
  1914. del solution[k]
  1915. determined = {}
  1916. update(determined, s)
  1917. while s:
  1918. # NOTE sort by default_sort_key to get deterministic result
  1919. k = max((k for k in s.values()),
  1920. key=lambda x: (len(x.free_symbols), default_sort_key(x)))
  1921. x = max(k.free_symbols, key=default_sort_key)
  1922. if len(k.free_symbols) != 1:
  1923. determined[x] = S.Zero
  1924. else:
  1925. val = solve(k)[0]
  1926. if val == 0 and all(v.subs(x, val) == 0 for v in s.values()):
  1927. determined[x] = S.One
  1928. else:
  1929. determined[x] = val
  1930. update(determined, s)
  1931. return determined
  1932. else:
  1933. # We try to select n variables which we want to be non-zero.
  1934. # All others will be assumed zero. We try to solve the modified system.
  1935. # If there is a non-trivial solution, just set the free variables to
  1936. # one. If we do this for increasing n, trying all combinations of
  1937. # variables, we will find an optimal solution.
  1938. # We speed up slightly by starting at one less than the number of
  1939. # variables the quick method manages.
  1940. from itertools import combinations
  1941. N = len(symbols)
  1942. bestsol = minsolve_linear_system(system, *symbols, quick=True)
  1943. n0 = len([x for x in bestsol.values() if x != 0])
  1944. for n in range(n0 - 1, 1, -1):
  1945. debug('minsolve: %s' % n)
  1946. thissol = None
  1947. for nonzeros in combinations(list(range(N)), n):
  1948. subm = Matrix([system.col(i).T for i in nonzeros] + [system.col(-1).T]).T
  1949. s = solve_linear_system(subm, *[symbols[i] for i in nonzeros])
  1950. if s and not all(v == 0 for v in s.values()):
  1951. subs = [(symbols[v], S.One) for v in nonzeros]
  1952. for k, v in s.items():
  1953. s[k] = v.subs(subs)
  1954. for sym in symbols:
  1955. if sym not in s:
  1956. if symbols.index(sym) in nonzeros:
  1957. s[sym] = S.One
  1958. else:
  1959. s[sym] = S.Zero
  1960. thissol = s
  1961. break
  1962. if thissol is None:
  1963. break
  1964. bestsol = thissol
  1965. return bestsol
  1966. def solve_linear_system(system, *symbols, **flags):
  1967. r"""
  1968. Solve system of $N$ linear equations with $M$ variables, which means
  1969. both under- and overdetermined systems are supported.
  1970. Explanation
  1971. ===========
  1972. The possible number of solutions is zero, one, or infinite. Respectively,
  1973. this procedure will return None or a dictionary with solutions. In the
  1974. case of underdetermined systems, all arbitrary parameters are skipped.
  1975. This may cause a situation in which an empty dictionary is returned.
  1976. In that case, all symbols can be assigned arbitrary values.
  1977. Input to this function is a $N\times M + 1$ matrix, which means it has
  1978. to be in augmented form. If you prefer to enter $N$ equations and $M$
  1979. unknowns then use ``solve(Neqs, *Msymbols)`` instead. Note: a local
  1980. copy of the matrix is made by this routine so the matrix that is
  1981. passed will not be modified.
  1982. The algorithm used here is fraction-free Gaussian elimination,
  1983. which results, after elimination, in an upper-triangular matrix.
  1984. Then solutions are found using back-substitution. This approach
  1985. is more efficient and compact than the Gauss-Jordan method.
  1986. Examples
  1987. ========
  1988. >>> from sympy import Matrix, solve_linear_system
  1989. >>> from sympy.abc import x, y
  1990. Solve the following system::
  1991. x + 4 y == 2
  1992. -2 x + y == 14
  1993. >>> system = Matrix(( (1, 4, 2), (-2, 1, 14)))
  1994. >>> solve_linear_system(system, x, y)
  1995. {x: -6, y: 2}
  1996. A degenerate system returns an empty dictionary:
  1997. >>> system = Matrix(( (0,0,0), (0,0,0) ))
  1998. >>> solve_linear_system(system, x, y)
  1999. {}
  2000. """
  2001. assert system.shape[1] == len(symbols) + 1
  2002. # This is just a wrapper for solve_lin_sys
  2003. eqs = list(system * Matrix(symbols + (-1,)))
  2004. eqs, ring = sympy_eqs_to_ring(eqs, symbols)
  2005. sol = solve_lin_sys(eqs, ring, _raw=False)
  2006. if sol is not None:
  2007. sol = {sym:val for sym, val in sol.items() if sym != val}
  2008. return sol
  2009. def solve_undetermined_coeffs(equ, coeffs, sym, **flags):
  2010. r"""
  2011. Solve equation of a type $p(x; a_1, \ldots, a_k) = q(x)$ where both
  2012. $p$ and $q$ are univariate polynomials that depend on $k$ parameters.
  2013. Explanation
  2014. ===========
  2015. The result of this function is a dictionary with symbolic values of those
  2016. parameters with respect to coefficients in $q$.
  2017. This function accepts both equations class instances and ordinary
  2018. SymPy expressions. Specification of parameters and variables is
  2019. obligatory for efficiency and simplicity reasons.
  2020. Examples
  2021. ========
  2022. >>> from sympy import Eq, solve_undetermined_coeffs
  2023. >>> from sympy.abc import a, b, c, x
  2024. >>> solve_undetermined_coeffs(Eq(2*a*x + a+b, x), [a, b], x)
  2025. {a: 1/2, b: -1/2}
  2026. >>> solve_undetermined_coeffs(Eq(a*c*x + a+b, x), [a, b], x)
  2027. {a: 1/c, b: -1/c}
  2028. """
  2029. if isinstance(equ, Eq):
  2030. # got equation, so move all the
  2031. # terms to the left hand side
  2032. equ = equ.lhs - equ.rhs
  2033. equ = cancel(equ).as_numer_denom()[0]
  2034. system = list(collect(equ.expand(), sym, evaluate=False).values())
  2035. if not any(equ.has(sym) for equ in system):
  2036. # consecutive powers in the input expressions have
  2037. # been successfully collected, so solve remaining
  2038. # system using Gaussian elimination algorithm
  2039. return solve(system, *coeffs, **flags)
  2040. else:
  2041. return None # no solutions
  2042. def solve_linear_system_LU(matrix, syms):
  2043. """
  2044. Solves the augmented matrix system using ``LUsolve`` and returns a
  2045. dictionary in which solutions are keyed to the symbols of *syms* as ordered.
  2046. Explanation
  2047. ===========
  2048. The matrix must be invertible.
  2049. Examples
  2050. ========
  2051. >>> from sympy import Matrix, solve_linear_system_LU
  2052. >>> from sympy.abc import x, y, z
  2053. >>> solve_linear_system_LU(Matrix([
  2054. ... [1, 2, 0, 1],
  2055. ... [3, 2, 2, 1],
  2056. ... [2, 0, 0, 1]]), [x, y, z])
  2057. {x: 1/2, y: 1/4, z: -1/2}
  2058. See Also
  2059. ========
  2060. LUsolve
  2061. """
  2062. if matrix.rows != matrix.cols - 1:
  2063. raise ValueError("Rows should be equal to columns - 1")
  2064. A = matrix[:matrix.rows, :matrix.rows]
  2065. b = matrix[:, matrix.cols - 1:]
  2066. soln = A.LUsolve(b)
  2067. solutions = {}
  2068. for i in range(soln.rows):
  2069. solutions[syms[i]] = soln[i, 0]
  2070. return solutions
  2071. def det_perm(M):
  2072. """
  2073. Return the determinant of *M* by using permutations to select factors.
  2074. Explanation
  2075. ===========
  2076. For sizes larger than 8 the number of permutations becomes prohibitively
  2077. large, or if there are no symbols in the matrix, it is better to use the
  2078. standard determinant routines (e.g., ``M.det()``.)
  2079. See Also
  2080. ========
  2081. det_minor
  2082. det_quick
  2083. """
  2084. args = []
  2085. s = True
  2086. n = M.rows
  2087. list_ = M.flat()
  2088. for perm in generate_bell(n):
  2089. fac = []
  2090. idx = 0
  2091. for j in perm:
  2092. fac.append(list_[idx + j])
  2093. idx += n
  2094. term = Mul(*fac) # disaster with unevaluated Mul -- takes forever for n=7
  2095. args.append(term if s else -term)
  2096. s = not s
  2097. return Add(*args)
  2098. def det_minor(M):
  2099. """
  2100. Return the ``det(M)`` computed from minors without
  2101. introducing new nesting in products.
  2102. See Also
  2103. ========
  2104. det_perm
  2105. det_quick
  2106. """
  2107. n = M.rows
  2108. if n == 2:
  2109. return M[0, 0]*M[1, 1] - M[1, 0]*M[0, 1]
  2110. else:
  2111. return sum([(1, -1)[i % 2]*Add(*[M[0, i]*d for d in
  2112. Add.make_args(det_minor(M.minor_submatrix(0, i)))])
  2113. if M[0, i] else S.Zero for i in range(n)])
  2114. def det_quick(M, method=None):
  2115. """
  2116. Return ``det(M)`` assuming that either
  2117. there are lots of zeros or the size of the matrix
  2118. is small. If this assumption is not met, then the normal
  2119. Matrix.det function will be used with method = ``method``.
  2120. See Also
  2121. ========
  2122. det_minor
  2123. det_perm
  2124. """
  2125. if any(i.has(Symbol) for i in M):
  2126. if M.rows < 8 and all(i.has(Symbol) for i in M):
  2127. return det_perm(M)
  2128. return det_minor(M)
  2129. else:
  2130. return M.det(method=method) if method else M.det()
  2131. def inv_quick(M):
  2132. """Return the inverse of ``M``, assuming that either
  2133. there are lots of zeros or the size of the matrix
  2134. is small.
  2135. """
  2136. if not all(i.is_Number for i in M):
  2137. if not any(i.is_Number for i in M):
  2138. det = lambda _: det_perm(_)
  2139. else:
  2140. det = lambda _: det_minor(_)
  2141. else:
  2142. return M.inv()
  2143. n = M.rows
  2144. d = det(M)
  2145. if d == S.Zero:
  2146. raise NonInvertibleMatrixError("Matrix det == 0; not invertible")
  2147. ret = zeros(n)
  2148. s1 = -1
  2149. for i in range(n):
  2150. s = s1 = -s1
  2151. for j in range(n):
  2152. di = det(M.minor_submatrix(i, j))
  2153. ret[j, i] = s*di/d
  2154. s = -s
  2155. return ret
  2156. # these are functions that have multiple inverse values per period
  2157. multi_inverses = {
  2158. sin: lambda x: (asin(x), S.Pi - asin(x)),
  2159. cos: lambda x: (acos(x), 2*S.Pi - acos(x)),
  2160. }
  2161. def _tsolve(eq, sym, **flags):
  2162. """
  2163. Helper for ``_solve`` that solves a transcendental equation with respect
  2164. to the given symbol. Various equations containing powers and logarithms,
  2165. can be solved.
  2166. There is currently no guarantee that all solutions will be returned or
  2167. that a real solution will be favored over a complex one.
  2168. Either a list of potential solutions will be returned or None will be
  2169. returned (in the case that no method was known to get a solution
  2170. for the equation). All other errors (like the inability to cast an
  2171. expression as a Poly) are unhandled.
  2172. Examples
  2173. ========
  2174. >>> from sympy import log
  2175. >>> from sympy.solvers.solvers import _tsolve as tsolve
  2176. >>> from sympy.abc import x
  2177. >>> tsolve(3**(2*x + 5) - 4, x)
  2178. [-5/2 + log(2)/log(3), (-5*log(3)/2 + log(2) + I*pi)/log(3)]
  2179. >>> tsolve(log(x) + 2*x, x)
  2180. [LambertW(2)/2]
  2181. """
  2182. if 'tsolve_saw' not in flags:
  2183. flags['tsolve_saw'] = []
  2184. if eq in flags['tsolve_saw']:
  2185. return None
  2186. else:
  2187. flags['tsolve_saw'].append(eq)
  2188. rhs, lhs = _invert(eq, sym)
  2189. if lhs == sym:
  2190. return [rhs]
  2191. try:
  2192. if lhs.is_Add:
  2193. # it's time to try factoring; powdenest is used
  2194. # to try get powers in standard form for better factoring
  2195. f = factor(powdenest(lhs - rhs))
  2196. if f.is_Mul:
  2197. return _solve(f, sym, **flags)
  2198. if rhs:
  2199. f = logcombine(lhs, force=flags.get('force', True))
  2200. if f.count(log) != lhs.count(log):
  2201. if isinstance(f, log):
  2202. return _solve(f.args[0] - exp(rhs), sym, **flags)
  2203. return _tsolve(f - rhs, sym, **flags)
  2204. elif lhs.is_Pow:
  2205. if lhs.exp.is_Integer:
  2206. if lhs - rhs != eq:
  2207. return _solve(lhs - rhs, sym, **flags)
  2208. if sym not in lhs.exp.free_symbols:
  2209. return _solve(lhs.base - rhs**(1/lhs.exp), sym, **flags)
  2210. # _tsolve calls this with Dummy before passing the actual number in.
  2211. if any(t.is_Dummy for t in rhs.free_symbols):
  2212. raise NotImplementedError # _tsolve will call here again...
  2213. # a ** g(x) == 0
  2214. if not rhs:
  2215. # f(x)**g(x) only has solutions where f(x) == 0 and g(x) != 0 at
  2216. # the same place
  2217. sol_base = _solve(lhs.base, sym, **flags)
  2218. return [s for s in sol_base if lhs.exp.subs(sym, s) != 0]
  2219. # a ** g(x) == b
  2220. if not lhs.base.has(sym):
  2221. if lhs.base == 0:
  2222. return _solve(lhs.exp, sym, **flags) if rhs != 0 else []
  2223. # Gets most solutions...
  2224. if lhs.base == rhs.as_base_exp()[0]:
  2225. # handles case when bases are equal
  2226. sol = _solve(lhs.exp - rhs.as_base_exp()[1], sym, **flags)
  2227. else:
  2228. # handles cases when bases are not equal and exp
  2229. # may or may not be equal
  2230. sol = _solve(exp(log(lhs.base)*lhs.exp)-exp(log(rhs)), sym, **flags)
  2231. # Check for duplicate solutions
  2232. def equal(expr1, expr2):
  2233. _ = Dummy()
  2234. eq = checksol(expr1 - _, _, expr2)
  2235. if eq is None:
  2236. if nsimplify(expr1) != nsimplify(expr2):
  2237. return False
  2238. # they might be coincidentally the same
  2239. # so check more rigorously
  2240. eq = expr1.equals(expr2)
  2241. return eq
  2242. # Guess a rational exponent
  2243. e_rat = nsimplify(log(abs(rhs))/log(abs(lhs.base)))
  2244. e_rat = simplify(posify(e_rat)[0])
  2245. n, d = fraction(e_rat)
  2246. if expand(lhs.base**n - rhs**d) == 0:
  2247. sol = [s for s in sol if not equal(lhs.exp.subs(sym, s), e_rat)]
  2248. sol.extend(_solve(lhs.exp - e_rat, sym, **flags))
  2249. return list(ordered(set(sol)))
  2250. # f(x) ** g(x) == c
  2251. else:
  2252. sol = []
  2253. logform = lhs.exp*log(lhs.base) - log(rhs)
  2254. if logform != lhs - rhs:
  2255. try:
  2256. sol.extend(_solve(logform, sym, **flags))
  2257. except NotImplementedError:
  2258. pass
  2259. # Collect possible solutions and check with substitution later.
  2260. check = []
  2261. if rhs == 1:
  2262. # f(x) ** g(x) = 1 -- g(x)=0 or f(x)=+-1
  2263. check.extend(_solve(lhs.exp, sym, **flags))
  2264. check.extend(_solve(lhs.base - 1, sym, **flags))
  2265. check.extend(_solve(lhs.base + 1, sym, **flags))
  2266. elif rhs.is_Rational:
  2267. for d in (i for i in divisors(abs(rhs.p)) if i != 1):
  2268. e, t = integer_log(rhs.p, d)
  2269. if not t:
  2270. continue # rhs.p != d**b
  2271. for s in divisors(abs(rhs.q)):
  2272. if s**e== rhs.q:
  2273. r = Rational(d, s)
  2274. check.extend(_solve(lhs.base - r, sym, **flags))
  2275. check.extend(_solve(lhs.base + r, sym, **flags))
  2276. check.extend(_solve(lhs.exp - e, sym, **flags))
  2277. elif rhs.is_irrational:
  2278. b_l, e_l = lhs.base.as_base_exp()
  2279. n, d = (e_l*lhs.exp).as_numer_denom()
  2280. b, e = sqrtdenest(rhs).as_base_exp()
  2281. check = [sqrtdenest(i) for i in (_solve(lhs.base - b, sym, **flags))]
  2282. check.extend([sqrtdenest(i) for i in (_solve(lhs.exp - e, sym, **flags))])
  2283. if e_l*d != 1:
  2284. check.extend(_solve(b_l**n - rhs**(e_l*d), sym, **flags))
  2285. for s in check:
  2286. ok = checksol(eq, sym, s)
  2287. if ok is None:
  2288. ok = eq.subs(sym, s).equals(0)
  2289. if ok:
  2290. sol.append(s)
  2291. return list(ordered(set(sol)))
  2292. elif lhs.is_Function and len(lhs.args) == 1:
  2293. if lhs.func in multi_inverses:
  2294. # sin(x) = 1/3 -> x - asin(1/3) & x - (pi - asin(1/3))
  2295. soln = []
  2296. for i in multi_inverses[type(lhs)](rhs):
  2297. soln.extend(_solve(lhs.args[0] - i, sym, **flags))
  2298. return list(ordered(soln))
  2299. elif lhs.func == LambertW:
  2300. return _solve(lhs.args[0] - rhs*exp(rhs), sym, **flags)
  2301. rewrite = lhs.rewrite(exp)
  2302. if rewrite != lhs:
  2303. return _solve(rewrite - rhs, sym, **flags)
  2304. except NotImplementedError:
  2305. pass
  2306. # maybe it is a lambert pattern
  2307. if flags.pop('bivariate', True):
  2308. # lambert forms may need some help being recognized, e.g. changing
  2309. # 2**(3*x) + x**3*log(2)**3 + 3*x**2*log(2)**2 + 3*x*log(2) + 1
  2310. # to 2**(3*x) + (x*log(2) + 1)**3
  2311. g = _filtered_gens(eq.as_poly(), sym)
  2312. up_or_log = set()
  2313. for gi in g:
  2314. if isinstance(gi, (exp, log)) or (gi.is_Pow and gi.base == S.Exp1):
  2315. up_or_log.add(gi)
  2316. elif gi.is_Pow:
  2317. gisimp = powdenest(expand_power_exp(gi))
  2318. if gisimp.is_Pow and sym in gisimp.exp.free_symbols:
  2319. up_or_log.add(gi)
  2320. eq_down = expand_log(expand_power_exp(eq)).subs(
  2321. dict(list(zip(up_or_log, [0]*len(up_or_log)))))
  2322. eq = expand_power_exp(factor(eq_down, deep=True) + (eq - eq_down))
  2323. rhs, lhs = _invert(eq, sym)
  2324. if lhs.has(sym):
  2325. try:
  2326. poly = lhs.as_poly()
  2327. g = _filtered_gens(poly, sym)
  2328. _eq = lhs - rhs
  2329. sols = _solve_lambert(_eq, sym, g)
  2330. # use a simplified form if it satisfies eq
  2331. # and has fewer operations
  2332. for n, s in enumerate(sols):
  2333. ns = nsimplify(s)
  2334. if ns != s and ns.count_ops() <= s.count_ops():
  2335. ok = checksol(_eq, sym, ns)
  2336. if ok is None:
  2337. ok = _eq.subs(sym, ns).equals(0)
  2338. if ok:
  2339. sols[n] = ns
  2340. return sols
  2341. except NotImplementedError:
  2342. # maybe it's a convoluted function
  2343. if len(g) == 2:
  2344. try:
  2345. gpu = bivariate_type(lhs - rhs, *g)
  2346. if gpu is None:
  2347. raise NotImplementedError
  2348. g, p, u = gpu
  2349. flags['bivariate'] = False
  2350. inversion = _tsolve(g - u, sym, **flags)
  2351. if inversion:
  2352. sol = _solve(p, u, **flags)
  2353. return list(ordered({i.subs(u, s)
  2354. for i in inversion for s in sol}))
  2355. except NotImplementedError:
  2356. pass
  2357. else:
  2358. pass
  2359. if flags.pop('force', True):
  2360. flags['force'] = False
  2361. pos, reps = posify(lhs - rhs)
  2362. if rhs == S.ComplexInfinity:
  2363. return []
  2364. for u, s in reps.items():
  2365. if s == sym:
  2366. break
  2367. else:
  2368. u = sym
  2369. if pos.has(u):
  2370. try:
  2371. soln = _solve(pos, u, **flags)
  2372. return list(ordered([s.subs(reps) for s in soln]))
  2373. except NotImplementedError:
  2374. pass
  2375. else:
  2376. pass # here for coverage
  2377. return # here for coverage
  2378. # TODO: option for calculating J numerically
  2379. @conserve_mpmath_dps
  2380. def nsolve(*args, dict=False, **kwargs):
  2381. r"""
  2382. Solve a nonlinear equation system numerically: ``nsolve(f, [args,] x0,
  2383. modules=['mpmath'], **kwargs)``.
  2384. Explanation
  2385. ===========
  2386. ``f`` is a vector function of symbolic expressions representing the system.
  2387. *args* are the variables. If there is only one variable, this argument can
  2388. be omitted. ``x0`` is a starting vector close to a solution.
  2389. Use the modules keyword to specify which modules should be used to
  2390. evaluate the function and the Jacobian matrix. Make sure to use a module
  2391. that supports matrices. For more information on the syntax, please see the
  2392. docstring of ``lambdify``.
  2393. If the keyword arguments contain ``dict=True`` (default is False) ``nsolve``
  2394. will return a list (perhaps empty) of solution mappings. This might be
  2395. especially useful if you want to use ``nsolve`` as a fallback to solve since
  2396. using the dict argument for both methods produces return values of
  2397. consistent type structure. Please note: to keep this consistent with
  2398. ``solve``, the solution will be returned in a list even though ``nsolve``
  2399. (currently at least) only finds one solution at a time.
  2400. Overdetermined systems are supported.
  2401. Examples
  2402. ========
  2403. >>> from sympy import Symbol, nsolve
  2404. >>> import mpmath
  2405. >>> mpmath.mp.dps = 15
  2406. >>> x1 = Symbol('x1')
  2407. >>> x2 = Symbol('x2')
  2408. >>> f1 = 3 * x1**2 - 2 * x2**2 - 1
  2409. >>> f2 = x1**2 - 2 * x1 + x2**2 + 2 * x2 - 8
  2410. >>> print(nsolve((f1, f2), (x1, x2), (-1, 1)))
  2411. Matrix([[-1.19287309935246], [1.27844411169911]])
  2412. For one-dimensional functions the syntax is simplified:
  2413. >>> from sympy import sin, nsolve
  2414. >>> from sympy.abc import x
  2415. >>> nsolve(sin(x), x, 2)
  2416. 3.14159265358979
  2417. >>> nsolve(sin(x), 2)
  2418. 3.14159265358979
  2419. To solve with higher precision than the default, use the prec argument:
  2420. >>> from sympy import cos
  2421. >>> nsolve(cos(x) - x, 1)
  2422. 0.739085133215161
  2423. >>> nsolve(cos(x) - x, 1, prec=50)
  2424. 0.73908513321516064165531208767387340401341175890076
  2425. >>> cos(_)
  2426. 0.73908513321516064165531208767387340401341175890076
  2427. To solve for complex roots of real functions, a nonreal initial point
  2428. must be specified:
  2429. >>> from sympy import I
  2430. >>> nsolve(x**2 + 2, I)
  2431. 1.4142135623731*I
  2432. ``mpmath.findroot`` is used and you can find their more extensive
  2433. documentation, especially concerning keyword parameters and
  2434. available solvers. Note, however, that functions which are very
  2435. steep near the root, the verification of the solution may fail. In
  2436. this case you should use the flag ``verify=False`` and
  2437. independently verify the solution.
  2438. >>> from sympy import cos, cosh
  2439. >>> f = cos(x)*cosh(x) - 1
  2440. >>> nsolve(f, 3.14*100)
  2441. Traceback (most recent call last):
  2442. ...
  2443. ValueError: Could not find root within given tolerance. (1.39267e+230 > 2.1684e-19)
  2444. >>> ans = nsolve(f, 3.14*100, verify=False); ans
  2445. 312.588469032184
  2446. >>> f.subs(x, ans).n(2)
  2447. 2.1e+121
  2448. >>> (f/f.diff(x)).subs(x, ans).n(2)
  2449. 7.4e-15
  2450. One might safely skip the verification if bounds of the root are known
  2451. and a bisection method is used:
  2452. >>> bounds = lambda i: (3.14*i, 3.14*(i + 1))
  2453. >>> nsolve(f, bounds(100), solver='bisect', verify=False)
  2454. 315.730061685774
  2455. Alternatively, a function may be better behaved when the
  2456. denominator is ignored. Since this is not always the case, however,
  2457. the decision of what function to use is left to the discretion of
  2458. the user.
  2459. >>> eq = x**2/(1 - x)/(1 - 2*x)**2 - 100
  2460. >>> nsolve(eq, 0.46)
  2461. Traceback (most recent call last):
  2462. ...
  2463. ValueError: Could not find root within given tolerance. (10000 > 2.1684e-19)
  2464. Try another starting point or tweak arguments.
  2465. >>> nsolve(eq.as_numer_denom()[0], 0.46)
  2466. 0.46792545969349058
  2467. """
  2468. # there are several other SymPy functions that use method= so
  2469. # guard against that here
  2470. if 'method' in kwargs:
  2471. raise ValueError(filldedent('''
  2472. Keyword "method" should not be used in this context. When using
  2473. some mpmath solvers directly, the keyword "method" is
  2474. used, but when using nsolve (and findroot) the keyword to use is
  2475. "solver".'''))
  2476. if 'prec' in kwargs:
  2477. import mpmath
  2478. mpmath.mp.dps = kwargs.pop('prec')
  2479. # keyword argument to return result as a dictionary
  2480. as_dict = dict
  2481. from builtins import dict # to unhide the builtin
  2482. # interpret arguments
  2483. if len(args) == 3:
  2484. f = args[0]
  2485. fargs = args[1]
  2486. x0 = args[2]
  2487. if iterable(fargs) and iterable(x0):
  2488. if len(x0) != len(fargs):
  2489. raise TypeError('nsolve expected exactly %i guess vectors, got %i'
  2490. % (len(fargs), len(x0)))
  2491. elif len(args) == 2:
  2492. f = args[0]
  2493. fargs = None
  2494. x0 = args[1]
  2495. if iterable(f):
  2496. raise TypeError('nsolve expected 3 arguments, got 2')
  2497. elif len(args) < 2:
  2498. raise TypeError('nsolve expected at least 2 arguments, got %i'
  2499. % len(args))
  2500. else:
  2501. raise TypeError('nsolve expected at most 3 arguments, got %i'
  2502. % len(args))
  2503. modules = kwargs.get('modules', ['mpmath'])
  2504. if iterable(f):
  2505. f = list(f)
  2506. for i, fi in enumerate(f):
  2507. if isinstance(fi, Eq):
  2508. f[i] = fi.lhs - fi.rhs
  2509. f = Matrix(f).T
  2510. if iterable(x0):
  2511. x0 = list(x0)
  2512. if not isinstance(f, Matrix):
  2513. # assume it's a SymPy expression
  2514. if isinstance(f, Eq):
  2515. f = f.lhs - f.rhs
  2516. syms = f.free_symbols
  2517. if fargs is None:
  2518. fargs = syms.copy().pop()
  2519. if not (len(syms) == 1 and (fargs in syms or fargs[0] in syms)):
  2520. raise ValueError(filldedent('''
  2521. expected a one-dimensional and numerical function'''))
  2522. # the function is much better behaved if there is no denominator
  2523. # but sending the numerator is left to the user since sometimes
  2524. # the function is better behaved when the denominator is present
  2525. # e.g., issue 11768
  2526. f = lambdify(fargs, f, modules)
  2527. x = sympify(findroot(f, x0, **kwargs))
  2528. if as_dict:
  2529. return [{fargs: x}]
  2530. return x
  2531. if len(fargs) > f.cols:
  2532. raise NotImplementedError(filldedent('''
  2533. need at least as many equations as variables'''))
  2534. verbose = kwargs.get('verbose', False)
  2535. if verbose:
  2536. print('f(x):')
  2537. print(f)
  2538. # derive Jacobian
  2539. J = f.jacobian(fargs)
  2540. if verbose:
  2541. print('J(x):')
  2542. print(J)
  2543. # create functions
  2544. f = lambdify(fargs, f.T, modules)
  2545. J = lambdify(fargs, J, modules)
  2546. # solve the system numerically
  2547. x = findroot(f, x0, J=J, **kwargs)
  2548. if as_dict:
  2549. return [dict(zip(fargs, [sympify(xi) for xi in x]))]
  2550. return Matrix(x)
  2551. def _invert(eq, *symbols, **kwargs):
  2552. """
  2553. Return tuple (i, d) where ``i`` is independent of *symbols* and ``d``
  2554. contains symbols.
  2555. Explanation
  2556. ===========
  2557. ``i`` and ``d`` are obtained after recursively using algebraic inversion
  2558. until an uninvertible ``d`` remains. If there are no free symbols then
  2559. ``d`` will be zero. Some (but not necessarily all) solutions to the
  2560. expression ``i - d`` will be related to the solutions of the original
  2561. expression.
  2562. Examples
  2563. ========
  2564. >>> from sympy.solvers.solvers import _invert as invert
  2565. >>> from sympy import sqrt, cos
  2566. >>> from sympy.abc import x, y
  2567. >>> invert(x - 3)
  2568. (3, x)
  2569. >>> invert(3)
  2570. (3, 0)
  2571. >>> invert(2*cos(x) - 1)
  2572. (1/2, cos(x))
  2573. >>> invert(sqrt(x) - 3)
  2574. (3, sqrt(x))
  2575. >>> invert(sqrt(x) + y, x)
  2576. (-y, sqrt(x))
  2577. >>> invert(sqrt(x) + y, y)
  2578. (-sqrt(x), y)
  2579. >>> invert(sqrt(x) + y, x, y)
  2580. (0, sqrt(x) + y)
  2581. If there is more than one symbol in a power's base and the exponent
  2582. is not an Integer, then the principal root will be used for the
  2583. inversion:
  2584. >>> invert(sqrt(x + y) - 2)
  2585. (4, x + y)
  2586. >>> invert(sqrt(x + y) - 2)
  2587. (4, x + y)
  2588. If the exponent is an Integer, setting ``integer_power`` to True
  2589. will force the principal root to be selected:
  2590. >>> invert(x**2 - 4, integer_power=True)
  2591. (2, x)
  2592. """
  2593. eq = sympify(eq)
  2594. if eq.args:
  2595. # make sure we are working with flat eq
  2596. eq = eq.func(*eq.args)
  2597. free = eq.free_symbols
  2598. if not symbols:
  2599. symbols = free
  2600. if not free & set(symbols):
  2601. return eq, S.Zero
  2602. dointpow = bool(kwargs.get('integer_power', False))
  2603. lhs = eq
  2604. rhs = S.Zero
  2605. while True:
  2606. was = lhs
  2607. while True:
  2608. indep, dep = lhs.as_independent(*symbols)
  2609. # dep + indep == rhs
  2610. if lhs.is_Add:
  2611. # this indicates we have done it all
  2612. if indep.is_zero:
  2613. break
  2614. lhs = dep
  2615. rhs -= indep
  2616. # dep * indep == rhs
  2617. else:
  2618. # this indicates we have done it all
  2619. if indep is S.One:
  2620. break
  2621. lhs = dep
  2622. rhs /= indep
  2623. # collect like-terms in symbols
  2624. if lhs.is_Add:
  2625. terms = {}
  2626. for a in lhs.args:
  2627. i, d = a.as_independent(*symbols)
  2628. terms.setdefault(d, []).append(i)
  2629. if any(len(v) > 1 for v in terms.values()):
  2630. args = []
  2631. for d, i in terms.items():
  2632. if len(i) > 1:
  2633. args.append(Add(*i)*d)
  2634. else:
  2635. args.append(i[0]*d)
  2636. lhs = Add(*args)
  2637. # if it's a two-term Add with rhs = 0 and two powers we can get the
  2638. # dependent terms together, e.g. 3*f(x) + 2*g(x) -> f(x)/g(x) = -2/3
  2639. if lhs.is_Add and not rhs and len(lhs.args) == 2 and \
  2640. not lhs.is_polynomial(*symbols):
  2641. a, b = ordered(lhs.args)
  2642. ai, ad = a.as_independent(*symbols)
  2643. bi, bd = b.as_independent(*symbols)
  2644. if any(_ispow(i) for i in (ad, bd)):
  2645. a_base, a_exp = ad.as_base_exp()
  2646. b_base, b_exp = bd.as_base_exp()
  2647. if a_base == b_base:
  2648. # a = -b
  2649. lhs = powsimp(powdenest(ad/bd))
  2650. rhs = -bi/ai
  2651. else:
  2652. rat = ad/bd
  2653. _lhs = powsimp(ad/bd)
  2654. if _lhs != rat:
  2655. lhs = _lhs
  2656. rhs = -bi/ai
  2657. elif ai == -bi:
  2658. if isinstance(ad, Function) and ad.func == bd.func:
  2659. if len(ad.args) == len(bd.args) == 1:
  2660. lhs = ad.args[0] - bd.args[0]
  2661. elif len(ad.args) == len(bd.args):
  2662. # should be able to solve
  2663. # f(x, y) - f(2 - x, 0) == 0 -> x == 1
  2664. raise NotImplementedError(
  2665. 'equal function with more than 1 argument')
  2666. else:
  2667. raise ValueError(
  2668. 'function with different numbers of args')
  2669. elif lhs.is_Mul and any(_ispow(a) for a in lhs.args):
  2670. lhs = powsimp(powdenest(lhs))
  2671. if lhs.is_Function:
  2672. if hasattr(lhs, 'inverse') and lhs.inverse() is not None and len(lhs.args) == 1:
  2673. # -1
  2674. # f(x) = g -> x = f (g)
  2675. #
  2676. # /!\ inverse should not be defined if there are multiple values
  2677. # for the function -- these are handled in _tsolve
  2678. #
  2679. rhs = lhs.inverse()(rhs)
  2680. lhs = lhs.args[0]
  2681. elif isinstance(lhs, atan2):
  2682. y, x = lhs.args
  2683. lhs = 2*atan(y/(sqrt(x**2 + y**2) + x))
  2684. elif lhs.func == rhs.func:
  2685. if len(lhs.args) == len(rhs.args) == 1:
  2686. lhs = lhs.args[0]
  2687. rhs = rhs.args[0]
  2688. elif len(lhs.args) == len(rhs.args):
  2689. # should be able to solve
  2690. # f(x, y) == f(2, 3) -> x == 2
  2691. # f(x, x + y) == f(2, 3) -> x == 2
  2692. raise NotImplementedError(
  2693. 'equal function with more than 1 argument')
  2694. else:
  2695. raise ValueError(
  2696. 'function with different numbers of args')
  2697. if rhs and lhs.is_Pow and lhs.exp.is_Integer and lhs.exp < 0:
  2698. lhs = 1/lhs
  2699. rhs = 1/rhs
  2700. # base**a = b -> base = b**(1/a) if
  2701. # a is an Integer and dointpow=True (this gives real branch of root)
  2702. # a is not an Integer and the equation is multivariate and the
  2703. # base has more than 1 symbol in it
  2704. # The rationale for this is that right now the multi-system solvers
  2705. # doesn't try to resolve generators to see, for example, if the whole
  2706. # system is written in terms of sqrt(x + y) so it will just fail, so we
  2707. # do that step here.
  2708. if lhs.is_Pow and (
  2709. lhs.exp.is_Integer and dointpow or not lhs.exp.is_Integer and
  2710. len(symbols) > 1 and len(lhs.base.free_symbols & set(symbols)) > 1):
  2711. rhs = rhs**(1/lhs.exp)
  2712. lhs = lhs.base
  2713. if lhs == was:
  2714. break
  2715. return rhs, lhs
  2716. def unrad(eq, *syms, **flags):
  2717. """
  2718. Remove radicals with symbolic arguments and return (eq, cov),
  2719. None, or raise an error.
  2720. Explanation
  2721. ===========
  2722. None is returned if there are no radicals to remove.
  2723. NotImplementedError is raised if there are radicals and they cannot be
  2724. removed or if the relationship between the original symbols and the
  2725. change of variable needed to rewrite the system as a polynomial cannot
  2726. be solved.
  2727. Otherwise the tuple, ``(eq, cov)``, is returned where:
  2728. *eq*, ``cov``
  2729. *eq* is an equation without radicals (in the symbol(s) of
  2730. interest) whose solutions are a superset of the solutions to the
  2731. original expression. *eq* might be rewritten in terms of a new
  2732. variable; the relationship to the original variables is given by
  2733. ``cov`` which is a list containing ``v`` and ``v**p - b`` where
  2734. ``p`` is the power needed to clear the radical and ``b`` is the
  2735. radical now expressed as a polynomial in the symbols of interest.
  2736. For example, for sqrt(2 - x) the tuple would be
  2737. ``(c, c**2 - 2 + x)``. The solutions of *eq* will contain
  2738. solutions to the original equation (if there are any).
  2739. *syms*
  2740. An iterable of symbols which, if provided, will limit the focus of
  2741. radical removal: only radicals with one or more of the symbols of
  2742. interest will be cleared. All free symbols are used if *syms* is not
  2743. set.
  2744. *flags* are used internally for communication during recursive calls.
  2745. Two options are also recognized:
  2746. ``take``, when defined, is interpreted as a single-argument function
  2747. that returns True if a given Pow should be handled.
  2748. Radicals can be removed from an expression if:
  2749. * All bases of the radicals are the same; a change of variables is
  2750. done in this case.
  2751. * If all radicals appear in one term of the expression.
  2752. * There are only four terms with sqrt() factors or there are less than
  2753. four terms having sqrt() factors.
  2754. * There are only two terms with radicals.
  2755. Examples
  2756. ========
  2757. >>> from sympy.solvers.solvers import unrad
  2758. >>> from sympy.abc import x
  2759. >>> from sympy import sqrt, Rational, root
  2760. >>> unrad(sqrt(x)*x**Rational(1, 3) + 2)
  2761. (x**5 - 64, [])
  2762. >>> unrad(sqrt(x) + root(x + 1, 3))
  2763. (-x**3 + x**2 + 2*x + 1, [])
  2764. >>> eq = sqrt(x) + root(x, 3) - 2
  2765. >>> unrad(eq)
  2766. (_p**3 + _p**2 - 2, [_p, _p**6 - x])
  2767. """
  2768. uflags = dict(check=False, simplify=False)
  2769. def _cov(p, e):
  2770. if cov:
  2771. # XXX - uncovered
  2772. oldp, olde = cov
  2773. if Poly(e, p).degree(p) in (1, 2):
  2774. cov[:] = [p, olde.subs(oldp, _solve(e, p, **uflags)[0])]
  2775. else:
  2776. raise NotImplementedError
  2777. else:
  2778. cov[:] = [p, e]
  2779. def _canonical(eq, cov):
  2780. if cov:
  2781. # change symbol to vanilla so no solutions are eliminated
  2782. p, e = cov
  2783. rep = {p: Dummy(p.name)}
  2784. eq = eq.xreplace(rep)
  2785. cov = [p.xreplace(rep), e.xreplace(rep)]
  2786. # remove constants and powers of factors since these don't change
  2787. # the location of the root; XXX should factor or factor_terms be used?
  2788. eq = factor_terms(_mexpand(eq.as_numer_denom()[0], recursive=True), clear=True)
  2789. if eq.is_Mul:
  2790. args = []
  2791. for f in eq.args:
  2792. if f.is_number:
  2793. continue
  2794. if f.is_Pow:
  2795. args.append(f.base)
  2796. else:
  2797. args.append(f)
  2798. eq = Mul(*args) # leave as Mul for more efficient solving
  2799. # make the sign canonical
  2800. margs = list(Mul.make_args(eq))
  2801. changed = False
  2802. for i, m in enumerate(margs):
  2803. if m.could_extract_minus_sign():
  2804. margs[i] = -m
  2805. changed = True
  2806. if changed:
  2807. eq = Mul(*margs, evaluate=False)
  2808. return eq, cov
  2809. def _Q(pow):
  2810. # return leading Rational of denominator of Pow's exponent
  2811. c = pow.as_base_exp()[1].as_coeff_Mul()[0]
  2812. if not c.is_Rational:
  2813. return S.One
  2814. return c.q
  2815. # define the _take method that will determine whether a term is of interest
  2816. def _take(d):
  2817. # return True if coefficient of any factor's exponent's den is not 1
  2818. for pow in Mul.make_args(d):
  2819. if not pow.is_Pow:
  2820. continue
  2821. if _Q(pow) == 1:
  2822. continue
  2823. if pow.free_symbols & syms:
  2824. return True
  2825. return False
  2826. _take = flags.setdefault('_take', _take)
  2827. if isinstance(eq, Eq):
  2828. eq = eq.lhs - eq.rhs # XXX legacy Eq as Eqn support
  2829. elif not isinstance(eq, Expr):
  2830. return
  2831. cov, nwas, rpt = [flags.setdefault(k, v) for k, v in
  2832. sorted(dict(cov=[], n=None, rpt=0).items())]
  2833. # preconditioning
  2834. eq = powdenest(factor_terms(eq, radical=True, clear=True))
  2835. eq = eq.as_numer_denom()[0]
  2836. eq = _mexpand(eq, recursive=True)
  2837. if eq.is_number:
  2838. return
  2839. # see if there are radicals in symbols of interest
  2840. syms = set(syms) or eq.free_symbols # _take uses this
  2841. poly = eq.as_poly()
  2842. gens = [g for g in poly.gens if _take(g)]
  2843. if not gens:
  2844. return
  2845. # recast poly in terms of eigen-gens
  2846. poly = eq.as_poly(*gens)
  2847. # - an exponent has a symbol of interest (don't handle)
  2848. if any(g.exp.has(*syms) for g in gens):
  2849. return
  2850. def _rads_bases_lcm(poly):
  2851. # if all the bases are the same or all the radicals are in one
  2852. # term, `lcm` will be the lcm of the denominators of the
  2853. # exponents of the radicals
  2854. lcm = 1
  2855. rads = set()
  2856. bases = set()
  2857. for g in poly.gens:
  2858. q = _Q(g)
  2859. if q != 1:
  2860. rads.add(g)
  2861. lcm = ilcm(lcm, q)
  2862. bases.add(g.base)
  2863. return rads, bases, lcm
  2864. rads, bases, lcm = _rads_bases_lcm(poly)
  2865. covsym = Dummy('p', nonnegative=True)
  2866. # only keep in syms symbols that actually appear in radicals;
  2867. # and update gens
  2868. newsyms = set()
  2869. for r in rads:
  2870. newsyms.update(syms & r.free_symbols)
  2871. if newsyms != syms:
  2872. syms = newsyms
  2873. # get terms together that have common generators
  2874. drad = dict(list(zip(rads, list(range(len(rads))))))
  2875. rterms = {(): []}
  2876. args = Add.make_args(poly.as_expr())
  2877. for t in args:
  2878. if _take(t):
  2879. common = set(t.as_poly().gens).intersection(rads)
  2880. key = tuple(sorted([drad[i] for i in common]))
  2881. else:
  2882. key = ()
  2883. rterms.setdefault(key, []).append(t)
  2884. others = Add(*rterms.pop(()))
  2885. rterms = [Add(*rterms[k]) for k in rterms.keys()]
  2886. # the output will depend on the order terms are processed, so
  2887. # make it canonical quickly
  2888. rterms = list(reversed(list(ordered(rterms))))
  2889. ok = False # we don't have a solution yet
  2890. depth = sqrt_depth(eq)
  2891. if len(rterms) == 1 and not (rterms[0].is_Add and lcm > 2):
  2892. eq = rterms[0]**lcm - ((-others)**lcm)
  2893. ok = True
  2894. else:
  2895. if len(rterms) == 1 and rterms[0].is_Add:
  2896. rterms = list(rterms[0].args)
  2897. if len(bases) == 1:
  2898. b = bases.pop()
  2899. if len(syms) > 1:
  2900. x = b.free_symbols
  2901. else:
  2902. x = syms
  2903. x = list(ordered(x))[0]
  2904. try:
  2905. inv = _solve(covsym**lcm - b, x, **uflags)
  2906. if not inv:
  2907. raise NotImplementedError
  2908. eq = poly.as_expr().subs(b, covsym**lcm).subs(x, inv[0])
  2909. _cov(covsym, covsym**lcm - b)
  2910. return _canonical(eq, cov)
  2911. except NotImplementedError:
  2912. pass
  2913. if len(rterms) == 2:
  2914. if not others:
  2915. eq = rterms[0]**lcm - (-rterms[1])**lcm
  2916. ok = True
  2917. elif not log(lcm, 2).is_Integer:
  2918. # the lcm-is-power-of-two case is handled below
  2919. r0, r1 = rterms
  2920. if flags.get('_reverse', False):
  2921. r1, r0 = r0, r1
  2922. i0 = _rads0, _bases0, lcm0 = _rads_bases_lcm(r0.as_poly())
  2923. i1 = _rads1, _bases1, lcm1 = _rads_bases_lcm(r1.as_poly())
  2924. for reverse in range(2):
  2925. if reverse:
  2926. i0, i1 = i1, i0
  2927. r0, r1 = r1, r0
  2928. _rads1, _, lcm1 = i1
  2929. _rads1 = Mul(*_rads1)
  2930. t1 = _rads1**lcm1
  2931. c = covsym**lcm1 - t1
  2932. for x in syms:
  2933. try:
  2934. sol = _solve(c, x, **uflags)
  2935. if not sol:
  2936. raise NotImplementedError
  2937. neweq = r0.subs(x, sol[0]) + covsym*r1/_rads1 + \
  2938. others
  2939. tmp = unrad(neweq, covsym)
  2940. if tmp:
  2941. eq, newcov = tmp
  2942. if newcov:
  2943. newp, newc = newcov
  2944. _cov(newp, c.subs(covsym,
  2945. _solve(newc, covsym, **uflags)[0]))
  2946. else:
  2947. _cov(covsym, c)
  2948. else:
  2949. eq = neweq
  2950. _cov(covsym, c)
  2951. ok = True
  2952. break
  2953. except NotImplementedError:
  2954. if reverse:
  2955. raise NotImplementedError(
  2956. 'no successful change of variable found')
  2957. else:
  2958. pass
  2959. if ok:
  2960. break
  2961. elif len(rterms) == 3:
  2962. # two cube roots and another with order less than 5
  2963. # (so an analytical solution can be found) or a base
  2964. # that matches one of the cube root bases
  2965. info = [_rads_bases_lcm(i.as_poly()) for i in rterms]
  2966. RAD = 0
  2967. BASES = 1
  2968. LCM = 2
  2969. if info[0][LCM] != 3:
  2970. info.append(info.pop(0))
  2971. rterms.append(rterms.pop(0))
  2972. elif info[1][LCM] != 3:
  2973. info.append(info.pop(1))
  2974. rterms.append(rterms.pop(1))
  2975. if info[0][LCM] == info[1][LCM] == 3:
  2976. if info[1][BASES] != info[2][BASES]:
  2977. info[0], info[1] = info[1], info[0]
  2978. rterms[0], rterms[1] = rterms[1], rterms[0]
  2979. if info[1][BASES] == info[2][BASES]:
  2980. eq = rterms[0]**3 + (rterms[1] + rterms[2] + others)**3
  2981. ok = True
  2982. elif info[2][LCM] < 5:
  2983. # a*root(A, 3) + b*root(B, 3) + others = c
  2984. a, b, c, d, A, B = [Dummy(i) for i in 'abcdAB']
  2985. # zz represents the unraded expression into which the
  2986. # specifics for this case are substituted
  2987. zz = (c - d)*(A**3*a**9 + 3*A**2*B*a**6*b**3 -
  2988. 3*A**2*a**6*c**3 + 9*A**2*a**6*c**2*d - 9*A**2*a**6*c*d**2 +
  2989. 3*A**2*a**6*d**3 + 3*A*B**2*a**3*b**6 + 21*A*B*a**3*b**3*c**3 -
  2990. 63*A*B*a**3*b**3*c**2*d + 63*A*B*a**3*b**3*c*d**2 -
  2991. 21*A*B*a**3*b**3*d**3 + 3*A*a**3*c**6 - 18*A*a**3*c**5*d +
  2992. 45*A*a**3*c**4*d**2 - 60*A*a**3*c**3*d**3 + 45*A*a**3*c**2*d**4 -
  2993. 18*A*a**3*c*d**5 + 3*A*a**3*d**6 + B**3*b**9 - 3*B**2*b**6*c**3 +
  2994. 9*B**2*b**6*c**2*d - 9*B**2*b**6*c*d**2 + 3*B**2*b**6*d**3 +
  2995. 3*B*b**3*c**6 - 18*B*b**3*c**5*d + 45*B*b**3*c**4*d**2 -
  2996. 60*B*b**3*c**3*d**3 + 45*B*b**3*c**2*d**4 - 18*B*b**3*c*d**5 +
  2997. 3*B*b**3*d**6 - c**9 + 9*c**8*d - 36*c**7*d**2 + 84*c**6*d**3 -
  2998. 126*c**5*d**4 + 126*c**4*d**5 - 84*c**3*d**6 + 36*c**2*d**7 -
  2999. 9*c*d**8 + d**9)
  3000. def _t(i):
  3001. b = Mul(*info[i][RAD])
  3002. return cancel(rterms[i]/b), Mul(*info[i][BASES])
  3003. aa, AA = _t(0)
  3004. bb, BB = _t(1)
  3005. cc = -rterms[2]
  3006. dd = others
  3007. eq = zz.xreplace(dict(zip(
  3008. (a, A, b, B, c, d),
  3009. (aa, AA, bb, BB, cc, dd))))
  3010. ok = True
  3011. # handle power-of-2 cases
  3012. if not ok:
  3013. if log(lcm, 2).is_Integer and (not others and
  3014. len(rterms) == 4 or len(rterms) < 4):
  3015. def _norm2(a, b):
  3016. return a**2 + b**2 + 2*a*b
  3017. if len(rterms) == 4:
  3018. # (r0+r1)**2 - (r2+r3)**2
  3019. r0, r1, r2, r3 = rterms
  3020. eq = _norm2(r0, r1) - _norm2(r2, r3)
  3021. ok = True
  3022. elif len(rterms) == 3:
  3023. # (r1+r2)**2 - (r0+others)**2
  3024. r0, r1, r2 = rterms
  3025. eq = _norm2(r1, r2) - _norm2(r0, others)
  3026. ok = True
  3027. elif len(rterms) == 2:
  3028. # r0**2 - (r1+others)**2
  3029. r0, r1 = rterms
  3030. eq = r0**2 - _norm2(r1, others)
  3031. ok = True
  3032. new_depth = sqrt_depth(eq) if ok else depth
  3033. rpt += 1 # XXX how many repeats with others unchanging is enough?
  3034. if not ok or (
  3035. nwas is not None and len(rterms) == nwas and
  3036. new_depth is not None and new_depth == depth and
  3037. rpt > 3):
  3038. raise NotImplementedError('Cannot remove all radicals')
  3039. flags.update(dict(cov=cov, n=len(rterms), rpt=rpt))
  3040. neq = unrad(eq, *syms, **flags)
  3041. if neq:
  3042. eq, cov = neq
  3043. eq, cov = _canonical(eq, cov)
  3044. return eq, cov
  3045. # Delayed imports
  3046. from sympy.solvers.bivariate import (
  3047. bivariate_type, _solve_lambert, _filtered_gens)