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
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from __future__ import annotations
3from typing import TYPE_CHECKING
4from collections.abc import Iterable
5from functools import reduce
6import re
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
23if TYPE_CHECKING:
24 from .numbers import Number
26from collections import defaultdict
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)
42@sympify_method_args
43class Expr(Basic, EvalfMixin):
44 """
45 Base class for algebraic expressions.
47 Explanation
48 ===========
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).
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
60 See Also
61 ========
63 sympy.core.basic.Basic
64 """
66 __slots__: tuple[str, ...] = ()
68 is_scalar = True # self derivative is 1
70 @property
71 def _diff_wrt(self):
72 """Return True if one can differentiate with respect to this
73 object, else False.
75 Explanation
76 ===========
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.
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.
92 Examples
93 ========
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
113 @cacheit
114 def sort_key(self, order=None):
116 coeff, expr = self.as_coeff_Mul()
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
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
141 args = tuple(
142 [ default_sort_key(arg, order=order) for arg in args ])
144 args = (len(args), tuple(args))
145 exp = exp.sort_key(order=order)
147 return expr.class_key(), args, exp, coeff
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
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
173 @property
174 def _add_handler(self):
175 return Add
177 @property
178 def _mul_handler(self):
179 return Mul
181 def __pos__(self):
182 return self
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)
191 def __abs__(self) -> Expr:
192 from sympy.functions.elementary.complexes import Abs
193 return Abs(self)
195 @sympify_return([('other', 'Expr')], NotImplemented)
196 @call_highest_priority('__radd__')
197 def __add__(self, other):
198 return Add(self, other)
200 @sympify_return([('other', 'Expr')], NotImplemented)
201 @call_highest_priority('__add__')
202 def __radd__(self, other):
203 return Add(other, self)
205 @sympify_return([('other', 'Expr')], NotImplemented)
206 @call_highest_priority('__rsub__')
207 def __sub__(self, other):
208 return Add(self, -other)
210 @sympify_return([('other', 'Expr')], NotImplemented)
211 @call_highest_priority('__sub__')
212 def __rsub__(self, other):
213 return Add(other, -self)
215 @sympify_return([('other', 'Expr')], NotImplemented)
216 @call_highest_priority('__rmul__')
217 def __mul__(self, other):
218 return Mul(self, other)
220 @sympify_return([('other', 'Expr')], NotImplemented)
221 @call_highest_priority('__mul__')
222 def __rmul__(self, other):
223 return Mul(other, self)
225 @sympify_return([('other', 'Expr')], NotImplemented)
226 @call_highest_priority('__rpow__')
227 def _pow(self, other):
228 return Pow(self, other)
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
247 @sympify_return([('other', 'Expr')], NotImplemented)
248 @call_highest_priority('__pow__')
249 def __rpow__(self, other):
250 return Pow(other, self)
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)
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)
270 @sympify_return([('other', 'Expr')], NotImplemented)
271 @call_highest_priority('__rmod__')
272 def __mod__(self, other):
273 return Mod(self, other)
275 @sympify_return([('other', 'Expr')], NotImplemented)
276 @call_highest_priority('__mod__')
277 def __rmod__(self, other):
278 return Mod(other, self)
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)
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)
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)
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)
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
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")
353 def __complex__(self):
354 result = self.evalf()
355 re, im = result.as_real_imag()
356 return complex(float(re), float(im))
358 @sympify_return([('other', 'Expr')], NotImplemented)
359 def __ge__(self, other):
360 from .relational import GreaterThan
361 return GreaterThan(self, other)
363 @sympify_return([('other', 'Expr')], NotImplemented)
364 def __le__(self, other):
365 from .relational import LessThan
366 return LessThan(self, other)
368 @sympify_return([('other', 'Expr')], NotImplemented)
369 def __gt__(self, other):
370 from .relational import StrictGreaterThan
371 return StrictGreaterThan(self, other)
373 @sympify_return([('other', 'Expr')], NotImplemented)
374 def __lt__(self, other):
375 from .relational import StrictLessThan
376 return StrictLessThan(self, other)
378 def __trunc__(self):
379 if not self.is_number:
380 raise TypeError("Cannot truncate symbols and expressions")
381 else:
382 return Integer(self)
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)
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)")
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.
416 Examples
417 ========
419 >>> from sympy import Function, Integral, cos, sin, pi
420 >>> from sympy.abc import x
421 >>> f = Function('f')
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
434 Not all numbers are Numbers in the SymPy sense:
436 >>> pi.is_number, pi.is_Number
437 (True, False)
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.
444 >>> cos(1).is_number and cos(1).is_comparable
445 True
447 >>> z = cos(1)**2 + sin(1)**2 - 1
448 >>> z.is_number
449 True
450 >>> z.is_comparable
451 False
453 See Also
454 ========
456 sympy.core.basic.Basic.is_comparable
457 """
458 return all(obj.is_number for obj in self.args)
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.
464 Explanation
465 ===========
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.
476 Examples
477 ========
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
490 See Also
491 ========
493 sympy.core.random.random_complex_number
494 """
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))
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
520 if nmag._prec == 1:
521 # increase the precision up to the default maximum
522 # precision to see if we can get any significance
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
530 if nmag._prec != 1:
531 if n is None:
532 n = max(prec, 15)
533 return self.evalf(n, subs=reps)
535 # never got any significance
536 return None
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.
542 Explanation
543 ===========
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:
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.
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.
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.
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.
572 If flag simplify=False is passed, self will not be simplified;
573 the default is True since self should be simplified before testing.
575 Examples
576 ========
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
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 """
613 def check_denominator_zeros(expression):
614 from sympy.solvers.solvers import denoms
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
627 simplify = flags.get('simplify', True)
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
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
642 # simplify unless this has already been done
643 expr = self
644 if simplify:
645 expr = expr.simplify()
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
653 # Don't attempt substitution or differentiation with non-number symbols
654 wrt_number = {sym for sym in wrt if sym.kind is NumberKind}
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
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
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.
715 Explanation
716 ===========
718 If ``self`` is a Number (or complex number) that is not zero, then
719 the result is False.
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.
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
733 other = sympify(other)
734 if self == other:
735 return True
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)
743 if not diff:
744 return True
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
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)
757 constant = diff.is_constant(simplify=False, failing_number=True)
759 if constant is False:
760 return False
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
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
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
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
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
847 if failing_expression:
848 return diff
849 return None
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
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
890 def _eval_is_extended_positive(self):
891 return self._eval_is_extended_positive_negative(positive=True)
893 def _eval_is_extended_negative(self):
894 return self._eval_is_extended_positive_negative(positive=False)
896 def _eval_interval(self, x, a, b):
897 """
898 Returns evaluation over an interval. For most functions this is:
900 self.subs(x, b) - self.subs(x, a),
902 possibly using limit() if NaN is returned from subs, or if
903 singularities are found between a and b.
905 If b or a is None, it only evaluates -self.subs(x, a) or self.subs(b, x),
906 respectively.
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
915 if (a is None and b is None):
916 raise ValueError('Both interval ends cannot be None.')
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 "+")
931 if isinstance(C, Limit):
932 raise NotImplementedError("Could not compute limit")
933 return C
935 if a == b:
936 return S.Zero
938 A = _eval_endpoint(left=True)
939 if A is S.NaN:
940 return A
942 B = _eval_endpoint(left=False)
944 if (a and b) is None:
945 return B - A
947 value = B - A
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
975 return value
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
982 def _eval_conjugate(self):
983 if self.is_extended_real:
984 return self
985 elif self.is_imaginary:
986 return -self
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)
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
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)
1025 def transpose(self):
1026 from sympy.functions.elementary.complexes import transpose
1027 return transpose(self)
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)
1042 def adjoint(self):
1043 from sympy.functions.elementary.complexes import adjoint
1044 return adjoint(self)
1046 @classmethod
1047 def _parse_order(cls, order):
1048 """Parse and configure the ordering of terms. """
1049 from sympy.polys.orderings import monomial_key
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:]
1059 monom_key = monomial_key(order)
1061 def neg(monom):
1062 return tuple([neg(m) if isinstance(m, tuple) else -m for m in monom])
1064 def key(term):
1065 _, ((re, im), monom, ncpart) = term
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))
1071 return monom, ncpart, coeff
1073 return key, reverse
1075 def as_ordered_factors(self, order=None):
1076 """Return list of ordered factors (if Mul) else [self]."""
1077 return [self]
1079 def as_poly(self, *gens, **args):
1080 """Converts ``self`` to a polynomial or returns ``None``.
1082 Explanation
1083 ===========
1085 >>> from sympy import sin
1086 >>> from sympy.abc import x, y
1088 >>> print((x**2 + x*y).as_poly())
1089 Poly(x**2 + x*y, x, y, domain='ZZ')
1091 >>> print((x**2 + x*y).as_poly(x, y))
1092 Poly(x**2 + x*y, x, y, domain='ZZ')
1094 >>> print((x**2 + sin(y)).as_poly(x, y))
1095 None
1097 """
1098 from sympy.polys.polyerrors import PolynomialError, GeneratorsNeeded
1099 from sympy.polys.polytools import Poly
1101 try:
1102 poly = Poly(self, *gens, **args)
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
1113 def as_ordered_terms(self, order=None, data=False):
1114 """
1115 Transform an expression to an ordered list of terms.
1117 Examples
1118 ========
1120 >>> from sympy import sin, cos
1121 >>> from sympy.abc import x
1123 >>> (sin(x)**2*cos(x) + sin(x)**2 + 1).as_ordered_terms()
1124 [sin(x)**2*cos(x), sin(x)**2, 1]
1126 """
1128 from .numbers import Number, NumberSymbol
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
1145 key, reverse = self._parse_order(order)
1146 terms, gens = self.as_terms()
1148 if not any(term.is_Order for term, _ in terms):
1149 ordered = sorted(terms, key=key, reverse=reverse)
1150 else:
1151 _terms, _order = [], []
1153 for term, repr in terms:
1154 if not term.is_Order:
1155 _terms.append((term, repr))
1156 else:
1157 _order.append((term, repr))
1159 ordered = sorted(_terms, key=key, reverse=True) \
1160 + sorted(_order, key=key, reverse=True)
1162 if data:
1163 return ordered, gens
1164 else:
1165 return [term for term, _ in ordered]
1167 def as_terms(self):
1168 """Transform an expression to a list of terms. """
1169 from .exprtools import decompose_power
1171 gens, terms = set(), []
1173 for term in Add.make_args(self):
1174 coeff, _term = term.as_coeff_Mul()
1176 coeff = complex(coeff)
1177 cpart, ncpart = {}, []
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
1189 if factor.is_commutative:
1190 base, exp = decompose_power(factor)
1192 cpart[base] = exp
1193 gens.add(base)
1194 else:
1195 ncpart.append(factor)
1197 coeff = coeff.real, coeff.imag
1198 ncpart = tuple(ncpart)
1200 terms.append((term, (coeff, cpart, ncpart)))
1202 gens = sorted(gens, key=default_sort_key)
1204 k, indices = len(gens), {}
1206 for i, g in enumerate(gens):
1207 indices[g] = i
1209 result = []
1211 for term, (coeff, cpart, ncpart) in terms:
1212 monom = [0]*k
1214 for base, exp in cpart.items():
1215 monom[indices[base]] = exp
1217 result.append((term, (coeff, tuple(monom), ncpart)))
1219 return result, gens
1221 def removeO(self):
1222 """Removes the additive O(..) symbol if there is one"""
1223 return self
1225 def getO(self):
1226 """Returns the additive O(..) symbol if there is one, else None."""
1227 return None
1229 def getn(self):
1230 """
1231 Returns the order of the expression.
1233 Explanation
1234 ===========
1236 The order is determined either from the O(...) term. If there
1237 is no O(...) term, it returns None.
1239 Examples
1240 ========
1242 >>> from sympy import O
1243 >>> from sympy.abc import x
1244 >>> (1 + x + O(x**2)).getn()
1245 2
1246 >>> (1 + x).getn()
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)
1273 raise NotImplementedError('not sure of order of %s' % o)
1275 def count_ops(self, visual=None):
1276 from .function import count_ops
1277 return count_ops(self, visual)
1279 def args_cnc(self, cset=False, warn=True, split_1=True):
1280 """Return [commutative factors, non-commutative factors] of self.
1282 Explanation
1283 ===========
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.
1291 Note: -1 is always separated from a Number unless split_1 is False.
1293 Examples
1294 ========
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}, []]
1310 The arg is always treated as a Mul:
1312 >>> (-2 + x + A).args_cnc()
1313 [[], [x - 2 + A]]
1314 >>> (-oo).args_cnc() # -oo is a singleton
1315 [[-1, oo], []]
1316 """
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 = []
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]]
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]
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.
1350 Explanation
1351 ===========
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.
1357 Examples
1358 ========
1360 >>> from sympy import symbols
1361 >>> from sympy.abc import x, y, z
1363 You can select terms that have an explicit negative in front of them:
1365 >>> (-x + 2*y).coeff(-1)
1366 x
1367 >>> (x - 2*y).coeff(-1)
1368 2*y
1370 You can select terms with no Rational coefficient:
1372 >>> (x + 2*y).coeff(1)
1373 x
1374 >>> (3 + 2*x + 4*x**2).coeff(1)
1375 0
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):
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]
1392 You can select terms that have a numerical term in front of them:
1394 >>> (-x - 2*y).coeff(2)
1395 -y
1396 >>> from sympy import sqrt
1397 >>> (x + sqrt(2)*x).coeff(sqrt(2))
1398 x
1400 The matching is exact:
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
1413 In addition, no factoring is done, so 1 + z*(1 + y) is not obtained
1414 from the following:
1416 >>> (x + z*(x + x*y)).coeff(x)
1417 1
1419 If such factoring is desired, factor_terms can be used first:
1421 >>> from sympy import factor_terms
1422 >>> factor_terms(x + z*(x + x*y)).coeff(x)
1423 z*(y + 1) + 1
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
1435 If there is more than one possible coefficient 0 is returned:
1437 >>> (n*m + m*n).coeff(n)
1438 0
1440 If there is only one possible coefficient, it is returned:
1442 >>> (n*m + x*m*n).coeff(m*n)
1443 x
1444 >>> (n*m + x*m*n).coeff(m*n, right=1)
1445 1
1447 See Also
1448 ========
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
1461 n = as_int(n)
1463 if not x:
1464 return S.Zero
1466 if x == self:
1467 if n == 1:
1468 return S.One
1469 return S.Zero
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)
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]
1488 # continue with the full method, looking for this power of x:
1489 x = x**n
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[:]
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.
1505 Examples
1506 ========
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
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
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])
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):])
1625 return S.Zero
1627 def as_expr(self, *gens):
1628 """
1629 Convert a polynomial to a SymPy expression.
1631 Examples
1632 ========
1634 >>> from sympy import sin
1635 >>> from sympy.abc import x, y
1637 >>> f = (x**2 + x*y).as_poly(x, y)
1638 >>> f.as_expr()
1639 x**2 + x*y
1641 >>> sin(x).as_expr()
1642 sin(x)
1644 """
1645 return self
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.
1654 Examples
1655 ========
1657 >>> from sympy import E, pi, sin, I, Poly
1658 >>> from sympy.abc import x
1660 >>> E.as_coefficient(E)
1661 1
1662 >>> (2*E).as_coefficient(E)
1663 2
1664 >>> (2*sin(E)*E).as_coefficient(E)
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.)
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
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.)
1688 >>> (2*E*x + x).as_coefficient(E)
1689 >>> (2*E*x + x).coeff(E)
1690 2*x
1692 >>> (E*(x + 1) + x).as_coefficient(E)
1694 >>> (2*pi*I).as_coefficient(pi*I)
1695 2
1696 >>> (2*I).as_coefficient(pi*I)
1698 See Also
1699 ========
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
1709 """
1711 r = self.extract_multiplicatively(expr)
1712 if r and not r.has(expr):
1713 return r
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.:
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
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.
1729 For nonzero `self`, the returned tuple (i, d) has the
1730 following interpretation:
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.
1739 To force the expression to be treated as an Add, use the hint as_Add=True
1741 Examples
1742 ========
1744 -- self is an Add
1746 >>> from sympy import sin, cos, exp
1747 >>> from sympy.abc import x, y, z
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)
1758 -- self is a Mul
1760 >>> (x*sin(x)*cos(y)).as_independent(x)
1761 (cos(y), x*sin(x))
1763 non-commutative terms cannot always be separated out when self is a Mul
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))
1778 -- self is anything else:
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))
1787 -- force self to be treated as an Add:
1789 >>> (3*x).as_independent(x, as_Add=True)
1790 (0, 3*x)
1792 -- force self to be treated as a Mul:
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)
1799 Note how the below differs from the above in making the
1800 constant on the dep term positive.
1802 >>> (y*(-3+x)).as_independent(x)
1803 (y, x - 3)
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
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
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
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))
1840 See Also
1841 ========
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
1853 if self is S.Zero:
1854 return (self, self)
1856 func = self.func
1857 if hint.get('as_Add', isinstance(self, Add) ):
1858 want = Add
1859 else:
1860 want = Mul
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)
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))
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()
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))
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.
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.
1917 >>> from sympy import symbols, I
1919 >>> x, y = symbols('x,y', real=True)
1921 >>> (x + y*I).as_real_imag()
1922 (x, y)
1924 >>> from sympy.abc import z, w
1926 >>> (z + w*I).as_real_imag()
1927 (re(z) - im(w), re(w) + im(z))
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))
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.
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
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.
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.
1965 Examples
1966 ========
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}
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
2009 def as_base_exp(self) -> tuple[Expr, Expr]:
2010 # a -> b ** e
2011 return self, S.One
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``.
2016 c should be a Rational multiplied by any factors of the Mul that are
2017 independent of deps.
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).
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.
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)``
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,)
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``.
2051 c should be a Rational added to any terms of the Add that are
2052 independent of deps.
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).
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.
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)``
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, ())
2078 """
2079 if deps:
2080 if not self.has_free(*deps):
2081 return self, ()
2082 return S.Zero, (self,)
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).
2090 Examples
2091 ========
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
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).
2118 Examples
2119 ========
2121 >>> from sympy import sqrt
2122 >>> from sympy.abc import x, y, z
2124 >>> eq = 2 + 2*x + 2*y*(3 + 3*y)
2126 The as_content_primitive function is recursive and retains structure:
2128 >>> eq.as_content_primitive()
2129 (2, x + 3*y*(y + 1) + 1)
2131 Integer powers will have Rationals extracted from the base:
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))
2138 Terms may end up joining once their as_content_primitives are added:
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)
2151 Radical content can also be factored out of the primitive:
2153 >>> (2*sqrt(2) + 4*sqrt(10)).as_content_primitive(radical=True)
2154 (2, sqrt(2)*(1 + 2*sqrt(5)))
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.
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
2167 def as_numer_denom(self):
2168 """Return the numerator and the denominator of an expression.
2170 expression -> a/b -> a, b
2172 This is just a stub that should be defined by
2173 an object's class methods to get anything else.
2175 See Also
2176 ========
2178 normal: return ``a/b`` instead of ``(a, b)``
2180 """
2181 return self, S.One
2183 def normal(self):
2184 """Return the expression as a fraction.
2186 expression -> a/b
2188 See Also
2189 ========
2191 as_numer_denom: return ``(a, b)`` instead of ``a/b``
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
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.
2208 Examples
2209 ========
2211 >>> from sympy import symbols, Rational
2213 >>> x, y = symbols('x,y', real=True)
2215 >>> ((x*y)**3).extract_multiplicatively(x**2 * y)
2216 x*y**2
2218 >>> ((x*y)**3).extract_multiplicatively(x**4 * y)
2220 >>> (2*x).extract_multiplicatively(2)
2221 x
2223 >>> (2*x).extract_multiplicatively(3)
2225 >>> (Rational(1, 2)*x).extract_multiplicatively(3)
2226 x/6
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
2239 if c.is_Add:
2240 cc, pc = c.primitive()
2241 if cc is not S.One:
2242 c = Mul(cc, pc, evaluate=False)
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
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)
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.
2343 Examples
2344 ========
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
2356 See Also
2357 ========
2358 extract_multiplicatively
2359 coeff
2360 as_coefficient
2362 """
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
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
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
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
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)
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.
2440 Examples
2441 ========
2443 >>> from sympy.abc import x, y
2444 >>> (x + y).expr_free_symbols # doctest: +SKIP
2445 {x, y}
2447 If the expression is contained in a non-expression object, do not return
2448 the free symbols. Compare:
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}
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.
2470 Examples
2471 ========
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}
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:
2482 >>> (x*(y - x)).could_extract_minus_sign()
2483 False
2485 To put something in canonical form wrt to sign, use `signsimp`:
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
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).
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)
2515 If allow_half is True, also extract exp_polar(I*pi):
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
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 = []
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
2572 def is_polynomial(self, *syms):
2573 r"""
2574 Return True if self is a polynomial in syms and False otherwise.
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.
2584 This is not part of the assumptions system. You cannot do
2585 Symbol('z', polynomial=True).
2587 Examples
2588 ========
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
2608 >>> n = Symbol('n', nonnegative=True, integer=True)
2609 >>> (x**n + 1).is_polynomial(x)
2610 False
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.
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
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
2634 See also .is_rational_function()
2636 """
2637 if syms:
2638 syms = set(map(sympify, syms))
2639 else:
2640 syms = self.free_symbols
2641 if not syms:
2642 return True
2644 return self._eval_is_polynomial(syms)
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
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.
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.
2666 This is not part of the assumptions system. You cannot do
2667 Symbol('z', rational_function=True).
2669 Examples
2670 ========
2672 >>> from sympy import Symbol, sin
2673 >>> from sympy.abc import x, y
2675 >>> (x/y).is_rational_function()
2676 True
2678 >>> (x**2).is_rational_function()
2679 True
2681 >>> (x/sin(y)).is_rational_function(y)
2682 False
2684 >>> n = Symbol('n', integer=True)
2685 >>> (x**n + 1).is_rational_function(x)
2686 False
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.
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
2702 See also is_algebraic_expr().
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
2712 return self._eval_is_rational_function(syms)
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
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``.
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.
2730 Examples
2731 ========
2733 >>> from sympy import zoo, log, sin, sqrt
2734 >>> from sympy.abc import x
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
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
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
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.
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
2775 """
2776 if not x.is_symbol:
2777 raise TypeError("{} should be of symbol type".format(x))
2778 a = sympify(a)
2780 return self._eval_is_meromorphic(x, a)
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
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.
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.
2800 Examples
2801 ========
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
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.
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
2821 See Also
2822 ========
2824 is_rational_function
2826 References
2827 ==========
2829 .. [1] https://en.wikipedia.org/wiki/Algebraic_expression
2831 """
2832 if syms:
2833 syms = set(map(sympify, syms))
2834 else:
2835 syms = self.free_symbols
2836 if not syms:
2837 return True
2839 return self._eval_is_algebraic_expr(syms)
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
2848 ###################################################################################
2849 ##################### SERIES, LEADING TERM, LIMIT, ORDER METHODS ##################
2850 ###################################################################################
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.
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).
2861 If ``x=None`` and ``self`` is univariate, the univariate symbol will
2862 be supplied, otherwise an error will be raised.
2864 Parameters
2865 ==========
2867 expr : Expression
2868 The expression whose series is to be expanded.
2870 x : Symbol
2871 It is the variable of the expression to be calculated.
2873 x0 : Value
2874 The value around which ``x`` is calculated. Can be any value
2875 from ``-oo`` to ``oo``.
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.
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``).
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.
2892 cdir : optional
2893 It stands for complex direction, and indicates the direction
2894 from which the expansion needs to be evaluated.
2896 Examples
2897 ========
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)
2913 If ``n=None`` then a generator of the series terms will be returned.
2915 >>> term=cos(x).series(n=None)
2916 >>> [next(term) for i in range(2)]
2917 [1, -x**2/2]
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.
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))
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))
2938 For rational expressions this method may return original expression without the Order term.
2939 >>> (1/x).series(x, n=8)
2940 1/x
2942 Returns
2943 =======
2945 Expr : Expression
2946 Series expansion of the expression about x0
2948 Raises
2949 ======
2951 TypeError
2952 If "n" and "x0" are infinity objects
2954 PoleError
2955 If "x0" is an infinity object
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()
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
2978 if len(dir) != 1 or dir not in '+-':
2979 raise ValueError("Dir must be '+' or '-'")
2981 x0 = sympify(x0)
2982 cdir = sympify(cdir)
2983 from sympy.functions.elementary.complexes import im, sign
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
3000 cdir = cdir/abs(cdir)
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)
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})
3021 # from here on it's x0=0 and dir='+' handling
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)
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
3080 try:
3081 from sympy.simplify.radsimp import collect
3082 return collect(s1, x) + o
3083 except NotImplementedError:
3084 return s1 + o
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
3114 return yield_lseries(self.removeO()._eval_lseries(x, logx=logx, cdir=cdir))
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)``.
3120 Parameters
3121 ==========
3123 self : Expression
3124 The expression whose series is to be expanded.
3126 x : Symbol
3127 It is the variable of the expression to be calculated.
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.
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.
3138 bound : Value, Integer
3139 Use the ``bound`` parameter to give limit on rewriting
3140 coefficients in its normalised form.
3142 Examples
3143 ========
3145 >>> from sympy import sin, exp
3146 >>> from sympy.abc import x
3148 >>> e = sin(1/x + exp(-x)) - sin(1/x)
3150 >>> e.aseries(x)
3151 (1/(24*x**4) - 1/(2*x**2) + 1 + O(x**(-6), (x, oo)))*exp(-x)
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))
3156 >>> e = exp(exp(x)/(1 - 1/x))
3158 >>> e.aseries(x)
3159 exp(exp(x)/(1 - 1/x))
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))
3164 For rational expressions this method may return original expression without the Order term.
3165 >>> (1/x).aseries(x, n=8)
3166 1/x
3168 Returns
3169 =======
3171 Expr
3172 Asymptotic series expansion of the expression.
3174 Notes
3175 =====
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.
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.
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``.
3190 References
3191 ==========
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
3199 See Also
3200 ========
3202 Expr.aseries: See the docstring of this function for complete details of this wrapper.
3203 """
3205 from .symbol import Dummy
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)
3211 from .function import PoleError
3212 from sympy.series.gruntz import mrv, rewrite
3214 try:
3215 om, exps = mrv(self, x)
3216 except PoleError:
3217 return self
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).
3223 from sympy.functions.elementary.exponential import exp, log
3224 from sympy.series.order import Order
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
3232 k = Dummy('k', positive=True)
3233 # f is rewritten in terms of omega
3234 func, logw = rewrite(exps, om, x, k)
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
3246 func = exp(self.args[0] - res.args[0]) / k
3247 logw = log(1/res)
3249 s = func.series(k, 0, n)
3251 # Hierarchical series
3252 if hir:
3253 return s.subs(k, exp(logw))
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
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
3275 if not o or has_ord:
3276 return s.subs(k, exp(logw))
3277 return (s + o).subs(k, exp(logw))
3280 def taylor_term(self, n, x, *previous_terms):
3281 """General method for the taylor term.
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
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)
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.
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::
3301 for term in sin(x).lseries(x):
3302 print term
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.
3309 See also nseries().
3310 """
3311 return self.series(x, x0, n=None, dir=dir, logx=logx, cdir=cdir)
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)
3322 while series.is_Order:
3323 n += 1
3324 series = self._eval_nseries(x, n=n, logx=logx, cdir=cdir)
3326 e = series.removeO()
3327 yield e
3328 if e is S.Zero:
3329 return
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
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.
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.
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.
3355 Advantage -- it's fast, because we do not have to determine how many
3356 terms we need to calculate in advance.
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.
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.
3366 See also lseries().
3368 Examples
3369 ========
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)
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):
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)
3392 In the following example, the expansion works but only returns self
3393 unless the ``logx`` parameter is used:
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)
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)
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.
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 )
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)
3431 def compute_leading_term(self, x, logx=None):
3432 """Deprecated function to compute the leading term of a series.
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
3439 SymPyDeprecationWarning(
3440 feature="compute_leading_term",
3441 useinstead="as_leading_term",
3442 issue=21843,
3443 deprecated_since_version="1.12"
3444 ).warn()
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
3454 from .symbol import Dummy
3455 from sympy.functions.elementary.exponential import log
3456 from sympy.series.order import Order
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
3466 if _logx is None:
3467 res = res.subs(logx, log(x))
3469 return res.as_leading_term(x)
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.
3476 The _eval_as_leading_term routines are used to do this, and they must
3477 always return a non-zero value.
3479 Examples
3480 ========
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)
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))
3507 def _eval_as_leading_term(self, x, logx=None, cdir=0):
3508 return self
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
3522 def leadterm(self, x, logx=None, cdir=0):
3523 """
3524 Returns the leading term a*x**b as a tuple (a, b).
3526 Examples
3527 ========
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)
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
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
3554 def as_coeff_Add(self, rational=False) -> tuple['Number', Expr]:
3555 """Efficiently extract the coefficient of a summation."""
3556 return S.Zero, self
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.
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
3568 return fps(self, x, x0, dir, hyper, order, rational, full)
3570 def fourier_series(self, limits=None):
3571 """Compute fourier sine/cosine series of self.
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
3578 return fourier_series(self, limits)
3580 ###################################################################################
3581 ##################### DERIVATIVE, INTEGRAL, FUNCTIONAL METHODS ####################
3582 ###################################################################################
3584 def diff(self, *symbols, **assumptions):
3585 assumptions.setdefault("evaluate", True)
3586 return _derivative_dispatch(self, *symbols, **assumptions)
3588 ###########################################################################
3589 ###################### EXPRESSION EXPANSION METHODS #######################
3590 ###########################################################################
3592 # Relevant subclasses should override _eval_expand_hint() methods. See
3593 # the docstring of expand() for more info.
3595 def _eval_expand_complex(self, **hints):
3596 real, imag = self.as_real_imag(**hints)
3597 return real + S.ImaginaryUnit*imag
3599 @staticmethod
3600 def _expand_hint(expr, hint, deep=True, **hints):
3601 """
3602 Helper for ``expand()``. Recursively calls ``expr._eval_expand_hint()``.
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)
3619 if hit:
3620 expr = expr.func(*sargs)
3622 if hasattr(expr, hint):
3623 newexpr = getattr(expr, hint)(**hints)
3624 if newexpr != expr:
3625 return (newexpr, True)
3627 return (expr, hit)
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.
3635 See the docstring of the expand() function in sympy.core.function for
3636 more information.
3638 """
3639 from sympy.simplify.radsimp import fraction
3641 hints.update(power_base=power_base, power_exp=power_exp, mul=mul,
3642 log=log, multinomial=multinomial, basic=basic)
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
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.
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
3672 def _expand_hint_key(hint):
3673 """Make multinomial come before mul"""
3674 if hint == 'mul':
3675 return 'mulz'
3676 return hint
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)
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
3698 if modulus is not None:
3699 modulus = sympify(modulus)
3701 if not modulus.is_Integer or modulus <= 0:
3702 raise ValueError(
3703 "modulus must be a positive integer, got %s" % modulus)
3705 terms = []
3707 for term in Add.make_args(expr):
3708 coeff, tail = term.as_coeff_Mul(rational=True)
3710 coeff %= modulus
3712 if coeff:
3713 terms.append(coeff*tail)
3715 expr = Add(*terms)
3717 return expr
3719 ###########################################################################
3720 ################### GLOBAL ACTION VERB WRAPPER METHODS ####################
3721 ###########################################################################
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)
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)
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)
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)
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)
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)
3753 def ratsimp(self):
3754 """See the ratsimp function in sympy.simplify"""
3755 from sympy.simplify.ratsimp import ratsimp
3756 return ratsimp(self)
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)
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)
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)
3773 def combsimp(self):
3774 """See the combsimp function in sympy.simplify"""
3775 from sympy.simplify.combsimp import combsimp
3776 return combsimp(self)
3778 def gammasimp(self):
3779 """See the gammasimp function in sympy.simplify"""
3780 from sympy.simplify.gammasimp import gammasimp
3781 return gammasimp(self)
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)
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)
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).
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)
3807 def round(self, n=None):
3808 """Return x rounded to the given decimal place.
3810 If a complex number would results, apply round to the real
3811 and imaginary components of the number.
3813 Examples
3814 ========
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
3824 The round method has a chopping effect:
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
3833 Notes
3834 =====
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):
3839 >>> isinstance(round(S(123), -2), Number)
3840 True
3841 """
3842 x = self
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
3858 p = as_int(n or 0)
3860 if x.is_Integer:
3861 return Integer(round(int(x), p))
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)
3953 __round__ = round
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))]
3960class AtomicExpr(Atom, Expr):
3961 """
3962 A parent class for object which are both atoms and Exprs.
3964 For example: Symbol, Number, Rational, Integer, ...
3965 But not: Add, Mul, Pow, ...
3966 """
3967 is_number = False
3968 is_Atom = True
3970 __slots__ = ()
3972 def _eval_derivative(self, s):
3973 if self == s:
3974 return S.One
3975 return S.Zero
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))
3990 def _eval_is_polynomial(self, syms):
3991 return True
3993 def _eval_is_rational_function(self, syms):
3994 return self not in _illegal
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)
4000 def _eval_is_algebraic_expr(self, syms):
4001 return True
4003 def _eval_nseries(self, x, n, logx, cdir=0):
4004 return self
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}
4017def _mag(x):
4018 r"""Return integer $i$ such that $0.1 \le x/10^i < 1$
4020 Examples
4021 ========
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
4047class UnevaluatedExpr(Expr):
4048 """
4049 Expression that is not evaluated unless released.
4051 Examples
4052 ========
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
4061 """
4063 def __new__(cls, arg, **kwargs):
4064 arg = _sympify(arg)
4065 obj = Expr.__new__(cls, arg, **kwargs)
4066 return obj
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]
4076def unchanged(func, *args):
4077 """Return True if `func` applied to the `args` is unchanged.
4078 Can be used instead of `assert foo == foo`.
4080 Examples
4081 ========
4083 >>> from sympy import Piecewise, cos, pi
4084 >>> from sympy.core.expr import unchanged
4085 >>> from sympy.abc import x
4087 >>> unchanged(cos, 1) # instead of assert cos(1) == cos(1)
4088 True
4090 >>> unchanged(cos, pi)
4091 False
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:
4098 >>> unchanged(Piecewise, (x, x > 1), (0, True))
4099 True
4100 """
4101 f = func(*args)
4102 return f.func == func and f.args == args
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()
4118 @staticmethod
4119 def _build_args(args):
4120 return [i.build() if isinstance(i, ExprBuilder) else i for i in args]
4122 def validate(self):
4123 if self.validator is None:
4124 return
4125 args = self._build_args(self.args)
4126 self.validator(*args)
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)
4134 def append_argument(self, arg, check=True):
4135 self.args.append(arg)
4136 if self.validator and check:
4137 self.validate(*self.args)
4139 def __getitem__(self, item):
4140 if item == 0:
4141 return self.op
4142 else:
4143 return self.args[item-1]
4145 def __repr__(self):
4146 return str(self.build())
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
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