Esempio n. 1
0
    def __new__(cls, expr, variables, point, **assumptions):
        if not ordered_iter(variables, Tuple):
            variables = [variables]
        variables = Tuple(*sympify(variables))

        if uniq(variables) != variables:
            repeated = repeated = [ v for v in set(variables)
                                    if list(variables).count(v) > 1 ]
            raise ValueError('cannot substitute expressions %s more than '
                             'once.' % repeated)

        if not ordered_iter(point, Tuple):
            point = [point]
        point = Tuple(*sympify(point))

        if len(point) != len(variables):
            raise ValueError('Number of point values must be the same as '
                             'the number of variables.')

        # it's necessary to use dummy variables internally
        new_variables = Tuple(*[ arg.as_dummy() if arg.is_Symbol else
            C.Dummy(str(arg)) for arg in variables ])
        expr = sympify(expr).subs(tuple(zip(variables, new_variables)))

        if expr.is_commutative:
            assumptions['commutative'] = True

        obj = Expr.__new__(cls, expr, new_variables, point, **assumptions)
        return obj
Esempio n. 2
0
    def _symbolgen(*symbols):
        """
        Generator of all symbols in the argument of the Derivative.

        Example:
        >> ._symbolgen(x, 3, y)
        (x, x, x, y)
        >> ._symbolgen(x, 10**6)
        (x, x, x, x, x, x, x, ...)

        The second example shows why we don't return a list, but a generator,
        so that the code that calls _symbolgen can return earlier for special
        cases, like x.diff(x, 10**6).
        """
        last_s = sympify(symbols[len(symbols)-1])
        for i in xrange(len(symbols)):
            s = sympify(symbols[i])
            next_s = None
            if s != last_s:
                next_s = sympify(symbols[i+1])

            if isinstance(s, Integer):
                continue
            elif isinstance(s, Symbol):
                # handle cases like (x, 3)
                if isinstance(next_s, Integer):
                    # yield (x, x, x)
                    for copy_s in repeat(s,int(next_s)):
                        yield copy_s
                else:
                    yield s
            else:
                yield s
Esempio n. 3
0
    def series(self, x, point=0, n=6, dir="+"):
        """
        Series expansion of "self" around "point".

        Usage:
            Returns the Taylor (Laurent or generalized) series of "self" around
            the point "point" (default 0) with respect to "x" until the n-th
            term (default n is 6).

            For dir="+" (default) it calculates the series from the right
            and for dir="-" the series from the left.
            For smooth functions this argument doesn't matter.

        Notes:
            This method is the most high level method and it returns the
            series including the O(x**n) term.

            Internally, it executes a method nseries(), see nseries() docstring
            for more information.
        """
        x = sympify(x)
        point = sympify(point)
        if dir == "+":
            return self.nseries(x, point, n)
        elif dir == "-":
            return self.subs(x, -x).nseries(x, -point, n).subs(x, -x)
        else:
            raise ValueError("Dir has to be '+' or '-'")
Esempio n. 4
0
    def __new__(cls, expr, *symbols, **assumptions):
        expr = sympify(expr)
        if not symbols:
            return expr
        symbols = Derivative._symbolgen(*symbols)
        if expr.is_commutative:
            assumptions['commutative'] = True
        evaluate = assumptions.pop('evaluate', False)
        if not evaluate and not isinstance(expr, Derivative):
            symbols = list(symbols)
            if len(symbols) == 0:
                # We make a special case for 0th derivative, because there
                # is no good way to unambiguously print this.
                return expr
            obj = Expr.__new__(cls, expr, *symbols, **assumptions)
            return obj
        unevaluated_symbols = []
        for s in symbols:
            s = sympify(s)
            if not isinstance(s, C.Symbol):
                raise ValueError('Invalid literal: %s is not a valid variable' % s)
            obj = expr._eval_derivative(s)
            if obj is None:
                unevaluated_symbols.append(s)
            elif obj is S.Zero:
                return S.Zero
            else:
                expr = obj

        if not unevaluated_symbols:
            return expr
        return Expr.__new__(cls, expr, *unevaluated_symbols, **assumptions)
Esempio n. 5
0
    def as_leading_term(self, *symbols):
        """
        Returns the leading term.

        Example:

        >>> from sympy.abc import x
        >>> (1+x+x**2).as_leading_term(x)
        1
        >>> (1/x**2+x+x**2).as_leading_term(x)
        x**(-2)

        Note:

        self is assumed to be the result returned by Basic.series().
        """
        from sympy import powsimp
        if len(symbols)>1:
            c = self
            for x in symbols:
                c = c.as_leading_term(x)
            return c
        elif not symbols:
            return self
        x = sympify(symbols[0])
        assert x.is_Symbol, `x`
        if not self.has(x):
            return self
        obj = self._eval_as_leading_term(x)
        if obj is not None:
            return powsimp(obj, deep=True, combine='exp')
        raise NotImplementedError('as_leading_term(%s, %s)' % (self, x))
Esempio n. 6
0
    def has(self, *patterns):
        """
        Return True if self has any of the patterns.

        Example:
        >>> from sympy.abc import x
        >>> (2*x).has(x)
        True
        >>> (2*x/x).has(x)
        False

        """
        from sympy.utilities.iterables import flatten
        from sympy.core.symbol import Wild
        if len(patterns)>1:
            for p in patterns:
                if self.has(p):
                    return True
            return False
        elif not patterns:
            raise TypeError("has() requires at least 1 argument (got none)")
        p = sympify(patterns[0])
        if isinstance(p, BasicType):
            return bool(self.atoms(p))
        if p.is_Atom and not isinstance(p, Wild):
            return p in self.atoms(p.func)
        if p.matches(self) is not None:
            return True
        for e in flatten(self.args):
            if isinstance(e, Basic) and e.has(p):
                return True
        return False
Esempio n. 7
0
 def _has(p):
     p = sympify(p)
     if isinstance(p, BasicType):
         return search(self, lambda w: isinstance(w, p), lambda w: True)
     if p.is_Atom and not isinstance(p, Wild):
         return search(self, lambda w: isinstance(w, p.func), lambda w: w in [p])
     return search(self, lambda w: p.matches(w) is not None, lambda w: True)
Esempio n. 8
0
    def find(self, query, group=False):
        """Find all subexpressions matching a query. """
        if not callable(query):
            query = sympify(query)
        if isinstance(query, type):
            _query = lambda expr: isinstance(expr, query)
        elif isinstance(query, Basic):
            _query = lambda expr: expr.match(query)
        else:
            _query = query

        results = []

        def rec_find(expr):
            q = _query(expr)
            if q or q == {}:
                results.append(expr)

            for arg in expr.args:
                rec_find(arg)

        rec_find(self)

        if not group:
            return set(results)
        else:
            groups = {}

            for result in results:
                if result in groups:
                    groups[result] += 1
                else:
                    groups[result] = 1

            return groups
Esempio n. 9
0
File: basic.py Progetto: wxgeo/sympy
    def matches(self, expr, repl_dict={}, evaluate=False):
        """
        Helper method for match() - switches the pattern and expr.

        Can be used to solve linear equations:
          >>> from sympy import Symbol, Wild, Integer
          >>> a,b = map(Symbol, 'ab')
          >>> x = Wild('x')
          >>> (a+b*x).matches(Integer(0))
          {x_: -a/b}

        """
        if evaluate:
            return self.subs(repl_dict).matches(expr, repl_dict)

        expr = sympify(expr)
        if not isinstance(expr, self.__class__):
            return None

        if self == expr:
            return repl_dict

        if len(self.args) != len(expr.args):
            return None

        d = repl_dict.copy()
        for arg, other_arg in zip(self.args, expr.args):
            if arg == other_arg:
                continue
            d = arg.subs(d).matches(other_arg, d)
            if d is None:
                return None
        return d
Esempio n. 10
0
File: basic.py Progetto: wxgeo/sympy
    def match(self, pattern):
        """
        Pattern matching.

        Wild symbols match all.

        Return None when expression (self) does not match
        with pattern. Otherwise return a dictionary such that

          pattern.subs(self.match(pattern)) == self

        Example:

        >>> from sympy import symbols, Wild
        >>> from sympy.abc import x, y
        >>> p = Wild("p")
        >>> q = Wild("q")
        >>> r = Wild("r")
        >>> e = (x+y)**(x+y)
        >>> e.match(p**p)
        {p_: x + y}
        >>> e.match(p**q)
        {p_: x + y, q_: x + y}
        >>> e = (2*x)**2
        >>> e.match(p*q**r)
        {p_: 4, q_: x, r_: 2}
        >>> (p*q**r).subs(e.match(p*q**r))
        4*x**2

        """
        pattern = sympify(pattern)
        return pattern.matches(self)
Esempio n. 11
0
 def __new__(cls, name, exclude=(), properties=(), **assumptions):
     exclude = tuple([sympify(x) for x in exclude])
     properties = tuple(properties)
     is_commutative = fuzzy_bool(assumptions.get("commutative", True))
     if is_commutative is None:
         raise ValueError("""Wild's commutativity must be True or False.""")
     assumptions["commutative"] = is_commutative
     return Wild.__xnew__(cls, name, exclude, properties, **assumptions)
Esempio n. 12
0
    def taylor_term(cls, n, x, *previous_terms):
        """General method for the taylor term.

        This method is slow, because it differentiates n-times.  Subclasses can
        redefine it to make it faster by using the "previous_terms".
        """
        x = sympify(x)
        return cls(x).diff(x, n).subs(x, 0) * x**n / C.Factorial(n)
Esempio n. 13
0
 def __sympifyit_wrapper(a, b):
     try:
         # If an external class has _op_priority, it knows how to deal
         # with sympy objects. Otherwise, it must be converted.
         if not hasattr(b, '_op_priority'):
             b = sympify(b, strict=True)
         return func(a, b)
     except SympifyError:
         return retval
Esempio n. 14
0
    def _matches(self, expr, repl_dict={}):
        # weed out negative one prefixes
        sign = 1
        a, b = self.as_two_terms()
        if a is S.NegativeOne:
            if b.is_Mul:
                sign = -sign
            else:
                # the remainder, b, is not a Mul anymore
                return b.matches(-expr, repl_dict)
        expr = sympify(expr)
        if expr.is_Mul and expr.args[0] is S.NegativeOne:
            expr = -expr
            sign = -sign

        if not expr.is_Mul:
            # expr can only match if it matches b and a matches +/- 1
            if len(self.args) == 2:
                # quickly test for equality
                if b == expr:
                    return a.matches(Rational(sign), repl_dict)
                # do more expensive match
                dd = b.matches(expr, repl_dict)
                if dd == None:
                    return None
                dd = a.matches(Rational(sign), dd)
                return dd
            return None

        d = repl_dict.copy()

        # weed out identical terms
        pp = list(self.args)
        ee = list(expr.args)
        for p in self.args:
            if p in expr.args:
                ee.remove(p)
                pp.remove(p)

        # only one symbol left in pattern -> match the remaining expression
        if len(pp) == 1 and isinstance(pp[0], C.Wild):
            if len(ee) == 1:
                d[pp[0]] = sign * ee[0]
            else:
                d[pp[0]] = sign * expr.func(*ee)
            return d

        if len(ee) != len(pp):
            return None

        for p, e in zip(pp, ee):
            d = p.xreplace(d).matches(e, d)
            if d is None:
                return None
        return d
Esempio n. 15
0
    def __xnew__(cls, name, exclude, properties, **assumptions):
        obj = Symbol.__xnew__(cls, name, **assumptions)

        if exclude is None:
            obj.exclude = None
        else:
            obj.exclude = tuple([sympify(x) for x in exclude])
        if properties is None:
            obj.properties = None
        else:
            obj.properties = tuple(properties)
        return obj
Esempio n. 16
0
def as_mpmath(x, prec, options):
    x = sympify(x)
    if isinstance(x, C.Zero):
        return mpf(0)
    if isinstance(x, C.Infinity):
        return mpf("inf")
    if isinstance(x, C.NegativeInfinity):
        return mpf("-inf")
    # XXX
    re, im, _, _ = evalf(x, prec, options)
    if im:
        return mpc(re or fzero, im)
    return mpf(re)
Esempio n. 17
0
        def _match(pattern):
            pattern = sympify(pattern)

            if isinstance(pattern, BasicType):
                return lambda expr: (isinstance(expr, pattern) or
                    (isinstance(expr, BasicType) and expr == pattern))
            else:
                if pattern.is_Add or pattern.is_Mul:
                    iterative, (c, nc) = True, _ncsplit(pattern)
                else:
                    iterative, (c, nc) = False, (None, None)

                return lambda expr: _contains(expr, pattern, iterative, c, nc)
Esempio n. 18
0
def expand_trig(expr, deep=True):
    """
    Wrapper around expand that only uses the trig hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import *
    >>> x, y = symbols('xy')
    >>> expand_trig(sin(x+y)*(x+y))
    (x + y)*(cos(x)*sin(y) + cos(y)*sin(x))
    """
    return sympify(expr).expand(deep=deep, trig=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 19
0
def expand_func(expr, deep=True):
    """
    Wrapper around expand that only uses the func hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import *
    >>> x = Symbol('x')
    >>> expand_func(gamma(x + 2))
    x*(1 + x)*gamma(x)
    """
    return sympify(expr).expand(deep=deep, func=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 20
0
def expand_log(expr, deep=True):
    """
    Wrapper around expand that only uses the log hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import *
    >>> x, y = symbols('xy', positive=True)
    >>> expand_log(exp(x+y)*(x+y)*log(x*y**2))
    (x + y)*(2*log(y) + log(x))*exp(x + y)
    """
    return sympify(expr).expand(deep=deep, log=True, mul=False,\
    power_exp=False, power_base=False, multinomial=False, basic=False)
Esempio n. 21
0
def expand_complex(expr, deep=True):
    """
    Wrapper around expand that only uses the complex hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import *
    >>> z = Symbol('z')
    >>> expand_complex(z**(2*I))
    I*im(z**(2*I)) + re(z**(2*I))
    """
    return sympify(expr).expand(deep=deep, complex=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 22
0
 def as_coeff_exponent(self, x):
     """ c*x**e -> c,e where x can be any symbolic expression.
     """
     x = sympify(x)
     wc = Wild('wc')
     we = Wild('we')
     p  = wc*x**we
     from sympy import collect
     self = collect(self, x)
     d = self.match(p)
     if d is not None and we in d:
         return d[wc], d[we]
     return self, S.Zero
Esempio n. 23
0
def expand_mul(expr, deep=True):
    """
    Wrapper around expand that only uses the mul hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import symbols, expand_mul, exp, log
    >>> x, y = symbols('x,y', positive=True)
    >>> expand_mul(exp(x+y)*(x+y)*log(x*y**2))
    x*exp(x + y)*log(x*y**2) + y*exp(x + y)*log(x*y**2)

    """
    return sympify(expr).expand(deep=deep, mul=True, power_exp=False,\
    power_base=False, basic=False, multinomial=False, log=False)
Esempio n. 24
0
def expand_multinomial(expr, deep=True):
    """
    Wrapper around expand that only uses the multinomial hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import symbols, expand_multinomial, exp
    >>> x, y = symbols('x y', positive=True)
    >>> expand_multinomial((x + exp(x + 1))**2)
    x**2 + 2*x*exp(1 + x) + exp(2 + 2*x)

    """
    return sympify(expr).expand(deep=deep, mul=False, power_exp=False,\
    power_base=False, basic=False, multinomial=True, log=False)
Esempio n. 25
0
def expand_multinomial(expr, deep=True):
    """
    Wrapper around expand that only uses the multinomial hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import symbols, expand_multinomial, exp
    >>> x, y = symbols('x y', positive=True)
    >>> expand_multinomial((x + exp(x + 1))**2)
    x**2 + 2*x*exp(x + 1) + exp(2*x + 2)

    """
    return sympify(expr).expand(deep=deep, mul=False, power_exp=False,\
    power_base=False, basic=False, multinomial=True, log=False)
Esempio n. 26
0
    def __new__(cls, variables, expr):
        try:
            variables = Tuple(*variables)
        except TypeError:
            variables = Tuple(variables)
        if len(variables) == 1 and variables[0] == expr:
            return S.IdentityFunction

        #use dummy variables internally, just to be sure
        new_variables = [C.Dummy(arg.name) for arg in variables]
        expr = sympify(expr).subs(tuple(zip(variables, new_variables)))

        obj = Expr.__new__(cls, Tuple(*new_variables), expr)
        return obj
Esempio n. 27
0
 def __new__(cls, *args, **options):
     args = (sympify(arg) for arg in args)
     try:
         _args = frozenset(cls._new_args_filter(args))
     except ShortCircuit:
         return cls.zero
     if not _args:
         return cls.identity
     elif len(_args) == 1:
         return set(_args).pop()
     else:
         obj = Expr.__new__(cls, _args)
         obj._argset = _args
         return obj
Esempio n. 28
0
def expand_log(expr, deep=True):
    """
    Wrapper around expand that only uses the log hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import symbols, expand_log, exp, log
    >>> x, y = symbols('x,y', positive=True)
    >>> expand_log(exp(x+y)*(x+y)*log(x*y**2))
    (x + y)*(log(x) + 2*log(y))*exp(x + y)

    """
    return sympify(expr).expand(deep=deep, log=True, mul=False,\
    power_exp=False, power_base=False, multinomial=False, basic=False)
Esempio n. 29
0
 def __new__(cls, *args, **assumptions):
     args = (sympify(arg) for arg in args)
     try:
         _args = frozenset(cls._new_args_filter(args))
     except ShortCircuit:
         return cls.zero
     if not _args:
         return cls.identity
     elif len(_args) == 1:
         return set(_args).pop()
     else:
         obj = Expr.__new__(cls, _args, **assumptions)
         obj._argset = _args
         return obj
Esempio n. 30
0
def expand_trig(expr, deep=True):
    """
    Wrapper around expand that only uses the trig hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import expand_trig, sin, cos
    >>> from sympy.abc import x, y
    >>> expand_trig(sin(x+y)*(x+y))
    (x + y)*(sin(x)*cos(y) + sin(y)*cos(x))

    """
    return sympify(expr).expand(deep=deep, trig=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 31
0
def expand_func(expr, deep=True):
    """
    Wrapper around expand that only uses the func hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import expand_func, gamma
    >>> from sympy.abc import x
    >>> expand_func(gamma(x + 2))
    x*(x + 1)*gamma(x)

    """
    return sympify(expr).expand(deep=deep, func=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 32
0
def expand_complex(expr, deep=True):
    """
    Wrapper around expand that only uses the complex hint.  See the expand
    docstring for more information.

    Example:
    >>> from sympy import expand_complex, I, im, re
    >>> from sympy.abc import z
    >>> expand_complex(z**(2*I))
    I*im(z**(2*I)) + re(z**(2*I))

    """
    return sympify(expr).expand(deep=deep, complex=True, basic=False,\
    log=False, mul=False, power_exp=False, power_base=False, multinomial=False)
Esempio n. 33
0
    def __new__(cls, variables, expr):
        try:
            variables = Tuple(*variables)
        except TypeError:
            variables = Tuple(variables)
        if len(variables) == 1 and variables[0] == expr:
            return S.IdentityFunction

        #use dummy variables internally, just to be sure
        new_variables = [C.Dummy(arg.name) for arg in variables]
        expr = sympify(expr).subs(tuple(zip(variables, new_variables)))

        obj = Expr.__new__(cls, Tuple(*new_variables), expr)
        return obj
Esempio n. 34
0
    def _contains(self, other):
        """
        Tests whether an element, other, is in the set.
        Relies on Python's set class. This tests for object equality
        All inputs are sympified

        >>> from sympy import FiniteSet

        >>> 1 in FiniteSet(1, 2)
        True
        >>> 5 in FiniteSet(1, 2)
        False

        """
        return sympify(other) in self.elements
Esempio n. 35
0
    def _contains(self, other):
        """
        Tests whether an element, other, is in the set.
        Relies on Python's set class. This tests for object equality
        All inputs are sympified

        >>> from sympy import FiniteSet

        >>> 1 in FiniteSet(1, 2)
        True
        >>> 5 in FiniteSet(1, 2)
        False

        """
        return sympify(other) in self.elements
Esempio n. 36
0
File: evalf.py Progetto: cran/rSymPy
def N(x, n=15, **options):
    """
    Calls x.evalf(n, **options).

    Both .evalf() and N() are equivalent, use the one that you like better.

    Example:
    >>> from sympy import Sum, Symbol, oo
    >>> k = Symbol("k")
    >>> Sum(1/k**k, (k, 1, oo))
    Sum(k**(-k), (k, 1, oo))
    >>> N(Sum(1/k**k, (k, 1, oo)), 4)
    1.291

    """
    return sympify(x).evalf(n, **options)
Esempio n. 37
0
def N(x, n=15, **options):
    """
    Calls x.evalf(n, **options).

    Both .evalf() and N() are equivalent, use the one that you like better.

    Example:
    >>> from sympy import Sum, Symbol, oo, N
    >>> from sympy.abc import k
    >>> Sum(1/k**k, (k, 1, oo))
    Sum(k**(-k), (k, 1, oo))
    >>> N(Sum(1/k**k, (k, 1, oo)), 4)
    1.291

    """
    return sympify(x).evalf(n, **options)
Esempio n. 38
0
def evalf_symbol(x, prec, options):
    val = options["subs"][x]
    if isinstance(val, mpf):
        if not val:
            return None, None, None, None
        return val._mpf_, None, prec, None
    else:
        if not "_cache" in options:
            options["_cache"] = {}
        cache = options["_cache"]
        cached, cached_prec = cache.get(x.name, (None, MINUS_INF))
        if cached_prec >= prec:
            return cached
        v = evalf(sympify(val), prec, options)
        cache[x.name] = (v, prec)
        return v
Esempio n. 39
0
def evalf_symbol(x, prec, options):
    val = options['subs'][x]
    if isinstance(val, mpf):
        if not val:
            return None, None, None, None
        return val._mpf_, None, prec, None
    else:
        if not '_cache' in options:
            options['_cache'] = {}
        cache = options['_cache']
        cached, cached_prec = cache.get(x.name, (None, MINUS_INF))
        if cached_prec >= prec:
            return cached
        v = evalf(sympify(val), prec, options)
        cache[x.name] = (v, prec)
        return v
Esempio n. 40
0
    def coeff(self, x, expand=True):
        """
        Returns the coefficient of the term "x" or None if there is no "x".

        Optional expand keyword argument allows one to control whether the
        expression is expanded before terms are collected, which can be useful
        if the term "x" isn't nested inside of terms and you don't want the
        returned coefficient to be expanded.

        Example:

        >>> from sympy import symbols
        >>> from sympy.abc import x, y, z
        >>> (3+2*x+4*x**2).coeff(1)
        >>> (3+2*x+4*x**2).coeff(x)
        2
        >>> (3+2*x+4*x**2).coeff(x**2)
        4
        >>> (3+2*x+4*x**2).coeff(x**3)
        >>> (z*(x+y)**2).coeff(z)
        2*x*y + x**2 + y**2
        >>> (z*(x+y)**2).coeff(z, expand=False)
        (x + y)**2
        >>>

        """
        from sympy import collect
        x = sympify(x)
        const = x.as_coeff_mul()[0]  # constant multiplying x
        if const != S.One:  # get rid of constants
            result = self.coeff(x / const)
            if result is not None:
                return (result / const)
            else:
                return None
        if x.is_Integer:
            return

        result = self
        if expand:
            result = result.expand(
            )  # collect expects its arguments in expanded form
        result = collect(result, x, evaluate=False, exact=True)
        if x in result:
            return result[x]
        else:
            return None
Esempio n. 41
0
    def _subs_dict(self, sequence):
        """Performs sequential substitution.

           Given a collection of key, value pairs, which correspond to
           old and new expressions respectively,  substitute all given
           pairs handling properly all overlapping keys  (according to
           'in' relation).

           We have to use naive O(n**2) sorting algorithm, as 'in'
           gives only partial order and all asymptotically faster
           fail (depending on the initial order).

           >>> from sympy import sqrt, sin, cos, exp
           >>> from sympy.abc import x, y

           >>> from sympy.abc import a, b, c, d, e

           >>> A = (sqrt(sin(2*x)), a)
           >>> B = (sin(2*x), b)
           >>> C = (cos(2*x), c)
           >>> D = (x, d)
           >>> E = (exp(x), e)

           >>> expr = sqrt(sin(2*x))*sin(exp(x)*x)*cos(2*x) + sin(2*x)

           >>> expr._subs_dict([A,B,C,D,E])
           a*c*sin(d*e) + b

        """
        sequence = sympify(sequence)

        if isinstance(sequence, dict):
            sequence = sequence.items()

        subst = []

        for pattern in sequence:
            for i, (expr, _) in enumerate(subst):
                if expr.has(pattern[0]):
                    subst.insert(i, pattern)
                    break
            else:
                subst.append(pattern)
        subst.reverse()

        return self._subs_list(subst)
Esempio n. 42
0
def N(x, n=15, **options):
    """
    Calls x.evalf(n, \*\*options).

    Both .n() and N() are equivalent to .evalf(); use the one that you like better.
    See also the docstring of .evalf() for information on the options.

    Examples
    ========

    >>> from sympy import Sum, oo, N
    >>> from sympy.abc import k
    >>> Sum(1/k**k, (k, 1, oo))
    Sum(k**(-k), (k, 1, oo))
    >>> N(_, 4)
    1.291

    """
    return sympify(x).evalf(n, **options)
Esempio n. 43
0
    def leadterm(self, x):
        """
        Returns the leading term a*x**b as a tuple (a, b).

        Example:

        >>> from sympy.abc import x
        >>> (1+x+x**2).leadterm(x)
        (1, 0)
        >>> (1/x**2+x+x**2).leadterm(x)
        (1, -2)

        Note:

        self is assumed to be the result returned by Basic.series().
        """
        from sympy import powsimp
        x = sympify(x)
        c, e = self.as_leading_term(x).as_coeff_exponent(x)
        c = powsimp(c, deep=True, combine='exp')
        if not c.has(x):
            return c, e
        raise ValueError("cannot compute leadterm(%s, %s), got c=%s" % (self, x, c))
Esempio n. 44
0
    def subs(self, *args, **kwargs):
        """
        Substitutes old for new in an expression after sympifying args.

        `args` is either:
          - two arguments, e.g. foo.subs(old, new)
          - one iterable argument, e.g. foo.subs(iterable). The iterable may be
             o an iterable container with (old, new) pairs. In this case the
               replacements are processed in the order given with successive
               patterns possibly affecting replacements already made.
             o a dict or set whose key/value items correspond to old/new pairs.
               In this case the old/new pairs will be sorted by op count and in
               case of a tie, by number of args and the default_sort_key. The
               resulting sorted list is then processed as an iterable container
               (see previous).

        If the keyword ``simultaneous`` is True, the subexpressions will not be
        evaluated until all the substitutions have been made.

        Examples
        ========

        >>> from sympy import pi, exp
        >>> from sympy.abc import x, y
        >>> (1 + x*y).subs(x, pi)
        pi*y + 1
        >>> (1 + x*y).subs({x:pi, y:2})
        1 + 2*pi
        >>> (1 + x*y).subs([(x, pi), (y, 2)])
        1 + 2*pi
        >>> reps = [(y, x**2), (x, 2)]
        >>> (x + y).subs(reps)
        6
        >>> (x + y).subs(reversed(reps))
        x**2 + 2

        >>> (x**2 + x**4).subs(x**2, y)
        y**2 + y

        To replace only the x**2 but not the x**4, use xreplace:

        >>> (x**2 + x**4).xreplace({x**2: y})
        x**4 + y

        To delay evaluation until all substitutions have been made,
        set the keyword ``simultaneous`` to True:

        >>> (x/y).subs([(x, 0), (y, 0)])
        0
        >>> (x/y).subs([(x, 0), (y, 0)], simultaneous=True)
        nan

        This has the added feature of not allowing subsequent substitutions
        to affect those already made:

        >>> ((x + y)/y).subs({x + y: y, y: x + y})
        1
        >>> ((x + y)/y).subs({x + y: y, y: x + y}, simultaneous=True)
        y/(x + y)

        In order to obtain a canonical result, unordered iterables are
        sorted by count_op length, number of arguments and by the
        default_sort_key to break any ties. All other iterables are left
        unsorted.

        >>> from sympy import sqrt, sin, cos, exp
        >>> from sympy.abc import a, b, c, d, e

        >>> A = (sqrt(sin(2*x)), a)
        >>> B = (sin(2*x), b)
        >>> C = (cos(2*x), c)
        >>> D = (x, d)
        >>> E = (exp(x), e)

        >>> expr = sqrt(sin(2*x))*sin(exp(x)*x)*cos(2*x) + sin(2*x)

        >>> expr.subs(dict([A,B,C,D,E]))
        a*c*sin(d*e) + b

        See Also
        ========
        replace: replacement capable of doing wildcard-like matching,
                 parsing of match, and conditional replacements
        xreplace: exact node replacement in expr tree; also capable of
                  using matching rules

        """
        from sympy.core.containers import Dict
        from sympy.utilities import default_sort_key

        unordered = False
        if len(args) == 1:
            sequence = args[0]
            if isinstance(sequence, set):
                unordered = True
            elif isinstance(sequence, (Dict, dict)):
                unordered = True
                sequence = sequence.items()
            elif not iterable(sequence):
                from sympy.utilities.misc import filldedent
                raise ValueError(
                    filldedent("""
                   When a single argument is passed to subs
                   it should be an iterable of (old, new) tuples."""))
        elif len(args) == 2:
            sequence = [args]
        else:
            raise ValueError("subs accepts either 1 or 2 arguments")

        sequence = list(sequence)
        for i in range(len(sequence)):
            o, n = sequence[i]
            so, sn = sympify(o), sympify(n)
            if not isinstance(so, Basic):
                if type(o) is str:
                    so = C.Symbol(o)
            sequence[i] = (so, sn)
            if _aresame(so, sn):
                sequence[i] = None
                continue
        sequence = filter(None, sequence)

        if unordered:
            sequence = dict(sequence)
            if not all(k.is_Atom for k in sequence):
                d = {}
                for o, n in sequence.iteritems():
                    try:
                        ops = o.count_ops(), len(o.args)
                    except TypeError:
                        ops = (0, 0)
                    d.setdefault(ops, []).append((o, n))
                newseq = []
                for k in sorted(d.keys(), reverse=True):
                    newseq.extend(
                        sorted([v[0] for v in d[k]], key=default_sort_key))
                sequence = [(k, sequence[k]) for k in newseq]
                del newseq, d
            else:
                sequence = sorted([(k, v) for (k, v) in sequence.iteritems()],
                                  key=default_sort_key)

        if kwargs.pop('simultaneous',
                      False):  # XXX should this be the default for dict subs?
            reps = {}
            rv = self
            for old, new in sequence:
                d = C.Dummy()
                rv = rv._subs(old, d)
                reps[d] = new
                if not isinstance(rv, Basic):
                    break
            return rv.xreplace(reps)
        else:
            rv = self
            for old, new in sequence:
                rv = rv._subs(old, new)
                if not isinstance(rv, Basic):
                    break
            return rv
Esempio n. 45
0
def count_ops(expr, visual=False):
    """
    Return a representation (integer or expression) of the operations in expr.

    If `visual` is False (default) then the sum of the coefficients of the
    visual expression will be returned.

    If `visual` is True then the number of each type of operation is shown
    with the core class types (or their virtual equivalent) multiplied by the
    number of times they occur.

    If expr is an iterable, the sum of the op counts of the
    items will be returned.

    Examples:
        >>> from sympy.abc import a, b, x, y
        >>> from sympy import sin, count_ops

    Although there isn't a SUB object, minus signs are interpreted as
    either negations or subtractions:
        >>> (x - y).count_ops(visual=True)
        SUB
        >>> (-x).count_ops(visual=True)
        NEG

    Here, there are two Adds and a Pow:
        >>> (1 + a + b**2).count_ops(visual=True)
        POW + 2*ADD

    In the following, an Add, Mul, Pow and two functions:
        >>> (sin(x)*x + sin(x)**2).count_ops(visual=True)
        ADD + MUL + POW + 2*SIN

    for a total of 5:
        >>> (sin(x)*x + sin(x)**2).count_ops(visual=False)
        5

    Note that "what you type" is not always what you get. The expression
    1/x/y is translated by sympy into 1/(x*y) so it gives a DIV and MUL rather
    than two DIVs:
        >>> (1/x/y).count_ops(visual=True)
        DIV + MUL

    The visual option can be used to demonstrate the difference in
    operations for expressions in different forms. Here, the Horner
    representation is compared with the expanded form of a polynomial:
        >>> eq=x*(1 + x*(2 + x*(3 + x)))
        >>> count_ops(eq.expand(), visual=True) - count_ops(eq, visual=True)
        -MUL + 3*POW

    The count_ops function also handles iterables:
        >>> count_ops([x, sin(x), None, True, x + 2], visual=False)
        2
        >>> count_ops([x, sin(x), None, True, x + 2], visual=True)
        ADD + SIN
        >>> count_ops({x: sin(x), x + 2: y + 1}, visual=True)
        SIN + 2*ADD

    """
    from sympy.simplify.simplify import fraction

    expr = sympify(expr)
    if isinstance(expr, Expr):

        ops = []
        args = [expr]
        NEG = C.Symbol('NEG')
        DIV = C.Symbol('DIV')
        SUB = C.Symbol('SUB')
        ADD = C.Symbol('ADD')

        def isneg(a):
            c = a.as_coeff_mul()[0]
            return c.is_Number and c.is_negative

        while args:
            a = args.pop()
            if a.is_Rational:
                #-1/3 = NEG + DIV
                if a is not S.One:
                    if a.p < 0:
                        ops.append(NEG)
                    if a.q != 1:
                        ops.append(DIV)
                    continue
            elif a.is_Mul:
                if isneg(a):
                    ops.append(NEG)
                    if a.args[0] is S.NegativeOne:
                        a = a.as_two_terms()[1]
                    else:
                        a = -a
                n, d = fraction(a)
                if n.is_Integer:
                    ops.append(DIV)
                    if n < 0:
                        ops.append(NEG)
                    args.append(d)
                    continue  # won't be -Mul but could be Add
                elif d is not S.One:
                    if not d.is_Integer:
                        args.append(d)
                    ops.append(DIV)
                    args.append(n)
                    continue  # could be -Mul
            elif a.is_Add:
                aargs = list(a.args)
                negs = 0
                for i, ai in enumerate(aargs):
                    if isneg(ai):
                        negs += 1
                        args.append(-ai)
                        if i > 0:
                            ops.append(SUB)
                    else:
                        args.append(ai)
                        if i > 0:
                            ops.append(ADD)
                if negs == len(aargs):  # -x - y = NEG + SUB
                    ops.append(NEG)
                elif isneg(aargs[0]
                           ):  # -x + y = SUB, but we already recorded an ADD
                    ops.append(SUB - ADD)
                continue
            if a.is_Pow and a.exp is S.NegativeOne:
                ops.append(DIV)
                args.append(a.base)  # won't be -Mul but could be Add
                continue
            if (a.is_Mul or a.is_Pow or a.is_Function
                    or isinstance(a, Derivative) or isinstance(a, C.Integral)):

                o = C.Symbol(a.func.__name__.upper())
                # count the args
                if (a.is_Mul or isinstance(a, C.LatticeOp)):
                    ops.append(o * (len(a.args) - 1))
                else:
                    ops.append(o)
            args.extend(a.args)

    elif type(expr) is dict:
        ops = [
            count_ops(k, visual=visual) + count_ops(v, visual=visual)
            for k, v in expr.iteritems()
        ]
    elif hasattr(expr, '__iter__'):
        ops = [count_ops(i, visual=visual) for i in expr]
    elif not isinstance(expr, Basic):
        ops = []
    else:  # it's Basic not isinstance(expr, Expr):
        assert isinstance(expr, Basic)
        ops = [count_ops(a, visual=visual) for a in expr.args]

    if not ops:
        if visual:
            return S.Zero
        return 0

    ops = Add(*ops)

    if visual:
        return ops

    if ops.is_Number:
        return int(ops)

    return sum(int((a.args or [1])[0]) for a in Add.make_args(ops))
Esempio n. 46
0
 def __new__(cls, *args, **assumptions):
     args = [sympify(arg) for arg in args]
     obj = Basic.__new__(cls, *args, **assumptions)
     return obj
Esempio n. 47
0
 def __pow__(self, exp):
     if not sympify(exp).is_Integer and exp>=0:
         raise ValueError("%s: Exponent must be a positive Integer"%exp)
     return ProductSet([self]*exp)
Esempio n. 48
0
 def __sympifyit_wrapper(a, b):
     return func(a, sympify(b, strict=True))
Esempio n. 49
0
    def _matches(self, expr, repl_dict={}, evaluate=False):
        # weed out negative one prefixes
        sign = 1
        if self.args[0] == -1:
            self = -self
            sign = -sign
        if expr.is_Mul and expr.args[0] == -1:
            expr = -expr
            sign = -sign

        if evaluate:
            return self.subs(repl_dict).matches(expr, repl_dict)
        expr = sympify(expr)
        if not isinstance(expr, self.__class__):
            # if we can omit the first factor, we can match it to sign * one
            if Mul(*self.args[1:]) == expr:
                return self.args[0].matches(Rational(sign), repl_dict,
                                            evaluate)
            # two-factor product: if the 2nd factor matches, the first part must be sign * one
            if len(self.args[:]) == 2:
                dd = self.args[1].matches(expr, repl_dict, evaluate)
                if dd == None:
                    return None
                dd = self.args[0].matches(Rational(sign), dd, evaluate)
                return dd
            return None

        if len(self.args[:]) == 0:
            if self == expr:
                return repl_dict
            return None
        d = repl_dict.copy()

        # weed out identical terms
        pp = list(self.args)
        ee = list(expr.args)
        for p in self.args:
            if p in expr.args:
                ee.remove(p)
                pp.remove(p)

        # only one symbol left in pattern -> match the remaining expression
        from symbol import Wild
        if len(pp) == 1 and isinstance(pp[0], Wild):
            if len(ee) == 1:
                d[pp[0]] = sign * ee[0]
            else:
                d[pp[0]] = sign * (type(expr)(*ee))
            return d

        if len(ee) != len(pp):
            return None

        i = 0
        for p, e in zip(pp, ee):
            if i == 0 and sign != 1:
                try:
                    e = sign * e
                except TypeError:
                    return None
            d = p.matches(e, d, evaluate=not i)
            i += 1
            if d is None:
                return None
        return d
Esempio n. 50
0
File: mul.py Progetto: pernici/sympy
    def _matches(self, expr, repl_dict={}, evaluate=False):
        if evaluate:
            return self.subs(repl_dict).matches(expr, repl_dict)

        # weed out negative one prefixes
        sign = 1
        a, b = self.as_two_terms()
        if a is S.NegativeOne:
            if b.is_Mul:
                sign = -sign
            else:
                # the remainder, b, is not a Mul anymore
                return b.matches(-expr, repl_dict, evaluate)
        expr = sympify(expr)
        if expr.is_Mul and expr.args[0] is S.NegativeOne:
            expr = -expr
            sign = -sign

        if not expr.is_Mul:
            # expr can only match if it matches b and a matches +/- 1
            if len(self.args) == 2:
                # quickly test for equality
                if b == expr:
                    return a.matches(Rational(sign), repl_dict, evaluate)
                # do more expensive match
                dd = b.matches(expr, repl_dict, evaluate)
                if dd == None:
                    return None
                dd = a.matches(Rational(sign), dd, evaluate)
                return dd
            return None

        d = repl_dict.copy()

        # weed out identical terms
        pp = list(self.args)
        ee = list(expr.args)
        for p in self.args:
            if p in expr.args:
                ee.remove(p)
                pp.remove(p)

        # only one symbol left in pattern -> match the remaining expression
        if len(pp) == 1 and isinstance(pp[0], C.Wild):
            if len(ee) == 1:
                d[pp[0]] = sign * ee[0]
            else:
                d[pp[0]] = sign * (type(expr)(*ee))
            return d

        if len(ee) != len(pp):
            return None

        i = 0
        for p, e in zip(pp, ee):
            if i == 0 and sign != 1:
                try:
                    e = sign * e
                except TypeError:
                    return None
            d = p.matches(e, d, evaluate=not i)
            i += 1
            if d is None:
                return None
        return d
Esempio n. 51
0
 def _subs_old_new(self, old, new):
     """Substitutes an expression old -> new."""
     old = sympify(old)
     new = sympify(new)
     return self._eval_subs(old, new)
Esempio n. 52
0
def expand(e, deep=True, modulus=None, power_base=True, power_exp=True, \
        mul=True, log=True, multinomial=True, basic=True, **hints):
    """
    Expand an expression using methods given as hints.

    Hints are applied with arbitrary order so your code shouldn't
    depend on the way hints are passed to this method.

    Hints evaluated unless explicitly set to False are:
      basic, log, multinomial, mul, power_base, and power_exp
    The following hints are supported but not applied unless set to True:
      complex, func, and trig.

    basic is a generic keyword for methods that want to be expanded
    automatically.  For example, Integral uses expand_basic to expand the
    integrand.  If you want your class expand methods to run automatically and
    they don't fit one of the already automatic methods, wrap it around
    _eval_expand_basic.

    If deep is set to True, things like arguments of functions are
    recursively expanded.  Use deep=False to only expand on the top
    level.

    Also see expand_log, expand_mul, expand_complex, expand_trig,
    and expand_func, which are wrappers around those expansion methods.

    >>> from sympy import cos, exp
    >>> from sympy.abc import x, y, z

    mul - Distributes multiplication over addition.
    >>> (y*(x + z)).expand(mul=True)
    x*y + y*z

    complex - Split an expression into real and imaginary parts.
    >>> (x+y).expand(complex=True)
    I*im(x) + I*im(y) + re(x) + re(y)
    >>> cos(x).expand(complex=True)
    cos(re(x))*cosh(im(x)) - I*sin(re(x))*sinh(im(x))

    power_exp - Expand addition in exponents into multiplied bases.
    >>> exp(x+y).expand(power_exp=True)
    exp(x)*exp(y)
    >>> (2**(x+y)).expand(power_exp=True)
    2**x*2**y

    power_base - Split powers of multiplied bases.
    >>> ((x*y)**z).expand(power_base=True)
    x**z*y**z

    log - Pull out power of an argument as a coefficient and split logs products
    into sums of logs.  Note that these only work if the arguments of the log
    function have the proper assumptions: the arguments must be positive and the
    exponents must be real.
    >>> from sympy import log, symbols
    >>> log(x**2*y).expand(log=True)
    log(y*x**2)
    >>> x, y = symbols('x,y', positive=True)
    >>> log(x**2*y).expand(log=True)
    2*log(x) + log(y)

    trig - Do trigonometric expansions.
    >>> cos(x+y).expand(trig=True)
    cos(x)*cos(y) - sin(x)*sin(y)

    func - Expand other functions.
    >>> from sympy import gamma
    >>> gamma(x+1).expand(func=True)
    x*gamma(x)

    multinomial - Expand (x + y + ...)**n where n is a positive integer.
    >>> ((x+y+z)**2).expand(multinomial=True)
    2*x*y + 2*x*z + 2*y*z + x**2 + y**2 + z**2

    You can shut off methods that you don't want.
    >>> (exp(x+y)*(x+y)).expand()
    x*exp(x)*exp(y) + y*exp(x)*exp(y)
    >>> (exp(x+y)*(x+y)).expand(power_exp=False)
    x*exp(x + y) + y*exp(x + y)
    >>> (exp(x+y)*(x+y)).expand(mul=False)
    (x + y)*exp(x)*exp(y)

    Use deep=False to only expand on the top level.
    >>> exp(x+exp(x+y)).expand()
    exp(x)*exp(exp(x)*exp(y))
    >>> exp(x+exp(x+y)).expand(deep=False)
    exp(x)*exp(exp(x + y))

    Note: because hints are applied in arbitrary order, some hints may
    prevent expansion by other hints if they are applied first.  In
    particular, mul may distribute multiplications and prevent log and
    power_base from expanding them.  Also, if mul is applied before multinomial,
    the expression might not be fully distributed.  The solution is to expand
    with mul=False first, then run expand_mul if you need further expansion.

    Examples:
    >>> from sympy import expand_log, expand, expand_mul
    >>> x, y, z = symbols('x,y,z', positive=True)

    >> expand(log(x*(y+z))) # could be either one below
    log(x*y + x*z)
    log(x) + log(y + z)

    >>> expand_log(log(x*y+x*z))
    log(x*y + x*z)

    >> expand(log(x*(y+z)), mul=False)
    log(x) + log(y + z)


    >> expand((x*(y+z))**x) # could be either one below
    (x*y + x*z)**x
    x**x*(y + z)**x

    >>> expand((x*(y+z))**x, mul=False)
    x**x*(y + z)**x


    >> expand(x*(y+z)**2) # could be either one below
    2*x*y*z + x*y**2 + x*z**2
    x*(y + z)**2

    >>> expand(x*(y+z)**2, mul=False)
    x*(2*y*z + y**2 + z**2)

    >>> expand_mul(_)
    2*x*y*z + x*y**2 + x*z**2

    """
    hints['power_base'] = power_base
    hints['power_exp'] = power_exp
    hints['mul'] = mul
    hints['log'] = log
    hints['multinomial'] = multinomial
    hints['basic'] = basic
    return sympify(e).expand(deep=deep, modulus=modulus, **hints)
Esempio n. 53
0
 def __sympifyit_wrapper(a, b):
     try:
         return func(a, sympify(b, strict=True))
     except SympifyError:
         return retval
Esempio n. 54
0
    def extract_multiplicatively(self, c):
        """Return None if it's not possible to make self in the form
           c * something in a nice way, i.e. preserving the properties
           of arguments of self.

           >>> from sympy import symbols, Rational

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

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

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

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

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

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

        """
        c = sympify(c)
        if c is S.One:
            return self
        elif c == self:
            return S.One
        elif c.is_Mul:
            x = self.extract_multiplicatively(c.as_two_terms()[0])
            if x != None:
                return x.extract_multiplicatively(c.as_two_terms()[1])
        quotient = self / c
        if self.is_Number:
            if self is S.Infinity:
                if c.is_positive:
                    return S.Infinity
            elif self is S.NegativeInfinity:
                if c.is_negative:
                    return S.Infinity
                elif c.is_positive:
                    return S.NegativeInfinity
            elif self is S.ComplexInfinity:
                if not c.is_zero:
                    return S.ComplexInfinity
            elif self is S.NaN:
                return S.NaN
            elif self.is_Integer:
                if not quotient.is_Integer:
                    return None
                elif self.is_positive and quotient.is_negative:
                    return None
                else:
                    return quotient
            elif self.is_Rational:
                if not quotient.is_Rational:
                    return None
                elif self.is_positive and quotient.is_negative:
                    return None
                else:
                    return quotient
            elif self.is_Real:
                if not quotient.is_Real:
                    return None
                elif self.is_positive and quotient.is_negative:
                    return None
                else:
                    return quotient
        elif self.is_NumberSymbol or self.is_Symbol or self is S.ImaginaryUnit:
            if quotient.is_Mul and len(quotient.args) == 2:
                if quotient.args[0].is_Integer and quotient.args[0].is_positive and quotient.args[1] == self:
                    return quotient
            elif quotient.is_Integer:
                return quotient
        elif self.is_Add:
            newargs = []
            for arg in self.args:
                newarg = arg.extract_multiplicatively(c)
                if newarg != None:
                    newargs.append(newarg)
                else:
                    return None
            return Add(*newargs)
        elif self.is_Mul:
            for i in xrange(len(self.args)):
                newargs = list(self.args)
                del(newargs[i])
                tmp = self._new_rawargs(*newargs).extract_multiplicatively(c)
                if tmp != None:
                    return tmp * self.args[i]
        elif self.is_Pow:
            if c.is_Pow and c.base == self.base:
                new_exp = self.exp.extract_additively(c.exp)
                if new_exp != None:
                    return self.base ** (new_exp)
            elif c == self.base:
                new_exp = self.exp.extract_additively(1)
                if new_exp != None:
                    return self.base ** (new_exp)
Esempio n. 55
0
    def extract_additively(self, c):
        """Return None if it's not possible to make self in the form
           something + c in a nice way, i.e. preserving the properties
           of arguments of self.

           >>> from sympy import symbols

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

           >>> ((x*y)**3).extract_additively(1)

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

           >>> (x+1).extract_additively(2*x)

           >>> (x+1).extract_additively(-x)
           1 + 2*x

           >>> (-x+1).extract_additively(2*x)
           1 - 3*x

        """
        c = sympify(c)
        if c is S.Zero:
            return self
        elif c == self:
            return S.Zero
        elif self is S.Zero:
            return None
        elif c.is_Add:
            x = self.extract_additively(c.as_two_terms()[0])
            if x != None:
                return x.extract_additively(c.as_two_terms()[1])
        sub = self - c
        if self.is_Number:
            if self.is_Integer:
                if not sub.is_Integer:
                    return None
                elif self.is_positive and sub.is_negative:
                    return None
                else:
                    return sub
            elif self.is_Rational:
                if not sub.is_Rational:
                    return None
                elif self.is_positive and sub.is_negative:
                    return None
                else:
                    return sub
            elif self.is_Real:
                if not sub.is_Real:
                    return None
                elif self.is_positive and sub.is_negative:
                    return None
                else:
                    return sub
        elif self.is_NumberSymbol or self.is_Symbol or self is S.ImaginaryUnit:
            if sub.is_Mul and len(sub.args) == 2:
                if sub.args[0].is_Integer and sub.args[0].is_positive and sub.args[1] == self:
                    return sub
            elif sub.is_Integer:
                return sub
        elif self.is_Add:
            terms = self.as_two_terms()
            subs0 = terms[0].extract_additively(c)
            if subs0 != None:
                return subs0 + terms[1]
            else:
                subs1 = terms[1].extract_additively(c)
                if subs1 != None:
                    return subs1 + terms[0]
        elif self.is_Mul:
            self_coeff, self_terms = self.as_coeff_mul()
            if c.is_Mul:
                c_coeff, c_terms = c.as_coeff_mul()
                if c_terms == self_terms:
                    new_coeff = self_coeff.extract_additively(c_coeff)
                    if new_coeff != None:
                        return new_coeff * c._new_rawargs(*c_terms)
            elif c == self_terms:
                new_coeff = self_coeff.extract_additively(1)
                if new_coeff != None:
                    return new_coeff * c
Esempio n. 56
0
 def matches(self, expr, repl_dict={}, evaluate=False):
     expr = sympify(expr)
     if self.is_commutative and expr.is_commutative:
         return AssocOp._matches_commutative(self, expr, repl_dict, evaluate)
     # todo for commutative parts, until then use the default matches method for non-commutative products
     return self._matches(expr, repl_dict, evaluate)
Esempio n. 57
0
 def __new__(cls, name, exclude=(), properties=(), **assumptions):
     exclude = tuple([sympify(x) for x in exclude])
     properties = tuple(properties)
     assumptions.setdefault('commutative', True)
     return Wild.__xnew__(cls, name, exclude, properties, **assumptions)
Esempio n. 58
0
 def __new__(cls, name, exclude=(), properties=(), **assumptions):
     exclude = tuple([sympify(x) for x in exclude])
     properties = tuple(properties)
     return Wild.__xnew__(cls, name, exclude, properties, **assumptions)
Esempio n. 59
0
    def __new__(cls, expr, *symbols, **assumptions):
        expr = sympify(expr)
        if not symbols:
            return expr

        # standardize symbols
        symbols = list(sympify(symbols))
        if not symbols[-1].is_Integer or len(symbols) == 1:
            symbols.append(S.One)
        symbol_count = []
        all_zero = True
        i = 0
        while i < len(symbols) - 1:  # process up to final Integer
            s, count = symbols[i:i + 2]
            iwas = i
            if s.is_Symbol:
                if count.is_Symbol:
                    count = 1
                    i += 1
                elif count.is_Integer:
                    count = int(count)
                    i += 2

            if i == iwas:  # didn't get an update because of bad input
                raise ValueError(
                    'Derivative expects Symbol [, Integer] args but got %s, %s'
                    % (s, count))

            symbol_count.append((s, count))
            if all_zero and not count == 0:
                all_zero = False

        # We make a special case for 0th derivative, because there
        # is no good way to unambiguously print this.
        if all_zero:
            return expr

        evaluate = assumptions.pop('evaluate', False)

        # look for a quick exit if there are symbols that are not in the free symbols
        if evaluate:
            if set(sc[0] for sc in symbol_count).difference(expr.free_symbols):
                return S.Zero

        # We make a generator so as to only generate a symbol when necessary.
        # If a high order of derivative is requested and the expr becomes 0
        # after a few differentiations, then we won't need the other symbols
        symbolgen = (s for s, count in symbol_count for i in xrange(count))

        if expr.is_commutative:
            assumptions['commutative'] = True

        if (not (hasattr(expr, '_eval_derivative') and evaluate)
                and not isinstance(expr, Derivative)):
            symbols = list(symbolgen)
            obj = Expr.__new__(cls, expr, *symbols, **assumptions)
            return obj

        # compute the derivative now
        unevaluated_symbols = []
        for s in symbolgen:
            obj = expr._eval_derivative(s)
            if obj is None:
                unevaluated_symbols.append(s)
            elif obj is S.Zero:
                return S.Zero
            else:
                expr = obj

        if not unevaluated_symbols:
            return expr

        return Expr.__new__(cls, expr, *unevaluated_symbols, **assumptions)
Esempio n. 60
-1
    def __new__(cls, expr, *symbols, **assumptions):
        expr = sympify(expr)
        if not symbols: return expr
        symbols = Derivative._symbolgen(*symbols)
        if expr.is_commutative:
            assumptions["commutative"] = True
        if "evaluate" in assumptions:
            evaluate = assumptions["evaluate"]
            del assumptions["evaluate"]
        else:
            evaluate = False
        if not evaluate and not isinstance(expr, Derivative):
            obj = Basic.__new__(cls, expr, *symbols, **assumptions)
            return obj
        unevaluated_symbols = []
        for s in symbols:
            s = sympify(s)
            if not isinstance(s, Symbol):
                raise ValueError('Invalid literal: %s is not a valid variable' % s)
            if not expr.has(s):
                return S.Zero
            obj = expr._eval_derivative(s)
            if obj is None:
                unevaluated_symbols.append(s)
            elif obj is S.Zero:
                return S.Zero
            else:
                expr = obj

        if not unevaluated_symbols:
            return expr
        return Basic.__new__(cls, expr, *unevaluated_symbols, **assumptions)