Пример #1
0
 def _eval_nseries(self, x, x0, n):
     assert len(self.args) == 1
     arg = self.args[0]
     arg0 = arg.limit(x, 0)
     from sympy import oo
     if arg0 in [-oo, oo]:
         raise PoleError("Cannot expand around %s" % (arg))
     if arg0 is not S.Zero:
         e = self.func(arg)
         e1 = e.expand()
         if e == e1:
             #for example when e = sin(x+1) or e = sin(cos(x))
             #let's try the general algorithm
             term = e.subs(x, S.Zero)
             series = term
             fact = S.One
             for i in range(n - 1):
                 i += 1
                 fact *= Rational(i)
                 e = e.diff(x)
                 term = e.subs(x, S.Zero) * (x**i) / fact
                 term = term.expand()
                 series += term
             return series + C.Order(x**n, x)
         return self.nseries(x, x0, n)
     l = []
     g = None
     for i in xrange(n + 2):
         g = self.taylor_term(i, arg, g)
         g = g.nseries(x, x0, n)
         l.append(g)
     return Add(*l) + C.Order(x**n, x)
Пример #2
0
    def _eval_expand_complex(self, *args):
        if self.exp.is_Integer:
            exp = self.exp
            re, im = self.base.as_real_imag()
            if exp >= 0:
                base = re + S.ImaginaryUnit * im
            else:
                mag = re ** 2 + im ** 2
                base = re / mag - S.ImaginaryUnit * (im / mag)
                exp = -exp
            return (base ** exp).expand()
        elif self.exp.is_Rational:
            # NOTE: This is not totally correct since for x**(p/q) with
            #       x being imaginary there are actually q roots, but
            #       only a single one is returned from here.
            re, im = self.base.as_real_imag()

            r = (re ** 2 + im ** 2) ** S.Half
            t = C.atan2(im, re)

            rp, tp = r ** self.exp, t * self.exp

            return rp * C.cos(tp) + rp * C.sin(tp) * S.ImaginaryUnit
        else:
            return C.re(self) + S.ImaginaryUnit * C.im(self)
Пример #3
0
def check_convergence(numer, denom, n):
    """
    Returns (h, g, p) where
    -- h is:
        > 0 for convergence of rate 1/factorial(n)**h
        < 0 for divergence of rate factorial(n)**(-h)
        = 0 for geometric or polynomial convergence or divergence

    -- abs(g) is:
        > 1 for geometric convergence of rate 1/h**n
        < 1 for geometric divergence of rate h**n
        = 1 for polynomial convergence or divergence

        (g < 0 indicates an alternating series)

    -- p is:
        > 1 for polynomial convergence of rate 1/n**h
        <= 1 for polynomial divergence of rate n**(-h)

    """
    npol = C.Poly(numer, n)
    dpol = C.Poly(denom, n)
    p = npol.degree()
    q = dpol.degree()
    rate = q - p
    if rate:
        return rate, None, None
    constant = dpol.LC() / npol.LC()
    if abs(constant) != 1:
        return rate, constant, None
    if npol.degree() == dpol.degree() == 0:
        return rate, constant, 0
    pc = npol.all_coeffs()[1]
    qc = dpol.all_coeffs()[1]
    return rate, constant, qc - pc
Пример #4
0
def evalf_log(expr, prec, options):
    arg = expr.args[0]
    workprec = prec + 10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(C.log(C.abs(arg, evaluate=False), evaluate=False), prec,
                       options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = (mpf_cmp(xre, fzero) < 0)

    re = mpf_log(mpf_abs(xre), prec, round_nearest)
    size = fastlog(re)
    if prec - size > workprec:
        # We actually need to compute 1+x accurately, not x
        arg = C.Add(S.NegativeOne, arg, evaluate=False)
        xre, xim, xre_acc, xim_acc = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        re = mpf_log(mpf_add(xre, fone, prec2), prec, round_nearest)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
Пример #5
0
    def _eval_expand_complex(self, *args):
        if self.exp.is_Integer:
            exp = self.exp
            re, im = self.base.as_real_imag()
            if exp >= 0:
                base = re + S.ImaginaryUnit*im
            else:
                mag = re**2 + im**2
                base = re/mag - S.ImaginaryUnit*(im/mag)
                exp = -exp
            return (base**exp).expand()
        elif self.exp.is_Rational:
            # NOTE: This is not totally correct since for x**(p/q) with
            #       x being imaginary there are actually q roots, but
            #       only a single one is returned from here.
            re, im = self.base.as_real_imag()

            r = (re**2 + im**2)**S.Half
            t = C.atan2(im, re)

            rp, tp = r**self.exp, t*self.exp

            return rp*C.cos(tp) + rp*C.sin(tp)*S.ImaginaryUnit
        else:
            return C.re(self) + S.ImaginaryUnit*C.im(self)
Пример #6
0
def evalf_log(expr, prec, options):
    arg = expr.args[0]
    workprec = prec+10
    xre, xim, xacc, _ = evalf(arg, workprec, options)

    if xim:
        # XXX: use get_abs etc instead
        re = evalf_log(C.log(C.abs(arg, evaluate=False), evaluate=False), prec, options)
        im = mpf_atan2(xim, xre or fzero, prec)
        return re[0], im, re[2], prec

    imaginary_term = (mpf_cmp(xre, fzero) < 0)

    re = mpf_log(mpf_abs(xre), prec, round_nearest)
    size = fastlog(re)
    if prec - size > workprec:
        # We actually need to compute 1+x accurately, not x
        arg = C.Add(S.NegativeOne,arg,evaluate=False)
        xre, xim, xre_acc, xim_acc = evalf_add(arg, prec, options)
        prec2 = workprec - fastlog(xre)
        re = mpf_log(mpf_add(xre, fone, prec2), prec, round_nearest)

    re_acc = prec

    if imaginary_term:
        return re, mpf_pi(prec), re_acc, prec
    else:
        return re, None, re_acc, None
Пример #7
0
 def as_real_imag(self, deep=True):
     other = []
     coeff = S(1)
     for a in self.args:
         if a.is_real:
             coeff *= a
         else:
             other.append(a)
     m = Mul(*other)
     return (coeff*C.re(m), coeff*C.im(m))
Пример #8
0
 def as_real_imag(self, deep=True):
     other = []
     coeff = S(1)
     for a in self.args:
         if a.is_real:
             coeff *= a
         else:
             other.append(a)
     m = Mul(*other)
     return (coeff * C.re(m), coeff * C.im(m))
Пример #9
0
def get_integer_part(expr, no, options, return_ints=False):
    """
    With no = 1, computes ceiling(expr)
    With no = -1, computes floor(expr)

    Note: this function either gives the exact result or signals failure.
    """

    # The expression is likely less than 2^30 or so
    assumed_size = 30
    ire, iim, ire_acc, iim_acc = evalf(expr, assumed_size, options)

    # We now know the size, so we can calculate how much extra precision
    # (if any) is needed to get within the nearest integer
    if ire and iim:
        gap = max(fastlog(ire) - ire_acc, fastlog(iim) - iim_acc)
    elif ire:
        gap = fastlog(ire) - ire_acc
    elif iim:
        gap = fastlog(iim) - iim_acc
    else:
        # ... or maybe the expression was exactly zero
        return None, None, None, None

    margin = 10

    if gap >= -margin:
        ire, iim, ire_acc, iim_acc = evalf(expr, margin + assumed_size + gap,
                                           options)

    # We can now easily find the nearest integer, but to find floor/ceil, we
    # must also calculate whether the difference to the nearest integer is
    # positive or negative (which may fail if very close)
    def calc_part(expr, nexpr):
        nint = int(to_int(nexpr, round_nearest))
        expr = C.Add(expr, -nint, evaluate=False)
        x, _, x_acc, _ = evalf(expr, 10, options)
        check_target(expr, (x, None, x_acc, None), 3)
        nint += int(no * (mpf_cmp(x or fzero, fzero) == no))
        nint = from_int(nint)
        return nint, fastlog(nint) + 10

    re, im, re_acc, im_acc = None, None, None, None

    if ire:
        re, re_acc = calc_part(C.re(expr, evaluate=False), ire)
    if iim:
        im, im_acc = calc_part(C.im(expr, evaluate=False), iim)

    if return_ints:
        return int(to_int(re or fzero)), int(to_int(im or fzero))
    return re, im, re_acc, im_acc
Пример #10
0
 def as_real_imag(self, deep=True, **hints):
     other = []
     coeff = S(1)
     for a in self.args:
         if a.is_real:
             coeff *= a
         else:
             other.append(a)
     m = Mul(*other)
     if hints.get('ignore') == m:
         return None
     else:
         return (coeff*C.re(m), coeff*C.im(m))
Пример #11
0
def evalf_piecewise(expr, prec, options):
    if 'subs' in options:
        expr = expr.subs(options['subs'])
        del options['subs']
        if hasattr(expr, 'func'):
            return evalf(expr, prec, options)
        if type(expr) == float:
            return evalf(C.Real(expr), prec, options)
        if type(expr) == int:
            return evalf(C.Integer(expr), prec, options)

    # We still have undefined symbols
    raise NotImplementedError
Пример #12
0
def get_integer_part(expr, no, options, return_ints=False):
    """
    With no = 1, computes ceiling(expr)
    With no = -1, computes floor(expr)

    Note: this function either gives the exact result or signals failure.
    """

    # The expression is likely less than 2^30 or so
    assumed_size = 30
    ire, iim, ire_acc, iim_acc = evalf(expr, assumed_size, options)

    # We now know the size, so we can calculate how much extra precision
    # (if any) is needed to get within the nearest integer
    if ire and iim:
        gap = max(fastlog(ire)-ire_acc, fastlog(iim)-iim_acc)
    elif ire:
        gap = fastlog(ire)-ire_acc
    elif iim:
        gap = fastlog(iim)-iim_acc
    else:
        # ... or maybe the expression was exactly zero
        return None, None, None, None

    margin = 10

    if gap >= -margin:
        ire, iim, ire_acc, iim_acc = evalf(expr, margin+assumed_size+gap, options)

    # We can now easily find the nearest integer, but to find floor/ceil, we
    # must also calculate whether the difference to the nearest integer is
    # positive or negative (which may fail if very close)
    def calc_part(expr, nexpr):
        nint = int(to_int(nexpr, round_nearest))
        expr = C.Add(expr, -nint, evaluate=False)
        x, _, x_acc, _ = evalf(expr, 10, options)
        check_target(expr, (x, None, x_acc, None), 3)
        nint += int(no*(mpf_cmp(x or fzero, fzero) == no))
        nint = from_int(nint)
        return nint, fastlog(nint) + 10

    re, im, re_acc, im_acc = None, None, None, None

    if ire:
        re, re_acc = calc_part(C.re(expr, evaluate=False), ire)
    if iim:
        im, im_acc = calc_part(C.im(expr, evaluate=False), iim)

    if return_ints:
        return int(to_int(re or fzero)), int(to_int(im or fzero))
    return re, im, re_acc, im_acc
Пример #13
0
def evalf_sum(expr, prec, options):
    func = expr.function
    limits = expr.limits
    if len(limits) != 1 or not isinstance(limits[0], tuple) or \
        len(limits[0]) != 3:
        raise NotImplementedError
    prec2 = prec + 10
    try:
        n, a, b = limits[0]
        if b != S.Infinity or a != int(a):
            raise NotImplementedError
        # Use fast hypergeometric summation if possible
        v = hypsum(func, n, int(a), prec2)
        delta = prec - fastlog(v)
        if fastlog(v) < -10:
            v = hypsum(func, n, int(a), delta)
        return v, None, min(prec, delta), None
    except NotImplementedError:
        # Euler-Maclaurin summation for general series
        eps = C.Real(2.0)**(-prec)
        for i in range(1, 5):
            m = n = 2**i * prec
            s, err = expr.euler_maclaurin(m=m, n=n, eps=eps, \
                eval_integral=False)
            err = err.evalf()
            if err <= eps:
                break
        err = fastlog(evalf(abs(err), 20, options)[0])
        re, im, re_acc, im_acc = evalf(s, prec2, options)
        re_acc = max(re_acc, -err)
        im_acc = max(im_acc, -err)
        return re, im, re_acc, im_acc
Пример #14
0
    def extract_leading_order(self, *symbols):
        """
        Returns the leading term and it's order.

        Examples:

        >>> (x+1+1/x**5).extract_leading_order(x)
        ((1/x**5, O(1/x**5)),)
        >>> (1+x).extract_leading_order(x)
        ((1, O(1, x)),)
        >>> (x+x**2).extract_leading_order(x)
        ((x, O(x)),)
        """
        lst = []
        seq = [(f, C.Order(f, *symbols)) for f in self.args]
        for ef,of in seq:
            for e,o in lst:
                if o.contains(of) and o != of:
                    of = None
                    break
            if of is None:
                continue
            new_lst = [(ef,of)]
            for e,o in lst:
                if of.contains(o) and o != of:
                    continue
                new_lst.append((e,o))
            lst = new_lst
        return tuple(lst)
Пример #15
0
 def calc_part(expr, nexpr):
     nint = int(to_int(nexpr, round_nearest))
     expr = C.Add(expr, -nint, evaluate=False)
     x, _, x_acc, _ = evalf(expr, 10, options)
     check_target(expr, (x, None, x_acc, None), 3)
     nint += int(no * (mpf_cmp(x or fzero, fzero) == no))
     nint = from_int(nint)
     return nint, fastlog(nint) + 10
Пример #16
0
    def _eval_as_leading_term(self, x):
        """General method for the leading term"""
        arg = self.args[0].as_leading_term(x)

        if C.Order(1, x).contains(arg):
            return arg
        else:
            return self.func(arg)
Пример #17
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)
Пример #18
0
    def as_real_imag(self, deep=True, **hints):
        from sympy.core.symbol import symbols
        from sympy.polys.polytools import poly
        from sympy.core.function import expand_multinomial
        if self.exp.is_Integer:
            exp = self.exp
            re, im = self.base.as_real_imag(deep=deep)
            a, b = symbols('a, b', dummy=True)
            if exp >= 0:
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial(self.base**exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**exp) # a = re, b = im; expr = (a + b*I)**exp
            else:
                mag = re**2 + im**2
                re, im = re/mag, -im/mag
                if re.is_Number and im.is_Number:
                    # We can be more efficient in this case
                    expr = expand_multinomial((re + im*S.ImaginaryUnit)**-exp)
                    return expr.as_real_imag()

                expr = poly((a + b)**-exp)

            # Terms with even b powers will be real
            r = [i for i in expr.terms() if not i[0][1] % 2]
            re_part = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            # Terms odd b powers will be imaginary
            r = [i for i in expr.terms() if i[0][1] % 4 == 1]
            im_part1 = Add(*[cc*a**aa*b**bb for (aa, bb), cc in r])
            r = [i for i in expr.terms() if i[0][1] % 4 == 3]
            im_part3 = Add(*[cc*a**a*b**bb for (aa, bb), cc in r])

            return (re_part.subs({a: re, b: S.ImaginaryUnit*im}),
            im_part1.subs({a: re, b: im}) + im_part3.subs({a: re, b: -im}))

        elif self.exp.is_Rational:
            # NOTE: This is not totally correct since for x**(p/q) with
            #       x being imaginary there are actually q roots, but
            #       only a single one is returned from here.
            re, im = self.base.as_real_imag(deep=deep)

            r = (re**2 + im**2)**S.Half
            t = C.atan2(im, re)

            rp, tp = r**self.exp, t*self.exp

            return (rp*C.cos(tp), rp*C.sin(tp))
        else:

            if deep:
                hints['complex'] = False
                return (C.re(self.expand(deep, complex=False)),
                C.im(self. expand(deep, **hints)))
            else:
                return (C.re(self), C.im(self))
Пример #19
0
 def _eval_subs(self, old, new):
     if self==old: return new
     if isinstance(old, self.__class__) and self.base==old.base:
         coeff1,terms1 = self.exp.as_coeff_terms()
         coeff2,terms2 = old.exp.as_coeff_terms()
         if terms1==terms2: return new ** (coeff1/coeff2) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3*y)
     if old.func is C.exp:
         coeff1,terms1 = old.args[0].as_coeff_terms()
         coeff2,terms2 = (self.exp * C.log(self.base)).as_coeff_terms()
         if terms1==terms2: return new ** (coeff1/coeff2) # (x**(2*y)).subs(exp(3*y*log(x)),z) -> z**(2/3*y)
     return self.base._eval_subs(old, new) ** self.exp._eval_subs(old, new)
Пример #20
0
 def _eval_subs(self, old, new):
     if self==old: return new
     if isinstance(old, self.__class__) and self.base==old.base:
         coeff1,terms1 = self.exp.as_coeff_terms()
         coeff2,terms2 = old.exp.as_coeff_terms()
         if terms1==terms2: return new ** (coeff1/coeff2) # (x**(2*y)).subs(x**(3*y),z) -> z**(2/3*y)
     if old.func is C.exp:
         coeff1,terms1 = old.args[0].as_coeff_terms()
         coeff2,terms2 = (self.exp * C.log(self.base)).as_coeff_terms()
         if terms1==terms2: return new ** (coeff1/coeff2) # (x**(2*y)).subs(exp(3*y*log(x)),z) -> z**(2/3*y)
     return self.base._eval_subs(old, new) ** self.exp._eval_subs(old, new)
Пример #21
0
 def _eval_as_leading_term(self, x):
     coeff, factors = self.as_coeff_factors(x)
     has_unbounded = bool([f for f in self.args if f.is_unbounded])
     if has_unbounded:
         if isinstance(factors, Basic):
             factors = factors.args
         factors = [f for f in factors if not f.is_bounded]
     if coeff is not S.Zero:
         o = C.Order(x)
     else:
         o = C.Order(factors[0]*x,x)
     n = 1
     s = self.nseries(x, 0, n)
     while s.is_Order:
         n +=1
         s = self.nseries(x, 0, n)
     if s.is_Add:
         s = s.removeO()
     if s.is_Add:
         lst = s.extract_leading_order(x)
         return Add(*[e for (e,f) in lst])
     return s.as_leading_term(x)
Пример #22
0
    def eval(cls, *args):
        obj = Expr.__new__(cls, *args)
        #use dummy variables internally, just to be sure
        nargs = len(args) - 1

        expression = args[nargs]
        funargs = [C.Symbol(arg.name, dummy=True) for arg in args[:nargs]]
        #probably could use something like foldl here
        for arg, funarg in zip(args[:nargs], funargs):
            expression = expression.subs(arg, funarg)
        funargs.append(expression)
        obj._args = tuple(funargs)

        return obj
Пример #23
0
    def as_real_imag(self, deep=True):
        """Performs complex expansion on 'self' and returns a tuple
           containing collected both real and imaginary parts. This
           method can't be confused with re() and im() functions,
           which does not perform complex expansion at evaluation.

           However it is possible to expand both re() and im()
           functions and get exactly the same results as with
           a single call to this function.

           >>> from sympy import symbols, I

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

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

           >>> from sympy.abc import z, w

           >>> (z + w*I).as_real_imag()
           (-im(w) + re(z), im(z) + re(w))

        """
        return (C.re(self), C.im(self))
Пример #24
0
 def __new__(cls, num, prec=15):
     prec = mpmath.settings.dps_to_prec(prec)
     if isinstance(num, (int, long)):
         return Integer(num)
     if isinstance(num, (str, decimal.Decimal)):
         _mpf_ = mlib.from_str(str(num), prec, rnd)
     elif isinstance(num, tuple) and len(num) == 4:
         _mpf_ = num
     else:
         _mpf_ = mpmath.mpf(num)._mpf_
     if not num:
         return C.Zero()
     obj = Basic.__new__(cls)
     obj._mpf_ = _mpf_
     obj._prec = prec
     return obj
Пример #25
0
    def testIt(self):
        from basic import C, call_f

        class D(C):
            def f(self, x=10):
                return x+1

        d = D()
        c = C()

        self.assertEqual(c.f(), 20)
        self.assertEqual(c.f(3), 6)
        self.assertEqual(d.f(), 11)
        self.assertEqual(d.f(3), 4)
        self.assertEqual(call_f(c), 20)
        self.assertEqual(call_f(c, 4), 8)
        self.assertEqual(call_f(d), 11)
        self.assertEqual(call_f(d, 3), 4)
Пример #26
0
    def __new__(cls, *args, **assumptions):
        if assumptions.get('evaluate') is False:
            return Basic.__new__(cls, *map(_sympify, args), **assumptions)
        if len(args)==0:
            return cls.identity()
        if len(args)==1:
            return _sympify(args[0])
        c_part, nc_part, order_symbols = cls.flatten(map(_sympify, args))
        if len(c_part) + len(nc_part) <= 1:
            if c_part: obj = c_part[0]
            elif nc_part: obj = nc_part[0]
            else: obj = cls.identity()
        else:
            obj = Basic.__new__(cls, *(c_part + nc_part), **assumptions)
            obj.is_commutative = not nc_part

        if order_symbols is not None:
            obj = C.Order(obj, *order_symbols)
        return obj
Пример #27
0
def _create_evalf_table():
    global evalf_table
    evalf_table = {
    C.Symbol : evalf_symbol,
    C.Dummy : evalf_symbol,
    C.Real : lambda x, prec, options: (x._mpf_, None, prec, None),
    C.Rational : lambda x, prec, options: (from_rational(x.p, x.q, prec), None, prec, None),
    C.Integer : lambda x, prec, options: (from_int(x.p, prec), None, prec, None),
    C.Zero : lambda x, prec, options: (None, None, prec, None),
    C.One : lambda x, prec, options: (fone, None, prec, None),
    C.Half : lambda x, prec, options: (fhalf, None, prec, None),
    C.Pi : lambda x, prec, options: (mpf_pi(prec), None, prec, None),
    C.Exp1 : lambda x, prec, options: (mpf_e(prec), None, prec, None),
    C.ImaginaryUnit : lambda x, prec, options: (None, fone, None, prec),
    C.NegativeOne : lambda x, prec, options: (fnone, None, prec, None),

    C.exp : lambda x, prec, options: evalf_pow(C.Pow(S.Exp1, x.args[0],
        evaluate=False), prec, options),

    C.cos : evalf_trig,
    C.sin : evalf_trig,

    C.Add : evalf_add,
    C.Mul : evalf_mul,
    C.Pow : evalf_pow,

    C.log : evalf_log,
    C.atan : evalf_atan,
    C.abs : evalf_abs,

    C.re : evalf_re,
    C.im : evalf_im,
    C.floor : evalf_floor,
    C.ceiling : evalf_ceiling,

    C.Integral : evalf_integral,
    C.Sum : evalf_sum,
    C.Piecewise : evalf_piecewise,

    C.bernoulli : evalf_bernoulli,
    }
Пример #28
0
 def _eval_expand_complex(self, *args):
     return C.re(self) + C.im(self)*S.ImaginaryUnit
Пример #29
0
def do_integral(expr, prec, options):
    func = expr.args[0]
    x, (xlow, xhigh) = expr.args[1][0]
    orig = mp.prec

    oldmaxprec = options.get('maxprec', DEFAULT_MAXPREC)
    options['maxprec'] = min(oldmaxprec, 2 * prec)

    try:
        mp.prec = prec + 5
        xlow = as_mpmath(xlow, prec + 15, options)
        xhigh = as_mpmath(xhigh, prec + 15, options)

        # Integration is like summation, and we can phone home from
        # the integrand function to update accuracy summation style
        # Note that this accuracy is inaccurate, since it fails
        # to account for the variable quadrature weights,
        # but it is better than nothing

        have_part = [False, False]
        max_real_term = [MINUS_INF]
        max_imag_term = [MINUS_INF]

        def f(t):
            re, im, re_acc, im_acc = evalf(func, mp.prec, {'subs': {x: t}})

            have_part[0] = re or have_part[0]
            have_part[1] = im or have_part[1]

            max_real_term[0] = max(max_real_term[0], fastlog(re))
            max_imag_term[0] = max(max_imag_term[0], fastlog(im))

            if im:
                return mpc(re or fzero, im)
            return mpf(re or fzero)

        if options.get('quad') == 'osc':
            A = C.Wild('A', exclude=[x])
            B = C.Wild('B', exclude=[x])
            D = C.Wild('D')
            m = func.match(C.cos(A * x + B) * D)
            if not m:
                m = func.match(C.sin(A * x + B) * D)
            if not m:
                raise ValueError(
                    "An integrand of the form sin(A*x+B)*f(x) "
                    "or cos(A*x+B)*f(x) is required for oscillatory quadrature"
                )
            period = as_mpmath(2 * S.Pi / m[A], prec + 15, options)
            result = quadosc(f, [xlow, xhigh], period=period)
            # XXX: quadosc does not do error detection yet
            quadrature_error = MINUS_INF
        else:
            result, quadrature_error = quadts(f, [xlow, xhigh], error=1)
            quadrature_error = fastlog(quadrature_error._mpf_)

    finally:
        options['maxprec'] = oldmaxprec
        mp.prec = orig

    if have_part[0]:
        re = result.real._mpf_
        if re == fzero:
            re = mpf_shift(fone,
                           min(-prec, -max_real_term[0], -quadrature_error))
            re_acc = -1
        else:
            re_acc = -max(max_real_term[0] - fastlog(re) - prec,
                          quadrature_error)
    else:
        re, re_acc = None, None

    if have_part[1]:
        im = result.imag._mpf_
        if im == fzero:
            im = mpf_shift(fone,
                           min(-prec, -max_imag_term[0], -quadrature_error))
            im_acc = -1
        else:
            im_acc = -max(max_imag_term[0] - fastlog(im) - prec,
                          quadrature_error)
    else:
        im, im_acc = None, None

    result = re, im, re_acc, im_acc
    return result
Пример #30
0
 def as_real_imag(self, deep=True):
     return (C.re(self), C.im(self))
Пример #31
0
 def _eval_expand_complex(self, *args):
     func = self.func(*[a._eval_expand_complex(*args) for a in self.args])
     return C.re(func) + S.ImaginaryUnit * C.im(func)
Пример #32
0
def do_integral(expr, prec, options):
    func = expr.args[0]
    x, (xlow, xhigh) = expr.args[1][0]
    orig = mp.prec

    oldmaxprec = options.get('maxprec', DEFAULT_MAXPREC)
    options['maxprec'] = min(oldmaxprec, 2*prec)

    try:
        mp.prec = prec+5
        xlow = as_mpmath(xlow, prec+15, options)
        xhigh = as_mpmath(xhigh, prec+15, options)

        # Integration is like summation, and we can phone home from
        # the integrand function to update accuracy summation style
        # Note that this accuracy is inaccurate, since it fails
        # to account for the variable quadrature weights,
        # but it is better than nothing

        have_part = [False, False]
        max_real_term = [MINUS_INF]
        max_imag_term = [MINUS_INF]

        def f(t):
            re, im, re_acc, im_acc = evalf(func, mp.prec, {'subs':{x:t}})

            have_part[0] = re or have_part[0]
            have_part[1] = im or have_part[1]

            max_real_term[0] = max(max_real_term[0], fastlog(re))
            max_imag_term[0] = max(max_imag_term[0], fastlog(im))

            if im:
                return mpc(re or fzero, im)
            return mpf(re or fzero)

        if options.get('quad') == 'osc':
            A = C.Wild('A', exclude=[x])
            B = C.Wild('B', exclude=[x])
            D = C.Wild('D')
            m = func.match(C.cos(A*x+B)*D)
            if not m:
                m = func.match(C.sin(A*x+B)*D)
            if not m:
                raise ValueError("An integrand of the form sin(A*x+B)*f(x) "
                  "or cos(A*x+B)*f(x) is required for oscillatory quadrature")
            period = as_mpmath(2*S.Pi/m[A], prec+15, options)
            result = quadosc(f, [xlow, xhigh], period=period)
            # XXX: quadosc does not do error detection yet
            quadrature_error = MINUS_INF
        else:
            result, quadrature_error = quadts(f, [xlow, xhigh], error=1)
            quadrature_error = fastlog(quadrature_error._mpf_)

    finally:
        options['maxprec'] = oldmaxprec
        mp.prec = orig

    if have_part[0]:
        re = result.real._mpf_
        if re == fzero:
            re = mpf_shift(fone, min(-prec,-max_real_term[0],-quadrature_error))
            re_acc = -1
        else:
            re_acc = -max(max_real_term[0]-fastlog(re)-prec, quadrature_error)
    else:
        re, re_acc = None, None

    if have_part[1]:
        im = result.imag._mpf_
        if im == fzero:
            im = mpf_shift(fone, min(-prec,-max_imag_term[0],-quadrature_error))
            im_acc = -1
        else:
            im_acc = -max(max_imag_term[0]-fastlog(im)-prec, quadrature_error)
    else:
        im, im_acc = None, None

    result = re, im, re_acc, im_acc
    return result
Пример #33
0
 def __abs__(self):
     return C.abs(self)
Пример #34
0
 def _eval_expand_complex(self, *args):
     func = self.func(*[ a._eval_expand_complex(*args) for a in self.args ])
     return C.re(func) + S.ImaginaryUnit * C.im(func)
Пример #35
0
 def _eval_as_leading_term(self, x):
     if not self.exp.has(x):
         return self.base.as_leading_term(x) ** self.exp
     return C.exp(self.exp * C.log(self.base)).as_leading_term(x)
Пример #36
0
 def __lt__(self, other):
     dif = self - other
     if dif.is_negative != dif.is_nonnegative:
         return dif.is_negative
     return C.StrictInequality(self, other)
Пример #37
0
 def _eval_expand_complex(self, deep=True, **hints):
     if deep:
         func = self.func(*[ a.expand(deep, **hints) for a in self.args ])
     else:
         func = self.func(*self.args)
     return C.re(func) + S.ImaginaryUnit * C.im(func)
Пример #38
0
 def fdiff(self, *indices):
     # FIXME FApply -> ?
     return C.FApply(C.FDerivative(*indices), self)
Пример #39
0
 def __gt__(self, other):
     dif = self - other
     if dif.is_positive != dif.is_nonpositive:
         return dif.is_positive
     return C.StrictInequality(other, self)
Пример #40
0
 def __le__(self, other):
     dif = self - other
     if dif.is_nonpositive != dif.is_positive:
         return dif.is_nonpositive
     return C.Inequality(self, other)
Пример #41
0
 def _eval_expand_complex(self, deep=True, **hints):
     if deep:
         func = self.func(*[a.expand(deep, **hints) for a in self.args])
     else:
         func = self.func(*self.args)
     return C.re(func) + S.ImaginaryUnit * C.im(func)
Пример #42
0
 def __ge__(self, other):
     dif = self - other
     if dif.is_nonnegative != dif.is_negative:
         return dif.is_nonnegative
     return C.Inequality(other, self)
Пример #43
0
 def _eval_power(self, exp):
     return C.exp(exp)
Пример #44
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_terms()
            if c.is_Mul:
                c_coeff, c_terms = c.as_coeff_terms()
                if c_terms == self_terms:
                    new_coeff = self_coeff.extract_additively(c_coeff)
                    if new_coeff != None:
                        return new_coeff * C.Mul(*self_terms)
            elif c == self_terms:
                new_coeff = self_coeff.extract_additively(1)
                if new_coeff != None:
                    return new_coeff * C.Mul(*self_terms)
Пример #45
0
 def _eval_derivative(self, s):
     dbase = self.base.diff(s)
     dexp = self.exp.diff(s)
     return self * (dexp * C.log(self.base) + dbase * self.exp / self.base)
Пример #46
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 C.Add(*newargs)
        elif self.is_Mul:
            for i in xrange(len(self.args)):
                newargs = list(self.args)
                del (newargs[i])
                tmp = C.Mul(*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)
Пример #47
0
 def __abs__(self):
     return C.abs(self)
Пример #48
0
 def _eval_expand_complex(self, deep=True, **hints):
         return C.re(self) + C.im(self)*S.ImaginaryUnit