add.py 42 KB

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