Coverage for /usr/lib/python3/dist-packages/sympy/core/expr.py: 28%

1714 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1from __future__ import annotations 

2 

3from typing import TYPE_CHECKING 

4from collections.abc import Iterable 

5from functools import reduce 

6import re 

7 

8from .sympify import sympify, _sympify 

9from .basic import Basic, Atom 

10from .singleton import S 

11from .evalf import EvalfMixin, pure_complex, DEFAULT_MAXPREC 

12from .decorators import call_highest_priority, sympify_method_args, sympify_return 

13from .cache import cacheit 

14from .sorting import default_sort_key 

15from .kind import NumberKind 

16from sympy.utilities.exceptions import sympy_deprecation_warning 

17from sympy.utilities.misc import as_int, func_name, filldedent 

18from sympy.utilities.iterables import has_variety, sift 

19from mpmath.libmp import mpf_log, prec_to_dps 

20from mpmath.libmp.libintmath import giant_steps 

21 

22 

23if TYPE_CHECKING: 

24 from .numbers import Number 

25 

26from collections import defaultdict 

27 

28 

29def _corem(eq, c): # helper for extract_additively 

30 # return co, diff from co*c + diff 

31 co = [] 

32 non = [] 

33 for i in Add.make_args(eq): 

34 ci = i.coeff(c) 

35 if not ci: 

36 non.append(i) 

37 else: 

38 co.append(ci) 

39 return Add(*co), Add(*non) 

40 

41 

42@sympify_method_args 

43class Expr(Basic, EvalfMixin): 

44 """ 

45 Base class for algebraic expressions. 

46 

47 Explanation 

48 =========== 

49 

50 Everything that requires arithmetic operations to be defined 

51 should subclass this class, instead of Basic (which should be 

52 used only for argument storage and expression manipulation, i.e. 

53 pattern matching, substitutions, etc). 

54 

55 If you want to override the comparisons of expressions: 

56 Should use _eval_is_ge for inequality, or _eval_is_eq, with multiple dispatch. 

57 _eval_is_ge return true if x >= y, false if x < y, and None if the two types 

58 are not comparable or the comparison is indeterminate 

59 

60 See Also 

61 ======== 

62 

63 sympy.core.basic.Basic 

64 """ 

65 

66 __slots__: tuple[str, ...] = () 

67 

68 is_scalar = True # self derivative is 1 

69 

70 @property 

71 def _diff_wrt(self): 

72 """Return True if one can differentiate with respect to this 

73 object, else False. 

74 

75 Explanation 

76 =========== 

77 

78 Subclasses such as Symbol, Function and Derivative return True 

79 to enable derivatives wrt them. The implementation in Derivative 

80 separates the Symbol and non-Symbol (_diff_wrt=True) variables and 

81 temporarily converts the non-Symbols into Symbols when performing 

82 the differentiation. By default, any object deriving from Expr 

83 will behave like a scalar with self.diff(self) == 1. If this is 

84 not desired then the object must also set `is_scalar = False` or 

85 else define an _eval_derivative routine. 

86 

87 Note, see the docstring of Derivative for how this should work 

88 mathematically. In particular, note that expr.subs(yourclass, Symbol) 

89 should be well-defined on a structural level, or this will lead to 

90 inconsistent results. 

91 

92 Examples 

93 ======== 

94 

95 >>> from sympy import Expr 

96 >>> e = Expr() 

97 >>> e._diff_wrt 

98 False 

99 >>> class MyScalar(Expr): 

100 ... _diff_wrt = True 

101 ... 

102 >>> MyScalar().diff(MyScalar()) 

103 1 

104 >>> class MySymbol(Expr): 

105 ... _diff_wrt = True 

106 ... is_scalar = False 

107 ... 

108 >>> MySymbol().diff(MySymbol()) 

109 Derivative(MySymbol(), MySymbol()) 

110 """ 

111 return False 

112 

113 @cacheit 

114 def sort_key(self, order=None): 

115 

116 coeff, expr = self.as_coeff_Mul() 

117 

118 if expr.is_Pow: 

119 if expr.base is S.Exp1: 

120 # If we remove this, many doctests will go crazy: 

121 # (keeps E**x sorted like the exp(x) function, 

122 # part of exp(x) to E**x transition) 

123 expr, exp = Function("exp")(expr.exp), S.One 

124 else: 

125 expr, exp = expr.args 

126 else: 

127 exp = S.One 

128 

129 if expr.is_Dummy: 

130 args = (expr.sort_key(),) 

131 elif expr.is_Atom: 

132 args = (str(expr),) 

133 else: 

134 if expr.is_Add: 

135 args = expr.as_ordered_terms(order=order) 

136 elif expr.is_Mul: 

137 args = expr.as_ordered_factors(order=order) 

138 else: 

139 args = expr.args 

140 

141 args = tuple( 

142 [ default_sort_key(arg, order=order) for arg in args ]) 

143 

144 args = (len(args), tuple(args)) 

145 exp = exp.sort_key(order=order) 

146 

147 return expr.class_key(), args, exp, coeff 

148 

149 def _hashable_content(self): 

150 """Return a tuple of information about self that can be used to 

151 compute the hash. If a class defines additional attributes, 

152 like ``name`` in Symbol, then this method should be updated 

153 accordingly to return such relevant attributes. 

154 Defining more than _hashable_content is necessary if __eq__ has 

155 been defined by a class. See note about this in Basic.__eq__.""" 

156 return self._args 

157 

158 # *************** 

159 # * Arithmetics * 

160 # *************** 

161 # Expr and its subclasses use _op_priority to determine which object 

162 # passed to a binary special method (__mul__, etc.) will handle the 

163 # operation. In general, the 'call_highest_priority' decorator will choose 

164 # the object with the highest _op_priority to handle the call. 

165 # Custom subclasses that want to define their own binary special methods 

166 # should set an _op_priority value that is higher than the default. 

167 # 

168 # **NOTE**: 

169 # This is a temporary fix, and will eventually be replaced with 

170 # something better and more powerful. See issue 5510. 

171 _op_priority = 10.0 

172 

173 @property 

174 def _add_handler(self): 

175 return Add 

176 

177 @property 

178 def _mul_handler(self): 

179 return Mul 

180 

181 def __pos__(self): 

182 return self 

183 

184 def __neg__(self): 

185 # Mul has its own __neg__ routine, so we just 

186 # create a 2-args Mul with the -1 in the canonical 

187 # slot 0. 

188 c = self.is_commutative 

189 return Mul._from_args((S.NegativeOne, self), c) 

190 

191 def __abs__(self) -> Expr: 

192 from sympy.functions.elementary.complexes import Abs 

193 return Abs(self) 

194 

195 @sympify_return([('other', 'Expr')], NotImplemented) 

196 @call_highest_priority('__radd__') 

197 def __add__(self, other): 

198 return Add(self, other) 

199 

200 @sympify_return([('other', 'Expr')], NotImplemented) 

201 @call_highest_priority('__add__') 

202 def __radd__(self, other): 

203 return Add(other, self) 

204 

205 @sympify_return([('other', 'Expr')], NotImplemented) 

206 @call_highest_priority('__rsub__') 

207 def __sub__(self, other): 

208 return Add(self, -other) 

209 

210 @sympify_return([('other', 'Expr')], NotImplemented) 

211 @call_highest_priority('__sub__') 

212 def __rsub__(self, other): 

213 return Add(other, -self) 

214 

215 @sympify_return([('other', 'Expr')], NotImplemented) 

216 @call_highest_priority('__rmul__') 

217 def __mul__(self, other): 

218 return Mul(self, other) 

219 

220 @sympify_return([('other', 'Expr')], NotImplemented) 

221 @call_highest_priority('__mul__') 

222 def __rmul__(self, other): 

223 return Mul(other, self) 

224 

225 @sympify_return([('other', 'Expr')], NotImplemented) 

226 @call_highest_priority('__rpow__') 

227 def _pow(self, other): 

228 return Pow(self, other) 

229 

230 def __pow__(self, other, mod=None) -> Expr: 

231 if mod is None: 

232 return self._pow(other) 

233 try: 

234 _self, other, mod = as_int(self), as_int(other), as_int(mod) 

235 if other >= 0: 

236 return _sympify(pow(_self, other, mod)) 

237 else: 

238 from .numbers import mod_inverse 

239 return _sympify(mod_inverse(pow(_self, -other, mod), mod)) 

240 except ValueError: 

241 power = self._pow(other) 

242 try: 

243 return power%mod 

244 except TypeError: 

245 return NotImplemented 

246 

247 @sympify_return([('other', 'Expr')], NotImplemented) 

248 @call_highest_priority('__pow__') 

249 def __rpow__(self, other): 

250 return Pow(other, self) 

251 

252 @sympify_return([('other', 'Expr')], NotImplemented) 

253 @call_highest_priority('__rtruediv__') 

254 def __truediv__(self, other): 

255 denom = Pow(other, S.NegativeOne) 

256 if self is S.One: 

257 return denom 

258 else: 

259 return Mul(self, denom) 

260 

261 @sympify_return([('other', 'Expr')], NotImplemented) 

262 @call_highest_priority('__truediv__') 

263 def __rtruediv__(self, other): 

264 denom = Pow(self, S.NegativeOne) 

265 if other is S.One: 

266 return denom 

267 else: 

268 return Mul(other, denom) 

269 

270 @sympify_return([('other', 'Expr')], NotImplemented) 

271 @call_highest_priority('__rmod__') 

272 def __mod__(self, other): 

273 return Mod(self, other) 

274 

275 @sympify_return([('other', 'Expr')], NotImplemented) 

276 @call_highest_priority('__mod__') 

277 def __rmod__(self, other): 

278 return Mod(other, self) 

279 

280 @sympify_return([('other', 'Expr')], NotImplemented) 

281 @call_highest_priority('__rfloordiv__') 

282 def __floordiv__(self, other): 

283 from sympy.functions.elementary.integers import floor 

284 return floor(self / other) 

285 

286 @sympify_return([('other', 'Expr')], NotImplemented) 

287 @call_highest_priority('__floordiv__') 

288 def __rfloordiv__(self, other): 

289 from sympy.functions.elementary.integers import floor 

290 return floor(other / self) 

291 

292 

293 @sympify_return([('other', 'Expr')], NotImplemented) 

294 @call_highest_priority('__rdivmod__') 

295 def __divmod__(self, other): 

296 from sympy.functions.elementary.integers import floor 

297 return floor(self / other), Mod(self, other) 

298 

299 @sympify_return([('other', 'Expr')], NotImplemented) 

300 @call_highest_priority('__divmod__') 

301 def __rdivmod__(self, other): 

302 from sympy.functions.elementary.integers import floor 

303 return floor(other / self), Mod(other, self) 

304 

305 def __int__(self): 

306 # Although we only need to round to the units position, we'll 

307 # get one more digit so the extra testing below can be avoided 

308 # unless the rounded value rounded to an integer, e.g. if an 

309 # expression were equal to 1.9 and we rounded to the unit position 

310 # we would get a 2 and would not know if this rounded up or not 

311 # without doing a test (as done below). But if we keep an extra 

312 # digit we know that 1.9 is not the same as 1 and there is no 

313 # need for further testing: our int value is correct. If the value 

314 # were 1.99, however, this would round to 2.0 and our int value is 

315 # off by one. So...if our round value is the same as the int value 

316 # (regardless of how much extra work we do to calculate extra decimal 

317 # places) we need to test whether we are off by one. 

318 from .symbol import Dummy 

319 if not self.is_number: 

320 raise TypeError("Cannot convert symbols to int") 

321 r = self.round(2) 

322 if not r.is_Number: 

323 raise TypeError("Cannot convert complex to int") 

324 if r in (S.NaN, S.Infinity, S.NegativeInfinity): 

325 raise TypeError("Cannot convert %s to int" % r) 

326 i = int(r) 

327 if not i: 

328 return 0 

329 # off-by-one check 

330 if i == r and not (self - i).equals(0): 

331 isign = 1 if i > 0 else -1 

332 x = Dummy() 

333 # in the following (self - i).evalf(2) will not always work while 

334 # (self - r).evalf(2) and the use of subs does; if the test that 

335 # was added when this comment was added passes, it might be safe 

336 # to simply use sign to compute this rather than doing this by hand: 

337 diff_sign = 1 if (self - x).evalf(2, subs={x: i}) > 0 else -1 

338 if diff_sign != isign: 

339 i -= isign 

340 return i 

341 

342 def __float__(self): 

343 # Don't bother testing if it's a number; if it's not this is going 

344 # to fail, and if it is we still need to check that it evalf'ed to 

345 # a number. 

346 result = self.evalf() 

347 if result.is_Number: 

348 return float(result) 

349 if result.is_number and result.as_real_imag()[1]: 

350 raise TypeError("Cannot convert complex to float") 

351 raise TypeError("Cannot convert expression to float") 

352 

353 def __complex__(self): 

354 result = self.evalf() 

355 re, im = result.as_real_imag() 

356 return complex(float(re), float(im)) 

357 

358 @sympify_return([('other', 'Expr')], NotImplemented) 

359 def __ge__(self, other): 

360 from .relational import GreaterThan 

361 return GreaterThan(self, other) 

362 

363 @sympify_return([('other', 'Expr')], NotImplemented) 

364 def __le__(self, other): 

365 from .relational import LessThan 

366 return LessThan(self, other) 

367 

368 @sympify_return([('other', 'Expr')], NotImplemented) 

369 def __gt__(self, other): 

370 from .relational import StrictGreaterThan 

371 return StrictGreaterThan(self, other) 

372 

373 @sympify_return([('other', 'Expr')], NotImplemented) 

374 def __lt__(self, other): 

375 from .relational import StrictLessThan 

376 return StrictLessThan(self, other) 

377 

378 def __trunc__(self): 

379 if not self.is_number: 

380 raise TypeError("Cannot truncate symbols and expressions") 

381 else: 

382 return Integer(self) 

383 

384 def __format__(self, format_spec: str): 

385 if self.is_number: 

386 mt = re.match(r'\+?\d*\.(\d+)f', format_spec) 

387 if mt: 

388 prec = int(mt.group(1)) 

389 rounded = self.round(prec) 

390 if rounded.is_Integer: 

391 return format(int(rounded), format_spec) 

392 if rounded.is_Float: 

393 return format(rounded, format_spec) 

394 return super().__format__(format_spec) 

395 

396 @staticmethod 

397 def _from_mpmath(x, prec): 

398 if hasattr(x, "_mpf_"): 

399 return Float._new(x._mpf_, prec) 

400 elif hasattr(x, "_mpc_"): 

401 re, im = x._mpc_ 

402 re = Float._new(re, prec) 

403 im = Float._new(im, prec)*S.ImaginaryUnit 

404 return re + im 

405 else: 

406 raise TypeError("expected mpmath number (mpf or mpc)") 

407 

408 @property 

409 def is_number(self): 

410 """Returns True if ``self`` has no free symbols and no 

411 undefined functions (AppliedUndef, to be precise). It will be 

412 faster than ``if not self.free_symbols``, however, since 

413 ``is_number`` will fail as soon as it hits a free symbol 

414 or undefined function. 

415 

416 Examples 

417 ======== 

418 

419 >>> from sympy import Function, Integral, cos, sin, pi 

420 >>> from sympy.abc import x 

421 >>> f = Function('f') 

422 

423 >>> x.is_number 

424 False 

425 >>> f(1).is_number 

426 False 

427 >>> (2*x).is_number 

428 False 

429 >>> (2 + Integral(2, x)).is_number 

430 False 

431 >>> (2 + Integral(2, (x, 1, 2))).is_number 

432 True 

433 

434 Not all numbers are Numbers in the SymPy sense: 

435 

436 >>> pi.is_number, pi.is_Number 

437 (True, False) 

438 

439 If something is a number it should evaluate to a number with 

440 real and imaginary parts that are Numbers; the result may not 

441 be comparable, however, since the real and/or imaginary part 

442 of the result may not have precision. 

443 

444 >>> cos(1).is_number and cos(1).is_comparable 

445 True 

446 

447 >>> z = cos(1)**2 + sin(1)**2 - 1 

448 >>> z.is_number 

449 True 

450 >>> z.is_comparable 

451 False 

452 

453 See Also 

454 ======== 

455 

456 sympy.core.basic.Basic.is_comparable 

457 """ 

458 return all(obj.is_number for obj in self.args) 

459 

460 def _random(self, n=None, re_min=-1, im_min=-1, re_max=1, im_max=1): 

461 """Return self evaluated, if possible, replacing free symbols with 

462 random complex values, if necessary. 

463 

464 Explanation 

465 =========== 

466 

467 The random complex value for each free symbol is generated 

468 by the random_complex_number routine giving real and imaginary 

469 parts in the range given by the re_min, re_max, im_min, and im_max 

470 values. The returned value is evaluated to a precision of n 

471 (if given) else the maximum of 15 and the precision needed 

472 to get more than 1 digit of precision. If the expression 

473 could not be evaluated to a number, or could not be evaluated 

474 to more than 1 digit of precision, then None is returned. 

475 

476 Examples 

477 ======== 

478 

479 >>> from sympy import sqrt 

480 >>> from sympy.abc import x, y 

481 >>> x._random() # doctest: +SKIP 

482 0.0392918155679172 + 0.916050214307199*I 

483 >>> x._random(2) # doctest: +SKIP 

484 -0.77 - 0.87*I 

485 >>> (x + y/2)._random(2) # doctest: +SKIP 

486 -0.57 + 0.16*I 

487 >>> sqrt(2)._random(2) 

488 1.4 

489 

490 See Also 

491 ======== 

492 

493 sympy.core.random.random_complex_number 

494 """ 

495 

496 free = self.free_symbols 

497 prec = 1 

498 if free: 

499 from sympy.core.random import random_complex_number 

500 a, c, b, d = re_min, re_max, im_min, im_max 

501 reps = dict(list(zip(free, [random_complex_number(a, b, c, d, rational=True) 

502 for zi in free]))) 

503 try: 

504 nmag = abs(self.evalf(2, subs=reps)) 

505 except (ValueError, TypeError): 

506 # if an out of range value resulted in evalf problems 

507 # then return None -- XXX is there a way to know how to 

508 # select a good random number for a given expression? 

509 # e.g. when calculating n! negative values for n should not 

510 # be used 

511 return None 

512 else: 

513 reps = {} 

514 nmag = abs(self.evalf(2)) 

515 

516 if not hasattr(nmag, '_prec'): 

517 # e.g. exp_polar(2*I*pi) doesn't evaluate but is_number is True 

518 return None 

519 

520 if nmag._prec == 1: 

521 # increase the precision up to the default maximum 

522 # precision to see if we can get any significance 

523 

524 # evaluate 

525 for prec in giant_steps(2, DEFAULT_MAXPREC): 

526 nmag = abs(self.evalf(prec, subs=reps)) 

527 if nmag._prec != 1: 

528 break 

529 

530 if nmag._prec != 1: 

531 if n is None: 

532 n = max(prec, 15) 

533 return self.evalf(n, subs=reps) 

534 

535 # never got any significance 

536 return None 

537 

538 def is_constant(self, *wrt, **flags): 

539 """Return True if self is constant, False if not, or None if 

540 the constancy could not be determined conclusively. 

541 

542 Explanation 

543 =========== 

544 

545 If an expression has no free symbols then it is a constant. If 

546 there are free symbols it is possible that the expression is a 

547 constant, perhaps (but not necessarily) zero. To test such 

548 expressions, a few strategies are tried: 

549 

550 1) numerical evaluation at two random points. If two such evaluations 

551 give two different values and the values have a precision greater than 

552 1 then self is not constant. If the evaluations agree or could not be 

553 obtained with any precision, no decision is made. The numerical testing 

554 is done only if ``wrt`` is different than the free symbols. 

555 

556 2) differentiation with respect to variables in 'wrt' (or all free 

557 symbols if omitted) to see if the expression is constant or not. This 

558 will not always lead to an expression that is zero even though an 

559 expression is constant (see added test in test_expr.py). If 

560 all derivatives are zero then self is constant with respect to the 

561 given symbols. 

562 

563 3) finding out zeros of denominator expression with free_symbols. 

564 It will not be constant if there are zeros. It gives more negative 

565 answers for expression that are not constant. 

566 

567 If neither evaluation nor differentiation can prove the expression is 

568 constant, None is returned unless two numerical values happened to be 

569 the same and the flag ``failing_number`` is True -- in that case the 

570 numerical value will be returned. 

571 

572 If flag simplify=False is passed, self will not be simplified; 

573 the default is True since self should be simplified before testing. 

574 

575 Examples 

576 ======== 

577 

578 >>> from sympy import cos, sin, Sum, S, pi 

579 >>> from sympy.abc import a, n, x, y 

580 >>> x.is_constant() 

581 False 

582 >>> S(2).is_constant() 

583 True 

584 >>> Sum(x, (x, 1, 10)).is_constant() 

585 True 

586 >>> Sum(x, (x, 1, n)).is_constant() 

587 False 

588 >>> Sum(x, (x, 1, n)).is_constant(y) 

589 True 

590 >>> Sum(x, (x, 1, n)).is_constant(n) 

591 False 

592 >>> Sum(x, (x, 1, n)).is_constant(x) 

593 True 

594 >>> eq = a*cos(x)**2 + a*sin(x)**2 - a 

595 >>> eq.is_constant() 

596 True 

597 >>> eq.subs({x: pi, a: 2}) == eq.subs({x: pi, a: 3}) == 0 

598 True 

599 

600 >>> (0**x).is_constant() 

601 False 

602 >>> x.is_constant() 

603 False 

604 >>> (x**x).is_constant() 

605 False 

606 >>> one = cos(x)**2 + sin(x)**2 

607 >>> one.is_constant() 

608 True 

609 >>> ((one - 1)**(x + 1)).is_constant() in (True, False) # could be 0 or 1 

610 True 

611 """ 

612 

613 def check_denominator_zeros(expression): 

614 from sympy.solvers.solvers import denoms 

615 

616 retNone = False 

617 for den in denoms(expression): 

618 z = den.is_zero 

619 if z is True: 

620 return True 

621 if z is None: 

622 retNone = True 

623 if retNone: 

624 return None 

625 return False 

626 

627 simplify = flags.get('simplify', True) 

628 

629 if self.is_number: 

630 return True 

631 free = self.free_symbols 

632 if not free: 

633 return True # assume f(1) is some constant 

634 

635 # if we are only interested in some symbols and they are not in the 

636 # free symbols then this expression is constant wrt those symbols 

637 wrt = set(wrt) 

638 if wrt and not wrt & free: 

639 return True 

640 wrt = wrt or free 

641 

642 # simplify unless this has already been done 

643 expr = self 

644 if simplify: 

645 expr = expr.simplify() 

646 

647 # is_zero should be a quick assumptions check; it can be wrong for 

648 # numbers (see test_is_not_constant test), giving False when it 

649 # shouldn't, but hopefully it will never give True unless it is sure. 

650 if expr.is_zero: 

651 return True 

652 

653 # Don't attempt substitution or differentiation with non-number symbols 

654 wrt_number = {sym for sym in wrt if sym.kind is NumberKind} 

655 

656 # try numerical evaluation to see if we get two different values 

657 failing_number = None 

658 if wrt_number == free: 

659 # try 0 (for a) and 1 (for b) 

660 try: 

661 a = expr.subs(list(zip(free, [0]*len(free))), 

662 simultaneous=True) 

663 if a is S.NaN: 

664 # evaluation may succeed when substitution fails 

665 a = expr._random(None, 0, 0, 0, 0) 

666 except ZeroDivisionError: 

667 a = None 

668 if a is not None and a is not S.NaN: 

669 try: 

670 b = expr.subs(list(zip(free, [1]*len(free))), 

671 simultaneous=True) 

672 if b is S.NaN: 

673 # evaluation may succeed when substitution fails 

674 b = expr._random(None, 1, 0, 1, 0) 

675 except ZeroDivisionError: 

676 b = None 

677 if b is not None and b is not S.NaN and b.equals(a) is False: 

678 return False 

679 # try random real 

680 b = expr._random(None, -1, 0, 1, 0) 

681 if b is not None and b is not S.NaN and b.equals(a) is False: 

682 return False 

683 # try random complex 

684 b = expr._random() 

685 if b is not None and b is not S.NaN: 

686 if b.equals(a) is False: 

687 return False 

688 failing_number = a if a.is_number else b 

689 

690 # now we will test each wrt symbol (or all free symbols) to see if the 

691 # expression depends on them or not using differentiation. This is 

692 # not sufficient for all expressions, however, so we don't return 

693 # False if we get a derivative other than 0 with free symbols. 

694 for w in wrt_number: 

695 deriv = expr.diff(w) 

696 if simplify: 

697 deriv = deriv.simplify() 

698 if deriv != 0: 

699 if not (pure_complex(deriv, or_real=True)): 

700 if flags.get('failing_number', False): 

701 return failing_number 

702 return False 

703 cd = check_denominator_zeros(self) 

704 if cd is True: 

705 return False 

706 elif cd is None: 

707 return None 

708 return True 

709 

710 def equals(self, other, failing_expression=False): 

711 """Return True if self == other, False if it does not, or None. If 

712 failing_expression is True then the expression which did not simplify 

713 to a 0 will be returned instead of None. 

714 

715 Explanation 

716 =========== 

717 

718 If ``self`` is a Number (or complex number) that is not zero, then 

719 the result is False. 

720 

721 If ``self`` is a number and has not evaluated to zero, evalf will be 

722 used to test whether the expression evaluates to zero. If it does so 

723 and the result has significance (i.e. the precision is either -1, for 

724 a Rational result, or is greater than 1) then the evalf value will be 

725 used to return True or False. 

726 

727 """ 

728 from sympy.simplify.simplify import nsimplify, simplify 

729 from sympy.solvers.solvers import solve 

730 from sympy.polys.polyerrors import NotAlgebraic 

731 from sympy.polys.numberfields import minimal_polynomial 

732 

733 other = sympify(other) 

734 if self == other: 

735 return True 

736 

737 # they aren't the same so see if we can make the difference 0; 

738 # don't worry about doing simplification steps one at a time 

739 # because if the expression ever goes to 0 then the subsequent 

740 # simplification steps that are done will be very fast. 

741 diff = factor_terms(simplify(self - other), radical=True) 

742 

743 if not diff: 

744 return True 

745 

746 if not diff.has(Add, Mod): 

747 # if there is no expanding to be done after simplifying 

748 # then this can't be a zero 

749 return False 

750 

751 factors = diff.as_coeff_mul()[1] 

752 if len(factors) > 1: # avoid infinity recursion 

753 fac_zero = [fac.equals(0) for fac in factors] 

754 if None not in fac_zero: # every part can be decided 

755 return any(fac_zero) 

756 

757 constant = diff.is_constant(simplify=False, failing_number=True) 

758 

759 if constant is False: 

760 return False 

761 

762 if not diff.is_number: 

763 if constant is None: 

764 # e.g. unless the right simplification is done, a symbolic 

765 # zero is possible (see expression of issue 6829: without 

766 # simplification constant will be None). 

767 return 

768 

769 if constant is True: 

770 # this gives a number whether there are free symbols or not 

771 ndiff = diff._random() 

772 # is_comparable will work whether the result is real 

773 # or complex; it could be None, however. 

774 if ndiff and ndiff.is_comparable: 

775 return False 

776 

777 # sometimes we can use a simplified result to give a clue as to 

778 # what the expression should be; if the expression is *not* zero 

779 # then we should have been able to compute that and so now 

780 # we can just consider the cases where the approximation appears 

781 # to be zero -- we try to prove it via minimal_polynomial. 

782 # 

783 # removed 

784 # ns = nsimplify(diff) 

785 # if diff.is_number and (not ns or ns == diff): 

786 # 

787 # The thought was that if it nsimplifies to 0 that's a sure sign 

788 # to try the following to prove it; or if it changed but wasn't 

789 # zero that might be a sign that it's not going to be easy to 

790 # prove. But tests seem to be working without that logic. 

791 # 

792 if diff.is_number: 

793 # try to prove via self-consistency 

794 surds = [s for s in diff.atoms(Pow) if s.args[0].is_Integer] 

795 # it seems to work better to try big ones first 

796 surds.sort(key=lambda x: -x.args[0]) 

797 for s in surds: 

798 try: 

799 # simplify is False here -- this expression has already 

800 # been identified as being hard to identify as zero; 

801 # we will handle the checking ourselves using nsimplify 

802 # to see if we are in the right ballpark or not and if so 

803 # *then* the simplification will be attempted. 

804 sol = solve(diff, s, simplify=False) 

805 if sol: 

806 if s in sol: 

807 # the self-consistent result is present 

808 return True 

809 if all(si.is_Integer for si in sol): 

810 # perfect powers are removed at instantiation 

811 # so surd s cannot be an integer 

812 return False 

813 if all(i.is_algebraic is False for i in sol): 

814 # a surd is algebraic 

815 return False 

816 if any(si in surds for si in sol): 

817 # it wasn't equal to s but it is in surds 

818 # and different surds are not equal 

819 return False 

820 if any(nsimplify(s - si) == 0 and 

821 simplify(s - si) == 0 for si in sol): 

822 return True 

823 if s.is_real: 

824 if any(nsimplify(si, [s]) == s and simplify(si) == s 

825 for si in sol): 

826 return True 

827 except NotImplementedError: 

828 pass 

829 

830 # try to prove with minimal_polynomial but know when 

831 # *not* to use this or else it can take a long time. e.g. issue 8354 

832 if True: # change True to condition that assures non-hang 

833 try: 

834 mp = minimal_polynomial(diff) 

835 if mp.is_Symbol: 

836 return True 

837 return False 

838 except (NotAlgebraic, NotImplementedError): 

839 pass 

840 

841 # diff has not simplified to zero; constant is either None, True 

842 # or the number with significance (is_comparable) that was randomly 

843 # calculated twice as the same value. 

844 if constant not in (True, None) and constant != 0: 

845 return False 

846 

847 if failing_expression: 

848 return diff 

849 return None 

850 

851 def _eval_is_extended_positive_negative(self, positive): 

852 from sympy.polys.numberfields import minimal_polynomial 

853 from sympy.polys.polyerrors import NotAlgebraic 

854 if self.is_number: 

855 # check to see that we can get a value 

856 try: 

857 n2 = self._eval_evalf(2) 

858 # XXX: This shouldn't be caught here 

859 # Catches ValueError: hypsum() failed to converge to the requested 

860 # 34 bits of accuracy 

861 except ValueError: 

862 return None 

863 if n2 is None: 

864 return None 

865 if getattr(n2, '_prec', 1) == 1: # no significance 

866 return None 

867 if n2 is S.NaN: 

868 return None 

869 

870 f = self.evalf(2) 

871 if f.is_Float: 

872 match = f, S.Zero 

873 else: 

874 match = pure_complex(f) 

875 if match is None: 

876 return False 

877 r, i = match 

878 if not (i.is_Number and r.is_Number): 

879 return False 

880 if r._prec != 1 and i._prec != 1: 

881 return bool(not i and ((r > 0) if positive else (r < 0))) 

882 elif r._prec == 1 and (not i or i._prec == 1) and \ 

883 self._eval_is_algebraic() and not self.has(Function): 

884 try: 

885 if minimal_polynomial(self).is_Symbol: 

886 return False 

887 except (NotAlgebraic, NotImplementedError): 

888 pass 

889 

890 def _eval_is_extended_positive(self): 

891 return self._eval_is_extended_positive_negative(positive=True) 

892 

893 def _eval_is_extended_negative(self): 

894 return self._eval_is_extended_positive_negative(positive=False) 

895 

896 def _eval_interval(self, x, a, b): 

897 """ 

898 Returns evaluation over an interval. For most functions this is: 

899 

900 self.subs(x, b) - self.subs(x, a), 

901 

902 possibly using limit() if NaN is returned from subs, or if 

903 singularities are found between a and b. 

904 

905 If b or a is None, it only evaluates -self.subs(x, a) or self.subs(b, x), 

906 respectively. 

907 

908 """ 

909 from sympy.calculus.accumulationbounds import AccumBounds 

910 from sympy.functions.elementary.exponential import log 

911 from sympy.series.limits import limit, Limit 

912 from sympy.sets.sets import Interval 

913 from sympy.solvers.solveset import solveset 

914 

915 if (a is None and b is None): 

916 raise ValueError('Both interval ends cannot be None.') 

917 

918 def _eval_endpoint(left): 

919 c = a if left else b 

920 if c is None: 

921 return S.Zero 

922 else: 

923 C = self.subs(x, c) 

924 if C.has(S.NaN, S.Infinity, S.NegativeInfinity, 

925 S.ComplexInfinity, AccumBounds): 

926 if (a < b) != False: 

927 C = limit(self, x, c, "+" if left else "-") 

928 else: 

929 C = limit(self, x, c, "-" if left else "+") 

930 

931 if isinstance(C, Limit): 

932 raise NotImplementedError("Could not compute limit") 

933 return C 

934 

935 if a == b: 

936 return S.Zero 

937 

938 A = _eval_endpoint(left=True) 

939 if A is S.NaN: 

940 return A 

941 

942 B = _eval_endpoint(left=False) 

943 

944 if (a and b) is None: 

945 return B - A 

946 

947 value = B - A 

948 

949 if a.is_comparable and b.is_comparable: 

950 if a < b: 

951 domain = Interval(a, b) 

952 else: 

953 domain = Interval(b, a) 

954 # check the singularities of self within the interval 

955 # if singularities is a ConditionSet (not iterable), catch the exception and pass 

956 singularities = solveset(self.cancel().as_numer_denom()[1], x, 

957 domain=domain) 

958 for logterm in self.atoms(log): 

959 singularities = singularities | solveset(logterm.args[0], x, 

960 domain=domain) 

961 try: 

962 for s in singularities: 

963 if value is S.NaN: 

964 # no need to keep adding, it will stay NaN 

965 break 

966 if not s.is_comparable: 

967 continue 

968 if (a < s) == (s < b) == True: 

969 value += -limit(self, x, s, "+") + limit(self, x, s, "-") 

970 elif (b < s) == (s < a) == True: 

971 value += limit(self, x, s, "+") - limit(self, x, s, "-") 

972 except TypeError: 

973 pass 

974 

975 return value 

976 

977 def _eval_power(self, other): 

978 # subclass to compute self**other for cases when 

979 # other is not NaN, 0, or 1 

980 return None 

981 

982 def _eval_conjugate(self): 

983 if self.is_extended_real: 

984 return self 

985 elif self.is_imaginary: 

986 return -self 

987 

988 def conjugate(self): 

989 """Returns the complex conjugate of 'self'.""" 

990 from sympy.functions.elementary.complexes import conjugate as c 

991 return c(self) 

992 

993 def dir(self, x, cdir): 

994 if self.is_zero: 

995 return S.Zero 

996 from sympy.functions.elementary.exponential import log 

997 minexp = S.Zero 

998 arg = self 

999 while arg: 

1000 minexp += S.One 

1001 arg = arg.diff(x) 

1002 coeff = arg.subs(x, 0) 

1003 if coeff is S.NaN: 

1004 coeff = arg.limit(x, 0) 

1005 if coeff is S.ComplexInfinity: 

1006 try: 

1007 coeff, _ = arg.leadterm(x) 

1008 if coeff.has(log(x)): 

1009 raise ValueError() 

1010 except ValueError: 

1011 coeff = arg.limit(x, 0) 

1012 if coeff != S.Zero: 

1013 break 

1014 return coeff*cdir**minexp 

1015 

1016 def _eval_transpose(self): 

1017 from sympy.functions.elementary.complexes import conjugate 

1018 if (self.is_complex or self.is_infinite): 

1019 return self 

1020 elif self.is_hermitian: 

1021 return conjugate(self) 

1022 elif self.is_antihermitian: 

1023 return -conjugate(self) 

1024 

1025 def transpose(self): 

1026 from sympy.functions.elementary.complexes import transpose 

1027 return transpose(self) 

1028 

1029 def _eval_adjoint(self): 

1030 from sympy.functions.elementary.complexes import conjugate, transpose 

1031 if self.is_hermitian: 

1032 return self 

1033 elif self.is_antihermitian: 

1034 return -self 

1035 obj = self._eval_conjugate() 

1036 if obj is not None: 

1037 return transpose(obj) 

1038 obj = self._eval_transpose() 

1039 if obj is not None: 

1040 return conjugate(obj) 

1041 

1042 def adjoint(self): 

1043 from sympy.functions.elementary.complexes import adjoint 

1044 return adjoint(self) 

1045 

1046 @classmethod 

1047 def _parse_order(cls, order): 

1048 """Parse and configure the ordering of terms. """ 

1049 from sympy.polys.orderings import monomial_key 

1050 

1051 startswith = getattr(order, "startswith", None) 

1052 if startswith is None: 

1053 reverse = False 

1054 else: 

1055 reverse = startswith('rev-') 

1056 if reverse: 

1057 order = order[4:] 

1058 

1059 monom_key = monomial_key(order) 

1060 

1061 def neg(monom): 

1062 return tuple([neg(m) if isinstance(m, tuple) else -m for m in monom]) 

1063 

1064 def key(term): 

1065 _, ((re, im), monom, ncpart) = term 

1066 

1067 monom = neg(monom_key(monom)) 

1068 ncpart = tuple([e.sort_key(order=order) for e in ncpart]) 

1069 coeff = ((bool(im), im), (re, im)) 

1070 

1071 return monom, ncpart, coeff 

1072 

1073 return key, reverse 

1074 

1075 def as_ordered_factors(self, order=None): 

1076 """Return list of ordered factors (if Mul) else [self].""" 

1077 return [self] 

1078 

1079 def as_poly(self, *gens, **args): 

1080 """Converts ``self`` to a polynomial or returns ``None``. 

1081 

1082 Explanation 

1083 =========== 

1084 

1085 >>> from sympy import sin 

1086 >>> from sympy.abc import x, y 

1087 

1088 >>> print((x**2 + x*y).as_poly()) 

1089 Poly(x**2 + x*y, x, y, domain='ZZ') 

1090 

1091 >>> print((x**2 + x*y).as_poly(x, y)) 

1092 Poly(x**2 + x*y, x, y, domain='ZZ') 

1093 

1094 >>> print((x**2 + sin(y)).as_poly(x, y)) 

1095 None 

1096 

1097 """ 

1098 from sympy.polys.polyerrors import PolynomialError, GeneratorsNeeded 

1099 from sympy.polys.polytools import Poly 

1100 

1101 try: 

1102 poly = Poly(self, *gens, **args) 

1103 

1104 if not poly.is_Poly: 

1105 return None 

1106 else: 

1107 return poly 

1108 except (PolynomialError, GeneratorsNeeded): 

1109 # PolynomialError is caught for e.g. exp(x).as_poly(x) 

1110 # GeneratorsNeeded is caught for e.g. S(2).as_poly() 

1111 return None 

1112 

1113 def as_ordered_terms(self, order=None, data=False): 

1114 """ 

1115 Transform an expression to an ordered list of terms. 

1116 

1117 Examples 

1118 ======== 

1119 

1120 >>> from sympy import sin, cos 

1121 >>> from sympy.abc import x 

1122 

1123 >>> (sin(x)**2*cos(x) + sin(x)**2 + 1).as_ordered_terms() 

1124 [sin(x)**2*cos(x), sin(x)**2, 1] 

1125 

1126 """ 

1127 

1128 from .numbers import Number, NumberSymbol 

1129 

1130 if order is None and self.is_Add: 

1131 # Spot the special case of Add(Number, Mul(Number, expr)) with the 

1132 # first number positive and the second number negative 

1133 key = lambda x:not isinstance(x, (Number, NumberSymbol)) 

1134 add_args = sorted(Add.make_args(self), key=key) 

1135 if (len(add_args) == 2 

1136 and isinstance(add_args[0], (Number, NumberSymbol)) 

1137 and isinstance(add_args[1], Mul)): 

1138 mul_args = sorted(Mul.make_args(add_args[1]), key=key) 

1139 if (len(mul_args) == 2 

1140 and isinstance(mul_args[0], Number) 

1141 and add_args[0].is_positive 

1142 and mul_args[0].is_negative): 

1143 return add_args 

1144 

1145 key, reverse = self._parse_order(order) 

1146 terms, gens = self.as_terms() 

1147 

1148 if not any(term.is_Order for term, _ in terms): 

1149 ordered = sorted(terms, key=key, reverse=reverse) 

1150 else: 

1151 _terms, _order = [], [] 

1152 

1153 for term, repr in terms: 

1154 if not term.is_Order: 

1155 _terms.append((term, repr)) 

1156 else: 

1157 _order.append((term, repr)) 

1158 

1159 ordered = sorted(_terms, key=key, reverse=True) \ 

1160 + sorted(_order, key=key, reverse=True) 

1161 

1162 if data: 

1163 return ordered, gens 

1164 else: 

1165 return [term for term, _ in ordered] 

1166 

1167 def as_terms(self): 

1168 """Transform an expression to a list of terms. """ 

1169 from .exprtools import decompose_power 

1170 

1171 gens, terms = set(), [] 

1172 

1173 for term in Add.make_args(self): 

1174 coeff, _term = term.as_coeff_Mul() 

1175 

1176 coeff = complex(coeff) 

1177 cpart, ncpart = {}, [] 

1178 

1179 if _term is not S.One: 

1180 for factor in Mul.make_args(_term): 

1181 if factor.is_number: 

1182 try: 

1183 coeff *= complex(factor) 

1184 except (TypeError, ValueError): 

1185 pass 

1186 else: 

1187 continue 

1188 

1189 if factor.is_commutative: 

1190 base, exp = decompose_power(factor) 

1191 

1192 cpart[base] = exp 

1193 gens.add(base) 

1194 else: 

1195 ncpart.append(factor) 

1196 

1197 coeff = coeff.real, coeff.imag 

1198 ncpart = tuple(ncpart) 

1199 

1200 terms.append((term, (coeff, cpart, ncpart))) 

1201 

1202 gens = sorted(gens, key=default_sort_key) 

1203 

1204 k, indices = len(gens), {} 

1205 

1206 for i, g in enumerate(gens): 

1207 indices[g] = i 

1208 

1209 result = [] 

1210 

1211 for term, (coeff, cpart, ncpart) in terms: 

1212 monom = [0]*k 

1213 

1214 for base, exp in cpart.items(): 

1215 monom[indices[base]] = exp 

1216 

1217 result.append((term, (coeff, tuple(monom), ncpart))) 

1218 

1219 return result, gens 

1220 

1221 def removeO(self): 

1222 """Removes the additive O(..) symbol if there is one""" 

1223 return self 

1224 

1225 def getO(self): 

1226 """Returns the additive O(..) symbol if there is one, else None.""" 

1227 return None 

1228 

1229 def getn(self): 

1230 """ 

1231 Returns the order of the expression. 

1232 

1233 Explanation 

1234 =========== 

1235 

1236 The order is determined either from the O(...) term. If there 

1237 is no O(...) term, it returns None. 

1238 

1239 Examples 

1240 ======== 

1241 

1242 >>> from sympy import O 

1243 >>> from sympy.abc import x 

1244 >>> (1 + x + O(x**2)).getn() 

1245 2 

1246 >>> (1 + x).getn() 

1247 

1248 """ 

1249 o = self.getO() 

1250 if o is None: 

1251 return None 

1252 elif o.is_Order: 

1253 o = o.expr 

1254 if o is S.One: 

1255 return S.Zero 

1256 if o.is_Symbol: 

1257 return S.One 

1258 if o.is_Pow: 

1259 return o.args[1] 

1260 if o.is_Mul: # x**n*log(x)**n or x**n/log(x)**n 

1261 for oi in o.args: 

1262 if oi.is_Symbol: 

1263 return S.One 

1264 if oi.is_Pow: 

1265 from .symbol import Dummy, Symbol 

1266 syms = oi.atoms(Symbol) 

1267 if len(syms) == 1: 

1268 x = syms.pop() 

1269 oi = oi.subs(x, Dummy('x', positive=True)) 

1270 if oi.base.is_Symbol and oi.exp.is_Rational: 

1271 return abs(oi.exp) 

1272 

1273 raise NotImplementedError('not sure of order of %s' % o) 

1274 

1275 def count_ops(self, visual=None): 

1276 from .function import count_ops 

1277 return count_ops(self, visual) 

1278 

1279 def args_cnc(self, cset=False, warn=True, split_1=True): 

1280 """Return [commutative factors, non-commutative factors] of self. 

1281 

1282 Explanation 

1283 =========== 

1284 

1285 self is treated as a Mul and the ordering of the factors is maintained. 

1286 If ``cset`` is True the commutative factors will be returned in a set. 

1287 If there were repeated factors (as may happen with an unevaluated Mul) 

1288 then an error will be raised unless it is explicitly suppressed by 

1289 setting ``warn`` to False. 

1290 

1291 Note: -1 is always separated from a Number unless split_1 is False. 

1292 

1293 Examples 

1294 ======== 

1295 

1296 >>> from sympy import symbols, oo 

1297 >>> A, B = symbols('A B', commutative=0) 

1298 >>> x, y = symbols('x y') 

1299 >>> (-2*x*y).args_cnc() 

1300 [[-1, 2, x, y], []] 

1301 >>> (-2.5*x).args_cnc() 

1302 [[-1, 2.5, x], []] 

1303 >>> (-2*x*A*B*y).args_cnc() 

1304 [[-1, 2, x, y], [A, B]] 

1305 >>> (-2*x*A*B*y).args_cnc(split_1=False) 

1306 [[-2, x, y], [A, B]] 

1307 >>> (-2*x*y).args_cnc(cset=True) 

1308 [{-1, 2, x, y}, []] 

1309 

1310 The arg is always treated as a Mul: 

1311 

1312 >>> (-2 + x + A).args_cnc() 

1313 [[], [x - 2 + A]] 

1314 >>> (-oo).args_cnc() # -oo is a singleton 

1315 [[-1, oo], []] 

1316 """ 

1317 

1318 if self.is_Mul: 

1319 args = list(self.args) 

1320 else: 

1321 args = [self] 

1322 for i, mi in enumerate(args): 

1323 if not mi.is_commutative: 

1324 c = args[:i] 

1325 nc = args[i:] 

1326 break 

1327 else: 

1328 c = args 

1329 nc = [] 

1330 

1331 if c and split_1 and ( 

1332 c[0].is_Number and 

1333 c[0].is_extended_negative and 

1334 c[0] is not S.NegativeOne): 

1335 c[:1] = [S.NegativeOne, -c[0]] 

1336 

1337 if cset: 

1338 clen = len(c) 

1339 c = set(c) 

1340 if clen and warn and len(c) != clen: 

1341 raise ValueError('repeated commutative arguments: %s' % 

1342 [ci for ci in c if list(self.args).count(ci) > 1]) 

1343 return [c, nc] 

1344 

1345 def coeff(self, x, n=1, right=False, _first=True): 

1346 """ 

1347 Returns the coefficient from the term(s) containing ``x**n``. If ``n`` 

1348 is zero then all terms independent of ``x`` will be returned. 

1349 

1350 Explanation 

1351 =========== 

1352 

1353 When ``x`` is noncommutative, the coefficient to the left (default) or 

1354 right of ``x`` can be returned. The keyword 'right' is ignored when 

1355 ``x`` is commutative. 

1356 

1357 Examples 

1358 ======== 

1359 

1360 >>> from sympy import symbols 

1361 >>> from sympy.abc import x, y, z 

1362 

1363 You can select terms that have an explicit negative in front of them: 

1364 

1365 >>> (-x + 2*y).coeff(-1) 

1366 x 

1367 >>> (x - 2*y).coeff(-1) 

1368 2*y 

1369 

1370 You can select terms with no Rational coefficient: 

1371 

1372 >>> (x + 2*y).coeff(1) 

1373 x 

1374 >>> (3 + 2*x + 4*x**2).coeff(1) 

1375 0 

1376 

1377 You can select terms independent of x by making n=0; in this case 

1378 expr.as_independent(x)[0] is returned (and 0 will be returned instead 

1379 of None): 

1380 

1381 >>> (3 + 2*x + 4*x**2).coeff(x, 0) 

1382 3 

1383 >>> eq = ((x + 1)**3).expand() + 1 

1384 >>> eq 

1385 x**3 + 3*x**2 + 3*x + 2 

1386 >>> [eq.coeff(x, i) for i in reversed(range(4))] 

1387 [1, 3, 3, 2] 

1388 >>> eq -= 2 

1389 >>> [eq.coeff(x, i) for i in reversed(range(4))] 

1390 [1, 3, 3, 0] 

1391 

1392 You can select terms that have a numerical term in front of them: 

1393 

1394 >>> (-x - 2*y).coeff(2) 

1395 -y 

1396 >>> from sympy import sqrt 

1397 >>> (x + sqrt(2)*x).coeff(sqrt(2)) 

1398 x 

1399 

1400 The matching is exact: 

1401 

1402 >>> (3 + 2*x + 4*x**2).coeff(x) 

1403 2 

1404 >>> (3 + 2*x + 4*x**2).coeff(x**2) 

1405 4 

1406 >>> (3 + 2*x + 4*x**2).coeff(x**3) 

1407 0 

1408 >>> (z*(x + y)**2).coeff((x + y)**2) 

1409 z 

1410 >>> (z*(x + y)**2).coeff(x + y) 

1411 0 

1412 

1413 In addition, no factoring is done, so 1 + z*(1 + y) is not obtained 

1414 from the following: 

1415 

1416 >>> (x + z*(x + x*y)).coeff(x) 

1417 1 

1418 

1419 If such factoring is desired, factor_terms can be used first: 

1420 

1421 >>> from sympy import factor_terms 

1422 >>> factor_terms(x + z*(x + x*y)).coeff(x) 

1423 z*(y + 1) + 1 

1424 

1425 >>> n, m, o = symbols('n m o', commutative=False) 

1426 >>> n.coeff(n) 

1427 1 

1428 >>> (3*n).coeff(n) 

1429 3 

1430 >>> (n*m + m*n*m).coeff(n) # = (1 + m)*n*m 

1431 1 + m 

1432 >>> (n*m + m*n*m).coeff(n, right=True) # = (1 + m)*n*m 

1433 m 

1434 

1435 If there is more than one possible coefficient 0 is returned: 

1436 

1437 >>> (n*m + m*n).coeff(n) 

1438 0 

1439 

1440 If there is only one possible coefficient, it is returned: 

1441 

1442 >>> (n*m + x*m*n).coeff(m*n) 

1443 x 

1444 >>> (n*m + x*m*n).coeff(m*n, right=1) 

1445 1 

1446 

1447 See Also 

1448 ======== 

1449 

1450 as_coefficient: separate the expression into a coefficient and factor 

1451 as_coeff_Add: separate the additive constant from an expression 

1452 as_coeff_Mul: separate the multiplicative constant from an expression 

1453 as_independent: separate x-dependent terms/factors from others 

1454 sympy.polys.polytools.Poly.coeff_monomial: efficiently find the single coefficient of a monomial in Poly 

1455 sympy.polys.polytools.Poly.nth: like coeff_monomial but powers of monomial terms are used 

1456 """ 

1457 x = sympify(x) 

1458 if not isinstance(x, Basic): 

1459 return S.Zero 

1460 

1461 n = as_int(n) 

1462 

1463 if not x: 

1464 return S.Zero 

1465 

1466 if x == self: 

1467 if n == 1: 

1468 return S.One 

1469 return S.Zero 

1470 

1471 if x is S.One: 

1472 co = [a for a in Add.make_args(self) 

1473 if a.as_coeff_Mul()[0] is S.One] 

1474 if not co: 

1475 return S.Zero 

1476 return Add(*co) 

1477 

1478 if n == 0: 

1479 if x.is_Add and self.is_Add: 

1480 c = self.coeff(x, right=right) 

1481 if not c: 

1482 return S.Zero 

1483 if not right: 

1484 return self - Add(*[a*x for a in Add.make_args(c)]) 

1485 return self - Add(*[x*a for a in Add.make_args(c)]) 

1486 return self.as_independent(x, as_Add=True)[0] 

1487 

1488 # continue with the full method, looking for this power of x: 

1489 x = x**n 

1490 

1491 def incommon(l1, l2): 

1492 if not l1 or not l2: 

1493 return [] 

1494 n = min(len(l1), len(l2)) 

1495 for i in range(n): 

1496 if l1[i] != l2[i]: 

1497 return l1[:i] 

1498 return l1[:] 

1499 

1500 def find(l, sub, first=True): 

1501 """ Find where list sub appears in list l. When ``first`` is True 

1502 the first occurrence from the left is returned, else the last 

1503 occurrence is returned. Return None if sub is not in l. 

1504 

1505 Examples 

1506 ======== 

1507 

1508 >> l = range(5)*2 

1509 >> find(l, [2, 3]) 

1510 2 

1511 >> find(l, [2, 3], first=0) 

1512 7 

1513 >> find(l, [2, 4]) 

1514 None 

1515 

1516 """ 

1517 if not sub or not l or len(sub) > len(l): 

1518 return None 

1519 n = len(sub) 

1520 if not first: 

1521 l.reverse() 

1522 sub.reverse() 

1523 for i in range(len(l) - n + 1): 

1524 if all(l[i + j] == sub[j] for j in range(n)): 

1525 break 

1526 else: 

1527 i = None 

1528 if not first: 

1529 l.reverse() 

1530 sub.reverse() 

1531 if i is not None and not first: 

1532 i = len(l) - (i + n) 

1533 return i 

1534 

1535 co = [] 

1536 args = Add.make_args(self) 

1537 self_c = self.is_commutative 

1538 x_c = x.is_commutative 

1539 if self_c and not x_c: 

1540 return S.Zero 

1541 if _first and self.is_Add and not self_c and not x_c: 

1542 # get the part that depends on x exactly 

1543 xargs = Mul.make_args(x) 

1544 d = Add(*[i for i in Add.make_args(self.as_independent(x)[1]) 

1545 if all(xi in Mul.make_args(i) for xi in xargs)]) 

1546 rv = d.coeff(x, right=right, _first=False) 

1547 if not rv.is_Add or not right: 

1548 return rv 

1549 c_part, nc_part = zip(*[i.args_cnc() for i in rv.args]) 

1550 if has_variety(c_part): 

1551 return rv 

1552 return Add(*[Mul._from_args(i) for i in nc_part]) 

1553 

1554 one_c = self_c or x_c 

1555 xargs, nx = x.args_cnc(cset=True, warn=bool(not x_c)) 

1556 # find the parts that pass the commutative terms 

1557 for a in args: 

1558 margs, nc = a.args_cnc(cset=True, warn=bool(not self_c)) 

1559 if nc is None: 

1560 nc = [] 

1561 if len(xargs) > len(margs): 

1562 continue 

1563 resid = margs.difference(xargs) 

1564 if len(resid) + len(xargs) == len(margs): 

1565 if one_c: 

1566 co.append(Mul(*(list(resid) + nc))) 

1567 else: 

1568 co.append((resid, nc)) 

1569 if one_c: 

1570 if co == []: 

1571 return S.Zero 

1572 elif co: 

1573 return Add(*co) 

1574 else: # both nc 

1575 # now check the non-comm parts 

1576 if not co: 

1577 return S.Zero 

1578 if all(n == co[0][1] for r, n in co): 

1579 ii = find(co[0][1], nx, right) 

1580 if ii is not None: 

1581 if not right: 

1582 return Mul(Add(*[Mul(*r) for r, c in co]), Mul(*co[0][1][:ii])) 

1583 else: 

1584 return Mul(*co[0][1][ii + len(nx):]) 

1585 beg = reduce(incommon, (n[1] for n in co)) 

1586 if beg: 

1587 ii = find(beg, nx, right) 

1588 if ii is not None: 

1589 if not right: 

1590 gcdc = co[0][0] 

1591 for i in range(1, len(co)): 

1592 gcdc = gcdc.intersection(co[i][0]) 

1593 if not gcdc: 

1594 break 

1595 return Mul(*(list(gcdc) + beg[:ii])) 

1596 else: 

1597 m = ii + len(nx) 

1598 return Add(*[Mul(*(list(r) + n[m:])) for r, n in co]) 

1599 end = list(reversed( 

1600 reduce(incommon, (list(reversed(n[1])) for n in co)))) 

1601 if end: 

1602 ii = find(end, nx, right) 

1603 if ii is not None: 

1604 if not right: 

1605 return Add(*[Mul(*(list(r) + n[:-len(end) + ii])) for r, n in co]) 

1606 else: 

1607 return Mul(*end[ii + len(nx):]) 

1608 # look for single match 

1609 hit = None 

1610 for i, (r, n) in enumerate(co): 

1611 ii = find(n, nx, right) 

1612 if ii is not None: 

1613 if not hit: 

1614 hit = ii, r, n 

1615 else: 

1616 break 

1617 else: 

1618 if hit: 

1619 ii, r, n = hit 

1620 if not right: 

1621 return Mul(*(list(r) + n[:ii])) 

1622 else: 

1623 return Mul(*n[ii + len(nx):]) 

1624 

1625 return S.Zero 

1626 

1627 def as_expr(self, *gens): 

1628 """ 

1629 Convert a polynomial to a SymPy expression. 

1630 

1631 Examples 

1632 ======== 

1633 

1634 >>> from sympy import sin 

1635 >>> from sympy.abc import x, y 

1636 

1637 >>> f = (x**2 + x*y).as_poly(x, y) 

1638 >>> f.as_expr() 

1639 x**2 + x*y 

1640 

1641 >>> sin(x).as_expr() 

1642 sin(x) 

1643 

1644 """ 

1645 return self 

1646 

1647 def as_coefficient(self, expr): 

1648 """ 

1649 Extracts symbolic coefficient at the given expression. In 

1650 other words, this functions separates 'self' into the product 

1651 of 'expr' and 'expr'-free coefficient. If such separation 

1652 is not possible it will return None. 

1653 

1654 Examples 

1655 ======== 

1656 

1657 >>> from sympy import E, pi, sin, I, Poly 

1658 >>> from sympy.abc import x 

1659 

1660 >>> E.as_coefficient(E) 

1661 1 

1662 >>> (2*E).as_coefficient(E) 

1663 2 

1664 >>> (2*sin(E)*E).as_coefficient(E) 

1665 

1666 Two terms have E in them so a sum is returned. (If one were 

1667 desiring the coefficient of the term exactly matching E then 

1668 the constant from the returned expression could be selected. 

1669 Or, for greater precision, a method of Poly can be used to 

1670 indicate the desired term from which the coefficient is 

1671 desired.) 

1672 

1673 >>> (2*E + x*E).as_coefficient(E) 

1674 x + 2 

1675 >>> _.args[0] # just want the exact match 

1676 2 

1677 >>> p = Poly(2*E + x*E); p 

1678 Poly(x*E + 2*E, x, E, domain='ZZ') 

1679 >>> p.coeff_monomial(E) 

1680 2 

1681 >>> p.nth(0, 1) 

1682 2 

1683 

1684 Since the following cannot be written as a product containing 

1685 E as a factor, None is returned. (If the coefficient ``2*x`` is 

1686 desired then the ``coeff`` method should be used.) 

1687 

1688 >>> (2*E*x + x).as_coefficient(E) 

1689 >>> (2*E*x + x).coeff(E) 

1690 2*x 

1691 

1692 >>> (E*(x + 1) + x).as_coefficient(E) 

1693 

1694 >>> (2*pi*I).as_coefficient(pi*I) 

1695 2 

1696 >>> (2*I).as_coefficient(pi*I) 

1697 

1698 See Also 

1699 ======== 

1700 

1701 coeff: return sum of terms have a given factor 

1702 as_coeff_Add: separate the additive constant from an expression 

1703 as_coeff_Mul: separate the multiplicative constant from an expression 

1704 as_independent: separate x-dependent terms/factors from others 

1705 sympy.polys.polytools.Poly.coeff_monomial: efficiently find the single coefficient of a monomial in Poly 

1706 sympy.polys.polytools.Poly.nth: like coeff_monomial but powers of monomial terms are used 

1707 

1708 

1709 """ 

1710 

1711 r = self.extract_multiplicatively(expr) 

1712 if r and not r.has(expr): 

1713 return r 

1714 

1715 def as_independent(self, *deps, **hint) -> tuple[Expr, Expr]: 

1716 """ 

1717 A mostly naive separation of a Mul or Add into arguments that are not 

1718 are dependent on deps. To obtain as complete a separation of variables 

1719 as possible, use a separation method first, e.g.: 

1720 

1721 * separatevars() to change Mul, Add and Pow (including exp) into Mul 

1722 * .expand(mul=True) to change Add or Mul into Add 

1723 * .expand(log=True) to change log expr into an Add 

1724 

1725 The only non-naive thing that is done here is to respect noncommutative 

1726 ordering of variables and to always return (0, 0) for `self` of zero 

1727 regardless of hints. 

1728 

1729 For nonzero `self`, the returned tuple (i, d) has the 

1730 following interpretation: 

1731 

1732 * i will has no variable that appears in deps 

1733 * d will either have terms that contain variables that are in deps, or 

1734 be equal to 0 (when self is an Add) or 1 (when self is a Mul) 

1735 * if self is an Add then self = i + d 

1736 * if self is a Mul then self = i*d 

1737 * otherwise (self, S.One) or (S.One, self) is returned. 

1738 

1739 To force the expression to be treated as an Add, use the hint as_Add=True 

1740 

1741 Examples 

1742 ======== 

1743 

1744 -- self is an Add 

1745 

1746 >>> from sympy import sin, cos, exp 

1747 >>> from sympy.abc import x, y, z 

1748 

1749 >>> (x + x*y).as_independent(x) 

1750 (0, x*y + x) 

1751 >>> (x + x*y).as_independent(y) 

1752 (x, x*y) 

1753 >>> (2*x*sin(x) + y + x + z).as_independent(x) 

1754 (y + z, 2*x*sin(x) + x) 

1755 >>> (2*x*sin(x) + y + x + z).as_independent(x, y) 

1756 (z, 2*x*sin(x) + x + y) 

1757 

1758 -- self is a Mul 

1759 

1760 >>> (x*sin(x)*cos(y)).as_independent(x) 

1761 (cos(y), x*sin(x)) 

1762 

1763 non-commutative terms cannot always be separated out when self is a Mul 

1764 

1765 >>> from sympy import symbols 

1766 >>> n1, n2, n3 = symbols('n1 n2 n3', commutative=False) 

1767 >>> (n1 + n1*n2).as_independent(n2) 

1768 (n1, n1*n2) 

1769 >>> (n2*n1 + n1*n2).as_independent(n2) 

1770 (0, n1*n2 + n2*n1) 

1771 >>> (n1*n2*n3).as_independent(n1) 

1772 (1, n1*n2*n3) 

1773 >>> (n1*n2*n3).as_independent(n2) 

1774 (n1, n2*n3) 

1775 >>> ((x-n1)*(x-y)).as_independent(x) 

1776 (1, (x - y)*(x - n1)) 

1777 

1778 -- self is anything else: 

1779 

1780 >>> (sin(x)).as_independent(x) 

1781 (1, sin(x)) 

1782 >>> (sin(x)).as_independent(y) 

1783 (sin(x), 1) 

1784 >>> exp(x+y).as_independent(x) 

1785 (1, exp(x + y)) 

1786 

1787 -- force self to be treated as an Add: 

1788 

1789 >>> (3*x).as_independent(x, as_Add=True) 

1790 (0, 3*x) 

1791 

1792 -- force self to be treated as a Mul: 

1793 

1794 >>> (3+x).as_independent(x, as_Add=False) 

1795 (1, x + 3) 

1796 >>> (-3+x).as_independent(x, as_Add=False) 

1797 (1, x - 3) 

1798 

1799 Note how the below differs from the above in making the 

1800 constant on the dep term positive. 

1801 

1802 >>> (y*(-3+x)).as_independent(x) 

1803 (y, x - 3) 

1804 

1805 -- use .as_independent() for true independence testing instead 

1806 of .has(). The former considers only symbols in the free 

1807 symbols while the latter considers all symbols 

1808 

1809 >>> from sympy import Integral 

1810 >>> I = Integral(x, (x, 1, 2)) 

1811 >>> I.has(x) 

1812 True 

1813 >>> x in I.free_symbols 

1814 False 

1815 >>> I.as_independent(x) == (I, 1) 

1816 True 

1817 >>> (I + x).as_independent(x) == (I, x) 

1818 True 

1819 

1820 Note: when trying to get independent terms, a separation method 

1821 might need to be used first. In this case, it is important to keep 

1822 track of what you send to this routine so you know how to interpret 

1823 the returned values 

1824 

1825 >>> from sympy import separatevars, log 

1826 >>> separatevars(exp(x+y)).as_independent(x) 

1827 (exp(y), exp(x)) 

1828 >>> (x + x*y).as_independent(y) 

1829 (x, x*y) 

1830 >>> separatevars(x + x*y).as_independent(y) 

1831 (x, y + 1) 

1832 >>> (x*(1 + y)).as_independent(y) 

1833 (x, y + 1) 

1834 >>> (x*(1 + y)).expand(mul=True).as_independent(y) 

1835 (x, x*y) 

1836 >>> a, b=symbols('a b', positive=True) 

1837 >>> (log(a*b).expand(log=True)).as_independent(b) 

1838 (log(a), log(b)) 

1839 

1840 See Also 

1841 ======== 

1842 

1843 separatevars 

1844 expand_log 

1845 sympy.core.add.Add.as_two_terms 

1846 sympy.core.mul.Mul.as_two_terms 

1847 as_coeff_mul 

1848 """ 

1849 from .symbol import Symbol 

1850 from .add import _unevaluated_Add 

1851 from .mul import _unevaluated_Mul 

1852 

1853 if self is S.Zero: 

1854 return (self, self) 

1855 

1856 func = self.func 

1857 if hint.get('as_Add', isinstance(self, Add) ): 

1858 want = Add 

1859 else: 

1860 want = Mul 

1861 

1862 # sift out deps into symbolic and other and ignore 

1863 # all symbols but those that are in the free symbols 

1864 sym = set() 

1865 other = [] 

1866 for d in deps: 

1867 if isinstance(d, Symbol): # Symbol.is_Symbol is True 

1868 sym.add(d) 

1869 else: 

1870 other.append(d) 

1871 

1872 def has(e): 

1873 """return the standard has() if there are no literal symbols, else 

1874 check to see that symbol-deps are in the free symbols.""" 

1875 has_other = e.has(*other) 

1876 if not sym: 

1877 return has_other 

1878 return has_other or e.has(*(e.free_symbols & sym)) 

1879 

1880 if (want is not func or 

1881 func is not Add and func is not Mul): 

1882 if has(self): 

1883 return (want.identity, self) 

1884 else: 

1885 return (self, want.identity) 

1886 else: 

1887 if func is Add: 

1888 args = list(self.args) 

1889 else: 

1890 args, nc = self.args_cnc() 

1891 

1892 d = sift(args, has) 

1893 depend = d[True] 

1894 indep = d[False] 

1895 if func is Add: # all terms were treated as commutative 

1896 return (Add(*indep), _unevaluated_Add(*depend)) 

1897 else: # handle noncommutative by stopping at first dependent term 

1898 for i, n in enumerate(nc): 

1899 if has(n): 

1900 depend.extend(nc[i:]) 

1901 break 

1902 indep.append(n) 

1903 return Mul(*indep), ( 

1904 Mul(*depend, evaluate=False) if nc else 

1905 _unevaluated_Mul(*depend)) 

1906 

1907 def as_real_imag(self, deep=True, **hints): 

1908 """Performs complex expansion on 'self' and returns a tuple 

1909 containing collected both real and imaginary parts. This 

1910 method cannot be confused with re() and im() functions, 

1911 which does not perform complex expansion at evaluation. 

1912 

1913 However it is possible to expand both re() and im() 

1914 functions and get exactly the same results as with 

1915 a single call to this function. 

1916 

1917 >>> from sympy import symbols, I 

1918 

1919 >>> x, y = symbols('x,y', real=True) 

1920 

1921 >>> (x + y*I).as_real_imag() 

1922 (x, y) 

1923 

1924 >>> from sympy.abc import z, w 

1925 

1926 >>> (z + w*I).as_real_imag() 

1927 (re(z) - im(w), re(w) + im(z)) 

1928 

1929 """ 

1930 if hints.get('ignore') == self: 

1931 return None 

1932 else: 

1933 from sympy.functions.elementary.complexes import im, re 

1934 return (re(self), im(self)) 

1935 

1936 def as_powers_dict(self): 

1937 """Return self as a dictionary of factors with each factor being 

1938 treated as a power. The keys are the bases of the factors and the 

1939 values, the corresponding exponents. The resulting dictionary should 

1940 be used with caution if the expression is a Mul and contains non- 

1941 commutative factors since the order that they appeared will be lost in 

1942 the dictionary. 

1943 

1944 See Also 

1945 ======== 

1946 as_ordered_factors: An alternative for noncommutative applications, 

1947 returning an ordered list of factors. 

1948 args_cnc: Similar to as_ordered_factors, but guarantees separation 

1949 of commutative and noncommutative factors. 

1950 """ 

1951 d = defaultdict(int) 

1952 d.update([self.as_base_exp()]) 

1953 return d 

1954 

1955 def as_coefficients_dict(self, *syms): 

1956 """Return a dictionary mapping terms to their Rational coefficient. 

1957 Since the dictionary is a defaultdict, inquiries about terms which 

1958 were not present will return a coefficient of 0. 

1959 

1960 If symbols ``syms`` are provided, any multiplicative terms 

1961 independent of them will be considered a coefficient and a 

1962 regular dictionary of syms-dependent generators as keys and 

1963 their corresponding coefficients as values will be returned. 

1964 

1965 Examples 

1966 ======== 

1967 

1968 >>> from sympy.abc import a, x, y 

1969 >>> (3*x + a*x + 4).as_coefficients_dict() 

1970 {1: 4, x: 3, a*x: 1} 

1971 >>> _[a] 

1972 0 

1973 >>> (3*a*x).as_coefficients_dict() 

1974 {a*x: 3} 

1975 >>> (3*a*x).as_coefficients_dict(x) 

1976 {x: 3*a} 

1977 >>> (3*a*x).as_coefficients_dict(y) 

1978 {1: 3*a*x} 

1979 

1980 """ 

1981 d = defaultdict(list) 

1982 if not syms: 

1983 for ai in Add.make_args(self): 

1984 c, m = ai.as_coeff_Mul() 

1985 d[m].append(c) 

1986 for k, v in d.items(): 

1987 if len(v) == 1: 

1988 d[k] = v[0] 

1989 else: 

1990 d[k] = Add(*v) 

1991 else: 

1992 ind, dep = self.as_independent(*syms, as_Add=True) 

1993 for i in Add.make_args(dep): 

1994 if i.is_Mul: 

1995 c, x = i.as_coeff_mul(*syms) 

1996 if c is S.One: 

1997 d[i].append(c) 

1998 else: 

1999 d[i._new_rawargs(*x)].append(c) 

2000 elif i: 

2001 d[i].append(S.One) 

2002 d = {k: Add(*d[k]) for k in d} 

2003 if ind is not S.Zero: 

2004 d.update({S.One: ind}) 

2005 di = defaultdict(int) 

2006 di.update(d) 

2007 return di 

2008 

2009 def as_base_exp(self) -> tuple[Expr, Expr]: 

2010 # a -> b ** e 

2011 return self, S.One 

2012 

2013 def as_coeff_mul(self, *deps, **kwargs) -> tuple[Expr, tuple[Expr, ...]]: 

2014 """Return the tuple (c, args) where self is written as a Mul, ``m``. 

2015 

2016 c should be a Rational multiplied by any factors of the Mul that are 

2017 independent of deps. 

2018 

2019 args should be a tuple of all other factors of m; args is empty 

2020 if self is a Number or if self is independent of deps (when given). 

2021 

2022 This should be used when you do not know if self is a Mul or not but 

2023 you want to treat self as a Mul or if you want to process the 

2024 individual arguments of the tail of self as a Mul. 

2025 

2026 - if you know self is a Mul and want only the head, use self.args[0]; 

2027 - if you do not want to process the arguments of the tail but need the 

2028 tail then use self.as_two_terms() which gives the head and tail; 

2029 - if you want to split self into an independent and dependent parts 

2030 use ``self.as_independent(*deps)`` 

2031 

2032 >>> from sympy import S 

2033 >>> from sympy.abc import x, y 

2034 >>> (S(3)).as_coeff_mul() 

2035 (3, ()) 

2036 >>> (3*x*y).as_coeff_mul() 

2037 (3, (x, y)) 

2038 >>> (3*x*y).as_coeff_mul(x) 

2039 (3*y, (x,)) 

2040 >>> (3*y).as_coeff_mul(x) 

2041 (3*y, ()) 

2042 """ 

2043 if deps: 

2044 if not self.has(*deps): 

2045 return self, () 

2046 return S.One, (self,) 

2047 

2048 def as_coeff_add(self, *deps) -> tuple[Expr, tuple[Expr, ...]]: 

2049 """Return the tuple (c, args) where self is written as an Add, ``a``. 

2050 

2051 c should be a Rational added to any terms of the Add that are 

2052 independent of deps. 

2053 

2054 args should be a tuple of all other terms of ``a``; args is empty 

2055 if self is a Number or if self is independent of deps (when given). 

2056 

2057 This should be used when you do not know if self is an Add or not but 

2058 you want to treat self as an Add or if you want to process the 

2059 individual arguments of the tail of self as an Add. 

2060 

2061 - if you know self is an Add and want only the head, use self.args[0]; 

2062 - if you do not want to process the arguments of the tail but need the 

2063 tail then use self.as_two_terms() which gives the head and tail. 

2064 - if you want to split self into an independent and dependent parts 

2065 use ``self.as_independent(*deps)`` 

2066 

2067 >>> from sympy import S 

2068 >>> from sympy.abc import x, y 

2069 >>> (S(3)).as_coeff_add() 

2070 (3, ()) 

2071 >>> (3 + x).as_coeff_add() 

2072 (3, (x,)) 

2073 >>> (3 + x + y).as_coeff_add(x) 

2074 (y + 3, (x,)) 

2075 >>> (3 + y).as_coeff_add(x) 

2076 (y + 3, ()) 

2077 

2078 """ 

2079 if deps: 

2080 if not self.has_free(*deps): 

2081 return self, () 

2082 return S.Zero, (self,) 

2083 

2084 def primitive(self): 

2085 """Return the positive Rational that can be extracted non-recursively 

2086 from every term of self (i.e., self is treated like an Add). This is 

2087 like the as_coeff_Mul() method but primitive always extracts a positive 

2088 Rational (never a negative or a Float). 

2089 

2090 Examples 

2091 ======== 

2092 

2093 >>> from sympy.abc import x 

2094 >>> (3*(x + 1)**2).primitive() 

2095 (3, (x + 1)**2) 

2096 >>> a = (6*x + 2); a.primitive() 

2097 (2, 3*x + 1) 

2098 >>> b = (x/2 + 3); b.primitive() 

2099 (1/2, x + 6) 

2100 >>> (a*b).primitive() == (1, a*b) 

2101 True 

2102 """ 

2103 if not self: 

2104 return S.One, S.Zero 

2105 c, r = self.as_coeff_Mul(rational=True) 

2106 if c.is_negative: 

2107 c, r = -c, -r 

2108 return c, r 

2109 

2110 def as_content_primitive(self, radical=False, clear=True): 

2111 """This method should recursively remove a Rational from all arguments 

2112 and return that (content) and the new self (primitive). The content 

2113 should always be positive and ``Mul(*foo.as_content_primitive()) == foo``. 

2114 The primitive need not be in canonical form and should try to preserve 

2115 the underlying structure if possible (i.e. expand_mul should not be 

2116 applied to self). 

2117 

2118 Examples 

2119 ======== 

2120 

2121 >>> from sympy import sqrt 

2122 >>> from sympy.abc import x, y, z 

2123 

2124 >>> eq = 2 + 2*x + 2*y*(3 + 3*y) 

2125 

2126 The as_content_primitive function is recursive and retains structure: 

2127 

2128 >>> eq.as_content_primitive() 

2129 (2, x + 3*y*(y + 1) + 1) 

2130 

2131 Integer powers will have Rationals extracted from the base: 

2132 

2133 >>> ((2 + 6*x)**2).as_content_primitive() 

2134 (4, (3*x + 1)**2) 

2135 >>> ((2 + 6*x)**(2*y)).as_content_primitive() 

2136 (1, (2*(3*x + 1))**(2*y)) 

2137 

2138 Terms may end up joining once their as_content_primitives are added: 

2139 

2140 >>> ((5*(x*(1 + y)) + 2*x*(3 + 3*y))).as_content_primitive() 

2141 (11, x*(y + 1)) 

2142 >>> ((3*(x*(1 + y)) + 2*x*(3 + 3*y))).as_content_primitive() 

2143 (9, x*(y + 1)) 

2144 >>> ((3*(z*(1 + y)) + 2.0*x*(3 + 3*y))).as_content_primitive() 

2145 (1, 6.0*x*(y + 1) + 3*z*(y + 1)) 

2146 >>> ((5*(x*(1 + y)) + 2*x*(3 + 3*y))**2).as_content_primitive() 

2147 (121, x**2*(y + 1)**2) 

2148 >>> ((x*(1 + y) + 0.4*x*(3 + 3*y))**2).as_content_primitive() 

2149 (1, 4.84*x**2*(y + 1)**2) 

2150 

2151 Radical content can also be factored out of the primitive: 

2152 

2153 >>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True) 

2154 (2, sqrt(2)*(1 + 2*sqrt(5))) 

2155 

2156 If clear=False (default is True) then content will not be removed 

2157 from an Add if it can be distributed to leave one or more 

2158 terms with integer coefficients. 

2159 

2160 >>> (x/2 + y).as_content_primitive() 

2161 (1/2, x + 2*y) 

2162 >>> (x/2 + y).as_content_primitive(clear=False) 

2163 (1, x/2 + y) 

2164 """ 

2165 return S.One, self 

2166 

2167 def as_numer_denom(self): 

2168 """Return the numerator and the denominator of an expression. 

2169 

2170 expression -> a/b -> a, b 

2171 

2172 This is just a stub that should be defined by 

2173 an object's class methods to get anything else. 

2174 

2175 See Also 

2176 ======== 

2177 

2178 normal: return ``a/b`` instead of ``(a, b)`` 

2179 

2180 """ 

2181 return self, S.One 

2182 

2183 def normal(self): 

2184 """Return the expression as a fraction. 

2185 

2186 expression -> a/b 

2187 

2188 See Also 

2189 ======== 

2190 

2191 as_numer_denom: return ``(a, b)`` instead of ``a/b`` 

2192 

2193 """ 

2194 from .mul import _unevaluated_Mul 

2195 n, d = self.as_numer_denom() 

2196 if d is S.One: 

2197 return n 

2198 if d.is_Number: 

2199 return _unevaluated_Mul(n, 1/d) 

2200 else: 

2201 return n/d 

2202 

2203 def extract_multiplicatively(self, c): 

2204 """Return None if it's not possible to make self in the form 

2205 c * something in a nice way, i.e. preserving the properties 

2206 of arguments of self. 

2207 

2208 Examples 

2209 ======== 

2210 

2211 >>> from sympy import symbols, Rational 

2212 

2213 >>> x, y = symbols('x,y', real=True) 

2214 

2215 >>> ((x*y)**3).extract_multiplicatively(x**2 * y) 

2216 x*y**2 

2217 

2218 >>> ((x*y)**3).extract_multiplicatively(x**4 * y) 

2219 

2220 >>> (2*x).extract_multiplicatively(2) 

2221 x 

2222 

2223 >>> (2*x).extract_multiplicatively(3) 

2224 

2225 >>> (Rational(1, 2)*x).extract_multiplicatively(3) 

2226 x/6 

2227 

2228 """ 

2229 from sympy.functions.elementary.exponential import exp 

2230 from .add import _unevaluated_Add 

2231 c = sympify(c) 

2232 if self is S.NaN: 

2233 return None 

2234 if c is S.One: 

2235 return self 

2236 elif c == self: 

2237 return S.One 

2238 

2239 if c.is_Add: 

2240 cc, pc = c.primitive() 

2241 if cc is not S.One: 

2242 c = Mul(cc, pc, evaluate=False) 

2243 

2244 if c.is_Mul: 

2245 a, b = c.as_two_terms() 

2246 x = self.extract_multiplicatively(a) 

2247 if x is not None: 

2248 return x.extract_multiplicatively(b) 

2249 else: 

2250 return x 

2251 

2252 quotient = self / c 

2253 if self.is_Number: 

2254 if self is S.Infinity: 

2255 if c.is_positive: 

2256 return S.Infinity 

2257 elif self is S.NegativeInfinity: 

2258 if c.is_negative: 

2259 return S.Infinity 

2260 elif c.is_positive: 

2261 return S.NegativeInfinity 

2262 elif self is S.ComplexInfinity: 

2263 if not c.is_zero: 

2264 return S.ComplexInfinity 

2265 elif self.is_Integer: 

2266 if not quotient.is_Integer: 

2267 return None 

2268 elif self.is_positive and quotient.is_negative: 

2269 return None 

2270 else: 

2271 return quotient 

2272 elif self.is_Rational: 

2273 if not quotient.is_Rational: 

2274 return None 

2275 elif self.is_positive and quotient.is_negative: 

2276 return None 

2277 else: 

2278 return quotient 

2279 elif self.is_Float: 

2280 if not quotient.is_Float: 

2281 return None 

2282 elif self.is_positive and quotient.is_negative: 

2283 return None 

2284 else: 

2285 return quotient 

2286 elif self.is_NumberSymbol or self.is_Symbol or self is S.ImaginaryUnit: 

2287 if quotient.is_Mul and len(quotient.args) == 2: 

2288 if quotient.args[0].is_Integer and quotient.args[0].is_positive and quotient.args[1] == self: 

2289 return quotient 

2290 elif quotient.is_Integer and c.is_Number: 

2291 return quotient 

2292 elif self.is_Add: 

2293 cs, ps = self.primitive() 

2294 # assert cs >= 1 

2295 if c.is_Number and c is not S.NegativeOne: 

2296 # assert c != 1 (handled at top) 

2297 if cs is not S.One: 

2298 if c.is_negative: 

2299 xc = -(cs.extract_multiplicatively(-c)) 

2300 else: 

2301 xc = cs.extract_multiplicatively(c) 

2302 if xc is not None: 

2303 return xc*ps # rely on 2-arg Mul to restore Add 

2304 return # |c| != 1 can only be extracted from cs 

2305 if c == ps: 

2306 return cs 

2307 # check args of ps 

2308 newargs = [] 

2309 for arg in ps.args: 

2310 newarg = arg.extract_multiplicatively(c) 

2311 if newarg is None: 

2312 return # all or nothing 

2313 newargs.append(newarg) 

2314 if cs is not S.One: 

2315 args = [cs*t for t in newargs] 

2316 # args may be in different order 

2317 return _unevaluated_Add(*args) 

2318 else: 

2319 return Add._from_args(newargs) 

2320 elif self.is_Mul: 

2321 args = list(self.args) 

2322 for i, arg in enumerate(args): 

2323 newarg = arg.extract_multiplicatively(c) 

2324 if newarg is not None: 

2325 args[i] = newarg 

2326 return Mul(*args) 

2327 elif self.is_Pow or isinstance(self, exp): 

2328 sb, se = self.as_base_exp() 

2329 cb, ce = c.as_base_exp() 

2330 if cb == sb: 

2331 new_exp = se.extract_additively(ce) 

2332 if new_exp is not None: 

2333 return Pow(sb, new_exp) 

2334 elif c == sb: 

2335 new_exp = self.exp.extract_additively(1) 

2336 if new_exp is not None: 

2337 return Pow(sb, new_exp) 

2338 

2339 def extract_additively(self, c): 

2340 """Return self - c if it's possible to subtract c from self and 

2341 make all matching coefficients move towards zero, else return None. 

2342 

2343 Examples 

2344 ======== 

2345 

2346 >>> from sympy.abc import x, y 

2347 >>> e = 2*x + 3 

2348 >>> e.extract_additively(x + 1) 

2349 x + 2 

2350 >>> e.extract_additively(3*x) 

2351 >>> e.extract_additively(4) 

2352 >>> (y*(x + 1)).extract_additively(x + 1) 

2353 >>> ((x + 1)*(x + 2*y + 1) + 3).extract_additively(x + 1) 

2354 (x + 1)*(x + 2*y) + 3 

2355 

2356 See Also 

2357 ======== 

2358 extract_multiplicatively 

2359 coeff 

2360 as_coefficient 

2361 

2362 """ 

2363 

2364 c = sympify(c) 

2365 if self is S.NaN: 

2366 return None 

2367 if c.is_zero: 

2368 return self 

2369 elif c == self: 

2370 return S.Zero 

2371 elif self == S.Zero: 

2372 return None 

2373 

2374 if self.is_Number: 

2375 if not c.is_Number: 

2376 return None 

2377 co = self 

2378 diff = co - c 

2379 # XXX should we match types? i.e should 3 - .1 succeed? 

2380 if (co > 0 and diff >= 0 and diff < co or 

2381 co < 0 and diff <= 0 and diff > co): 

2382 return diff 

2383 return None 

2384 

2385 if c.is_Number: 

2386 co, t = self.as_coeff_Add() 

2387 xa = co.extract_additively(c) 

2388 if xa is None: 

2389 return None 

2390 return xa + t 

2391 

2392 # handle the args[0].is_Number case separately 

2393 # since we will have trouble looking for the coeff of 

2394 # a number. 

2395 if c.is_Add and c.args[0].is_Number: 

2396 # whole term as a term factor 

2397 co = self.coeff(c) 

2398 xa0 = (co.extract_additively(1) or 0)*c 

2399 if xa0: 

2400 diff = self - co*c 

2401 return (xa0 + (diff.extract_additively(c) or diff)) or None 

2402 # term-wise 

2403 h, t = c.as_coeff_Add() 

2404 sh, st = self.as_coeff_Add() 

2405 xa = sh.extract_additively(h) 

2406 if xa is None: 

2407 return None 

2408 xa2 = st.extract_additively(t) 

2409 if xa2 is None: 

2410 return None 

2411 return xa + xa2 

2412 

2413 # whole term as a term factor 

2414 co, diff = _corem(self, c) 

2415 xa0 = (co.extract_additively(1) or 0)*c 

2416 if xa0: 

2417 return (xa0 + (diff.extract_additively(c) or diff)) or None 

2418 # term-wise 

2419 coeffs = [] 

2420 for a in Add.make_args(c): 

2421 ac, at = a.as_coeff_Mul() 

2422 co = self.coeff(at) 

2423 if not co: 

2424 return None 

2425 coc, cot = co.as_coeff_Add() 

2426 xa = coc.extract_additively(ac) 

2427 if xa is None: 

2428 return None 

2429 self -= co*at 

2430 coeffs.append((cot + xa)*at) 

2431 coeffs.append(self) 

2432 return Add(*coeffs) 

2433 

2434 @property 

2435 def expr_free_symbols(self): 

2436 """ 

2437 Like ``free_symbols``, but returns the free symbols only if 

2438 they are contained in an expression node. 

2439 

2440 Examples 

2441 ======== 

2442 

2443 >>> from sympy.abc import x, y 

2444 >>> (x + y).expr_free_symbols # doctest: +SKIP 

2445 {x, y} 

2446 

2447 If the expression is contained in a non-expression object, do not return 

2448 the free symbols. Compare: 

2449 

2450 >>> from sympy import Tuple 

2451 >>> t = Tuple(x + y) 

2452 >>> t.expr_free_symbols # doctest: +SKIP 

2453 set() 

2454 >>> t.free_symbols 

2455 {x, y} 

2456 """ 

2457 sympy_deprecation_warning(""" 

2458 The expr_free_symbols property is deprecated. Use free_symbols to get 

2459 the free symbols of an expression. 

2460 """, 

2461 deprecated_since_version="1.9", 

2462 active_deprecations_target="deprecated-expr-free-symbols") 

2463 return {j for i in self.args for j in i.expr_free_symbols} 

2464 

2465 def could_extract_minus_sign(self): 

2466 """Return True if self has -1 as a leading factor or has 

2467 more literal negative signs than positive signs in a sum, 

2468 otherwise False. 

2469 

2470 Examples 

2471 ======== 

2472 

2473 >>> from sympy.abc import x, y 

2474 >>> e = x - y 

2475 >>> {i.could_extract_minus_sign() for i in (e, -e)} 

2476 {False, True} 

2477 

2478 Though the ``y - x`` is considered like ``-(x - y)``, since it 

2479 is in a product without a leading factor of -1, the result is 

2480 false below: 

2481 

2482 >>> (x*(y - x)).could_extract_minus_sign() 

2483 False 

2484 

2485 To put something in canonical form wrt to sign, use `signsimp`: 

2486 

2487 >>> from sympy import signsimp 

2488 >>> signsimp(x*(y - x)) 

2489 -x*(x - y) 

2490 >>> _.could_extract_minus_sign() 

2491 True 

2492 """ 

2493 return False 

2494 

2495 def extract_branch_factor(self, allow_half=False): 

2496 """ 

2497 Try to write self as ``exp_polar(2*pi*I*n)*z`` in a nice way. 

2498 Return (z, n). 

2499 

2500 >>> from sympy import exp_polar, I, pi 

2501 >>> from sympy.abc import x, y 

2502 >>> exp_polar(I*pi).extract_branch_factor() 

2503 (exp_polar(I*pi), 0) 

2504 >>> exp_polar(2*I*pi).extract_branch_factor() 

2505 (1, 1) 

2506 >>> exp_polar(-pi*I).extract_branch_factor() 

2507 (exp_polar(I*pi), -1) 

2508 >>> exp_polar(3*pi*I + x).extract_branch_factor() 

2509 (exp_polar(x + I*pi), 1) 

2510 >>> (y*exp_polar(-5*pi*I)*exp_polar(3*pi*I + 2*pi*x)).extract_branch_factor() 

2511 (y*exp_polar(2*pi*x), -1) 

2512 >>> exp_polar(-I*pi/2).extract_branch_factor() 

2513 (exp_polar(-I*pi/2), 0) 

2514 

2515 If allow_half is True, also extract exp_polar(I*pi): 

2516 

2517 >>> exp_polar(I*pi).extract_branch_factor(allow_half=True) 

2518 (1, 1/2) 

2519 >>> exp_polar(2*I*pi).extract_branch_factor(allow_half=True) 

2520 (1, 1) 

2521 >>> exp_polar(3*I*pi).extract_branch_factor(allow_half=True) 

2522 (1, 3/2) 

2523 >>> exp_polar(-I*pi).extract_branch_factor(allow_half=True) 

2524 (1, -1/2) 

2525 """ 

2526 from sympy.functions.elementary.exponential import exp_polar 

2527 from sympy.functions.elementary.integers import ceiling 

2528 

2529 n = S.Zero 

2530 res = S.One 

2531 args = Mul.make_args(self) 

2532 exps = [] 

2533 for arg in args: 

2534 if isinstance(arg, exp_polar): 

2535 exps += [arg.exp] 

2536 else: 

2537 res *= arg 

2538 piimult = S.Zero 

2539 extras = [] 

2540 

2541 ipi = S.Pi*S.ImaginaryUnit 

2542 while exps: 

2543 exp = exps.pop() 

2544 if exp.is_Add: 

2545 exps += exp.args 

2546 continue 

2547 if exp.is_Mul: 

2548 coeff = exp.as_coefficient(ipi) 

2549 if coeff is not None: 

2550 piimult += coeff 

2551 continue 

2552 extras += [exp] 

2553 if piimult.is_number: 

2554 coeff = piimult 

2555 tail = () 

2556 else: 

2557 coeff, tail = piimult.as_coeff_add(*piimult.free_symbols) 

2558 # round down to nearest multiple of 2 

2559 branchfact = ceiling(coeff/2 - S.Half)*2 

2560 n += branchfact/2 

2561 c = coeff - branchfact 

2562 if allow_half: 

2563 nc = c.extract_additively(1) 

2564 if nc is not None: 

2565 n += S.Half 

2566 c = nc 

2567 newexp = ipi*Add(*((c, ) + tail)) + Add(*extras) 

2568 if newexp != 0: 

2569 res *= exp_polar(newexp) 

2570 return res, n 

2571 

2572 def is_polynomial(self, *syms): 

2573 r""" 

2574 Return True if self is a polynomial in syms and False otherwise. 

2575 

2576 This checks if self is an exact polynomial in syms. This function 

2577 returns False for expressions that are "polynomials" with symbolic 

2578 exponents. Thus, you should be able to apply polynomial algorithms to 

2579 expressions for which this returns True, and Poly(expr, \*syms) should 

2580 work if and only if expr.is_polynomial(\*syms) returns True. The 

2581 polynomial does not have to be in expanded form. If no symbols are 

2582 given, all free symbols in the expression will be used. 

2583 

2584 This is not part of the assumptions system. You cannot do 

2585 Symbol('z', polynomial=True). 

2586 

2587 Examples 

2588 ======== 

2589 

2590 >>> from sympy import Symbol, Function 

2591 >>> x = Symbol('x') 

2592 >>> ((x**2 + 1)**4).is_polynomial(x) 

2593 True 

2594 >>> ((x**2 + 1)**4).is_polynomial() 

2595 True 

2596 >>> (2**x + 1).is_polynomial(x) 

2597 False 

2598 >>> (2**x + 1).is_polynomial(2**x) 

2599 True 

2600 >>> f = Function('f') 

2601 >>> (f(x) + 1).is_polynomial(x) 

2602 False 

2603 >>> (f(x) + 1).is_polynomial(f(x)) 

2604 True 

2605 >>> (1/f(x) + 1).is_polynomial(f(x)) 

2606 False 

2607 

2608 >>> n = Symbol('n', nonnegative=True, integer=True) 

2609 >>> (x**n + 1).is_polynomial(x) 

2610 False 

2611 

2612 This function does not attempt any nontrivial simplifications that may 

2613 result in an expression that does not appear to be a polynomial to 

2614 become one. 

2615 

2616 >>> from sympy import sqrt, factor, cancel 

2617 >>> y = Symbol('y', positive=True) 

2618 >>> a = sqrt(y**2 + 2*y + 1) 

2619 >>> a.is_polynomial(y) 

2620 False 

2621 >>> factor(a) 

2622 y + 1 

2623 >>> factor(a).is_polynomial(y) 

2624 True 

2625 

2626 >>> b = (y**2 + 2*y + 1)/(y + 1) 

2627 >>> b.is_polynomial(y) 

2628 False 

2629 >>> cancel(b) 

2630 y + 1 

2631 >>> cancel(b).is_polynomial(y) 

2632 True 

2633 

2634 See also .is_rational_function() 

2635 

2636 """ 

2637 if syms: 

2638 syms = set(map(sympify, syms)) 

2639 else: 

2640 syms = self.free_symbols 

2641 if not syms: 

2642 return True 

2643 

2644 return self._eval_is_polynomial(syms) 

2645 

2646 def _eval_is_polynomial(self, syms): 

2647 if self in syms: 

2648 return True 

2649 if not self.has_free(*syms): 

2650 # constant polynomial 

2651 return True 

2652 # subclasses should return True or False 

2653 

2654 def is_rational_function(self, *syms): 

2655 """ 

2656 Test whether function is a ratio of two polynomials in the given 

2657 symbols, syms. When syms is not given, all free symbols will be used. 

2658 The rational function does not have to be in expanded or in any kind of 

2659 canonical form. 

2660 

2661 This function returns False for expressions that are "rational 

2662 functions" with symbolic exponents. Thus, you should be able to call 

2663 .as_numer_denom() and apply polynomial algorithms to the result for 

2664 expressions for which this returns True. 

2665 

2666 This is not part of the assumptions system. You cannot do 

2667 Symbol('z', rational_function=True). 

2668 

2669 Examples 

2670 ======== 

2671 

2672 >>> from sympy import Symbol, sin 

2673 >>> from sympy.abc import x, y 

2674 

2675 >>> (x/y).is_rational_function() 

2676 True 

2677 

2678 >>> (x**2).is_rational_function() 

2679 True 

2680 

2681 >>> (x/sin(y)).is_rational_function(y) 

2682 False 

2683 

2684 >>> n = Symbol('n', integer=True) 

2685 >>> (x**n + 1).is_rational_function(x) 

2686 False 

2687 

2688 This function does not attempt any nontrivial simplifications that may 

2689 result in an expression that does not appear to be a rational function 

2690 to become one. 

2691 

2692 >>> from sympy import sqrt, factor 

2693 >>> y = Symbol('y', positive=True) 

2694 >>> a = sqrt(y**2 + 2*y + 1)/y 

2695 >>> a.is_rational_function(y) 

2696 False 

2697 >>> factor(a) 

2698 (y + 1)/y 

2699 >>> factor(a).is_rational_function(y) 

2700 True 

2701 

2702 See also is_algebraic_expr(). 

2703 

2704 """ 

2705 if syms: 

2706 syms = set(map(sympify, syms)) 

2707 else: 

2708 syms = self.free_symbols 

2709 if not syms: 

2710 return self not in _illegal 

2711 

2712 return self._eval_is_rational_function(syms) 

2713 

2714 def _eval_is_rational_function(self, syms): 

2715 if self in syms: 

2716 return True 

2717 if not self.has_xfree(syms): 

2718 return True 

2719 # subclasses should return True or False 

2720 

2721 def is_meromorphic(self, x, a): 

2722 """ 

2723 This tests whether an expression is meromorphic as 

2724 a function of the given symbol ``x`` at the point ``a``. 

2725 

2726 This method is intended as a quick test that will return 

2727 None if no decision can be made without simplification or 

2728 more detailed analysis. 

2729 

2730 Examples 

2731 ======== 

2732 

2733 >>> from sympy import zoo, log, sin, sqrt 

2734 >>> from sympy.abc import x 

2735 

2736 >>> f = 1/x**2 + 1 - 2*x**3 

2737 >>> f.is_meromorphic(x, 0) 

2738 True 

2739 >>> f.is_meromorphic(x, 1) 

2740 True 

2741 >>> f.is_meromorphic(x, zoo) 

2742 True 

2743 

2744 >>> g = x**log(3) 

2745 >>> g.is_meromorphic(x, 0) 

2746 False 

2747 >>> g.is_meromorphic(x, 1) 

2748 True 

2749 >>> g.is_meromorphic(x, zoo) 

2750 False 

2751 

2752 >>> h = sin(1/x)*x**2 

2753 >>> h.is_meromorphic(x, 0) 

2754 False 

2755 >>> h.is_meromorphic(x, 1) 

2756 True 

2757 >>> h.is_meromorphic(x, zoo) 

2758 True 

2759 

2760 Multivalued functions are considered meromorphic when their 

2761 branches are meromorphic. Thus most functions are meromorphic 

2762 everywhere except at essential singularities and branch points. 

2763 In particular, they will be meromorphic also on branch cuts 

2764 except at their endpoints. 

2765 

2766 >>> log(x).is_meromorphic(x, -1) 

2767 True 

2768 >>> log(x).is_meromorphic(x, 0) 

2769 False 

2770 >>> sqrt(x).is_meromorphic(x, -1) 

2771 True 

2772 >>> sqrt(x).is_meromorphic(x, 0) 

2773 False 

2774 

2775 """ 

2776 if not x.is_symbol: 

2777 raise TypeError("{} should be of symbol type".format(x)) 

2778 a = sympify(a) 

2779 

2780 return self._eval_is_meromorphic(x, a) 

2781 

2782 def _eval_is_meromorphic(self, x, a): 

2783 if self == x: 

2784 return True 

2785 if not self.has_free(x): 

2786 return True 

2787 # subclasses should return True or False 

2788 

2789 def is_algebraic_expr(self, *syms): 

2790 """ 

2791 This tests whether a given expression is algebraic or not, in the 

2792 given symbols, syms. When syms is not given, all free symbols 

2793 will be used. The rational function does not have to be in expanded 

2794 or in any kind of canonical form. 

2795 

2796 This function returns False for expressions that are "algebraic 

2797 expressions" with symbolic exponents. This is a simple extension to the 

2798 is_rational_function, including rational exponentiation. 

2799 

2800 Examples 

2801 ======== 

2802 

2803 >>> from sympy import Symbol, sqrt 

2804 >>> x = Symbol('x', real=True) 

2805 >>> sqrt(1 + x).is_rational_function() 

2806 False 

2807 >>> sqrt(1 + x).is_algebraic_expr() 

2808 True 

2809 

2810 This function does not attempt any nontrivial simplifications that may 

2811 result in an expression that does not appear to be an algebraic 

2812 expression to become one. 

2813 

2814 >>> from sympy import exp, factor 

2815 >>> a = sqrt(exp(x)**2 + 2*exp(x) + 1)/(exp(x) + 1) 

2816 >>> a.is_algebraic_expr(x) 

2817 False 

2818 >>> factor(a).is_algebraic_expr() 

2819 True 

2820 

2821 See Also 

2822 ======== 

2823 

2824 is_rational_function 

2825 

2826 References 

2827 ========== 

2828 

2829 .. [1] https://en.wikipedia.org/wiki/Algebraic_expression 

2830 

2831 """ 

2832 if syms: 

2833 syms = set(map(sympify, syms)) 

2834 else: 

2835 syms = self.free_symbols 

2836 if not syms: 

2837 return True 

2838 

2839 return self._eval_is_algebraic_expr(syms) 

2840 

2841 def _eval_is_algebraic_expr(self, syms): 

2842 if self in syms: 

2843 return True 

2844 if not self.has_free(*syms): 

2845 return True 

2846 # subclasses should return True or False 

2847 

2848 ################################################################################### 

2849 ##################### SERIES, LEADING TERM, LIMIT, ORDER METHODS ################## 

2850 ################################################################################### 

2851 

2852 def series(self, x=None, x0=0, n=6, dir="+", logx=None, cdir=0): 

2853 """ 

2854 Series expansion of "self" around ``x = x0`` yielding either terms of 

2855 the series one by one (the lazy series given when n=None), else 

2856 all the terms at once when n != None. 

2857 

2858 Returns the series expansion of "self" around the point ``x = x0`` 

2859 with respect to ``x`` up to ``O((x - x0)**n, x, x0)`` (default n is 6). 

2860 

2861 If ``x=None`` and ``self`` is univariate, the univariate symbol will 

2862 be supplied, otherwise an error will be raised. 

2863 

2864 Parameters 

2865 ========== 

2866 

2867 expr : Expression 

2868 The expression whose series is to be expanded. 

2869 

2870 x : Symbol 

2871 It is the variable of the expression to be calculated. 

2872 

2873 x0 : Value 

2874 The value around which ``x`` is calculated. Can be any value 

2875 from ``-oo`` to ``oo``. 

2876 

2877 n : Value 

2878 The value used to represent the order in terms of ``x**n``, 

2879 up to which the series is to be expanded. 

2880 

2881 dir : String, optional 

2882 The series-expansion can be bi-directional. If ``dir="+"``, 

2883 then (x->x0+). If ``dir="-", then (x->x0-). For infinite 

2884 ``x0`` (``oo`` or ``-oo``), the ``dir`` argument is determined 

2885 from the direction of the infinity (i.e., ``dir="-"`` for 

2886 ``oo``). 

2887 

2888 logx : optional 

2889 It is used to replace any log(x) in the returned series with a 

2890 symbolic value rather than evaluating the actual value. 

2891 

2892 cdir : optional 

2893 It stands for complex direction, and indicates the direction 

2894 from which the expansion needs to be evaluated. 

2895 

2896 Examples 

2897 ======== 

2898 

2899 >>> from sympy import cos, exp, tan 

2900 >>> from sympy.abc import x, y 

2901 >>> cos(x).series() 

2902 1 - x**2/2 + x**4/24 + O(x**6) 

2903 >>> cos(x).series(n=4) 

2904 1 - x**2/2 + O(x**4) 

2905 >>> cos(x).series(x, x0=1, n=2) 

2906 cos(1) - (x - 1)*sin(1) + O((x - 1)**2, (x, 1)) 

2907 >>> e = cos(x + exp(y)) 

2908 >>> e.series(y, n=2) 

2909 cos(x + 1) - y*sin(x + 1) + O(y**2) 

2910 >>> e.series(x, n=2) 

2911 cos(exp(y)) - x*sin(exp(y)) + O(x**2) 

2912 

2913 If ``n=None`` then a generator of the series terms will be returned. 

2914 

2915 >>> term=cos(x).series(n=None) 

2916 >>> [next(term) for i in range(2)] 

2917 [1, -x**2/2] 

2918 

2919 For ``dir=+`` (default) the series is calculated from the right and 

2920 for ``dir=-`` the series from the left. For smooth functions this 

2921 flag will not alter the results. 

2922 

2923 >>> abs(x).series(dir="+") 

2924 x 

2925 >>> abs(x).series(dir="-") 

2926 -x 

2927 >>> f = tan(x) 

2928 >>> f.series(x, 2, 6, "+") 

2929 tan(2) + (1 + tan(2)**2)*(x - 2) + (x - 2)**2*(tan(2)**3 + tan(2)) + 

2930 (x - 2)**3*(1/3 + 4*tan(2)**2/3 + tan(2)**4) + (x - 2)**4*(tan(2)**5 + 

2931 5*tan(2)**3/3 + 2*tan(2)/3) + (x - 2)**5*(2/15 + 17*tan(2)**2/15 + 

2932 2*tan(2)**4 + tan(2)**6) + O((x - 2)**6, (x, 2)) 

2933 

2934 >>> f.series(x, 2, 3, "-") 

2935 tan(2) + (2 - x)*(-tan(2)**2 - 1) + (2 - x)**2*(tan(2)**3 + tan(2)) 

2936 + O((x - 2)**3, (x, 2)) 

2937 

2938 For rational expressions this method may return original expression without the Order term. 

2939 >>> (1/x).series(x, n=8) 

2940 1/x 

2941 

2942 Returns 

2943 ======= 

2944 

2945 Expr : Expression 

2946 Series expansion of the expression about x0 

2947 

2948 Raises 

2949 ====== 

2950 

2951 TypeError 

2952 If "n" and "x0" are infinity objects 

2953 

2954 PoleError 

2955 If "x0" is an infinity object 

2956 

2957 """ 

2958 if x is None: 

2959 syms = self.free_symbols 

2960 if not syms: 

2961 return self 

2962 elif len(syms) > 1: 

2963 raise ValueError('x must be given for multivariate functions.') 

2964 x = syms.pop() 

2965 

2966 from .symbol import Dummy, Symbol 

2967 if isinstance(x, Symbol): 

2968 dep = x in self.free_symbols 

2969 else: 

2970 d = Dummy() 

2971 dep = d in self.xreplace({x: d}).free_symbols 

2972 if not dep: 

2973 if n is None: 

2974 return (s for s in [self]) 

2975 else: 

2976 return self 

2977 

2978 if len(dir) != 1 or dir not in '+-': 

2979 raise ValueError("Dir must be '+' or '-'") 

2980 

2981 x0 = sympify(x0) 

2982 cdir = sympify(cdir) 

2983 from sympy.functions.elementary.complexes import im, sign 

2984 

2985 if not cdir.is_zero: 

2986 if cdir.is_real: 

2987 dir = '+' if cdir.is_positive else '-' 

2988 else: 

2989 dir = '+' if im(cdir).is_positive else '-' 

2990 else: 

2991 if x0 and x0.is_infinite: 

2992 cdir = sign(x0).simplify() 

2993 elif str(dir) == "+": 

2994 cdir = S.One 

2995 elif str(dir) == "-": 

2996 cdir = S.NegativeOne 

2997 elif cdir == S.Zero: 

2998 cdir = S.One 

2999 

3000 cdir = cdir/abs(cdir) 

3001 

3002 if x0 and x0.is_infinite: 

3003 from .function import PoleError 

3004 try: 

3005 s = self.subs(x, cdir/x).series(x, n=n, dir='+', cdir=1) 

3006 if n is None: 

3007 return (si.subs(x, cdir/x) for si in s) 

3008 return s.subs(x, cdir/x) 

3009 except PoleError: 

3010 s = self.subs(x, cdir*x).aseries(x, n=n) 

3011 return s.subs(x, cdir*x) 

3012 

3013 # use rep to shift origin to x0 and change sign (if dir is negative) 

3014 # and undo the process with rep2 

3015 if x0 or cdir != 1: 

3016 s = self.subs({x: x0 + cdir*x}).series(x, x0=0, n=n, dir='+', logx=logx, cdir=1) 

3017 if n is None: # lseries... 

3018 return (si.subs({x: x/cdir - x0/cdir}) for si in s) 

3019 return s.subs({x: x/cdir - x0/cdir}) 

3020 

3021 # from here on it's x0=0 and dir='+' handling 

3022 

3023 if x.is_positive is x.is_negative is None or x.is_Symbol is not True: 

3024 # replace x with an x that has a positive assumption 

3025 xpos = Dummy('x', positive=True) 

3026 rv = self.subs(x, xpos).series(xpos, x0, n, dir, logx=logx, cdir=cdir) 

3027 if n is None: 

3028 return (s.subs(xpos, x) for s in rv) 

3029 else: 

3030 return rv.subs(xpos, x) 

3031 

3032 from sympy.series.order import Order 

3033 if n is not None: # nseries handling 

3034 s1 = self._eval_nseries(x, n=n, logx=logx, cdir=cdir) 

3035 o = s1.getO() or S.Zero 

3036 if o: 

3037 # make sure the requested order is returned 

3038 ngot = o.getn() 

3039 if ngot > n: 

3040 # leave o in its current form (e.g. with x*log(x)) so 

3041 # it eats terms properly, then replace it below 

3042 if n != 0: 

3043 s1 += o.subs(x, x**Rational(n, ngot)) 

3044 else: 

3045 s1 += Order(1, x) 

3046 elif ngot < n: 

3047 # increase the requested number of terms to get the desired 

3048 # number keep increasing (up to 9) until the received order 

3049 # is different than the original order and then predict how 

3050 # many additional terms are needed 

3051 from sympy.functions.elementary.integers import ceiling 

3052 for more in range(1, 9): 

3053 s1 = self._eval_nseries(x, n=n + more, logx=logx, cdir=cdir) 

3054 newn = s1.getn() 

3055 if newn != ngot: 

3056 ndo = n + ceiling((n - ngot)*more/(newn - ngot)) 

3057 s1 = self._eval_nseries(x, n=ndo, logx=logx, cdir=cdir) 

3058 while s1.getn() < n: 

3059 s1 = self._eval_nseries(x, n=ndo, logx=logx, cdir=cdir) 

3060 ndo += 1 

3061 break 

3062 else: 

3063 raise ValueError('Could not calculate %s terms for %s' 

3064 % (str(n), self)) 

3065 s1 += Order(x**n, x) 

3066 o = s1.getO() 

3067 s1 = s1.removeO() 

3068 elif s1.has(Order): 

3069 # asymptotic expansion 

3070 return s1 

3071 else: 

3072 o = Order(x**n, x) 

3073 s1done = s1.doit() 

3074 try: 

3075 if (s1done + o).removeO() == s1done: 

3076 o = S.Zero 

3077 except NotImplementedError: 

3078 return s1 

3079 

3080 try: 

3081 from sympy.simplify.radsimp import collect 

3082 return collect(s1, x) + o 

3083 except NotImplementedError: 

3084 return s1 + o 

3085 

3086 else: # lseries handling 

3087 def yield_lseries(s): 

3088 """Return terms of lseries one at a time.""" 

3089 for si in s: 

3090 if not si.is_Add: 

3091 yield si 

3092 continue 

3093 # yield terms 1 at a time if possible 

3094 # by increasing order until all the 

3095 # terms have been returned 

3096 yielded = 0 

3097 o = Order(si, x)*x 

3098 ndid = 0 

3099 ndo = len(si.args) 

3100 while 1: 

3101 do = (si - yielded + o).removeO() 

3102 o *= x 

3103 if not do or do.is_Order: 

3104 continue 

3105 if do.is_Add: 

3106 ndid += len(do.args) 

3107 else: 

3108 ndid += 1 

3109 yield do 

3110 if ndid == ndo: 

3111 break 

3112 yielded += do 

3113 

3114 return yield_lseries(self.removeO()._eval_lseries(x, logx=logx, cdir=cdir)) 

3115 

3116 def aseries(self, x=None, n=6, bound=0, hir=False): 

3117 """Asymptotic Series expansion of self. 

3118 This is equivalent to ``self.series(x, oo, n)``. 

3119 

3120 Parameters 

3121 ========== 

3122 

3123 self : Expression 

3124 The expression whose series is to be expanded. 

3125 

3126 x : Symbol 

3127 It is the variable of the expression to be calculated. 

3128 

3129 n : Value 

3130 The value used to represent the order in terms of ``x**n``, 

3131 up to which the series is to be expanded. 

3132 

3133 hir : Boolean 

3134 Set this parameter to be True to produce hierarchical series. 

3135 It stops the recursion at an early level and may provide nicer 

3136 and more useful results. 

3137 

3138 bound : Value, Integer 

3139 Use the ``bound`` parameter to give limit on rewriting 

3140 coefficients in its normalised form. 

3141 

3142 Examples 

3143 ======== 

3144 

3145 >>> from sympy import sin, exp 

3146 >>> from sympy.abc import x 

3147 

3148 >>> e = sin(1/x + exp(-x)) - sin(1/x) 

3149 

3150 >>> e.aseries(x) 

3151 (1/(24*x**4) - 1/(2*x**2) + 1 + O(x**(-6), (x, oo)))*exp(-x) 

3152 

3153 >>> e.aseries(x, n=3, hir=True) 

3154 -exp(-2*x)*sin(1/x)/2 + exp(-x)*cos(1/x) + O(exp(-3*x), (x, oo)) 

3155 

3156 >>> e = exp(exp(x)/(1 - 1/x)) 

3157 

3158 >>> e.aseries(x) 

3159 exp(exp(x)/(1 - 1/x)) 

3160 

3161 >>> e.aseries(x, bound=3) # doctest: +SKIP 

3162 exp(exp(x)/x**2)*exp(exp(x)/x)*exp(-exp(x) + exp(x)/(1 - 1/x) - exp(x)/x - exp(x)/x**2)*exp(exp(x)) 

3163 

3164 For rational expressions this method may return original expression without the Order term. 

3165 >>> (1/x).aseries(x, n=8) 

3166 1/x 

3167 

3168 Returns 

3169 ======= 

3170 

3171 Expr 

3172 Asymptotic series expansion of the expression. 

3173 

3174 Notes 

3175 ===== 

3176 

3177 This algorithm is directly induced from the limit computational algorithm provided by Gruntz. 

3178 It majorly uses the mrv and rewrite sub-routines. The overall idea of this algorithm is first 

3179 to look for the most rapidly varying subexpression w of a given expression f and then expands f 

3180 in a series in w. Then same thing is recursively done on the leading coefficient 

3181 till we get constant coefficients. 

3182 

3183 If the most rapidly varying subexpression of a given expression f is f itself, 

3184 the algorithm tries to find a normalised representation of the mrv set and rewrites f 

3185 using this normalised representation. 

3186 

3187 If the expansion contains an order term, it will be either ``O(x ** (-n))`` or ``O(w ** (-n))`` 

3188 where ``w`` belongs to the most rapidly varying expression of ``self``. 

3189 

3190 References 

3191 ========== 

3192 

3193 .. [1] Gruntz, Dominik. A new algorithm for computing asymptotic series. 

3194 In: Proc. 1993 Int. Symp. Symbolic and Algebraic Computation. 1993. 

3195 pp. 239-244. 

3196 .. [2] Gruntz thesis - p90 

3197 .. [3] https://en.wikipedia.org/wiki/Asymptotic_expansion 

3198 

3199 See Also 

3200 ======== 

3201 

3202 Expr.aseries: See the docstring of this function for complete details of this wrapper. 

3203 """ 

3204 

3205 from .symbol import Dummy 

3206 

3207 if x.is_positive is x.is_negative is None: 

3208 xpos = Dummy('x', positive=True) 

3209 return self.subs(x, xpos).aseries(xpos, n, bound, hir).subs(xpos, x) 

3210 

3211 from .function import PoleError 

3212 from sympy.series.gruntz import mrv, rewrite 

3213 

3214 try: 

3215 om, exps = mrv(self, x) 

3216 except PoleError: 

3217 return self 

3218 

3219 # We move one level up by replacing `x` by `exp(x)`, and then 

3220 # computing the asymptotic series for f(exp(x)). Then asymptotic series 

3221 # can be obtained by moving one-step back, by replacing x by ln(x). 

3222 

3223 from sympy.functions.elementary.exponential import exp, log 

3224 from sympy.series.order import Order 

3225 

3226 if x in om: 

3227 s = self.subs(x, exp(x)).aseries(x, n, bound, hir).subs(x, log(x)) 

3228 if s.getO(): 

3229 return s + Order(1/x**n, (x, S.Infinity)) 

3230 return s 

3231 

3232 k = Dummy('k', positive=True) 

3233 # f is rewritten in terms of omega 

3234 func, logw = rewrite(exps, om, x, k) 

3235 

3236 if self in om: 

3237 if bound <= 0: 

3238 return self 

3239 s = (self.exp).aseries(x, n, bound=bound) 

3240 s = s.func(*[t.removeO() for t in s.args]) 

3241 try: 

3242 res = exp(s.subs(x, 1/x).as_leading_term(x).subs(x, 1/x)) 

3243 except PoleError: 

3244 res = self 

3245 

3246 func = exp(self.args[0] - res.args[0]) / k 

3247 logw = log(1/res) 

3248 

3249 s = func.series(k, 0, n) 

3250 

3251 # Hierarchical series 

3252 if hir: 

3253 return s.subs(k, exp(logw)) 

3254 

3255 o = s.getO() 

3256 terms = sorted(Add.make_args(s.removeO()), key=lambda i: int(i.as_coeff_exponent(k)[1])) 

3257 s = S.Zero 

3258 has_ord = False 

3259 

3260 # Then we recursively expand these coefficients one by one into 

3261 # their asymptotic series in terms of their most rapidly varying subexpressions. 

3262 for t in terms: 

3263 coeff, expo = t.as_coeff_exponent(k) 

3264 if coeff.has(x): 

3265 # Recursive step 

3266 snew = coeff.aseries(x, n, bound=bound-1) 

3267 if has_ord and snew.getO(): 

3268 break 

3269 elif snew.getO(): 

3270 has_ord = True 

3271 s += (snew * k**expo) 

3272 else: 

3273 s += t 

3274 

3275 if not o or has_ord: 

3276 return s.subs(k, exp(logw)) 

3277 return (s + o).subs(k, exp(logw)) 

3278 

3279 

3280 def taylor_term(self, n, x, *previous_terms): 

3281 """General method for the taylor term. 

3282 

3283 This method is slow, because it differentiates n-times. Subclasses can 

3284 redefine it to make it faster by using the "previous_terms". 

3285 """ 

3286 from .symbol import Dummy 

3287 from sympy.functions.combinatorial.factorials import factorial 

3288 

3289 x = sympify(x) 

3290 _x = Dummy('x') 

3291 return self.subs(x, _x).diff(_x, n).subs(_x, x).subs(x, 0) * x**n / factorial(n) 

3292 

3293 def lseries(self, x=None, x0=0, dir='+', logx=None, cdir=0): 

3294 """ 

3295 Wrapper for series yielding an iterator of the terms of the series. 

3296 

3297 Note: an infinite series will yield an infinite iterator. The following, 

3298 for exaxmple, will never terminate. It will just keep printing terms 

3299 of the sin(x) series:: 

3300 

3301 for term in sin(x).lseries(x): 

3302 print term 

3303 

3304 The advantage of lseries() over nseries() is that many times you are 

3305 just interested in the next term in the series (i.e. the first term for 

3306 example), but you do not know how many you should ask for in nseries() 

3307 using the "n" parameter. 

3308 

3309 See also nseries(). 

3310 """ 

3311 return self.series(x, x0, n=None, dir=dir, logx=logx, cdir=cdir) 

3312 

3313 def _eval_lseries(self, x, logx=None, cdir=0): 

3314 # default implementation of lseries is using nseries(), and adaptively 

3315 # increasing the "n". As you can see, it is not very efficient, because 

3316 # we are calculating the series over and over again. Subclasses should 

3317 # override this method and implement much more efficient yielding of 

3318 # terms. 

3319 n = 0 

3320 series = self._eval_nseries(x, n=n, logx=logx, cdir=cdir) 

3321 

3322 while series.is_Order: 

3323 n += 1 

3324 series = self._eval_nseries(x, n=n, logx=logx, cdir=cdir) 

3325 

3326 e = series.removeO() 

3327 yield e 

3328 if e is S.Zero: 

3329 return 

3330 

3331 while 1: 

3332 while 1: 

3333 n += 1 

3334 series = self._eval_nseries(x, n=n, logx=logx, cdir=cdir).removeO() 

3335 if e != series: 

3336 break 

3337 if (series - self).cancel() is S.Zero: 

3338 return 

3339 yield series - e 

3340 e = series 

3341 

3342 def nseries(self, x=None, x0=0, n=6, dir='+', logx=None, cdir=0): 

3343 """ 

3344 Wrapper to _eval_nseries if assumptions allow, else to series. 

3345 

3346 If x is given, x0 is 0, dir='+', and self has x, then _eval_nseries is 

3347 called. This calculates "n" terms in the innermost expressions and 

3348 then builds up the final series just by "cross-multiplying" everything 

3349 out. 

3350 

3351 The optional ``logx`` parameter can be used to replace any log(x) in the 

3352 returned series with a symbolic value to avoid evaluating log(x) at 0. A 

3353 symbol to use in place of log(x) should be provided. 

3354 

3355 Advantage -- it's fast, because we do not have to determine how many 

3356 terms we need to calculate in advance. 

3357 

3358 Disadvantage -- you may end up with less terms than you may have 

3359 expected, but the O(x**n) term appended will always be correct and 

3360 so the result, though perhaps shorter, will also be correct. 

3361 

3362 If any of those assumptions is not met, this is treated like a 

3363 wrapper to series which will try harder to return the correct 

3364 number of terms. 

3365 

3366 See also lseries(). 

3367 

3368 Examples 

3369 ======== 

3370 

3371 >>> from sympy import sin, log, Symbol 

3372 >>> from sympy.abc import x, y 

3373 >>> sin(x).nseries(x, 0, 6) 

3374 x - x**3/6 + x**5/120 + O(x**6) 

3375 >>> log(x+1).nseries(x, 0, 5) 

3376 x - x**2/2 + x**3/3 - x**4/4 + O(x**5) 

3377 

3378 Handling of the ``logx`` parameter --- in the following example the 

3379 expansion fails since ``sin`` does not have an asymptotic expansion 

3380 at -oo (the limit of log(x) as x approaches 0): 

3381 

3382 >>> e = sin(log(x)) 

3383 >>> e.nseries(x, 0, 6) 

3384 Traceback (most recent call last): 

3385 ... 

3386 PoleError: ... 

3387 ... 

3388 >>> logx = Symbol('logx') 

3389 >>> e.nseries(x, 0, 6, logx=logx) 

3390 sin(logx) 

3391 

3392 In the following example, the expansion works but only returns self 

3393 unless the ``logx`` parameter is used: 

3394 

3395 >>> e = x**y 

3396 >>> e.nseries(x, 0, 2) 

3397 x**y 

3398 >>> e.nseries(x, 0, 2, logx=logx) 

3399 exp(logx*y) 

3400 

3401 """ 

3402 if x and x not in self.free_symbols: 

3403 return self 

3404 if x is None or x0 or dir != '+': # {see XPOS above} or (x.is_positive == x.is_negative == None): 

3405 return self.series(x, x0, n, dir, cdir=cdir) 

3406 else: 

3407 return self._eval_nseries(x, n=n, logx=logx, cdir=cdir) 

3408 

3409 def _eval_nseries(self, x, n, logx, cdir): 

3410 """ 

3411 Return terms of series for self up to O(x**n) at x=0 

3412 from the positive direction. 

3413 

3414 This is a method that should be overridden in subclasses. Users should 

3415 never call this method directly (use .nseries() instead), so you do not 

3416 have to write docstrings for _eval_nseries(). 

3417 """ 

3418 raise NotImplementedError(filldedent(""" 

3419 The _eval_nseries method should be added to 

3420 %s to give terms up to O(x**n) at x=0 

3421 from the positive direction so it is available when 

3422 nseries calls it.""" % self.func) 

3423 ) 

3424 

3425 def limit(self, x, xlim, dir='+'): 

3426 """ Compute limit x->xlim. 

3427 """ 

3428 from sympy.series.limits import limit 

3429 return limit(self, x, xlim, dir) 

3430 

3431 def compute_leading_term(self, x, logx=None): 

3432 """Deprecated function to compute the leading term of a series. 

3433 

3434 as_leading_term is only allowed for results of .series() 

3435 This is a wrapper to compute a series first. 

3436 """ 

3437 from sympy.utilities.exceptions import SymPyDeprecationWarning 

3438 

3439 SymPyDeprecationWarning( 

3440 feature="compute_leading_term", 

3441 useinstead="as_leading_term", 

3442 issue=21843, 

3443 deprecated_since_version="1.12" 

3444 ).warn() 

3445 

3446 from sympy.functions.elementary.piecewise import Piecewise, piecewise_fold 

3447 if self.has(Piecewise): 

3448 expr = piecewise_fold(self) 

3449 else: 

3450 expr = self 

3451 if self.removeO() == 0: 

3452 return self 

3453 

3454 from .symbol import Dummy 

3455 from sympy.functions.elementary.exponential import log 

3456 from sympy.series.order import Order 

3457 

3458 _logx = logx 

3459 logx = Dummy('logx') if logx is None else logx 

3460 res = Order(1) 

3461 incr = S.One 

3462 while res.is_Order: 

3463 res = expr._eval_nseries(x, n=1+incr, logx=logx).cancel().powsimp().trigsimp() 

3464 incr *= 2 

3465 

3466 if _logx is None: 

3467 res = res.subs(logx, log(x)) 

3468 

3469 return res.as_leading_term(x) 

3470 

3471 @cacheit 

3472 def as_leading_term(self, *symbols, logx=None, cdir=0): 

3473 """ 

3474 Returns the leading (nonzero) term of the series expansion of self. 

3475 

3476 The _eval_as_leading_term routines are used to do this, and they must 

3477 always return a non-zero value. 

3478 

3479 Examples 

3480 ======== 

3481 

3482 >>> from sympy.abc import x 

3483 >>> (1 + x + x**2).as_leading_term(x) 

3484 1 

3485 >>> (1/x**2 + x + x**2).as_leading_term(x) 

3486 x**(-2) 

3487 

3488 """ 

3489 if len(symbols) > 1: 

3490 c = self 

3491 for x in symbols: 

3492 c = c.as_leading_term(x, logx=logx, cdir=cdir) 

3493 return c 

3494 elif not symbols: 

3495 return self 

3496 x = sympify(symbols[0]) 

3497 if not x.is_symbol: 

3498 raise ValueError('expecting a Symbol but got %s' % x) 

3499 if x not in self.free_symbols: 

3500 return self 

3501 obj = self._eval_as_leading_term(x, logx=logx, cdir=cdir) 

3502 if obj is not None: 

3503 from sympy.simplify.powsimp import powsimp 

3504 return powsimp(obj, deep=True, combine='exp') 

3505 raise NotImplementedError('as_leading_term(%s, %s)' % (self, x)) 

3506 

3507 def _eval_as_leading_term(self, x, logx=None, cdir=0): 

3508 return self 

3509 

3510 def as_coeff_exponent(self, x) -> tuple[Expr, Expr]: 

3511 """ ``c*x**e -> c,e`` where x can be any symbolic expression. 

3512 """ 

3513 from sympy.simplify.radsimp import collect 

3514 s = collect(self, x) 

3515 c, p = s.as_coeff_mul(x) 

3516 if len(p) == 1: 

3517 b, e = p[0].as_base_exp() 

3518 if b == x: 

3519 return c, e 

3520 return s, S.Zero 

3521 

3522 def leadterm(self, x, logx=None, cdir=0): 

3523 """ 

3524 Returns the leading term a*x**b as a tuple (a, b). 

3525 

3526 Examples 

3527 ======== 

3528 

3529 >>> from sympy.abc import x 

3530 >>> (1+x+x**2).leadterm(x) 

3531 (1, 0) 

3532 >>> (1/x**2+x+x**2).leadterm(x) 

3533 (1, -2) 

3534 

3535 """ 

3536 from .symbol import Dummy 

3537 from sympy.functions.elementary.exponential import log 

3538 l = self.as_leading_term(x, logx=logx, cdir=cdir) 

3539 d = Dummy('logx') 

3540 if l.has(log(x)): 

3541 l = l.subs(log(x), d) 

3542 c, e = l.as_coeff_exponent(x) 

3543 if x in c.free_symbols: 

3544 raise ValueError(filldedent(""" 

3545 cannot compute leadterm(%s, %s). The coefficient 

3546 should have been free of %s but got %s""" % (self, x, x, c))) 

3547 c = c.subs(d, log(x)) 

3548 return c, e 

3549 

3550 def as_coeff_Mul(self, rational: bool = False) -> tuple['Number', Expr]: 

3551 """Efficiently extract the coefficient of a product.""" 

3552 return S.One, self 

3553 

3554 def as_coeff_Add(self, rational=False) -> tuple['Number', Expr]: 

3555 """Efficiently extract the coefficient of a summation.""" 

3556 return S.Zero, self 

3557 

3558 def fps(self, x=None, x0=0, dir=1, hyper=True, order=4, rational=True, 

3559 full=False): 

3560 """ 

3561 Compute formal power power series of self. 

3562 

3563 See the docstring of the :func:`fps` function in sympy.series.formal for 

3564 more information. 

3565 """ 

3566 from sympy.series.formal import fps 

3567 

3568 return fps(self, x, x0, dir, hyper, order, rational, full) 

3569 

3570 def fourier_series(self, limits=None): 

3571 """Compute fourier sine/cosine series of self. 

3572 

3573 See the docstring of the :func:`fourier_series` in sympy.series.fourier 

3574 for more information. 

3575 """ 

3576 from sympy.series.fourier import fourier_series 

3577 

3578 return fourier_series(self, limits) 

3579 

3580 ################################################################################### 

3581 ##################### DERIVATIVE, INTEGRAL, FUNCTIONAL METHODS #################### 

3582 ################################################################################### 

3583 

3584 def diff(self, *symbols, **assumptions): 

3585 assumptions.setdefault("evaluate", True) 

3586 return _derivative_dispatch(self, *symbols, **assumptions) 

3587 

3588 ########################################################################### 

3589 ###################### EXPRESSION EXPANSION METHODS ####################### 

3590 ########################################################################### 

3591 

3592 # Relevant subclasses should override _eval_expand_hint() methods. See 

3593 # the docstring of expand() for more info. 

3594 

3595 def _eval_expand_complex(self, **hints): 

3596 real, imag = self.as_real_imag(**hints) 

3597 return real + S.ImaginaryUnit*imag 

3598 

3599 @staticmethod 

3600 def _expand_hint(expr, hint, deep=True, **hints): 

3601 """ 

3602 Helper for ``expand()``. Recursively calls ``expr._eval_expand_hint()``. 

3603 

3604 Returns ``(expr, hit)``, where expr is the (possibly) expanded 

3605 ``expr`` and ``hit`` is ``True`` if ``expr`` was truly expanded and 

3606 ``False`` otherwise. 

3607 """ 

3608 hit = False 

3609 # XXX: Hack to support non-Basic args 

3610 # | 

3611 # V 

3612 if deep and getattr(expr, 'args', ()) and not expr.is_Atom: 

3613 sargs = [] 

3614 for arg in expr.args: 

3615 arg, arghit = Expr._expand_hint(arg, hint, **hints) 

3616 hit |= arghit 

3617 sargs.append(arg) 

3618 

3619 if hit: 

3620 expr = expr.func(*sargs) 

3621 

3622 if hasattr(expr, hint): 

3623 newexpr = getattr(expr, hint)(**hints) 

3624 if newexpr != expr: 

3625 return (newexpr, True) 

3626 

3627 return (expr, hit) 

3628 

3629 @cacheit 

3630 def expand(self, deep=True, modulus=None, power_base=True, power_exp=True, 

3631 mul=True, log=True, multinomial=True, basic=True, **hints): 

3632 """ 

3633 Expand an expression using hints. 

3634 

3635 See the docstring of the expand() function in sympy.core.function for 

3636 more information. 

3637 

3638 """ 

3639 from sympy.simplify.radsimp import fraction 

3640 

3641 hints.update(power_base=power_base, power_exp=power_exp, mul=mul, 

3642 log=log, multinomial=multinomial, basic=basic) 

3643 

3644 expr = self 

3645 if hints.pop('frac', False): 

3646 n, d = [a.expand(deep=deep, modulus=modulus, **hints) 

3647 for a in fraction(self)] 

3648 return n/d 

3649 elif hints.pop('denom', False): 

3650 n, d = fraction(self) 

3651 return n/d.expand(deep=deep, modulus=modulus, **hints) 

3652 elif hints.pop('numer', False): 

3653 n, d = fraction(self) 

3654 return n.expand(deep=deep, modulus=modulus, **hints)/d 

3655 

3656 # Although the hints are sorted here, an earlier hint may get applied 

3657 # at a given node in the expression tree before another because of how 

3658 # the hints are applied. e.g. expand(log(x*(y + z))) -> log(x*y + 

3659 # x*z) because while applying log at the top level, log and mul are 

3660 # applied at the deeper level in the tree so that when the log at the 

3661 # upper level gets applied, the mul has already been applied at the 

3662 # lower level. 

3663 

3664 # Additionally, because hints are only applied once, the expression 

3665 # may not be expanded all the way. For example, if mul is applied 

3666 # before multinomial, x*(x + 1)**2 won't be expanded all the way. For 

3667 # now, we just use a special case to make multinomial run before mul, 

3668 # so that at least polynomials will be expanded all the way. In the 

3669 # future, smarter heuristics should be applied. 

3670 # TODO: Smarter heuristics 

3671 

3672 def _expand_hint_key(hint): 

3673 """Make multinomial come before mul""" 

3674 if hint == 'mul': 

3675 return 'mulz' 

3676 return hint 

3677 

3678 for hint in sorted(hints.keys(), key=_expand_hint_key): 

3679 use_hint = hints[hint] 

3680 if use_hint: 

3681 hint = '_eval_expand_' + hint 

3682 expr, hit = Expr._expand_hint(expr, hint, deep=deep, **hints) 

3683 

3684 while True: 

3685 was = expr 

3686 if hints.get('multinomial', False): 

3687 expr, _ = Expr._expand_hint( 

3688 expr, '_eval_expand_multinomial', deep=deep, **hints) 

3689 if hints.get('mul', False): 

3690 expr, _ = Expr._expand_hint( 

3691 expr, '_eval_expand_mul', deep=deep, **hints) 

3692 if hints.get('log', False): 

3693 expr, _ = Expr._expand_hint( 

3694 expr, '_eval_expand_log', deep=deep, **hints) 

3695 if expr == was: 

3696 break 

3697 

3698 if modulus is not None: 

3699 modulus = sympify(modulus) 

3700 

3701 if not modulus.is_Integer or modulus <= 0: 

3702 raise ValueError( 

3703 "modulus must be a positive integer, got %s" % modulus) 

3704 

3705 terms = [] 

3706 

3707 for term in Add.make_args(expr): 

3708 coeff, tail = term.as_coeff_Mul(rational=True) 

3709 

3710 coeff %= modulus 

3711 

3712 if coeff: 

3713 terms.append(coeff*tail) 

3714 

3715 expr = Add(*terms) 

3716 

3717 return expr 

3718 

3719 ########################################################################### 

3720 ################### GLOBAL ACTION VERB WRAPPER METHODS #################### 

3721 ########################################################################### 

3722 

3723 def integrate(self, *args, **kwargs): 

3724 """See the integrate function in sympy.integrals""" 

3725 from sympy.integrals.integrals import integrate 

3726 return integrate(self, *args, **kwargs) 

3727 

3728 def nsimplify(self, constants=(), tolerance=None, full=False): 

3729 """See the nsimplify function in sympy.simplify""" 

3730 from sympy.simplify.simplify import nsimplify 

3731 return nsimplify(self, constants, tolerance, full) 

3732 

3733 def separate(self, deep=False, force=False): 

3734 """See the separate function in sympy.simplify""" 

3735 from .function import expand_power_base 

3736 return expand_power_base(self, deep=deep, force=force) 

3737 

3738 def collect(self, syms, func=None, evaluate=True, exact=False, distribute_order_term=True): 

3739 """See the collect function in sympy.simplify""" 

3740 from sympy.simplify.radsimp import collect 

3741 return collect(self, syms, func, evaluate, exact, distribute_order_term) 

3742 

3743 def together(self, *args, **kwargs): 

3744 """See the together function in sympy.polys""" 

3745 from sympy.polys.rationaltools import together 

3746 return together(self, *args, **kwargs) 

3747 

3748 def apart(self, x=None, **args): 

3749 """See the apart function in sympy.polys""" 

3750 from sympy.polys.partfrac import apart 

3751 return apart(self, x, **args) 

3752 

3753 def ratsimp(self): 

3754 """See the ratsimp function in sympy.simplify""" 

3755 from sympy.simplify.ratsimp import ratsimp 

3756 return ratsimp(self) 

3757 

3758 def trigsimp(self, **args): 

3759 """See the trigsimp function in sympy.simplify""" 

3760 from sympy.simplify.trigsimp import trigsimp 

3761 return trigsimp(self, **args) 

3762 

3763 def radsimp(self, **kwargs): 

3764 """See the radsimp function in sympy.simplify""" 

3765 from sympy.simplify.radsimp import radsimp 

3766 return radsimp(self, **kwargs) 

3767 

3768 def powsimp(self, *args, **kwargs): 

3769 """See the powsimp function in sympy.simplify""" 

3770 from sympy.simplify.powsimp import powsimp 

3771 return powsimp(self, *args, **kwargs) 

3772 

3773 def combsimp(self): 

3774 """See the combsimp function in sympy.simplify""" 

3775 from sympy.simplify.combsimp import combsimp 

3776 return combsimp(self) 

3777 

3778 def gammasimp(self): 

3779 """See the gammasimp function in sympy.simplify""" 

3780 from sympy.simplify.gammasimp import gammasimp 

3781 return gammasimp(self) 

3782 

3783 def factor(self, *gens, **args): 

3784 """See the factor() function in sympy.polys.polytools""" 

3785 from sympy.polys.polytools import factor 

3786 return factor(self, *gens, **args) 

3787 

3788 def cancel(self, *gens, **args): 

3789 """See the cancel function in sympy.polys""" 

3790 from sympy.polys.polytools import cancel 

3791 return cancel(self, *gens, **args) 

3792 

3793 def invert(self, g, *gens, **args): 

3794 """Return the multiplicative inverse of ``self`` mod ``g`` 

3795 where ``self`` (and ``g``) may be symbolic expressions). 

3796 

3797 See Also 

3798 ======== 

3799 sympy.core.numbers.mod_inverse, sympy.polys.polytools.invert 

3800 """ 

3801 if self.is_number and getattr(g, 'is_number', True): 

3802 from .numbers import mod_inverse 

3803 return mod_inverse(self, g) 

3804 from sympy.polys.polytools import invert 

3805 return invert(self, g, *gens, **args) 

3806 

3807 def round(self, n=None): 

3808 """Return x rounded to the given decimal place. 

3809 

3810 If a complex number would results, apply round to the real 

3811 and imaginary components of the number. 

3812 

3813 Examples 

3814 ======== 

3815 

3816 >>> from sympy import pi, E, I, S, Number 

3817 >>> pi.round() 

3818 3 

3819 >>> pi.round(2) 

3820 3.14 

3821 >>> (2*pi + E*I).round() 

3822 6 + 3*I 

3823 

3824 The round method has a chopping effect: 

3825 

3826 >>> (2*pi + I/10).round() 

3827 6 

3828 >>> (pi/10 + 2*I).round() 

3829 2*I 

3830 >>> (pi/10 + E*I).round(2) 

3831 0.31 + 2.72*I 

3832 

3833 Notes 

3834 ===== 

3835 

3836 The Python ``round`` function uses the SymPy ``round`` method so it 

3837 will always return a SymPy number (not a Python float or int): 

3838 

3839 >>> isinstance(round(S(123), -2), Number) 

3840 True 

3841 """ 

3842 x = self 

3843 

3844 if not x.is_number: 

3845 raise TypeError("Cannot round symbolic expression") 

3846 if not x.is_Atom: 

3847 if not pure_complex(x.n(2), or_real=True): 

3848 raise TypeError( 

3849 'Expected a number but got %s:' % func_name(x)) 

3850 elif x in _illegal: 

3851 return x 

3852 if x.is_extended_real is False: 

3853 r, i = x.as_real_imag() 

3854 return r.round(n) + S.ImaginaryUnit*i.round(n) 

3855 if not x: 

3856 return S.Zero if n is None else x 

3857 

3858 p = as_int(n or 0) 

3859 

3860 if x.is_Integer: 

3861 return Integer(round(int(x), p)) 

3862 

3863 digits_to_decimal = _mag(x) # _mag(12) = 2, _mag(.012) = -1 

3864 allow = digits_to_decimal + p 

3865 precs = [f._prec for f in x.atoms(Float)] 

3866 dps = prec_to_dps(max(precs)) if precs else None 

3867 if dps is None: 

3868 # assume everything is exact so use the Python 

3869 # float default or whatever was requested 

3870 dps = max(15, allow) 

3871 else: 

3872 allow = min(allow, dps) 

3873 # this will shift all digits to right of decimal 

3874 # and give us dps to work with as an int 

3875 shift = -digits_to_decimal + dps 

3876 extra = 1 # how far we look past known digits 

3877 # NOTE 

3878 # mpmath will calculate the binary representation to 

3879 # an arbitrary number of digits but we must base our 

3880 # answer on a finite number of those digits, e.g. 

3881 # .575 2589569785738035/2**52 in binary. 

3882 # mpmath shows us that the first 18 digits are 

3883 # >>> Float(.575).n(18) 

3884 # 0.574999999999999956 

3885 # The default precision is 15 digits and if we ask 

3886 # for 15 we get 

3887 # >>> Float(.575).n(15) 

3888 # 0.575000000000000 

3889 # mpmath handles rounding at the 15th digit. But we 

3890 # need to be careful since the user might be asking 

3891 # for rounding at the last digit and our semantics 

3892 # are to round toward the even final digit when there 

3893 # is a tie. So the extra digit will be used to make 

3894 # that decision. In this case, the value is the same 

3895 # to 15 digits: 

3896 # >>> Float(.575).n(16) 

3897 # 0.5750000000000000 

3898 # Now converting this to the 15 known digits gives 

3899 # 575000000000000.0 

3900 # which rounds to integer 

3901 # 5750000000000000 

3902 # And now we can round to the desired digt, e.g. at 

3903 # the second from the left and we get 

3904 # 5800000000000000 

3905 # and rescaling that gives 

3906 # 0.58 

3907 # as the final result. 

3908 # If the value is made slightly less than 0.575 we might 

3909 # still obtain the same value: 

3910 # >>> Float(.575-1e-16).n(16)*10**15 

3911 # 574999999999999.8 

3912 # What 15 digits best represents the known digits (which are 

3913 # to the left of the decimal? 5750000000000000, the same as 

3914 # before. The only way we will round down (in this case) is 

3915 # if we declared that we had more than 15 digits of precision. 

3916 # For example, if we use 16 digits of precision, the integer 

3917 # we deal with is 

3918 # >>> Float(.575-1e-16).n(17)*10**16 

3919 # 5749999999999998.4 

3920 # and this now rounds to 5749999999999998 and (if we round to 

3921 # the 2nd digit from the left) we get 5700000000000000. 

3922 # 

3923 xf = x.n(dps + extra)*Pow(10, shift) 

3924 xi = Integer(xf) 

3925 # use the last digit to select the value of xi 

3926 # nearest to x before rounding at the desired digit 

3927 sign = 1 if x > 0 else -1 

3928 dif2 = sign*(xf - xi).n(extra) 

3929 if dif2 < 0: 

3930 raise NotImplementedError( 

3931 'not expecting int(x) to round away from 0') 

3932 if dif2 > .5: 

3933 xi += sign # round away from 0 

3934 elif dif2 == .5: 

3935 xi += sign if xi%2 else -sign # round toward even 

3936 # shift p to the new position 

3937 ip = p - shift 

3938 # let Python handle the int rounding then rescale 

3939 xr = round(xi.p, ip) 

3940 # restore scale 

3941 rv = Rational(xr, Pow(10, shift)) 

3942 # return Float or Integer 

3943 if rv.is_Integer: 

3944 if n is None: # the single-arg case 

3945 return rv 

3946 # use str or else it won't be a float 

3947 return Float(str(rv), dps) # keep same precision 

3948 else: 

3949 if not allow and rv > self: 

3950 allow += 1 

3951 return Float(rv, allow) 

3952 

3953 __round__ = round 

3954 

3955 def _eval_derivative_matrix_lines(self, x): 

3956 from sympy.matrices.expressions.matexpr import _LeftRightArgs 

3957 return [_LeftRightArgs([S.One, S.One], higher=self._eval_derivative(x))] 

3958 

3959 

3960class AtomicExpr(Atom, Expr): 

3961 """ 

3962 A parent class for object which are both atoms and Exprs. 

3963 

3964 For example: Symbol, Number, Rational, Integer, ... 

3965 But not: Add, Mul, Pow, ... 

3966 """ 

3967 is_number = False 

3968 is_Atom = True 

3969 

3970 __slots__ = () 

3971 

3972 def _eval_derivative(self, s): 

3973 if self == s: 

3974 return S.One 

3975 return S.Zero 

3976 

3977 def _eval_derivative_n_times(self, s, n): 

3978 from .containers import Tuple 

3979 from sympy.matrices.expressions.matexpr import MatrixExpr 

3980 from sympy.matrices.common import MatrixCommon 

3981 if isinstance(s, (MatrixCommon, Tuple, Iterable, MatrixExpr)): 

3982 return super()._eval_derivative_n_times(s, n) 

3983 from .relational import Eq 

3984 from sympy.functions.elementary.piecewise import Piecewise 

3985 if self == s: 

3986 return Piecewise((self, Eq(n, 0)), (1, Eq(n, 1)), (0, True)) 

3987 else: 

3988 return Piecewise((self, Eq(n, 0)), (0, True)) 

3989 

3990 def _eval_is_polynomial(self, syms): 

3991 return True 

3992 

3993 def _eval_is_rational_function(self, syms): 

3994 return self not in _illegal 

3995 

3996 def _eval_is_meromorphic(self, x, a): 

3997 from sympy.calculus.accumulationbounds import AccumBounds 

3998 return (not self.is_Number or self.is_finite) and not isinstance(self, AccumBounds) 

3999 

4000 def _eval_is_algebraic_expr(self, syms): 

4001 return True 

4002 

4003 def _eval_nseries(self, x, n, logx, cdir=0): 

4004 return self 

4005 

4006 @property 

4007 def expr_free_symbols(self): 

4008 sympy_deprecation_warning(""" 

4009 The expr_free_symbols property is deprecated. Use free_symbols to get 

4010 the free symbols of an expression. 

4011 """, 

4012 deprecated_since_version="1.9", 

4013 active_deprecations_target="deprecated-expr-free-symbols") 

4014 return {self} 

4015 

4016 

4017def _mag(x): 

4018 r"""Return integer $i$ such that $0.1 \le x/10^i < 1$ 

4019 

4020 Examples 

4021 ======== 

4022 

4023 >>> from sympy.core.expr import _mag 

4024 >>> from sympy import Float 

4025 >>> _mag(Float(.1)) 

4026 0 

4027 >>> _mag(Float(.01)) 

4028 -1 

4029 >>> _mag(Float(1234)) 

4030 4 

4031 """ 

4032 from math import log10, ceil, log 

4033 xpos = abs(x.n()) 

4034 if not xpos: 

4035 return S.Zero 

4036 try: 

4037 mag_first_dig = int(ceil(log10(xpos))) 

4038 except (ValueError, OverflowError): 

4039 mag_first_dig = int(ceil(Float(mpf_log(xpos._mpf_, 53))/log(10))) 

4040 # check that we aren't off by 1 

4041 if (xpos/10**mag_first_dig) >= 1: 

4042 assert 1 <= (xpos/10**mag_first_dig) < 10 

4043 mag_first_dig += 1 

4044 return mag_first_dig 

4045 

4046 

4047class UnevaluatedExpr(Expr): 

4048 """ 

4049 Expression that is not evaluated unless released. 

4050 

4051 Examples 

4052 ======== 

4053 

4054 >>> from sympy import UnevaluatedExpr 

4055 >>> from sympy.abc import x 

4056 >>> x*(1/x) 

4057 1 

4058 >>> x*UnevaluatedExpr(1/x) 

4059 x*1/x 

4060 

4061 """ 

4062 

4063 def __new__(cls, arg, **kwargs): 

4064 arg = _sympify(arg) 

4065 obj = Expr.__new__(cls, arg, **kwargs) 

4066 return obj 

4067 

4068 def doit(self, **hints): 

4069 if hints.get("deep", True): 

4070 return self.args[0].doit(**hints) 

4071 else: 

4072 return self.args[0] 

4073 

4074 

4075 

4076def unchanged(func, *args): 

4077 """Return True if `func` applied to the `args` is unchanged. 

4078 Can be used instead of `assert foo == foo`. 

4079 

4080 Examples 

4081 ======== 

4082 

4083 >>> from sympy import Piecewise, cos, pi 

4084 >>> from sympy.core.expr import unchanged 

4085 >>> from sympy.abc import x 

4086 

4087 >>> unchanged(cos, 1) # instead of assert cos(1) == cos(1) 

4088 True 

4089 

4090 >>> unchanged(cos, pi) 

4091 False 

4092 

4093 Comparison of args uses the builtin capabilities of the object's 

4094 arguments to test for equality so args can be defined loosely. Here, 

4095 the ExprCondPair arguments of Piecewise compare as equal to the 

4096 tuples that can be used to create the Piecewise: 

4097 

4098 >>> unchanged(Piecewise, (x, x > 1), (0, True)) 

4099 True 

4100 """ 

4101 f = func(*args) 

4102 return f.func == func and f.args == args 

4103 

4104 

4105class ExprBuilder: 

4106 def __init__(self, op, args=None, validator=None, check=True): 

4107 if not hasattr(op, "__call__"): 

4108 raise TypeError("op {} needs to be callable".format(op)) 

4109 self.op = op 

4110 if args is None: 

4111 self.args = [] 

4112 else: 

4113 self.args = args 

4114 self.validator = validator 

4115 if (validator is not None) and check: 

4116 self.validate() 

4117 

4118 @staticmethod 

4119 def _build_args(args): 

4120 return [i.build() if isinstance(i, ExprBuilder) else i for i in args] 

4121 

4122 def validate(self): 

4123 if self.validator is None: 

4124 return 

4125 args = self._build_args(self.args) 

4126 self.validator(*args) 

4127 

4128 def build(self, check=True): 

4129 args = self._build_args(self.args) 

4130 if self.validator and check: 

4131 self.validator(*args) 

4132 return self.op(*args) 

4133 

4134 def append_argument(self, arg, check=True): 

4135 self.args.append(arg) 

4136 if self.validator and check: 

4137 self.validate(*self.args) 

4138 

4139 def __getitem__(self, item): 

4140 if item == 0: 

4141 return self.op 

4142 else: 

4143 return self.args[item-1] 

4144 

4145 def __repr__(self): 

4146 return str(self.build()) 

4147 

4148 def search_element(self, elem): 

4149 for i, arg in enumerate(self.args): 

4150 if isinstance(arg, ExprBuilder): 

4151 ret = arg.search_index(elem) 

4152 if ret is not None: 

4153 return (i,) + ret 

4154 elif id(arg) == id(elem): 

4155 return (i,) 

4156 return None 

4157 

4158 

4159from .mul import Mul 

4160from .add import Add 

4161from .power import Pow 

4162from .function import Function, _derivative_dispatch 

4163from .mod import Mod 

4164from .exprtools import factor_terms 

4165from .numbers import Float, Integer, Rational, _illegal