add.py 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287
  1. from typing import Tuple as tTuple
  2. from collections import defaultdict
  3. from functools import cmp_to_key, reduce
  4. from operator import attrgetter
  5. from .basic import Basic
  6. from .parameters import global_parameters
  7. from .logic import _fuzzy_group, fuzzy_or, fuzzy_not
  8. from .singleton import S
  9. from .operations import AssocOp, AssocOpDispatcher
  10. from .cache import cacheit
  11. from .numbers import ilcm, igcd, equal_valued
  12. from .expr import Expr
  13. from .kind import UndefinedKind
  14. from sympy.utilities.iterables import is_sequence, sift
  15. # Key for sorting commutative args in canonical order
  16. _args_sortkey = cmp_to_key(Basic.compare)
  17. def _could_extract_minus_sign(expr):
  18. # assume expr is Add-like
  19. # We choose the one with less arguments with minus signs
  20. negative_args = sum(1 for i in expr.args
  21. if i.could_extract_minus_sign())
  22. positive_args = len(expr.args) - negative_args
  23. if positive_args > negative_args:
  24. return False
  25. elif positive_args < negative_args:
  26. return True
  27. # choose based on .sort_key() to prefer
  28. # x - 1 instead of 1 - x and
  29. # 3 - sqrt(2) instead of -3 + sqrt(2)
  30. return bool(expr.sort_key() < (-expr).sort_key())
  31. def _addsort(args):
  32. # in-place sorting of args
  33. args.sort(key=_args_sortkey)
  34. def _unevaluated_Add(*args):
  35. """Return a well-formed unevaluated Add: Numbers are collected and
  36. put in slot 0 and args are sorted. Use this when args have changed
  37. but you still want to return an unevaluated Add.
  38. Examples
  39. ========
  40. >>> from sympy.core.add import _unevaluated_Add as uAdd
  41. >>> from sympy import S, Add
  42. >>> from sympy.abc import x, y
  43. >>> a = uAdd(*[S(1.0), x, S(2)])
  44. >>> a.args[0]
  45. 3.00000000000000
  46. >>> a.args[1]
  47. x
  48. Beyond the Number being in slot 0, there is no other assurance of
  49. order for the arguments since they are hash sorted. So, for testing
  50. purposes, output produced by this in some other function can only
  51. be tested against the output of this function or as one of several
  52. options:
  53. >>> opts = (Add(x, y, evaluate=False), Add(y, x, evaluate=False))
  54. >>> a = uAdd(x, y)
  55. >>> assert a in opts and a == uAdd(x, y)
  56. >>> uAdd(x + 1, x + 2)
  57. x + x + 3
  58. """
  59. args = list(args)
  60. newargs = []
  61. co = S.Zero
  62. while args:
  63. a = args.pop()
  64. if a.is_Add:
  65. # this will keep nesting from building up
  66. # so that x + (x + 1) -> x + x + 1 (3 args)
  67. args.extend(a.args)
  68. elif a.is_Number:
  69. co += a
  70. else:
  71. newargs.append(a)
  72. _addsort(newargs)
  73. if co:
  74. newargs.insert(0, co)
  75. return Add._from_args(newargs)
  76. class Add(Expr, AssocOp):
  77. """
  78. Expression representing addition operation for algebraic group.
  79. .. deprecated:: 1.7
  80. Using arguments that aren't subclasses of :class:`~.Expr` in core
  81. operators (:class:`~.Mul`, :class:`~.Add`, and :class:`~.Pow`) is
  82. deprecated. See :ref:`non-expr-args-deprecated` for details.
  83. Every argument of ``Add()`` must be ``Expr``. Infix operator ``+``
  84. on most scalar objects in SymPy calls this class.
  85. Another use of ``Add()`` is to represent the structure of abstract
  86. addition so that its arguments can be substituted to return different
  87. class. Refer to examples section for this.
  88. ``Add()`` evaluates the argument unless ``evaluate=False`` is passed.
  89. The evaluation logic includes:
  90. 1. Flattening
  91. ``Add(x, Add(y, z))`` -> ``Add(x, y, z)``
  92. 2. Identity removing
  93. ``Add(x, 0, y)`` -> ``Add(x, y)``
  94. 3. Coefficient collecting by ``.as_coeff_Mul()``
  95. ``Add(x, 2*x)`` -> ``Mul(3, x)``
  96. 4. Term sorting
  97. ``Add(y, x, 2)`` -> ``Add(2, x, y)``
  98. If no argument is passed, identity element 0 is returned. If single
  99. element is passed, that element is returned.
  100. Note that ``Add(*args)`` is more efficient than ``sum(args)`` because
  101. it flattens the arguments. ``sum(a, b, c, ...)`` recursively adds the
  102. arguments as ``a + (b + (c + ...))``, which has quadratic complexity.
  103. On the other hand, ``Add(a, b, c, d)`` does not assume nested
  104. structure, making the complexity linear.
  105. Since addition is group operation, every argument should have the
  106. same :obj:`sympy.core.kind.Kind()`.
  107. Examples
  108. ========
  109. >>> from sympy import Add, I
  110. >>> from sympy.abc import x, y
  111. >>> Add(x, 1)
  112. x + 1
  113. >>> Add(x, x)
  114. 2*x
  115. >>> 2*x**2 + 3*x + I*y + 2*y + 2*x/5 + 1.0*y + 1
  116. 2*x**2 + 17*x/5 + 3.0*y + I*y + 1
  117. If ``evaluate=False`` is passed, result is not evaluated.
  118. >>> Add(1, 2, evaluate=False)
  119. 1 + 2
  120. >>> Add(x, x, evaluate=False)
  121. x + x
  122. ``Add()`` also represents the general structure of addition operation.
  123. >>> from sympy import MatrixSymbol
  124. >>> A,B = MatrixSymbol('A', 2,2), MatrixSymbol('B', 2,2)
  125. >>> expr = Add(x,y).subs({x:A, y:B})
  126. >>> expr
  127. A + B
  128. >>> type(expr)
  129. <class 'sympy.matrices.expressions.matadd.MatAdd'>
  130. Note that the printers do not display in args order.
  131. >>> Add(x, 1)
  132. x + 1
  133. >>> Add(x, 1).args
  134. (1, x)
  135. See Also
  136. ========
  137. MatAdd
  138. """
  139. __slots__ = ()
  140. args: tTuple[Expr, ...]
  141. is_Add = True
  142. _args_type = Expr
  143. @classmethod
  144. def flatten(cls, seq):
  145. """
  146. Takes the sequence "seq" of nested Adds and returns a flatten list.
  147. Returns: (commutative_part, noncommutative_part, order_symbols)
  148. Applies associativity, all terms are commutable with respect to
  149. addition.
  150. NB: the removal of 0 is already handled by AssocOp.__new__
  151. See Also
  152. ========
  153. sympy.core.mul.Mul.flatten
  154. """
  155. from sympy.calculus.accumulationbounds import AccumBounds
  156. from sympy.matrices.expressions import MatrixExpr
  157. from sympy.tensor.tensor import TensExpr
  158. rv = None
  159. if len(seq) == 2:
  160. a, b = seq
  161. if b.is_Rational:
  162. a, b = b, a
  163. if a.is_Rational:
  164. if b.is_Mul:
  165. rv = [a, b], [], None
  166. if rv:
  167. if all(s.is_commutative for s in rv[0]):
  168. return rv
  169. return [], rv[0], None
  170. terms = {} # term -> coeff
  171. # e.g. x**2 -> 5 for ... + 5*x**2 + ...
  172. coeff = S.Zero # coefficient (Number or zoo) to always be in slot 0
  173. # e.g. 3 + ...
  174. order_factors = []
  175. extra = []
  176. for o in seq:
  177. # O(x)
  178. if o.is_Order:
  179. if o.expr.is_zero:
  180. continue
  181. for o1 in order_factors:
  182. if o1.contains(o):
  183. o = None
  184. break
  185. if o is None:
  186. continue
  187. order_factors = [o] + [
  188. o1 for o1 in order_factors if not o.contains(o1)]
  189. continue
  190. # 3 or NaN
  191. elif o.is_Number:
  192. if (o is S.NaN or coeff is S.ComplexInfinity and
  193. o.is_finite is False) and not extra:
  194. # we know for sure the result will be nan
  195. return [S.NaN], [], None
  196. if coeff.is_Number or isinstance(coeff, AccumBounds):
  197. coeff += o
  198. if coeff is S.NaN and not extra:
  199. # we know for sure the result will be nan
  200. return [S.NaN], [], None
  201. continue
  202. elif isinstance(o, AccumBounds):
  203. coeff = o.__add__(coeff)
  204. continue
  205. elif isinstance(o, MatrixExpr):
  206. # can't add 0 to Matrix so make sure coeff is not 0
  207. extra.append(o)
  208. continue
  209. elif isinstance(o, TensExpr):
  210. coeff = o.__add__(coeff) if coeff else o
  211. continue
  212. elif o is S.ComplexInfinity:
  213. if coeff.is_finite is False and not extra:
  214. # we know for sure the result will be nan
  215. return [S.NaN], [], None
  216. coeff = S.ComplexInfinity
  217. continue
  218. # Add([...])
  219. elif o.is_Add:
  220. # NB: here we assume Add is always commutative
  221. seq.extend(o.args) # TODO zerocopy?
  222. continue
  223. # Mul([...])
  224. elif o.is_Mul:
  225. c, s = o.as_coeff_Mul()
  226. # check for unevaluated Pow, e.g. 2**3 or 2**(-1/2)
  227. elif o.is_Pow:
  228. b, e = o.as_base_exp()
  229. if b.is_Number and (e.is_Integer or
  230. (e.is_Rational and e.is_negative)):
  231. seq.append(b**e)
  232. continue
  233. c, s = S.One, o
  234. else:
  235. # everything else
  236. c = S.One
  237. s = o
  238. # now we have:
  239. # o = c*s, where
  240. #
  241. # c is a Number
  242. # s is an expression with number factor extracted
  243. # let's collect terms with the same s, so e.g.
  244. # 2*x**2 + 3*x**2 -> 5*x**2
  245. if s in terms:
  246. terms[s] += c
  247. if terms[s] is S.NaN and not extra:
  248. # we know for sure the result will be nan
  249. return [S.NaN], [], None
  250. else:
  251. terms[s] = c
  252. # now let's construct new args:
  253. # [2*x**2, x**3, 7*x**4, pi, ...]
  254. newseq = []
  255. noncommutative = False
  256. for s, c in terms.items():
  257. # 0*s
  258. if c.is_zero:
  259. continue
  260. # 1*s
  261. elif c is S.One:
  262. newseq.append(s)
  263. # c*s
  264. else:
  265. if s.is_Mul:
  266. # Mul, already keeps its arguments in perfect order.
  267. # so we can simply put c in slot0 and go the fast way.
  268. cs = s._new_rawargs(*((c,) + s.args))
  269. newseq.append(cs)
  270. elif s.is_Add:
  271. # we just re-create the unevaluated Mul
  272. newseq.append(Mul(c, s, evaluate=False))
  273. else:
  274. # alternatively we have to call all Mul's machinery (slow)
  275. newseq.append(Mul(c, s))
  276. noncommutative = noncommutative or not s.is_commutative
  277. # oo, -oo
  278. if coeff is S.Infinity:
  279. newseq = [f for f in newseq if not (f.is_extended_nonnegative or f.is_real)]
  280. elif coeff is S.NegativeInfinity:
  281. newseq = [f for f in newseq if not (f.is_extended_nonpositive or f.is_real)]
  282. if coeff is S.ComplexInfinity:
  283. # zoo might be
  284. # infinite_real + finite_im
  285. # finite_real + infinite_im
  286. # infinite_real + infinite_im
  287. # addition of a finite real or imaginary number won't be able to
  288. # change the zoo nature; adding an infinite qualtity would result
  289. # in a NaN condition if it had sign opposite of the infinite
  290. # portion of zoo, e.g., infinite_real - infinite_real.
  291. newseq = [c for c in newseq if not (c.is_finite and
  292. c.is_extended_real is not None)]
  293. # process O(x)
  294. if order_factors:
  295. newseq2 = []
  296. for t in newseq:
  297. for o in order_factors:
  298. # x + O(x) -> O(x)
  299. if o.contains(t):
  300. t = None
  301. break
  302. # x + O(x**2) -> x + O(x**2)
  303. if t is not None:
  304. newseq2.append(t)
  305. newseq = newseq2 + order_factors
  306. # 1 + O(1) -> O(1)
  307. for o in order_factors:
  308. if o.contains(coeff):
  309. coeff = S.Zero
  310. break
  311. # order args canonically
  312. _addsort(newseq)
  313. # current code expects coeff to be first
  314. if coeff is not S.Zero:
  315. newseq.insert(0, coeff)
  316. if extra:
  317. newseq += extra
  318. noncommutative = True
  319. # we are done
  320. if noncommutative:
  321. return [], newseq, None
  322. else:
  323. return newseq, [], None
  324. @classmethod
  325. def class_key(cls):
  326. return 3, 1, cls.__name__
  327. @property
  328. def kind(self):
  329. k = attrgetter('kind')
  330. kinds = map(k, self.args)
  331. kinds = frozenset(kinds)
  332. if len(kinds) != 1:
  333. # Since addition is group operator, kind must be same.
  334. # We know that this is unexpected signature, so return this.
  335. result = UndefinedKind
  336. else:
  337. result, = kinds
  338. return result
  339. def could_extract_minus_sign(self):
  340. return _could_extract_minus_sign(self)
  341. @cacheit
  342. def as_coeff_add(self, *deps):
  343. """
  344. Returns a tuple (coeff, args) where self is treated as an Add and coeff
  345. is the Number term and args is a tuple of all other terms.
  346. Examples
  347. ========
  348. >>> from sympy.abc import x
  349. >>> (7 + 3*x).as_coeff_add()
  350. (7, (3*x,))
  351. >>> (7*x).as_coeff_add()
  352. (0, (7*x,))
  353. """
  354. if deps:
  355. l1, l2 = sift(self.args, lambda x: x.has_free(*deps), binary=True)
  356. return self._new_rawargs(*l2), tuple(l1)
  357. coeff, notrat = self.args[0].as_coeff_add()
  358. if coeff is not S.Zero:
  359. return coeff, notrat + self.args[1:]
  360. return S.Zero, self.args
  361. def as_coeff_Add(self, rational=False, deps=None):
  362. """
  363. Efficiently extract the coefficient of a summation.
  364. """
  365. coeff, args = self.args[0], self.args[1:]
  366. if coeff.is_Number and not rational or coeff.is_Rational:
  367. return coeff, self._new_rawargs(*args)
  368. return S.Zero, self
  369. # Note, we intentionally do not implement Add.as_coeff_mul(). Rather, we
  370. # let Expr.as_coeff_mul() just always return (S.One, self) for an Add. See
  371. # issue 5524.
  372. def _eval_power(self, e):
  373. from .evalf import pure_complex
  374. from .relational import is_eq
  375. if len(self.args) == 2 and any(_.is_infinite for _ in self.args):
  376. if e.is_zero is False and is_eq(e, S.One) is False:
  377. # looking for literal a + I*b
  378. a, b = self.args
  379. if a.coeff(S.ImaginaryUnit):
  380. a, b = b, a
  381. ico = b.coeff(S.ImaginaryUnit)
  382. if ico and ico.is_extended_real and a.is_extended_real:
  383. if e.is_extended_negative:
  384. return S.Zero
  385. if e.is_extended_positive:
  386. return S.ComplexInfinity
  387. return
  388. if e.is_Rational and self.is_number:
  389. ri = pure_complex(self)
  390. if ri:
  391. r, i = ri
  392. if e.q == 2:
  393. from sympy.functions.elementary.miscellaneous import sqrt
  394. D = sqrt(r**2 + i**2)
  395. if D.is_Rational:
  396. from .exprtools import factor_terms
  397. from sympy.functions.elementary.complexes import sign
  398. from .function import expand_multinomial
  399. # (r, i, D) is a Pythagorean triple
  400. root = sqrt(factor_terms((D - r)/2))**e.p
  401. return root*expand_multinomial((
  402. # principle value
  403. (D + r)/abs(i) + sign(i)*S.ImaginaryUnit)**e.p)
  404. elif e == -1:
  405. return _unevaluated_Mul(
  406. r - i*S.ImaginaryUnit,
  407. 1/(r**2 + i**2))
  408. elif e.is_Number and abs(e) != 1:
  409. # handle the Float case: (2.0 + 4*x)**e -> 4**e*(0.5 + x)**e
  410. c, m = zip(*[i.as_coeff_Mul() for i in self.args])
  411. if any(i.is_Float for i in c): # XXX should this always be done?
  412. big = -1
  413. for i in c:
  414. if abs(i) >= big:
  415. big = abs(i)
  416. if big > 0 and not equal_valued(big, 1):
  417. from sympy.functions.elementary.complexes import sign
  418. bigs = (big, -big)
  419. c = [sign(i) if i in bigs else i/big for i in c]
  420. addpow = Add(*[c*m for c, m in zip(c, m)])**e
  421. return big**e*addpow
  422. @cacheit
  423. def _eval_derivative(self, s):
  424. return self.func(*[a.diff(s) for a in self.args])
  425. def _eval_nseries(self, x, n, logx, cdir=0):
  426. terms = [t.nseries(x, n=n, logx=logx, cdir=cdir) for t in self.args]
  427. return self.func(*terms)
  428. def _matches_simple(self, expr, repl_dict):
  429. # handle (w+3).matches('x+5') -> {w: x+2}
  430. coeff, terms = self.as_coeff_add()
  431. if len(terms) == 1:
  432. return terms[0].matches(expr - coeff, repl_dict)
  433. return
  434. def matches(self, expr, repl_dict=None, old=False):
  435. return self._matches_commutative(expr, repl_dict, old)
  436. @staticmethod
  437. def _combine_inverse(lhs, rhs):
  438. """
  439. Returns lhs - rhs, but treats oo like a symbol so oo - oo
  440. returns 0, instead of a nan.
  441. """
  442. from sympy.simplify.simplify import signsimp
  443. inf = (S.Infinity, S.NegativeInfinity)
  444. if lhs.has(*inf) or rhs.has(*inf):
  445. from .symbol import Dummy
  446. oo = Dummy('oo')
  447. reps = {
  448. S.Infinity: oo,
  449. S.NegativeInfinity: -oo}
  450. ireps = {v: k for k, v in reps.items()}
  451. eq = lhs.xreplace(reps) - rhs.xreplace(reps)
  452. if eq.has(oo):
  453. eq = eq.replace(
  454. lambda x: x.is_Pow and x.base is oo,
  455. lambda x: x.base)
  456. rv = eq.xreplace(ireps)
  457. else:
  458. rv = lhs - rhs
  459. srv = signsimp(rv)
  460. return srv if srv.is_Number else rv
  461. @cacheit
  462. def as_two_terms(self):
  463. """Return head and tail of self.
  464. This is the most efficient way to get the head and tail of an
  465. expression.
  466. - if you want only the head, use self.args[0];
  467. - if you want to process the arguments of the tail then use
  468. self.as_coef_add() which gives the head and a tuple containing
  469. the arguments of the tail when treated as an Add.
  470. - if you want the coefficient when self is treated as a Mul
  471. then use self.as_coeff_mul()[0]
  472. >>> from sympy.abc import x, y
  473. >>> (3*x - 2*y + 5).as_two_terms()
  474. (5, 3*x - 2*y)
  475. """
  476. return self.args[0], self._new_rawargs(*self.args[1:])
  477. def as_numer_denom(self):
  478. """
  479. Decomposes an expression to its numerator part and its
  480. denominator part.
  481. Examples
  482. ========
  483. >>> from sympy.abc import x, y, z
  484. >>> (x*y/z).as_numer_denom()
  485. (x*y, z)
  486. >>> (x*(y + 1)/y**7).as_numer_denom()
  487. (x*(y + 1), y**7)
  488. See Also
  489. ========
  490. sympy.core.expr.Expr.as_numer_denom
  491. """
  492. # clear rational denominator
  493. content, expr = self.primitive()
  494. if not isinstance(expr, Add):
  495. return Mul(content, expr, evaluate=False).as_numer_denom()
  496. ncon, dcon = content.as_numer_denom()
  497. # collect numerators and denominators of the terms
  498. nd = defaultdict(list)
  499. for f in expr.args:
  500. ni, di = f.as_numer_denom()
  501. nd[di].append(ni)
  502. # check for quick exit
  503. if len(nd) == 1:
  504. d, n = nd.popitem()
  505. return self.func(
  506. *[_keep_coeff(ncon, ni) for ni in n]), _keep_coeff(dcon, d)
  507. # sum up the terms having a common denominator
  508. for d, n in nd.items():
  509. if len(n) == 1:
  510. nd[d] = n[0]
  511. else:
  512. nd[d] = self.func(*n)
  513. # assemble single numerator and denominator
  514. denoms, numers = [list(i) for i in zip(*iter(nd.items()))]
  515. n, d = self.func(*[Mul(*(denoms[:i] + [numers[i]] + denoms[i + 1:]))
  516. for i in range(len(numers))]), Mul(*denoms)
  517. return _keep_coeff(ncon, n), _keep_coeff(dcon, d)
  518. def _eval_is_polynomial(self, syms):
  519. return all(term._eval_is_polynomial(syms) for term in self.args)
  520. def _eval_is_rational_function(self, syms):
  521. return all(term._eval_is_rational_function(syms) for term in self.args)
  522. def _eval_is_meromorphic(self, x, a):
  523. return _fuzzy_group((arg.is_meromorphic(x, a) for arg in self.args),
  524. quick_exit=True)
  525. def _eval_is_algebraic_expr(self, syms):
  526. return all(term._eval_is_algebraic_expr(syms) for term in self.args)
  527. # assumption methods
  528. _eval_is_real = lambda self: _fuzzy_group(
  529. (a.is_real for a in self.args), quick_exit=True)
  530. _eval_is_extended_real = lambda self: _fuzzy_group(
  531. (a.is_extended_real for a in self.args), quick_exit=True)
  532. _eval_is_complex = lambda self: _fuzzy_group(
  533. (a.is_complex for a in self.args), quick_exit=True)
  534. _eval_is_antihermitian = lambda self: _fuzzy_group(
  535. (a.is_antihermitian for a in self.args), quick_exit=True)
  536. _eval_is_finite = lambda self: _fuzzy_group(
  537. (a.is_finite for a in self.args), quick_exit=True)
  538. _eval_is_hermitian = lambda self: _fuzzy_group(
  539. (a.is_hermitian for a in self.args), quick_exit=True)
  540. _eval_is_integer = lambda self: _fuzzy_group(
  541. (a.is_integer for a in self.args), quick_exit=True)
  542. _eval_is_rational = lambda self: _fuzzy_group(
  543. (a.is_rational for a in self.args), quick_exit=True)
  544. _eval_is_algebraic = lambda self: _fuzzy_group(
  545. (a.is_algebraic for a in self.args), quick_exit=True)
  546. _eval_is_commutative = lambda self: _fuzzy_group(
  547. a.is_commutative for a in self.args)
  548. def _eval_is_infinite(self):
  549. sawinf = False
  550. for a in self.args:
  551. ainf = a.is_infinite
  552. if ainf is None:
  553. return None
  554. elif ainf is True:
  555. # infinite+infinite might not be infinite
  556. if sawinf is True:
  557. return None
  558. sawinf = True
  559. return sawinf
  560. def _eval_is_imaginary(self):
  561. nz = []
  562. im_I = []
  563. for a in self.args:
  564. if a.is_extended_real:
  565. if a.is_zero:
  566. pass
  567. elif a.is_zero is False:
  568. nz.append(a)
  569. else:
  570. return
  571. elif a.is_imaginary:
  572. im_I.append(a*S.ImaginaryUnit)
  573. elif a.is_Mul and S.ImaginaryUnit in a.args:
  574. coeff, ai = a.as_coeff_mul(S.ImaginaryUnit)
  575. if ai == (S.ImaginaryUnit,) and coeff.is_extended_real:
  576. im_I.append(-coeff)
  577. else:
  578. return
  579. else:
  580. return
  581. b = self.func(*nz)
  582. if b != self:
  583. if b.is_zero:
  584. return fuzzy_not(self.func(*im_I).is_zero)
  585. elif b.is_zero is False:
  586. return False
  587. def _eval_is_zero(self):
  588. if self.is_commutative is False:
  589. # issue 10528: there is no way to know if a nc symbol
  590. # is zero or not
  591. return
  592. nz = []
  593. z = 0
  594. im_or_z = False
  595. im = 0
  596. for a in self.args:
  597. if a.is_extended_real:
  598. if a.is_zero:
  599. z += 1
  600. elif a.is_zero is False:
  601. nz.append(a)
  602. else:
  603. return
  604. elif a.is_imaginary:
  605. im += 1
  606. elif a.is_Mul and S.ImaginaryUnit in a.args:
  607. coeff, ai = a.as_coeff_mul(S.ImaginaryUnit)
  608. if ai == (S.ImaginaryUnit,) and coeff.is_extended_real:
  609. im_or_z = True
  610. else:
  611. return
  612. else:
  613. return
  614. if z == len(self.args):
  615. return True
  616. if len(nz) in [0, len(self.args)]:
  617. return None
  618. b = self.func(*nz)
  619. if b.is_zero:
  620. if not im_or_z:
  621. if im == 0:
  622. return True
  623. elif im == 1:
  624. return False
  625. if b.is_zero is False:
  626. return False
  627. def _eval_is_odd(self):
  628. l = [f for f in self.args if not (f.is_even is True)]
  629. if not l:
  630. return False
  631. if l[0].is_odd:
  632. return self._new_rawargs(*l[1:]).is_even
  633. def _eval_is_irrational(self):
  634. for t in self.args:
  635. a = t.is_irrational
  636. if a:
  637. others = list(self.args)
  638. others.remove(t)
  639. if all(x.is_rational is True for x in others):
  640. return True
  641. return None
  642. if a is None:
  643. return
  644. return False
  645. def _all_nonneg_or_nonppos(self):
  646. nn = np = 0
  647. for a in self.args:
  648. if a.is_nonnegative:
  649. if np:
  650. return False
  651. nn = 1
  652. elif a.is_nonpositive:
  653. if nn:
  654. return False
  655. np = 1
  656. else:
  657. break
  658. else:
  659. return True
  660. def _eval_is_extended_positive(self):
  661. if self.is_number:
  662. return super()._eval_is_extended_positive()
  663. c, a = self.as_coeff_Add()
  664. if not c.is_zero:
  665. from .exprtools import _monotonic_sign
  666. v = _monotonic_sign(a)
  667. if v is not None:
  668. s = v + c
  669. if s != self and s.is_extended_positive and a.is_extended_nonnegative:
  670. return True
  671. if len(self.free_symbols) == 1:
  672. v = _monotonic_sign(self)
  673. if v is not None and v != self and v.is_extended_positive:
  674. return True
  675. pos = nonneg = nonpos = unknown_sign = False
  676. saw_INF = set()
  677. args = [a for a in self.args if not a.is_zero]
  678. if not args:
  679. return False
  680. for a in args:
  681. ispos = a.is_extended_positive
  682. infinite = a.is_infinite
  683. if infinite:
  684. saw_INF.add(fuzzy_or((ispos, a.is_extended_nonnegative)))
  685. if True in saw_INF and False in saw_INF:
  686. return
  687. if ispos:
  688. pos = True
  689. continue
  690. elif a.is_extended_nonnegative:
  691. nonneg = True
  692. continue
  693. elif a.is_extended_nonpositive:
  694. nonpos = True
  695. continue
  696. if infinite is None:
  697. return
  698. unknown_sign = True
  699. if saw_INF:
  700. if len(saw_INF) > 1:
  701. return
  702. return saw_INF.pop()
  703. elif unknown_sign:
  704. return
  705. elif not nonpos and not nonneg and pos:
  706. return True
  707. elif not nonpos and pos:
  708. return True
  709. elif not pos and not nonneg:
  710. return False
  711. def _eval_is_extended_nonnegative(self):
  712. if not self.is_number:
  713. c, a = self.as_coeff_Add()
  714. if not c.is_zero and a.is_extended_nonnegative:
  715. from .exprtools import _monotonic_sign
  716. v = _monotonic_sign(a)
  717. if v is not None:
  718. s = v + c
  719. if s != self and s.is_extended_nonnegative:
  720. return True
  721. if len(self.free_symbols) == 1:
  722. v = _monotonic_sign(self)
  723. if v is not None and v != self and v.is_extended_nonnegative:
  724. return True
  725. def _eval_is_extended_nonpositive(self):
  726. if not self.is_number:
  727. c, a = self.as_coeff_Add()
  728. if not c.is_zero and a.is_extended_nonpositive:
  729. from .exprtools import _monotonic_sign
  730. v = _monotonic_sign(a)
  731. if v is not None:
  732. s = v + c
  733. if s != self and s.is_extended_nonpositive:
  734. return True
  735. if len(self.free_symbols) == 1:
  736. v = _monotonic_sign(self)
  737. if v is not None and v != self and v.is_extended_nonpositive:
  738. return True
  739. def _eval_is_extended_negative(self):
  740. if self.is_number:
  741. return super()._eval_is_extended_negative()
  742. c, a = self.as_coeff_Add()
  743. if not c.is_zero:
  744. from .exprtools import _monotonic_sign
  745. v = _monotonic_sign(a)
  746. if v is not None:
  747. s = v + c
  748. if s != self and s.is_extended_negative and a.is_extended_nonpositive:
  749. return True
  750. if len(self.free_symbols) == 1:
  751. v = _monotonic_sign(self)
  752. if v is not None and v != self and v.is_extended_negative:
  753. return True
  754. neg = nonpos = nonneg = unknown_sign = False
  755. saw_INF = set()
  756. args = [a for a in self.args if not a.is_zero]
  757. if not args:
  758. return False
  759. for a in args:
  760. isneg = a.is_extended_negative
  761. infinite = a.is_infinite
  762. if infinite:
  763. saw_INF.add(fuzzy_or((isneg, a.is_extended_nonpositive)))
  764. if True in saw_INF and False in saw_INF:
  765. return
  766. if isneg:
  767. neg = True
  768. continue
  769. elif a.is_extended_nonpositive:
  770. nonpos = True
  771. continue
  772. elif a.is_extended_nonnegative:
  773. nonneg = True
  774. continue
  775. if infinite is None:
  776. return
  777. unknown_sign = True
  778. if saw_INF:
  779. if len(saw_INF) > 1:
  780. return
  781. return saw_INF.pop()
  782. elif unknown_sign:
  783. return
  784. elif not nonneg and not nonpos and neg:
  785. return True
  786. elif not nonneg and neg:
  787. return True
  788. elif not neg and not nonpos:
  789. return False
  790. def _eval_subs(self, old, new):
  791. if not old.is_Add:
  792. if old is S.Infinity and -old in self.args:
  793. # foo - oo is foo + (-oo) internally
  794. return self.xreplace({-old: -new})
  795. return None
  796. coeff_self, terms_self = self.as_coeff_Add()
  797. coeff_old, terms_old = old.as_coeff_Add()
  798. if coeff_self.is_Rational and coeff_old.is_Rational:
  799. if terms_self == terms_old: # (2 + a).subs( 3 + a, y) -> -1 + y
  800. return self.func(new, coeff_self, -coeff_old)
  801. if terms_self == -terms_old: # (2 + a).subs(-3 - a, y) -> -1 - y
  802. return self.func(-new, coeff_self, coeff_old)
  803. if coeff_self.is_Rational and coeff_old.is_Rational \
  804. or coeff_self == coeff_old:
  805. args_old, args_self = self.func.make_args(
  806. terms_old), self.func.make_args(terms_self)
  807. if len(args_old) < len(args_self): # (a+b+c).subs(b+c,x) -> a+x
  808. self_set = set(args_self)
  809. old_set = set(args_old)
  810. if old_set < self_set:
  811. ret_set = self_set - old_set
  812. return self.func(new, coeff_self, -coeff_old,
  813. *[s._subs(old, new) for s in ret_set])
  814. args_old = self.func.make_args(
  815. -terms_old) # (a+b+c+d).subs(-b-c,x) -> a-x+d
  816. old_set = set(args_old)
  817. if old_set < self_set:
  818. ret_set = self_set - old_set
  819. return self.func(-new, coeff_self, coeff_old,
  820. *[s._subs(old, new) for s in ret_set])
  821. def removeO(self):
  822. args = [a for a in self.args if not a.is_Order]
  823. return self._new_rawargs(*args)
  824. def getO(self):
  825. args = [a for a in self.args if a.is_Order]
  826. if args:
  827. return self._new_rawargs(*args)
  828. @cacheit
  829. def extract_leading_order(self, symbols, point=None):
  830. """
  831. Returns the leading term and its order.
  832. Examples
  833. ========
  834. >>> from sympy.abc import x
  835. >>> (x + 1 + 1/x**5).extract_leading_order(x)
  836. ((x**(-5), O(x**(-5))),)
  837. >>> (1 + x).extract_leading_order(x)
  838. ((1, O(1)),)
  839. >>> (x + x**2).extract_leading_order(x)
  840. ((x, O(x)),)
  841. """
  842. from sympy.series.order import Order
  843. lst = []
  844. symbols = list(symbols if is_sequence(symbols) else [symbols])
  845. if not point:
  846. point = [0]*len(symbols)
  847. seq = [(f, Order(f, *zip(symbols, point))) for f in self.args]
  848. for ef, of in seq:
  849. for e, o in lst:
  850. if o.contains(of) and o != of:
  851. of = None
  852. break
  853. if of is None:
  854. continue
  855. new_lst = [(ef, of)]
  856. for e, o in lst:
  857. if of.contains(o) and o != of:
  858. continue
  859. new_lst.append((e, o))
  860. lst = new_lst
  861. return tuple(lst)
  862. def as_real_imag(self, deep=True, **hints):
  863. """
  864. Return a tuple representing a complex number.
  865. Examples
  866. ========
  867. >>> from sympy import I
  868. >>> (7 + 9*I).as_real_imag()
  869. (7, 9)
  870. >>> ((1 + I)/(1 - I)).as_real_imag()
  871. (0, 1)
  872. >>> ((1 + 2*I)*(1 + 3*I)).as_real_imag()
  873. (-5, 5)
  874. """
  875. sargs = self.args
  876. re_part, im_part = [], []
  877. for term in sargs:
  878. re, im = term.as_real_imag(deep=deep)
  879. re_part.append(re)
  880. im_part.append(im)
  881. return (self.func(*re_part), self.func(*im_part))
  882. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  883. from sympy.core.symbol import Dummy, Symbol
  884. from sympy.series.order import Order
  885. from sympy.functions.elementary.exponential import log
  886. from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold
  887. from .function import expand_mul
  888. o = self.getO()
  889. if o is None:
  890. o = Order(0)
  891. old = self.removeO()
  892. if old.has(Piecewise):
  893. old = piecewise_fold(old)
  894. # This expansion is the last part of expand_log. expand_log also calls
  895. # expand_mul with factor=True, which would be more expensive
  896. if any(isinstance(a, log) for a in self.args):
  897. logflags = {"deep": True, "log": True, "mul": False, "power_exp": False,
  898. "power_base": False, "multinomial": False, "basic": False, "force": False,
  899. "factor": False}
  900. old = old.expand(**logflags)
  901. expr = expand_mul(old)
  902. if not expr.is_Add:
  903. return expr.as_leading_term(x, logx=logx, cdir=cdir)
  904. infinite = [t for t in expr.args if t.is_infinite]
  905. _logx = Dummy('logx') if logx is None else logx
  906. leading_terms = [t.as_leading_term(x, logx=_logx, cdir=cdir) for t in expr.args]
  907. min, new_expr = Order(0), 0
  908. try:
  909. for term in leading_terms:
  910. order = Order(term, x)
  911. if not min or order not in min:
  912. min = order
  913. new_expr = term
  914. elif min in order:
  915. new_expr += term
  916. except TypeError:
  917. return expr
  918. if logx is None:
  919. new_expr = new_expr.subs(_logx, log(x))
  920. is_zero = new_expr.is_zero
  921. if is_zero is None:
  922. new_expr = new_expr.trigsimp().cancel()
  923. is_zero = new_expr.is_zero
  924. if is_zero is True:
  925. # simple leading term analysis gave us cancelled terms but we have to send
  926. # back a term, so compute the leading term (via series)
  927. try:
  928. n0 = min.getn()
  929. except NotImplementedError:
  930. n0 = S.One
  931. if n0.has(Symbol):
  932. n0 = S.One
  933. res = Order(1)
  934. incr = S.One
  935. while res.is_Order:
  936. res = old._eval_nseries(x, n=n0+incr, logx=logx, cdir=cdir).cancel().powsimp().trigsimp()
  937. incr *= 2
  938. return res.as_leading_term(x, logx=logx, cdir=cdir)
  939. elif new_expr is S.NaN:
  940. return old.func._from_args(infinite) + o
  941. else:
  942. return new_expr
  943. def _eval_adjoint(self):
  944. return self.func(*[t.adjoint() for t in self.args])
  945. def _eval_conjugate(self):
  946. return self.func(*[t.conjugate() for t in self.args])
  947. def _eval_transpose(self):
  948. return self.func(*[t.transpose() for t in self.args])
  949. def primitive(self):
  950. """
  951. Return ``(R, self/R)`` where ``R``` is the Rational GCD of ``self```.
  952. ``R`` is collected only from the leading coefficient of each term.
  953. Examples
  954. ========
  955. >>> from sympy.abc import x, y
  956. >>> (2*x + 4*y).primitive()
  957. (2, x + 2*y)
  958. >>> (2*x/3 + 4*y/9).primitive()
  959. (2/9, 3*x + 2*y)
  960. >>> (2*x/3 + 4.2*y).primitive()
  961. (1/3, 2*x + 12.6*y)
  962. No subprocessing of term factors is performed:
  963. >>> ((2 + 2*x)*x + 2).primitive()
  964. (1, x*(2*x + 2) + 2)
  965. Recursive processing can be done with the ``as_content_primitive()``
  966. method:
  967. >>> ((2 + 2*x)*x + 2).as_content_primitive()
  968. (2, x*(x + 1) + 1)
  969. See also: primitive() function in polytools.py
  970. """
  971. terms = []
  972. inf = False
  973. for a in self.args:
  974. c, m = a.as_coeff_Mul()
  975. if not c.is_Rational:
  976. c = S.One
  977. m = a
  978. inf = inf or m is S.ComplexInfinity
  979. terms.append((c.p, c.q, m))
  980. if not inf:
  981. ngcd = reduce(igcd, [t[0] for t in terms], 0)
  982. dlcm = reduce(ilcm, [t[1] for t in terms], 1)
  983. else:
  984. ngcd = reduce(igcd, [t[0] for t in terms if t[1]], 0)
  985. dlcm = reduce(ilcm, [t[1] for t in terms if t[1]], 1)
  986. if ngcd == dlcm == 1:
  987. return S.One, self
  988. if not inf:
  989. for i, (p, q, term) in enumerate(terms):
  990. terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
  991. else:
  992. for i, (p, q, term) in enumerate(terms):
  993. if q:
  994. terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
  995. else:
  996. terms[i] = _keep_coeff(Rational(p, q), term)
  997. # we don't need a complete re-flattening since no new terms will join
  998. # so we just use the same sort as is used in Add.flatten. When the
  999. # coefficient changes, the ordering of terms may change, e.g.
  1000. # (3*x, 6*y) -> (2*y, x)
  1001. #
  1002. # We do need to make sure that term[0] stays in position 0, however.
  1003. #
  1004. if terms[0].is_Number or terms[0] is S.ComplexInfinity:
  1005. c = terms.pop(0)
  1006. else:
  1007. c = None
  1008. _addsort(terms)
  1009. if c:
  1010. terms.insert(0, c)
  1011. return Rational(ngcd, dlcm), self._new_rawargs(*terms)
  1012. def as_content_primitive(self, radical=False, clear=True):
  1013. """Return the tuple (R, self/R) where R is the positive Rational
  1014. extracted from self. If radical is True (default is False) then
  1015. common radicals will be removed and included as a factor of the
  1016. primitive expression.
  1017. Examples
  1018. ========
  1019. >>> from sympy import sqrt
  1020. >>> (3 + 3*sqrt(2)).as_content_primitive()
  1021. (3, 1 + sqrt(2))
  1022. Radical content can also be factored out of the primitive:
  1023. >>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
  1024. (2, sqrt(2)*(1 + 2*sqrt(5)))
  1025. See docstring of Expr.as_content_primitive for more examples.
  1026. """
  1027. con, prim = self.func(*[_keep_coeff(*a.as_content_primitive(
  1028. radical=radical, clear=clear)) for a in self.args]).primitive()
  1029. if not clear and not con.is_Integer and prim.is_Add:
  1030. con, d = con.as_numer_denom()
  1031. _p = prim/d
  1032. if any(a.as_coeff_Mul()[0].is_Integer for a in _p.args):
  1033. prim = _p
  1034. else:
  1035. con /= d
  1036. if radical and prim.is_Add:
  1037. # look for common radicals that can be removed
  1038. args = prim.args
  1039. rads = []
  1040. common_q = None
  1041. for m in args:
  1042. term_rads = defaultdict(list)
  1043. for ai in Mul.make_args(m):
  1044. if ai.is_Pow:
  1045. b, e = ai.as_base_exp()
  1046. if e.is_Rational and b.is_Integer:
  1047. term_rads[e.q].append(abs(int(b))**e.p)
  1048. if not term_rads:
  1049. break
  1050. if common_q is None:
  1051. common_q = set(term_rads.keys())
  1052. else:
  1053. common_q = common_q & set(term_rads.keys())
  1054. if not common_q:
  1055. break
  1056. rads.append(term_rads)
  1057. else:
  1058. # process rads
  1059. # keep only those in common_q
  1060. for r in rads:
  1061. for q in list(r.keys()):
  1062. if q not in common_q:
  1063. r.pop(q)
  1064. for q in r:
  1065. r[q] = Mul(*r[q])
  1066. # find the gcd of bases for each q
  1067. G = []
  1068. for q in common_q:
  1069. g = reduce(igcd, [r[q] for r in rads], 0)
  1070. if g != 1:
  1071. G.append(g**Rational(1, q))
  1072. if G:
  1073. G = Mul(*G)
  1074. args = [ai/G for ai in args]
  1075. prim = G*prim.func(*args)
  1076. return con, prim
  1077. @property
  1078. def _sorted_args(self):
  1079. from .sorting import default_sort_key
  1080. return tuple(sorted(self.args, key=default_sort_key))
  1081. def _eval_difference_delta(self, n, step):
  1082. from sympy.series.limitseq import difference_delta as dd
  1083. return self.func(*[dd(a, n, step) for a in self.args])
  1084. @property
  1085. def _mpc_(self):
  1086. """
  1087. Convert self to an mpmath mpc if possible
  1088. """
  1089. from .numbers import Float
  1090. re_part, rest = self.as_coeff_Add()
  1091. im_part, imag_unit = rest.as_coeff_Mul()
  1092. if not imag_unit == S.ImaginaryUnit:
  1093. # ValueError may seem more reasonable but since it's a @property,
  1094. # we need to use AttributeError to keep from confusing things like
  1095. # hasattr.
  1096. raise AttributeError("Cannot convert Add to mpc. Must be of the form Number + Number*I")
  1097. return (Float(re_part)._mpf_, Float(im_part)._mpf_)
  1098. def __neg__(self):
  1099. if not global_parameters.distribute:
  1100. return super().__neg__()
  1101. return Mul(S.NegativeOne, self)
  1102. add = AssocOpDispatcher('add')
  1103. from .mul import Mul, _keep_coeff, _unevaluated_Mul
  1104. from .numbers import Rational