m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1281 lines
42 KiB

6 months ago
  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
  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. """Nice order of classes"""
  327. return 3, 1, cls.__name__
  328. @property
  329. def kind(self):
  330. k = attrgetter('kind')
  331. kinds = map(k, self.args)
  332. kinds = frozenset(kinds)
  333. if len(kinds) != 1:
  334. # Since addition is group operator, kind must be same.
  335. # We know that this is unexpected signature, so return this.
  336. result = UndefinedKind
  337. else:
  338. result, = kinds
  339. return result
  340. def could_extract_minus_sign(self):
  341. return _could_extract_minus_sign(self)
  342. def as_coefficients_dict(a):
  343. """Return a dictionary mapping terms to their Rational coefficient.
  344. Since the dictionary is a defaultdict, inquiries about terms which
  345. were not present will return a coefficient of 0. If an expression is
  346. not an Add it is considered to have a single term.
  347. Examples
  348. ========
  349. >>> from sympy.abc import a, x
  350. >>> (3*x + a*x + 4).as_coefficients_dict()
  351. {1: 4, x: 3, a*x: 1}
  352. >>> _[a]
  353. 0
  354. >>> (3*a*x).as_coefficients_dict()
  355. {a*x: 3}
  356. """
  357. d = defaultdict(list)
  358. for ai in a.args:
  359. c, m = ai.as_coeff_Mul()
  360. d[m].append(c)
  361. for k, v in d.items():
  362. if len(v) == 1:
  363. d[k] = v[0]
  364. else:
  365. d[k] = Add(*v)
  366. di = defaultdict(int)
  367. di.update(d)
  368. return di
  369. @cacheit
  370. def as_coeff_add(self, *deps):
  371. """
  372. Returns a tuple (coeff, args) where self is treated as an Add and coeff
  373. is the Number term and args is a tuple of all other terms.
  374. Examples
  375. ========
  376. >>> from sympy.abc import x
  377. >>> (7 + 3*x).as_coeff_add()
  378. (7, (3*x,))
  379. >>> (7*x).as_coeff_add()
  380. (0, (7*x,))
  381. """
  382. if deps:
  383. l1, l2 = sift(self.args, lambda x: x.has_free(*deps), binary=True)
  384. return self._new_rawargs(*l2), tuple(l1)
  385. coeff, notrat = self.args[0].as_coeff_add()
  386. if coeff is not S.Zero:
  387. return coeff, notrat + self.args[1:]
  388. return S.Zero, self.args
  389. def as_coeff_Add(self, rational=False, deps=None):
  390. """
  391. Efficiently extract the coefficient of a summation.
  392. """
  393. coeff, args = self.args[0], self.args[1:]
  394. if coeff.is_Number and not rational or coeff.is_Rational:
  395. return coeff, self._new_rawargs(*args)
  396. return S.Zero, self
  397. # Note, we intentionally do not implement Add.as_coeff_mul(). Rather, we
  398. # let Expr.as_coeff_mul() just always return (S.One, self) for an Add. See
  399. # issue 5524.
  400. def _eval_power(self, e):
  401. from .evalf import pure_complex
  402. from .relational import is_eq
  403. if len(self.args) == 2 and any(_.is_infinite for _ in self.args):
  404. if e.is_zero is False and is_eq(e, S.One) is False:
  405. # looking for literal a + I*b
  406. a, b = self.args
  407. if a.coeff(S.ImaginaryUnit):
  408. a, b = b, a
  409. ico = b.coeff(S.ImaginaryUnit)
  410. if ico and ico.is_extended_real and a.is_extended_real:
  411. if e.is_extended_negative:
  412. return S.Zero
  413. if e.is_extended_positive:
  414. return S.ComplexInfinity
  415. return
  416. if e.is_Rational and self.is_number:
  417. ri = pure_complex(self)
  418. if ri:
  419. r, i = ri
  420. if e.q == 2:
  421. from sympy.functions.elementary.miscellaneous import sqrt
  422. D = sqrt(r**2 + i**2)
  423. if D.is_Rational:
  424. from .exprtools import factor_terms
  425. from sympy.functions.elementary.complexes import sign
  426. from .function import expand_multinomial
  427. # (r, i, D) is a Pythagorean triple
  428. root = sqrt(factor_terms((D - r)/2))**e.p
  429. return root*expand_multinomial((
  430. # principle value
  431. (D + r)/abs(i) + sign(i)*S.ImaginaryUnit)**e.p)
  432. elif e == -1:
  433. return _unevaluated_Mul(
  434. r - i*S.ImaginaryUnit,
  435. 1/(r**2 + i**2))
  436. elif e.is_Number and abs(e) != 1:
  437. # handle the Float case: (2.0 + 4*x)**e -> 4**e*(0.5 + x)**e
  438. c, m = zip(*[i.as_coeff_Mul() for i in self.args])
  439. if any(i.is_Float for i in c): # XXX should this always be done?
  440. big = -1
  441. for i in c:
  442. if abs(i) >= big:
  443. big = abs(i)
  444. if big > 0 and big != 1:
  445. from sympy.functions.elementary.complexes import sign
  446. bigs = (big, -big)
  447. c = [sign(i) if i in bigs else i/big for i in c]
  448. addpow = Add(*[c*m for c, m in zip(c, m)])**e
  449. return big**e*addpow
  450. @cacheit
  451. def _eval_derivative(self, s):
  452. return self.func(*[a.diff(s) for a in self.args])
  453. def _eval_nseries(self, x, n, logx, cdir=0):
  454. terms = [t.nseries(x, n=n, logx=logx, cdir=cdir) for t in self.args]
  455. return self.func(*terms)
  456. def _matches_simple(self, expr, repl_dict):
  457. # handle (w+3).matches('x+5') -> {w: x+2}
  458. coeff, terms = self.as_coeff_add()
  459. if len(terms) == 1:
  460. return terms[0].matches(expr - coeff, repl_dict)
  461. return
  462. def matches(self, expr, repl_dict=None, old=False):
  463. return self._matches_commutative(expr, repl_dict, old)
  464. @staticmethod
  465. def _combine_inverse(lhs, rhs):
  466. """
  467. Returns lhs - rhs, but treats oo like a symbol so oo - oo
  468. returns 0, instead of a nan.
  469. """
  470. from sympy.simplify.simplify import signsimp
  471. inf = (S.Infinity, S.NegativeInfinity)
  472. if lhs.has(*inf) or rhs.has(*inf):
  473. from .symbol import Dummy
  474. oo = Dummy('oo')
  475. reps = {
  476. S.Infinity: oo,
  477. S.NegativeInfinity: -oo}
  478. ireps = {v: k for k, v in reps.items()}
  479. eq = lhs.xreplace(reps) - rhs.xreplace(reps)
  480. if eq.has(oo):
  481. eq = eq.replace(
  482. lambda x: x.is_Pow and x.base is oo,
  483. lambda x: x.base)
  484. rv = eq.xreplace(ireps)
  485. else:
  486. rv = lhs - rhs
  487. srv = signsimp(rv)
  488. return srv if srv.is_Number else rv
  489. @cacheit
  490. def as_two_terms(self):
  491. """Return head and tail of self.
  492. This is the most efficient way to get the head and tail of an
  493. expression.
  494. - if you want only the head, use self.args[0];
  495. - if you want to process the arguments of the tail then use
  496. self.as_coef_add() which gives the head and a tuple containing
  497. the arguments of the tail when treated as an Add.
  498. - if you want the coefficient when self is treated as a Mul
  499. then use self.as_coeff_mul()[0]
  500. >>> from sympy.abc import x, y
  501. >>> (3*x - 2*y + 5).as_two_terms()
  502. (5, 3*x - 2*y)
  503. """
  504. return self.args[0], self._new_rawargs(*self.args[1:])
  505. def as_numer_denom(self):
  506. """
  507. Decomposes an expression to its numerator part and its
  508. denominator part.
  509. Examples
  510. ========
  511. >>> from sympy.abc import x, y, z
  512. >>> (x*y/z).as_numer_denom()
  513. (x*y, z)
  514. >>> (x*(y + 1)/y**7).as_numer_denom()
  515. (x*(y + 1), y**7)
  516. See Also
  517. ========
  518. sympy.core.expr.Expr.as_numer_denom
  519. """
  520. # clear rational denominator
  521. content, expr = self.primitive()
  522. if not isinstance(expr, Add):
  523. return Mul(content, expr, evaluate=False).as_numer_denom()
  524. ncon, dcon = content.as_numer_denom()
  525. # collect numerators and denominators of the terms
  526. nd = defaultdict(list)
  527. for f in expr.args:
  528. ni, di = f.as_numer_denom()
  529. nd[di].append(ni)
  530. # check for quick exit
  531. if len(nd) == 1:
  532. d, n = nd.popitem()
  533. return self.func(
  534. *[_keep_coeff(ncon, ni) for ni in n]), _keep_coeff(dcon, d)
  535. # sum up the terms having a common denominator
  536. for d, n in nd.items():
  537. if len(n) == 1:
  538. nd[d] = n[0]
  539. else:
  540. nd[d] = self.func(*n)
  541. # assemble single numerator and denominator
  542. denoms, numers = [list(i) for i in zip(*iter(nd.items()))]
  543. n, d = self.func(*[Mul(*(denoms[:i] + [numers[i]] + denoms[i + 1:]))
  544. for i in range(len(numers))]), Mul(*denoms)
  545. return _keep_coeff(ncon, n), _keep_coeff(dcon, d)
  546. def _eval_is_polynomial(self, syms):
  547. return all(term._eval_is_polynomial(syms) for term in self.args)
  548. def _eval_is_rational_function(self, syms):
  549. return all(term._eval_is_rational_function(syms) for term in self.args)
  550. def _eval_is_meromorphic(self, x, a):
  551. return _fuzzy_group((arg.is_meromorphic(x, a) for arg in self.args),
  552. quick_exit=True)
  553. def _eval_is_algebraic_expr(self, syms):
  554. return all(term._eval_is_algebraic_expr(syms) for term in self.args)
  555. # assumption methods
  556. _eval_is_real = lambda self: _fuzzy_group(
  557. (a.is_real for a in self.args), quick_exit=True)
  558. _eval_is_extended_real = lambda self: _fuzzy_group(
  559. (a.is_extended_real for a in self.args), quick_exit=True)
  560. _eval_is_complex = lambda self: _fuzzy_group(
  561. (a.is_complex for a in self.args), quick_exit=True)
  562. _eval_is_antihermitian = lambda self: _fuzzy_group(
  563. (a.is_antihermitian for a in self.args), quick_exit=True)
  564. _eval_is_finite = lambda self: _fuzzy_group(
  565. (a.is_finite for a in self.args), quick_exit=True)
  566. _eval_is_hermitian = lambda self: _fuzzy_group(
  567. (a.is_hermitian for a in self.args), quick_exit=True)
  568. _eval_is_integer = lambda self: _fuzzy_group(
  569. (a.is_integer for a in self.args), quick_exit=True)
  570. _eval_is_rational = lambda self: _fuzzy_group(
  571. (a.is_rational for a in self.args), quick_exit=True)
  572. _eval_is_algebraic = lambda self: _fuzzy_group(
  573. (a.is_algebraic for a in self.args), quick_exit=True)
  574. _eval_is_commutative = lambda self: _fuzzy_group(
  575. a.is_commutative for a in self.args)
  576. def _eval_is_infinite(self):
  577. sawinf = False
  578. for a in self.args:
  579. ainf = a.is_infinite
  580. if ainf is None:
  581. return None
  582. elif ainf is True:
  583. # infinite+infinite might not be infinite
  584. if sawinf is True:
  585. return None
  586. sawinf = True
  587. return sawinf
  588. def _eval_is_imaginary(self):
  589. nz = []
  590. im_I = []
  591. for a in self.args:
  592. if a.is_extended_real:
  593. if a.is_zero:
  594. pass
  595. elif a.is_zero is False:
  596. nz.append(a)
  597. else:
  598. return
  599. elif a.is_imaginary:
  600. im_I.append(a*S.ImaginaryUnit)
  601. elif (S.ImaginaryUnit*a).is_extended_real:
  602. im_I.append(a*S.ImaginaryUnit)
  603. else:
  604. return
  605. b = self.func(*nz)
  606. if b.is_zero:
  607. return fuzzy_not(self.func(*im_I).is_zero)
  608. elif b.is_zero is False:
  609. return False
  610. def _eval_is_zero(self):
  611. if self.is_commutative is False:
  612. # issue 10528: there is no way to know if a nc symbol
  613. # is zero or not
  614. return
  615. nz = []
  616. z = 0
  617. im_or_z = False
  618. im = 0
  619. for a in self.args:
  620. if a.is_extended_real:
  621. if a.is_zero:
  622. z += 1
  623. elif a.is_zero is False:
  624. nz.append(a)
  625. else:
  626. return
  627. elif a.is_imaginary:
  628. im += 1
  629. elif (S.ImaginaryUnit*a).is_extended_real:
  630. im_or_z = True
  631. else:
  632. return
  633. if z == len(self.args):
  634. return True
  635. if len(nz) in [0, len(self.args)]:
  636. return None
  637. b = self.func(*nz)
  638. if b.is_zero:
  639. if not im_or_z:
  640. if im == 0:
  641. return True
  642. elif im == 1:
  643. return False
  644. if b.is_zero is False:
  645. return False
  646. def _eval_is_odd(self):
  647. l = [f for f in self.args if not (f.is_even is True)]
  648. if not l:
  649. return False
  650. if l[0].is_odd:
  651. return self._new_rawargs(*l[1:]).is_even
  652. def _eval_is_irrational(self):
  653. for t in self.args:
  654. a = t.is_irrational
  655. if a:
  656. others = list(self.args)
  657. others.remove(t)
  658. if all(x.is_rational is True for x in others):
  659. return True
  660. return None
  661. if a is None:
  662. return
  663. return False
  664. def _eval_is_extended_positive(self):
  665. if self.is_number:
  666. return super()._eval_is_extended_positive()
  667. c, a = self.as_coeff_Add()
  668. if not c.is_zero:
  669. from .exprtools import _monotonic_sign
  670. v = _monotonic_sign(a)
  671. if v is not None:
  672. s = v + c
  673. if s != self and s.is_extended_positive and a.is_extended_nonnegative:
  674. return True
  675. if len(self.free_symbols) == 1:
  676. v = _monotonic_sign(self)
  677. if v is not None and v != self and v.is_extended_positive:
  678. return True
  679. pos = nonneg = nonpos = unknown_sign = False
  680. saw_INF = set()
  681. args = [a for a in self.args if not a.is_zero]
  682. if not args:
  683. return False
  684. for a in args:
  685. ispos = a.is_extended_positive
  686. infinite = a.is_infinite
  687. if infinite:
  688. saw_INF.add(fuzzy_or((ispos, a.is_extended_nonnegative)))
  689. if True in saw_INF and False in saw_INF:
  690. return
  691. if ispos:
  692. pos = True
  693. continue
  694. elif a.is_extended_nonnegative:
  695. nonneg = True
  696. continue
  697. elif a.is_extended_nonpositive:
  698. nonpos = True
  699. continue
  700. if infinite is None:
  701. return
  702. unknown_sign = True
  703. if saw_INF:
  704. if len(saw_INF) > 1:
  705. return
  706. return saw_INF.pop()
  707. elif unknown_sign:
  708. return
  709. elif not nonpos and not nonneg and pos:
  710. return True
  711. elif not nonpos and pos:
  712. return True
  713. elif not pos and not nonneg:
  714. return False
  715. def _eval_is_extended_nonnegative(self):
  716. if not self.is_number:
  717. c, a = self.as_coeff_Add()
  718. if not c.is_zero and a.is_extended_nonnegative:
  719. from .exprtools import _monotonic_sign
  720. v = _monotonic_sign(a)
  721. if v is not None:
  722. s = v + c
  723. if s != self and s.is_extended_nonnegative:
  724. return True
  725. if len(self.free_symbols) == 1:
  726. v = _monotonic_sign(self)
  727. if v is not None and v != self and v.is_extended_nonnegative:
  728. return True
  729. def _eval_is_extended_nonpositive(self):
  730. if not self.is_number:
  731. c, a = self.as_coeff_Add()
  732. if not c.is_zero and a.is_extended_nonpositive:
  733. from .exprtools import _monotonic_sign
  734. v = _monotonic_sign(a)
  735. if v is not None:
  736. s = v + c
  737. if s != self and s.is_extended_nonpositive:
  738. return True
  739. if len(self.free_symbols) == 1:
  740. v = _monotonic_sign(self)
  741. if v is not None and v != self and v.is_extended_nonpositive:
  742. return True
  743. def _eval_is_extended_negative(self):
  744. if self.is_number:
  745. return super()._eval_is_extended_negative()
  746. c, a = self.as_coeff_Add()
  747. if not c.is_zero:
  748. from .exprtools import _monotonic_sign
  749. v = _monotonic_sign(a)
  750. if v is not None:
  751. s = v + c
  752. if s != self and s.is_extended_negative and a.is_extended_nonpositive:
  753. return True
  754. if len(self.free_symbols) == 1:
  755. v = _monotonic_sign(self)
  756. if v is not None and v != self and v.is_extended_negative:
  757. return True
  758. neg = nonpos = nonneg = unknown_sign = False
  759. saw_INF = set()
  760. args = [a for a in self.args if not a.is_zero]
  761. if not args:
  762. return False
  763. for a in args:
  764. isneg = a.is_extended_negative
  765. infinite = a.is_infinite
  766. if infinite:
  767. saw_INF.add(fuzzy_or((isneg, a.is_extended_nonpositive)))
  768. if True in saw_INF and False in saw_INF:
  769. return
  770. if isneg:
  771. neg = True
  772. continue
  773. elif a.is_extended_nonpositive:
  774. nonpos = True
  775. continue
  776. elif a.is_extended_nonnegative:
  777. nonneg = True
  778. continue
  779. if infinite is None:
  780. return
  781. unknown_sign = True
  782. if saw_INF:
  783. if len(saw_INF) > 1:
  784. return
  785. return saw_INF.pop()
  786. elif unknown_sign:
  787. return
  788. elif not nonneg and not nonpos and neg:
  789. return True
  790. elif not nonneg and neg:
  791. return True
  792. elif not neg and not nonpos:
  793. return False
  794. def _eval_subs(self, old, new):
  795. if not old.is_Add:
  796. if old is S.Infinity and -old in self.args:
  797. # foo - oo is foo + (-oo) internally
  798. return self.xreplace({-old: -new})
  799. return None
  800. coeff_self, terms_self = self.as_coeff_Add()
  801. coeff_old, terms_old = old.as_coeff_Add()
  802. if coeff_self.is_Rational and coeff_old.is_Rational:
  803. if terms_self == terms_old: # (2 + a).subs( 3 + a, y) -> -1 + y
  804. return self.func(new, coeff_self, -coeff_old)
  805. if terms_self == -terms_old: # (2 + a).subs(-3 - a, y) -> -1 - y
  806. return self.func(-new, coeff_self, coeff_old)
  807. if coeff_self.is_Rational and coeff_old.is_Rational \
  808. or coeff_self == coeff_old:
  809. args_old, args_self = self.func.make_args(
  810. terms_old), self.func.make_args(terms_self)
  811. if len(args_old) < len(args_self): # (a+b+c).subs(b+c,x) -> a+x
  812. self_set = set(args_self)
  813. old_set = set(args_old)
  814. if old_set < self_set:
  815. ret_set = self_set - old_set
  816. return self.func(new, coeff_self, -coeff_old,
  817. *[s._subs(old, new) for s in ret_set])
  818. args_old = self.func.make_args(
  819. -terms_old) # (a+b+c+d).subs(-b-c,x) -> a-x+d
  820. old_set = set(args_old)
  821. if old_set < self_set:
  822. ret_set = self_set - old_set
  823. return self.func(-new, coeff_self, coeff_old,
  824. *[s._subs(old, new) for s in ret_set])
  825. def removeO(self):
  826. args = [a for a in self.args if not a.is_Order]
  827. return self._new_rawargs(*args)
  828. def getO(self):
  829. args = [a for a in self.args if a.is_Order]
  830. if args:
  831. return self._new_rawargs(*args)
  832. @cacheit
  833. def extract_leading_order(self, symbols, point=None):
  834. """
  835. Returns the leading term and its order.
  836. Examples
  837. ========
  838. >>> from sympy.abc import x
  839. >>> (x + 1 + 1/x**5).extract_leading_order(x)
  840. ((x**(-5), O(x**(-5))),)
  841. >>> (1 + x).extract_leading_order(x)
  842. ((1, O(1)),)
  843. >>> (x + x**2).extract_leading_order(x)
  844. ((x, O(x)),)
  845. """
  846. from sympy.series.order import Order
  847. lst = []
  848. symbols = list(symbols if is_sequence(symbols) else [symbols])
  849. if not point:
  850. point = [0]*len(symbols)
  851. seq = [(f, Order(f, *zip(symbols, point))) for f in self.args]
  852. for ef, of in seq:
  853. for e, o in lst:
  854. if o.contains(of) and o != of:
  855. of = None
  856. break
  857. if of is None:
  858. continue
  859. new_lst = [(ef, of)]
  860. for e, o in lst:
  861. if of.contains(o) and o != of:
  862. continue
  863. new_lst.append((e, o))
  864. lst = new_lst
  865. return tuple(lst)
  866. def as_real_imag(self, deep=True, **hints):
  867. """
  868. returns a tuple representing a complex number
  869. Examples
  870. ========
  871. >>> from sympy import I
  872. >>> (7 + 9*I).as_real_imag()
  873. (7, 9)
  874. >>> ((1 + I)/(1 - I)).as_real_imag()
  875. (0, 1)
  876. >>> ((1 + 2*I)*(1 + 3*I)).as_real_imag()
  877. (-5, 5)
  878. """
  879. sargs = self.args
  880. re_part, im_part = [], []
  881. for term in sargs:
  882. re, im = term.as_real_imag(deep=deep)
  883. re_part.append(re)
  884. im_part.append(im)
  885. return (self.func(*re_part), self.func(*im_part))
  886. def _eval_as_leading_term(self, x, logx=None, cdir=0):
  887. from sympy.series.order import Order
  888. from sympy.functions.elementary.exponential import log
  889. from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold
  890. from .function import expand_mul
  891. old = self
  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 = dict(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. leading_terms = [t.as_leading_term(x, logx=logx, cdir=cdir) for t in expr.args]
  906. min, new_expr = Order(0), 0
  907. try:
  908. for term in leading_terms:
  909. order = Order(term, x)
  910. if not min or order not in min:
  911. min = order
  912. new_expr = term
  913. elif min in order:
  914. new_expr += term
  915. except TypeError:
  916. return expr
  917. is_zero = new_expr.is_zero
  918. if is_zero is None:
  919. new_expr = new_expr.trigsimp().cancel()
  920. is_zero = new_expr.is_zero
  921. if is_zero is True:
  922. # simple leading term analysis gave us cancelled terms but we have to send
  923. # back a term, so compute the leading term (via series)
  924. n0 = min.getn()
  925. res = Order(1)
  926. incr = S.One
  927. while res.is_Order:
  928. res = old._eval_nseries(x, n=n0+incr, logx=None, cdir=cdir).cancel().powsimp().trigsimp()
  929. incr *= 2
  930. return res.as_leading_term(x, logx=logx, cdir=cdir)
  931. elif new_expr is S.NaN:
  932. return old.func._from_args(infinite)
  933. else:
  934. return new_expr
  935. def _eval_adjoint(self):
  936. return self.func(*[t.adjoint() for t in self.args])
  937. def _eval_conjugate(self):
  938. return self.func(*[t.conjugate() for t in self.args])
  939. def _eval_transpose(self):
  940. return self.func(*[t.transpose() for t in self.args])
  941. def primitive(self):
  942. """
  943. Return ``(R, self/R)`` where ``R``` is the Rational GCD of ``self```.
  944. ``R`` is collected only from the leading coefficient of each term.
  945. Examples
  946. ========
  947. >>> from sympy.abc import x, y
  948. >>> (2*x + 4*y).primitive()
  949. (2, x + 2*y)
  950. >>> (2*x/3 + 4*y/9).primitive()
  951. (2/9, 3*x + 2*y)
  952. >>> (2*x/3 + 4.2*y).primitive()
  953. (1/3, 2*x + 12.6*y)
  954. No subprocessing of term factors is performed:
  955. >>> ((2 + 2*x)*x + 2).primitive()
  956. (1, x*(2*x + 2) + 2)
  957. Recursive processing can be done with the ``as_content_primitive()``
  958. method:
  959. >>> ((2 + 2*x)*x + 2).as_content_primitive()
  960. (2, x*(x + 1) + 1)
  961. See also: primitive() function in polytools.py
  962. """
  963. terms = []
  964. inf = False
  965. for a in self.args:
  966. c, m = a.as_coeff_Mul()
  967. if not c.is_Rational:
  968. c = S.One
  969. m = a
  970. inf = inf or m is S.ComplexInfinity
  971. terms.append((c.p, c.q, m))
  972. if not inf:
  973. ngcd = reduce(igcd, [t[0] for t in terms], 0)
  974. dlcm = reduce(ilcm, [t[1] for t in terms], 1)
  975. else:
  976. ngcd = reduce(igcd, [t[0] for t in terms if t[1]], 0)
  977. dlcm = reduce(ilcm, [t[1] for t in terms if t[1]], 1)
  978. if ngcd == dlcm == 1:
  979. return S.One, self
  980. if not inf:
  981. for i, (p, q, term) in enumerate(terms):
  982. terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
  983. else:
  984. for i, (p, q, term) in enumerate(terms):
  985. if q:
  986. terms[i] = _keep_coeff(Rational((p//ngcd)*(dlcm//q)), term)
  987. else:
  988. terms[i] = _keep_coeff(Rational(p, q), term)
  989. # we don't need a complete re-flattening since no new terms will join
  990. # so we just use the same sort as is used in Add.flatten. When the
  991. # coefficient changes, the ordering of terms may change, e.g.
  992. # (3*x, 6*y) -> (2*y, x)
  993. #
  994. # We do need to make sure that term[0] stays in position 0, however.
  995. #
  996. if terms[0].is_Number or terms[0] is S.ComplexInfinity:
  997. c = terms.pop(0)
  998. else:
  999. c = None
  1000. _addsort(terms)
  1001. if c:
  1002. terms.insert(0, c)
  1003. return Rational(ngcd, dlcm), self._new_rawargs(*terms)
  1004. def as_content_primitive(self, radical=False, clear=True):
  1005. """Return the tuple (R, self/R) where R is the positive Rational
  1006. extracted from self. If radical is True (default is False) then
  1007. common radicals will be removed and included as a factor of the
  1008. primitive expression.
  1009. Examples
  1010. ========
  1011. >>> from sympy import sqrt
  1012. >>> (3 + 3*sqrt(2)).as_content_primitive()
  1013. (3, 1 + sqrt(2))
  1014. Radical content can also be factored out of the primitive:
  1015. >>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
  1016. (2, sqrt(2)*(1 + 2*sqrt(5)))
  1017. See docstring of Expr.as_content_primitive for more examples.
  1018. """
  1019. con, prim = self.func(*[_keep_coeff(*a.as_content_primitive(
  1020. radical=radical, clear=clear)) for a in self.args]).primitive()
  1021. if not clear and not con.is_Integer and prim.is_Add:
  1022. con, d = con.as_numer_denom()
  1023. _p = prim/d
  1024. if any(a.as_coeff_Mul()[0].is_Integer for a in _p.args):
  1025. prim = _p
  1026. else:
  1027. con /= d
  1028. if radical and prim.is_Add:
  1029. # look for common radicals that can be removed
  1030. args = prim.args
  1031. rads = []
  1032. common_q = None
  1033. for m in args:
  1034. term_rads = defaultdict(list)
  1035. for ai in Mul.make_args(m):
  1036. if ai.is_Pow:
  1037. b, e = ai.as_base_exp()
  1038. if e.is_Rational and b.is_Integer:
  1039. term_rads[e.q].append(abs(int(b))**e.p)
  1040. if not term_rads:
  1041. break
  1042. if common_q is None:
  1043. common_q = set(term_rads.keys())
  1044. else:
  1045. common_q = common_q & set(term_rads.keys())
  1046. if not common_q:
  1047. break
  1048. rads.append(term_rads)
  1049. else:
  1050. # process rads
  1051. # keep only those in common_q
  1052. for r in rads:
  1053. for q in list(r.keys()):
  1054. if q not in common_q:
  1055. r.pop(q)
  1056. for q in r:
  1057. r[q] = prod(r[q])
  1058. # find the gcd of bases for each q
  1059. G = []
  1060. for q in common_q:
  1061. g = reduce(igcd, [r[q] for r in rads], 0)
  1062. if g != 1:
  1063. G.append(g**Rational(1, q))
  1064. if G:
  1065. G = Mul(*G)
  1066. args = [ai/G for ai in args]
  1067. prim = G*prim.func(*args)
  1068. return con, prim
  1069. @property
  1070. def _sorted_args(self):
  1071. from .sorting import default_sort_key
  1072. return tuple(sorted(self.args, key=default_sort_key))
  1073. def _eval_difference_delta(self, n, step):
  1074. from sympy.series.limitseq import difference_delta as dd
  1075. return self.func(*[dd(a, n, step) for a in self.args])
  1076. @property
  1077. def _mpc_(self):
  1078. """
  1079. Convert self to an mpmath mpc if possible
  1080. """
  1081. from .numbers import Float
  1082. re_part, rest = self.as_coeff_Add()
  1083. im_part, imag_unit = rest.as_coeff_Mul()
  1084. if not imag_unit == S.ImaginaryUnit:
  1085. # ValueError may seem more reasonable but since it's a @property,
  1086. # we need to use AttributeError to keep from confusing things like
  1087. # hasattr.
  1088. raise AttributeError("Cannot convert Add to mpc. Must be of the form Number + Number*I")
  1089. return (Float(re_part)._mpf_, Float(im_part)._mpf_)
  1090. def __neg__(self):
  1091. if not global_parameters.distribute:
  1092. return super().__neg__()
  1093. return Add(*[-i for i in self.args])
  1094. add = AssocOpDispatcher('add')
  1095. from .mul import Mul, _keep_coeff, prod, _unevaluated_Mul
  1096. from .numbers import Rational