123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924 |
- from sympy.core import Function, S, sympify, NumberKind
- from sympy.utilities.iterables import sift
- from sympy.core.add import Add
- from sympy.core.containers import Tuple
- from sympy.core.operations import LatticeOp, ShortCircuit
- from sympy.core.function import (Application, Lambda,
- ArgumentIndexError)
- from sympy.core.expr import Expr
- from sympy.core.exprtools import factor_terms
- from sympy.core.mod import Mod
- from sympy.core.mul import Mul
- from sympy.core.numbers import Rational
- from sympy.core.power import Pow
- from sympy.core.relational import Eq, Relational
- from sympy.core.singleton import Singleton
- from sympy.core.sorting import ordered
- from sympy.core.symbol import Dummy
- from sympy.core.rules import Transform
- from sympy.core.logic import fuzzy_and, fuzzy_or, _torf
- from sympy.core.traversal import walk
- from sympy.core.numbers import Integer
- from sympy.logic.boolalg import And, Or
- def _minmax_as_Piecewise(op, *args):
- # helper for Min/Max rewrite as Piecewise
- from sympy.functions.elementary.piecewise import Piecewise
- ec = []
- for i, a in enumerate(args):
- c = []
- for j in range(i + 1, len(args)):
- c.append(Relational(a, args[j], op))
- ec.append((a, And(*c)))
- return Piecewise(*ec)
- class IdentityFunction(Lambda, metaclass=Singleton):
- """
- The identity function
- Examples
- ========
- >>> from sympy import Id, Symbol
- >>> x = Symbol('x')
- >>> Id(x)
- x
- """
- _symbol = Dummy('x')
- @property
- def signature(self):
- return Tuple(self._symbol)
- @property
- def expr(self):
- return self._symbol
- Id = S.IdentityFunction
- ###############################################################################
- ############################# ROOT and SQUARE ROOT FUNCTION ###################
- ###############################################################################
- def sqrt(arg, evaluate=None):
- """Returns the principal square root.
- Parameters
- ==========
- evaluate : bool, optional
- The parameter determines if the expression should be evaluated.
- If ``None``, its value is taken from
- ``global_parameters.evaluate``.
- Examples
- ========
- >>> from sympy import sqrt, Symbol, S
- >>> x = Symbol('x')
- >>> sqrt(x)
- sqrt(x)
- >>> sqrt(x)**2
- x
- Note that sqrt(x**2) does not simplify to x.
- >>> sqrt(x**2)
- sqrt(x**2)
- This is because the two are not equal to each other in general.
- For example, consider x == -1:
- >>> from sympy import Eq
- >>> Eq(sqrt(x**2), x).subs(x, -1)
- False
- This is because sqrt computes the principal square root, so the square may
- put the argument in a different branch. This identity does hold if x is
- positive:
- >>> y = Symbol('y', positive=True)
- >>> sqrt(y**2)
- y
- You can force this simplification by using the powdenest() function with
- the force option set to True:
- >>> from sympy import powdenest
- >>> sqrt(x**2)
- sqrt(x**2)
- >>> powdenest(sqrt(x**2), force=True)
- x
- To get both branches of the square root you can use the rootof function:
- >>> from sympy import rootof
- >>> [rootof(x**2-3,i) for i in (0,1)]
- [-sqrt(3), sqrt(3)]
- Although ``sqrt`` is printed, there is no ``sqrt`` function so looking for
- ``sqrt`` in an expression will fail:
- >>> from sympy.utilities.misc import func_name
- >>> func_name(sqrt(x))
- 'Pow'
- >>> sqrt(x).has(sqrt)
- False
- To find ``sqrt`` look for ``Pow`` with an exponent of ``1/2``:
- >>> (x + 1/sqrt(x)).find(lambda i: i.is_Pow and abs(i.exp) is S.Half)
- {1/sqrt(x)}
- See Also
- ========
- sympy.polys.rootoftools.rootof, root, real_root
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Square_root
- .. [2] https://en.wikipedia.org/wiki/Principal_value
- """
- # arg = sympify(arg) is handled by Pow
- return Pow(arg, S.Half, evaluate=evaluate)
- def cbrt(arg, evaluate=None):
- """Returns the principal cube root.
- Parameters
- ==========
- evaluate : bool, optional
- The parameter determines if the expression should be evaluated.
- If ``None``, its value is taken from
- ``global_parameters.evaluate``.
- Examples
- ========
- >>> from sympy import cbrt, Symbol
- >>> x = Symbol('x')
- >>> cbrt(x)
- x**(1/3)
- >>> cbrt(x)**3
- x
- Note that cbrt(x**3) does not simplify to x.
- >>> cbrt(x**3)
- (x**3)**(1/3)
- This is because the two are not equal to each other in general.
- For example, consider `x == -1`:
- >>> from sympy import Eq
- >>> Eq(cbrt(x**3), x).subs(x, -1)
- False
- This is because cbrt computes the principal cube root, this
- identity does hold if `x` is positive:
- >>> y = Symbol('y', positive=True)
- >>> cbrt(y**3)
- y
- See Also
- ========
- sympy.polys.rootoftools.rootof, root, real_root
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Cube_root
- .. [2] https://en.wikipedia.org/wiki/Principal_value
- """
- return Pow(arg, Rational(1, 3), evaluate=evaluate)
- def root(arg, n, k=0, evaluate=None):
- r"""Returns the *k*-th *n*-th root of ``arg``.
- Parameters
- ==========
- k : int, optional
- Should be an integer in $\{0, 1, ..., n-1\}$.
- Defaults to the principal root if $0$.
- evaluate : bool, optional
- The parameter determines if the expression should be evaluated.
- If ``None``, its value is taken from
- ``global_parameters.evaluate``.
- Examples
- ========
- >>> from sympy import root, Rational
- >>> from sympy.abc import x, n
- >>> root(x, 2)
- sqrt(x)
- >>> root(x, 3)
- x**(1/3)
- >>> root(x, n)
- x**(1/n)
- >>> root(x, -Rational(2, 3))
- x**(-3/2)
- To get the k-th n-th root, specify k:
- >>> root(-2, 3, 2)
- -(-1)**(2/3)*2**(1/3)
- To get all n n-th roots you can use the rootof function.
- The following examples show the roots of unity for n
- equal 2, 3 and 4:
- >>> from sympy import rootof
- >>> [rootof(x**2 - 1, i) for i in range(2)]
- [-1, 1]
- >>> [rootof(x**3 - 1,i) for i in range(3)]
- [1, -1/2 - sqrt(3)*I/2, -1/2 + sqrt(3)*I/2]
- >>> [rootof(x**4 - 1,i) for i in range(4)]
- [-1, 1, -I, I]
- SymPy, like other symbolic algebra systems, returns the
- complex root of negative numbers. This is the principal
- root and differs from the text-book result that one might
- be expecting. For example, the cube root of -8 does not
- come back as -2:
- >>> root(-8, 3)
- 2*(-1)**(1/3)
- The real_root function can be used to either make the principal
- result real (or simply to return the real root directly):
- >>> from sympy import real_root
- >>> real_root(_)
- -2
- >>> real_root(-32, 5)
- -2
- Alternatively, the n//2-th n-th root of a negative number can be
- computed with root:
- >>> root(-32, 5, 5//2)
- -2
- See Also
- ========
- sympy.polys.rootoftools.rootof
- sympy.core.power.integer_nthroot
- sqrt, real_root
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Square_root
- .. [2] https://en.wikipedia.org/wiki/Real_root
- .. [3] https://en.wikipedia.org/wiki/Root_of_unity
- .. [4] https://en.wikipedia.org/wiki/Principal_value
- .. [5] http://mathworld.wolfram.com/CubeRoot.html
- """
- n = sympify(n)
- if k:
- return Mul(Pow(arg, S.One/n, evaluate=evaluate), S.NegativeOne**(2*k/n), evaluate=evaluate)
- return Pow(arg, 1/n, evaluate=evaluate)
- def real_root(arg, n=None, evaluate=None):
- r"""Return the real *n*'th-root of *arg* if possible.
- Parameters
- ==========
- n : int or None, optional
- If *n* is ``None``, then all instances of
- $(-n)^{1/\text{odd}}$ will be changed to $-n^{1/\text{odd}}$.
- This will only create a real root of a principal root.
- The presence of other factors may cause the result to not be
- real.
- evaluate : bool, optional
- The parameter determines if the expression should be evaluated.
- If ``None``, its value is taken from
- ``global_parameters.evaluate``.
- Examples
- ========
- >>> from sympy import root, real_root
- >>> real_root(-8, 3)
- -2
- >>> root(-8, 3)
- 2*(-1)**(1/3)
- >>> real_root(_)
- -2
- If one creates a non-principal root and applies real_root, the
- result will not be real (so use with caution):
- >>> root(-8, 3, 2)
- -2*(-1)**(2/3)
- >>> real_root(_)
- -2*(-1)**(2/3)
- See Also
- ========
- sympy.polys.rootoftools.rootof
- sympy.core.power.integer_nthroot
- root, sqrt
- """
- from sympy.functions.elementary.complexes import Abs, im, sign
- from sympy.functions.elementary.piecewise import Piecewise
- if n is not None:
- return Piecewise(
- (root(arg, n, evaluate=evaluate), Or(Eq(n, S.One), Eq(n, S.NegativeOne))),
- (Mul(sign(arg), root(Abs(arg), n, evaluate=evaluate), evaluate=evaluate),
- And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One))),
- (root(arg, n, evaluate=evaluate), True))
- rv = sympify(arg)
- n1pow = Transform(lambda x: -(-x.base)**x.exp,
- lambda x:
- x.is_Pow and
- x.base.is_negative and
- x.exp.is_Rational and
- x.exp.p == 1 and x.exp.q % 2)
- return rv.xreplace(n1pow)
- ###############################################################################
- ############################# MINIMUM and MAXIMUM #############################
- ###############################################################################
- class MinMaxBase(Expr, LatticeOp):
- def __new__(cls, *args, **assumptions):
- evaluate = assumptions.pop('evaluate', True)
- args = (sympify(arg) for arg in args)
- # first standard filter, for cls.zero and cls.identity
- # also reshape Max(a, Max(b, c)) to Max(a, b, c)
- if evaluate:
- try:
- args = frozenset(cls._new_args_filter(args))
- except ShortCircuit:
- return cls.zero
- else:
- args = frozenset(args)
- if evaluate:
- # remove redundant args that are easily identified
- args = cls._collapse_arguments(args, **assumptions)
- # find local zeros
- args = cls._find_localzeros(args, **assumptions)
- if not args:
- return cls.identity
- if len(args) == 1:
- return list(args).pop()
- # base creation
- _args = frozenset(args)
- obj = Expr.__new__(cls, *ordered(_args), **assumptions)
- obj._argset = _args
- return obj
- @classmethod
- def _collapse_arguments(cls, args, **assumptions):
- """Remove redundant args.
- Examples
- ========
- >>> from sympy import Min, Max
- >>> from sympy.abc import a, b, c, d, e
- Any arg in parent that appears in any
- parent-like function in any of the flat args
- of parent can be removed from that sub-arg:
- >>> Min(a, Max(b, Min(a, c, d)))
- Min(a, Max(b, Min(c, d)))
- If the arg of parent appears in an opposite-than parent
- function in any of the flat args of parent that function
- can be replaced with the arg:
- >>> Min(a, Max(b, Min(c, d, Max(a, e))))
- Min(a, Max(b, Min(a, c, d)))
- """
- if not args:
- return args
- args = list(ordered(args))
- if cls == Min:
- other = Max
- else:
- other = Min
- # find global comparable max of Max and min of Min if a new
- # value is being introduced in these args at position 0 of
- # the ordered args
- if args[0].is_number:
- sifted = mins, maxs = [], []
- for i in args:
- for v in walk(i, Min, Max):
- if v.args[0].is_comparable:
- sifted[isinstance(v, Max)].append(v)
- small = Min.identity
- for i in mins:
- v = i.args[0]
- if v.is_number and (v < small) == True:
- small = v
- big = Max.identity
- for i in maxs:
- v = i.args[0]
- if v.is_number and (v > big) == True:
- big = v
- # at the point when this function is called from __new__,
- # there may be more than one numeric arg present since
- # local zeros have not been handled yet, so look through
- # more than the first arg
- if cls == Min:
- for i in range(len(args)):
- if not args[i].is_number:
- break
- if (args[i] < small) == True:
- small = args[i]
- elif cls == Max:
- for i in range(len(args)):
- if not args[i].is_number:
- break
- if (args[i] > big) == True:
- big = args[i]
- T = None
- if cls == Min:
- if small != Min.identity:
- other = Max
- T = small
- elif big != Max.identity:
- other = Min
- T = big
- if T is not None:
- # remove numerical redundancy
- for i in range(len(args)):
- a = args[i]
- if isinstance(a, other):
- a0 = a.args[0]
- if ((a0 > T) if other == Max else (a0 < T)) == True:
- args[i] = cls.identity
- # remove redundant symbolic args
- def do(ai, a):
- if not isinstance(ai, (Min, Max)):
- return ai
- cond = a in ai.args
- if not cond:
- return ai.func(*[do(i, a) for i in ai.args],
- evaluate=False)
- if isinstance(ai, cls):
- return ai.func(*[do(i, a) for i in ai.args if i != a],
- evaluate=False)
- return a
- for i, a in enumerate(args):
- args[i + 1:] = [do(ai, a) for ai in args[i + 1:]]
- # factor out common elements as for
- # Min(Max(x, y), Max(x, z)) -> Max(x, Min(y, z))
- # and vice versa when swapping Min/Max -- do this only for the
- # easy case where all functions contain something in common;
- # trying to find some optimal subset of args to modify takes
- # too long
- def factor_minmax(args):
- is_other = lambda arg: isinstance(arg, other)
- other_args, remaining_args = sift(args, is_other, binary=True)
- if not other_args:
- return args
- # Min(Max(x, y, z), Max(x, y, u, v)) -> {x,y}, ({z}, {u,v})
- arg_sets = [set(arg.args) for arg in other_args]
- common = set.intersection(*arg_sets)
- if not common:
- return args
- new_other_args = list(common)
- arg_sets_diff = [arg_set - common for arg_set in arg_sets]
- # If any set is empty after removing common then all can be
- # discarded e.g. Min(Max(a, b, c), Max(a, b)) -> Max(a, b)
- if all(arg_sets_diff):
- other_args_diff = [other(*s, evaluate=False) for s in arg_sets_diff]
- new_other_args.append(cls(*other_args_diff, evaluate=False))
- other_args_factored = other(*new_other_args, evaluate=False)
- return remaining_args + [other_args_factored]
- if len(args) > 1:
- args = factor_minmax(args)
- return args
- @classmethod
- def _new_args_filter(cls, arg_sequence):
- """
- Generator filtering args.
- first standard filter, for cls.zero and cls.identity.
- Also reshape ``Max(a, Max(b, c))`` to ``Max(a, b, c)``,
- and check arguments for comparability
- """
- for arg in arg_sequence:
- # pre-filter, checking comparability of arguments
- if not isinstance(arg, Expr) or arg.is_extended_real is False or (
- arg.is_number and
- not arg.is_comparable):
- raise ValueError("The argument '%s' is not comparable." % arg)
- if arg == cls.zero:
- raise ShortCircuit(arg)
- elif arg == cls.identity:
- continue
- elif arg.func == cls:
- yield from arg.args
- else:
- yield arg
- @classmethod
- def _find_localzeros(cls, values, **options):
- """
- Sequentially allocate values to localzeros.
- When a value is identified as being more extreme than another member it
- replaces that member; if this is never true, then the value is simply
- appended to the localzeros.
- """
- localzeros = set()
- for v in values:
- is_newzero = True
- localzeros_ = list(localzeros)
- for z in localzeros_:
- if id(v) == id(z):
- is_newzero = False
- else:
- con = cls._is_connected(v, z)
- if con:
- is_newzero = False
- if con is True or con == cls:
- localzeros.remove(z)
- localzeros.update([v])
- if is_newzero:
- localzeros.update([v])
- return localzeros
- @classmethod
- def _is_connected(cls, x, y):
- """
- Check if x and y are connected somehow.
- """
- for i in range(2):
- if x == y:
- return True
- t, f = Max, Min
- for op in "><":
- for j in range(2):
- try:
- if op == ">":
- v = x >= y
- else:
- v = x <= y
- except TypeError:
- return False # non-real arg
- if not v.is_Relational:
- return t if v else f
- t, f = f, t
- x, y = y, x
- x, y = y, x # run next pass with reversed order relative to start
- # simplification can be expensive, so be conservative
- # in what is attempted
- x = factor_terms(x - y)
- y = S.Zero
- return False
- def _eval_derivative(self, s):
- # f(x).diff(s) -> x.diff(s) * f.fdiff(1)(s)
- i = 0
- l = []
- for a in self.args:
- i += 1
- da = a.diff(s)
- if da.is_zero:
- continue
- try:
- df = self.fdiff(i)
- except ArgumentIndexError:
- df = Function.fdiff(self, i)
- l.append(df * da)
- return Add(*l)
- def _eval_rewrite_as_Abs(self, *args, **kwargs):
- from sympy.functions.elementary.complexes import Abs
- s = (args[0] + self.func(*args[1:]))/2
- d = abs(args[0] - self.func(*args[1:]))/2
- return (s + d if isinstance(self, Max) else s - d).rewrite(Abs)
- def evalf(self, n=15, **options):
- return self.func(*[a.evalf(n, **options) for a in self.args])
- def n(self, *args, **kwargs):
- return self.evalf(*args, **kwargs)
- _eval_is_algebraic = lambda s: _torf(i.is_algebraic for i in s.args)
- _eval_is_antihermitian = lambda s: _torf(i.is_antihermitian for i in s.args)
- _eval_is_commutative = lambda s: _torf(i.is_commutative for i in s.args)
- _eval_is_complex = lambda s: _torf(i.is_complex for i in s.args)
- _eval_is_composite = lambda s: _torf(i.is_composite for i in s.args)
- _eval_is_even = lambda s: _torf(i.is_even for i in s.args)
- _eval_is_finite = lambda s: _torf(i.is_finite for i in s.args)
- _eval_is_hermitian = lambda s: _torf(i.is_hermitian for i in s.args)
- _eval_is_imaginary = lambda s: _torf(i.is_imaginary for i in s.args)
- _eval_is_infinite = lambda s: _torf(i.is_infinite for i in s.args)
- _eval_is_integer = lambda s: _torf(i.is_integer for i in s.args)
- _eval_is_irrational = lambda s: _torf(i.is_irrational for i in s.args)
- _eval_is_negative = lambda s: _torf(i.is_negative for i in s.args)
- _eval_is_noninteger = lambda s: _torf(i.is_noninteger for i in s.args)
- _eval_is_nonnegative = lambda s: _torf(i.is_nonnegative for i in s.args)
- _eval_is_nonpositive = lambda s: _torf(i.is_nonpositive for i in s.args)
- _eval_is_nonzero = lambda s: _torf(i.is_nonzero for i in s.args)
- _eval_is_odd = lambda s: _torf(i.is_odd for i in s.args)
- _eval_is_polar = lambda s: _torf(i.is_polar for i in s.args)
- _eval_is_positive = lambda s: _torf(i.is_positive for i in s.args)
- _eval_is_prime = lambda s: _torf(i.is_prime for i in s.args)
- _eval_is_rational = lambda s: _torf(i.is_rational for i in s.args)
- _eval_is_real = lambda s: _torf(i.is_real for i in s.args)
- _eval_is_extended_real = lambda s: _torf(i.is_extended_real for i in s.args)
- _eval_is_transcendental = lambda s: _torf(i.is_transcendental for i in s.args)
- _eval_is_zero = lambda s: _torf(i.is_zero for i in s.args)
- class Max(MinMaxBase, Application):
- r"""
- Return, if possible, the maximum value of the list.
- When number of arguments is equal one, then
- return this argument.
- When number of arguments is equal two, then
- return, if possible, the value from (a, b) that is $\ge$ the other.
- In common case, when the length of list greater than 2, the task
- is more complicated. Return only the arguments, which are greater
- than others, if it is possible to determine directional relation.
- If is not possible to determine such a relation, return a partially
- evaluated result.
- Assumptions are used to make the decision too.
- Also, only comparable arguments are permitted.
- It is named ``Max`` and not ``max`` to avoid conflicts
- with the built-in function ``max``.
- Examples
- ========
- >>> from sympy import Max, Symbol, oo
- >>> from sympy.abc import x, y, z
- >>> p = Symbol('p', positive=True)
- >>> n = Symbol('n', negative=True)
- >>> Max(x, -2)
- Max(-2, x)
- >>> Max(x, -2).subs(x, 3)
- 3
- >>> Max(p, -2)
- p
- >>> Max(x, y)
- Max(x, y)
- >>> Max(x, y) == Max(y, x)
- True
- >>> Max(x, Max(y, z))
- Max(x, y, z)
- >>> Max(n, 8, p, 7, -oo)
- Max(8, p)
- >>> Max (1, x, oo)
- oo
- * Algorithm
- The task can be considered as searching of supremums in the
- directed complete partial orders [1]_.
- The source values are sequentially allocated by the isolated subsets
- in which supremums are searched and result as Max arguments.
- If the resulted supremum is single, then it is returned.
- The isolated subsets are the sets of values which are only the comparable
- with each other in the current set. E.g. natural numbers are comparable with
- each other, but not comparable with the `x` symbol. Another example: the
- symbol `x` with negative assumption is comparable with a natural number.
- Also there are "least" elements, which are comparable with all others,
- and have a zero property (maximum or minimum for all elements).
- For example, in case of $\infty$, the allocation operation is terminated
- and only this value is returned.
- Assumption:
- - if $A > B > C$ then $A > C$
- - if $A = B$ then $B$ can be removed
- References
- ==========
- .. [1] https://en.wikipedia.org/wiki/Directed_complete_partial_order
- .. [2] https://en.wikipedia.org/wiki/Lattice_%28order%29
- See Also
- ========
- Min : find minimum values
- """
- zero = S.Infinity
- identity = S.NegativeInfinity
- def fdiff( self, argindex ):
- from sympy.functions.special.delta_functions import Heaviside
- n = len(self.args)
- if 0 < argindex and argindex <= n:
- argindex -= 1
- if n == 2:
- return Heaviside(self.args[argindex] - self.args[1 - argindex])
- newargs = tuple([self.args[i] for i in range(n) if i != argindex])
- return Heaviside(self.args[argindex] - Max(*newargs))
- else:
- raise ArgumentIndexError(self, argindex)
- def _eval_rewrite_as_Heaviside(self, *args, **kwargs):
- from sympy.functions.special.delta_functions import Heaviside
- return Add(*[j*Mul(*[Heaviside(j - i) for i in args if i!=j]) \
- for j in args])
- def _eval_rewrite_as_Piecewise(self, *args, **kwargs):
- return _minmax_as_Piecewise('>=', *args)
- def _eval_is_positive(self):
- return fuzzy_or(a.is_positive for a in self.args)
- def _eval_is_nonnegative(self):
- return fuzzy_or(a.is_nonnegative for a in self.args)
- def _eval_is_negative(self):
- return fuzzy_and(a.is_negative for a in self.args)
- class Min(MinMaxBase, Application):
- """
- Return, if possible, the minimum value of the list.
- It is named ``Min`` and not ``min`` to avoid conflicts
- with the built-in function ``min``.
- Examples
- ========
- >>> from sympy import Min, Symbol, oo
- >>> from sympy.abc import x, y
- >>> p = Symbol('p', positive=True)
- >>> n = Symbol('n', negative=True)
- >>> Min(x, -2)
- Min(-2, x)
- >>> Min(x, -2).subs(x, 3)
- -2
- >>> Min(p, -3)
- -3
- >>> Min(x, y)
- Min(x, y)
- >>> Min(n, 8, p, -7, p, oo)
- Min(-7, n)
- See Also
- ========
- Max : find maximum values
- """
- zero = S.NegativeInfinity
- identity = S.Infinity
- def fdiff( self, argindex ):
- from sympy.functions.special.delta_functions import Heaviside
- n = len(self.args)
- if 0 < argindex and argindex <= n:
- argindex -= 1
- if n == 2:
- return Heaviside( self.args[1-argindex] - self.args[argindex] )
- newargs = tuple([ self.args[i] for i in range(n) if i != argindex])
- return Heaviside( Min(*newargs) - self.args[argindex] )
- else:
- raise ArgumentIndexError(self, argindex)
- def _eval_rewrite_as_Heaviside(self, *args, **kwargs):
- from sympy.functions.special.delta_functions import Heaviside
- return Add(*[j*Mul(*[Heaviside(i-j) for i in args if i!=j]) \
- for j in args])
- def _eval_rewrite_as_Piecewise(self, *args, **kwargs):
- return _minmax_as_Piecewise('<=', *args)
- def _eval_is_positive(self):
- return fuzzy_and(a.is_positive for a in self.args)
- def _eval_is_nonnegative(self):
- return fuzzy_and(a.is_nonnegative for a in self.args)
- def _eval_is_negative(self):
- return fuzzy_or(a.is_negative for a in self.args)
- class Rem(Function):
- """Returns the remainder when ``p`` is divided by ``q`` where ``p`` is finite
- and ``q`` is not equal to zero. The result, ``p - int(p/q)*q``, has the same sign
- as the divisor.
- Parameters
- ==========
- p : Expr
- Dividend.
- q : Expr
- Divisor.
- Notes
- =====
- ``Rem`` corresponds to the ``%`` operator in C.
- Examples
- ========
- >>> from sympy.abc import x, y
- >>> from sympy import Rem
- >>> Rem(x**3, y)
- Rem(x**3, y)
- >>> Rem(x**3, y).subs({x: -5, y: 3})
- -2
- See Also
- ========
- Mod
- """
- kind = NumberKind
- @classmethod
- def eval(cls, p, q):
- def doit(p, q):
- """ the function remainder if both p,q are numbers
- and q is not zero
- """
- if q.is_zero:
- raise ZeroDivisionError("Division by zero")
- if p is S.NaN or q is S.NaN or p.is_finite is False or q.is_finite is False:
- return S.NaN
- if p is S.Zero or p in (q, -q) or (p.is_integer and q == 1):
- return S.Zero
- if q.is_Number:
- if p.is_Number:
- return p - Integer(p/q)*q
- rv = doit(p, q)
- if rv is not None:
- return rv
|