Пример #1
0
    def _eval_expand_log(self, deep=True, **hints):
        from sympy.concrete import Sum, Product
        force = hints.get('force', False)
        factor = hints.get('factor', False)
        if (len(self.args) == 2):
            return expand_log(self.func(*self.args), deep=deep, force=force)
        arg = self.args[0]
        if arg.is_Integer:
            # remove perfect powers
            p = perfect_power(arg)
            logarg = None
            coeff = 1
            if p is not False:
                arg, coeff = p
                logarg = self.func(arg)
            # expand as product of its prime factors if factor=True
            if factor:
                p = factorint(arg)
                if arg not in p.keys():
                    logarg = sum(n * log(val) for val, n in p.items())
            if logarg is not None:
                return coeff * logarg
        elif arg.is_Rational:
            return log(arg.p) - log(arg.q)
        elif arg.is_Mul:
            expr = []
            nonpos = []
            for x in arg.args:
                if force or x.is_positive or x.is_polar:
                    a = self.func(x)
                    if isinstance(a, log):
                        expr.append(self.func(x)._eval_expand_log(**hints))
                    else:
                        expr.append(a)
                elif x.is_negative:
                    a = self.func(-x)
                    expr.append(a)
                    nonpos.append(S.NegativeOne)
                else:
                    nonpos.append(x)
            return Add(*expr) + log(Mul(*nonpos))
        elif arg.is_Pow or isinstance(arg, exp):
            if force or (
                    arg.exp.is_extended_real and
                (arg.base.is_positive or
                 ((arg.exp + 1).is_positive and
                  (arg.exp - 1).is_nonpositive))) or arg.base.is_polar:
                b = arg.base
                e = arg.exp
                a = self.func(b)
                if isinstance(a, log):
                    return unpolarify(e) * a._eval_expand_log(**hints)
                else:
                    return unpolarify(e) * a
        elif isinstance(arg, Product):
            if force or arg.function.is_positive:
                return Sum(log(arg.function), *arg.limits)

        return self.func(arg)
Пример #2
0
def test_expint():
    """ Test various exponential integrals. """
    from sympy.core.symbol import Symbol
    from sympy.functions.elementary.complexes import unpolarify
    from sympy.functions.elementary.hyperbolic import sinh
    from sympy.functions.special.error_functions import (Chi, Ci, Ei, Shi, Si,
                                                         expint)
    assert simplify(
        unpolarify(
            integrate(exp(-z * x) / x**y, (x, 1, oo),
                      meijerg=True,
                      conds='none').rewrite(expint).expand(
                          func=True))) == expint(y, z)

    assert integrate(exp(-z*x)/x, (x, 1, oo), meijerg=True,
                     conds='none').rewrite(expint).expand() == \
        expint(1, z)
    assert integrate(exp(-z*x)/x**2, (x, 1, oo), meijerg=True,
                     conds='none').rewrite(expint).expand() == \
        expint(2, z).rewrite(Ei).rewrite(expint)
    assert integrate(exp(-z*x)/x**3, (x, 1, oo), meijerg=True,
                     conds='none').rewrite(expint).expand() == \
        expint(3, z).rewrite(Ei).rewrite(expint).expand()

    t = Symbol('t', positive=True)
    assert integrate(-cos(x) / x, (x, t, oo), meijerg=True).expand() == Ci(t)
    assert integrate(-sin(x)/x, (x, t, oo), meijerg=True).expand() == \
        Si(t) - pi/2
    assert integrate(sin(x) / x, (x, 0, z), meijerg=True) == Si(z)
    assert integrate(sinh(x) / x, (x, 0, z), meijerg=True) == Shi(z)
    assert integrate(exp(-x)/x, x, meijerg=True).expand().rewrite(expint) == \
        I*pi - expint(1, x)
    assert integrate(exp(-x)/x**2, x, meijerg=True).rewrite(expint).expand() \
        == expint(1, x) - exp(-x)/x - I*pi

    u = Symbol('u', polar=True)
    assert integrate(cos(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
        == Ci(u)
    assert integrate(cosh(u)/u, u, meijerg=True).expand().as_independent(u)[1] \
        == Chi(u)

    assert integrate(
        expint(1, x), x,
        meijerg=True).rewrite(expint).expand() == x * expint(1, x) - exp(-x)
    assert integrate(expint(2, x), x, meijerg=True
            ).rewrite(expint).expand() == \
        -x**2*expint(1, x)/2 + x*exp(-x)/2 - exp(-x)/2
    assert simplify(unpolarify(integrate(expint(y, x), x,
                 meijerg=True).rewrite(expint).expand(func=True))) == \
        -expint(y + 1, x)

    assert integrate(Si(x), x, meijerg=True) == x * Si(x) + cos(x)
    assert integrate(Ci(u), u, meijerg=True).expand() == u * Ci(u) - sin(u)
    assert integrate(Shi(x), x, meijerg=True) == x * Shi(x) - cosh(x)
    assert integrate(Chi(u), u, meijerg=True).expand() == u * Chi(u) - sinh(u)

    assert integrate(Si(x) * exp(-x), (x, 0, oo), meijerg=True) == pi / 4
    assert integrate(expint(1, x) * sin(x), (x, 0, oo),
                     meijerg=True) == log(2) / 2
Пример #3
0
    def _eval_expand_func(self, **hints):
        from sympy.polys.polytools import Poly
        z, s, a = self.args
        if z == 1:
            return zeta(s, a)
        if s.is_Integer and s <= 0:
            t = Dummy('t')
            p = Poly((t + a)**(-s), t)
            start = 1/(1 - t)
            res = S.Zero
            for c in reversed(p.all_coeffs()):
                res += c*start
                start = t*start.diff(t)
            return res.subs(t, z)

        if a.is_Rational:
            # See section 18 of
            #   Kelly B. Roach.  Hypergeometric Function Representations.
            #   In: Proceedings of the 1997 International Symposium on Symbolic and
            #   Algebraic Computation, pages 205-211, New York, 1997. ACM.
            # TODO should something be polarified here?
            add = S.Zero
            mul = S.One
            # First reduce a to the interaval (0, 1]
            if a > 1:
                n = floor(a)
                if n == a:
                    n -= 1
                a -= n
                mul = z**(-n)
                add = Add(*[-z**(k - n)/(a + k)**s for k in range(n)])
            elif a <= 0:
                n = floor(-a) + 1
                a += n
                mul = z**n
                add = Add(*[z**(n - 1 - k)/(a - k - 1)**s for k in range(n)])

            m, n = S([a.p, a.q])
            zet = exp_polar(2*pi*I/n)
            root = z**(1/n)
            return add + mul*n**(s - 1)*Add(
                *[polylog(s, zet**k*root)._eval_expand_func(**hints)
                  / (unpolarify(zet)**k*root)**m for k in range(n)])

        # TODO use minpoly instead of ad-hoc methods when issue 5888 is fixed
        if isinstance(z, exp) and (z.args[0]/(pi*I)).is_Rational or z in [-1, I, -I]:
            # TODO reference?
            if z == -1:
                p, q = S([1, 2])
            elif z == I:
                p, q = S([1, 4])
            elif z == -I:
                p, q = S([-1, 4])
            else:
                arg = z.args[0]/(2*pi*I)
                p, q = S([arg.p, arg.q])
            return Add(*[exp(2*pi*I*k*p/q)/q**s*zeta(s, (k + a)/q)
                         for k in range(q)])

        return lerchphi(z, s, a)
Пример #4
0
 def eval(cls, ap, bq, z):
     from sympy.functions.elementary.complexes import unpolarify
     if len(ap) <= len(bq) or (len(ap) == len(bq) + 1 and
                               (Abs(z) <= 1) == True):
         nz = unpolarify(z)
         if z != nz:
             return hyper(ap, bq, nz)
Пример #5
0
def can_do_meijer(a1, a2, b1, b2, numeric=True):
    """
    This helper function tries to hyperexpand() the meijer g-function
    corresponding to the parameters a1, a2, b1, b2.
    It returns False if this expansion still contains g-functions.
    If numeric is True, it also tests the so-obtained formula numerically
    (at random values) and returns False if the test fails.
    Else it returns True.
    """
    from sympy.core.function import expand
    from sympy.functions.elementary.complexes import unpolarify
    r = hyperexpand(meijerg(a1, a2, b1, b2, z))
    if r.has(meijerg):
        return False
    # NOTE hyperexpand() returns a truly branched function, whereas numerical
    #      evaluation only works on the main branch. Since we are evaluating on
    #      the main branch, this should not be a problem, but expressions like
    #      exp_polar(I*pi/2*x)**a are evaluated incorrectly. We thus have to get
    #      rid of them. The expand heuristically does this...
    r = unpolarify(expand(r, force=True, power_base=True, power_exp=False,
                          mul=False, log=False, multinomial=False, basic=False))

    if not numeric:
        return True

    repl = {}
    for n, ai in enumerate(meijerg(a1, a2, b1, b2, z).free_symbols - {z}):
        repl[ai] = randcplx(n)
    return tn(meijerg(a1, a2, b1, b2, z).subs(repl), r.subs(repl), z)
Пример #6
0
    def eval(cls, a, x):
        # For lack of a better place, we use this one to extract branching
        # information. The following can be
        # found in the literature (c/f references given above), albeit scattered:
        # 1) For fixed x != 0, lowergamma(s, x) is an entire function of s
        # 2) For fixed positive integers s, lowergamma(s, x) is an entire
        #    function of x.
        # 3) For fixed non-positive integers s,
        #    lowergamma(s, exp(I*2*pi*n)*x) =
        #              2*pi*I*n*(-1)**(-s)/factorial(-s) + lowergamma(s, x)
        #    (this follows from lowergamma(s, x).diff(x) = x**(s-1)*exp(-x)).
        # 4) For fixed non-integral s,
        #    lowergamma(s, x) = x**s*gamma(s)*lowergamma_unbranched(s, x),
        #    where lowergamma_unbranched(s, x) is an entire function (in fact
        #    of both s and x), i.e.
        #    lowergamma(s, exp(2*I*pi*n)*x) = exp(2*pi*I*n*a)*lowergamma(a, x)
        if x is S.Zero:
            return S.Zero
        nx, n = x.extract_branch_factor()
        if a.is_integer and a.is_positive:
            nx = unpolarify(x)
            if nx != x:
                return lowergamma(a, nx)
        elif a.is_integer and a.is_nonpositive:
            if n != 0:
                return 2 * pi * I * n * S.NegativeOne**(
                    -a) / factorial(-a) + lowergamma(a, nx)
        elif n != 0:
            return exp(2 * pi * I * n * a) * lowergamma(a, nx)

        # Special values.
        if a.is_Number:
            if a is S.One:
                return S.One - exp(-x)
            elif a is S.Half:
                return sqrt(pi) * erf(sqrt(x))
            elif a.is_Integer or (2 * a).is_Integer:
                b = a - 1
                if b.is_positive:
                    if a.is_integer:
                        return factorial(b) - exp(-x) * factorial(b) * Add(
                            *[x**k / factorial(k) for k in range(a)])
                    else:
                        return gamma(a) * (
                            lowergamma(S.Half, x) / sqrt(pi) - exp(-x) * Add(*[
                                x**(k - S.Half) / gamma(S.Half + k)
                                for k in range(1, a + S.Half)
                            ]))

                if not a.is_Integer:
                    return S.NegativeOne**(S.Half - a) * pi * erf(
                        sqrt(x)) / gamma(1 - a) + exp(-x) * Add(*[
                            x**(k + a - 1) * gamma(a) / gamma(a + k)
                            for k in range(1,
                                           Rational(3, 2) - a)
                        ])

        if x.is_zero:
            return S.Zero
Пример #7
0
 def repl(nu, z):
     if (nu % 1) == S(1)/2:
         return simplify(trigsimp(unpolarify(
                 fro(nu, z0).rewrite(besselj).rewrite(jn).expand(
                     func=True)).subs(z0, z)))
     elif nu.is_Integer and nu > 1:
         return fro(nu, z).expand(func=True)
     return fro(nu, z)
 def repl(nu, z):
     if (nu % 1) == S(1)/2:
         return exptrigsimp(trigsimp(unpolarify(
                 fro(nu, z0).rewrite(besselj).rewrite(jn).expand(
                     func=True)).subs(z0, z)))
     elif nu.is_Integer and nu > 1:
         return fro(nu, z).expand(func=True)
     return fro(nu, z)
Пример #9
0
    def eval(cls, n, z):
        n, z = map(sympify, (n, z))

        if n.is_integer:
            if n.is_nonnegative:
                nz = unpolarify(z)
                if z != nz:
                    return polygamma(n, nz)

            if n.is_positive:
                if z is S.Half:
                    return S.NegativeOne**(n + 1) * factorial(n) * (
                        2**(n + 1) - 1) * zeta(n + 1)

            if n is S.NegativeOne:
                return loggamma(z)
            else:
                if z.is_Number:
                    if z is S.NaN:
                        return S.NaN
                    elif z is S.Infinity:
                        if n.is_Number:
                            if n.is_zero:
                                return S.Infinity
                            else:
                                return S.Zero
                        if n.is_zero:
                            return S.Infinity
                    elif z.is_Integer:
                        if z.is_nonpositive:
                            return S.ComplexInfinity
                        else:
                            if n.is_zero:
                                return harmonic(z - 1, 1) - S.EulerGamma
                            elif n.is_odd:
                                return S.NegativeOne**(
                                    n + 1) * factorial(n) * zeta(n + 1, z)

        if n.is_zero:
            if z is S.NaN:
                return S.NaN
            elif z.is_Rational:

                p, q = z.as_numer_denom()

                # only expand for small denominators to avoid creating long expressions
                if q <= 5:
                    return expand_func(polygamma(S.Zero, z, evaluate=False))

            elif z in (S.Infinity, S.NegativeInfinity):
                return S.Infinity
            else:
                t = z.extract_multiplicatively(S.ImaginaryUnit)
                if t in (S.Infinity, S.NegativeInfinity):
                    return S.Infinity
Пример #10
0
 def fdiff(self, argindex=2):
     from sympy.functions.special.hyper import meijerg
     if argindex == 2:
         a, z = self.args
         return -exp(-unpolarify(z)) * z**(a - 1)
     elif argindex == 1:
         a, z = self.args
         return uppergamma(a, z) * log(z) + meijerg([], [1, 1], [0, 0, a],
                                                    [], z)
     else:
         raise ArgumentIndexError(self, argindex)
Пример #11
0
def test_expint():
    from sympy.functions.elementary.miscellaneous import Max
    from sympy.functions.special.error_functions import (Ci, E1, Ei, Si)
    from sympy.functions.special.zeta_functions import lerchphi
    from sympy.simplify.simplify import simplify
    aneg = Symbol('a', negative=True)
    u = Symbol('u', polar=True)

    assert mellin_transform(E1(x), x, s) == (gamma(s)/s, (0, oo), True)
    assert inverse_mellin_transform(gamma(s)/s, s, x,
              (0, oo)).rewrite(expint).expand() == E1(x)
    assert mellin_transform(expint(a, x), x, s) == \
        (gamma(s)/(a + s - 1), (Max(1 - re(a), 0), oo), True)
    # XXX IMT has hickups with complicated strips ...
    assert simplify(unpolarify(
                    inverse_mellin_transform(gamma(s)/(aneg + s - 1), s, x,
                  (1 - aneg, oo)).rewrite(expint).expand(func=True))) == \
        expint(aneg, x)

    assert mellin_transform(Si(x), x, s) == \
        (-2**s*sqrt(pi)*gamma(s/2 + S.Half)/(
        2*s*gamma(-s/2 + 1)), (-1, 0), True)
    assert inverse_mellin_transform(-2**s*sqrt(pi)*gamma((s + 1)/2)
                                    /(2*s*gamma(-s/2 + 1)), s, x, (-1, 0)) \
        == Si(x)

    assert mellin_transform(Ci(sqrt(x)), x, s) == \
        (-2**(2*s - 1)*sqrt(pi)*gamma(s)/(s*gamma(-s + S.Half)), (0, 1), True)
    assert inverse_mellin_transform(
        -4**s*sqrt(pi)*gamma(s)/(2*s*gamma(-s + S.Half)),
        s, u, (0, 1)).expand() == Ci(sqrt(u))

    # TODO LT of Si, Shi, Chi is a mess ...
    assert laplace_transform(Ci(x), x, s) == (-log(1 + s**2)/2/s, 0, True)
    assert laplace_transform(expint(a, x), x, s) == \
        (lerchphi(s*exp_polar(I*pi), 1, a), 0, re(a) > S.Zero)
    assert laplace_transform(expint(1, x), x, s) == (log(s + 1)/s, 0, True)
    assert laplace_transform(expint(2, x), x, s) == \
        ((s - log(s + 1))/s**2, 0, True)

    assert inverse_laplace_transform(-log(1 + s**2)/2/s, s, u).expand() == \
        Heaviside(u)*Ci(u)
    assert inverse_laplace_transform(log(s + 1)/s, s, x).rewrite(expint) == \
        Heaviside(x)*E1(x)
    assert inverse_laplace_transform((s - log(s + 1))/s**2, s,
                x).rewrite(expint).expand() == \
        (expint(2, x)*Heaviside(x)).rewrite(Ei).rewrite(expint).expand()
Пример #12
0
    def eval(cls, s, z):
        s, z = sympify((s, z))
        if z is S.One:
            return zeta(s)
        elif z is S.NegativeOne:
            return -dirichlet_eta(s)
        elif z is S.Zero:
            return S.Zero
        elif s == 2:
            if z == S.Half:
                return pi**2/12 - log(2)**2/2
            elif z == 2:
                return pi**2/4 - I*pi*log(2)
            elif z == -(sqrt(5) - 1)/2:
                return -pi**2/15 + log((sqrt(5)-1)/2)**2/2
            elif z == -(sqrt(5) + 1)/2:
                return -pi**2/10 - log((sqrt(5)+1)/2)**2
            elif z == (3 - sqrt(5))/2:
                return pi**2/15 - log((sqrt(5)-1)/2)**2
            elif z == (sqrt(5) - 1)/2:
                return pi**2/10 - log((sqrt(5)-1)/2)**2

        if z.is_zero:
            return S.Zero

        # Make an effort to determine if z is 1 to avoid replacing into
        # expression with singularity
        zone = z.equals(S.One)

        if zone:
            return zeta(s)
        elif zone is False:
            # For s = 0 or -1 use explicit formulas to evaluate, but
            # automatically expanding polylog(1, z) to -log(1-z) seems
            # undesirable for summation methods based on hypergeometric
            # functions
            if s is S.Zero:
                return z/(1 - z)
            elif s is S.NegativeOne:
                return z/(1 - z)**2
            if s.is_zero:
                return z/(1 - z)

        # polylog is branched, but not over the unit disk
        if z.has(exp_polar, polar_lift) and (zone or (Abs(z) <= S.One) == True):
            return cls(s, unpolarify(z))
Пример #13
0
def _prep_tuple(v):
    """
    Turn an iterable argument *v* into a tuple and unpolarify, since both
    hypergeometric and meijer g-functions are unbranched in their parameters.

    Examples
    ========

    >>> from sympy.functions.special.hyper import _prep_tuple
    >>> _prep_tuple([1, 2, 3])
    (1, 2, 3)
    >>> _prep_tuple((4, 5))
    (4, 5)
    >>> _prep_tuple((7, 8, 9))
    (7, 8, 9)

    """
    return TupleArg(*[unpolarify(x) for x in v])
Пример #14
0
def test_unpolarify():
    from sympy.functions.elementary.complexes import (polar_lift,
                                                      principal_branch,
                                                      unpolarify)
    from sympy.core.relational import Ne
    from sympy.functions.elementary.hyperbolic import tanh
    from sympy.functions.special.error_functions import erf
    from sympy.functions.special.gamma_functions import (gamma, uppergamma)
    from sympy.abc import x
    p = exp_polar(7 * I) + 1
    u = exp(7 * I) + 1

    assert unpolarify(1) == 1
    assert unpolarify(p) == u
    assert unpolarify(p**2) == u**2
    assert unpolarify(p**x) == p**x
    assert unpolarify(p * x) == u * x
    assert unpolarify(p + x) == u + x
    assert unpolarify(sqrt(sin(p))) == sqrt(sin(u))

    # Test reduction to principal branch 2*pi.
    t = principal_branch(x, 2 * pi)
    assert unpolarify(t) == x
    assert unpolarify(sqrt(t)) == sqrt(t)

    # Test exponents_only.
    assert unpolarify(p**p, exponents_only=True) == p**u
    assert unpolarify(uppergamma(x, p**p)) == uppergamma(x, p**u)

    # Test functions.
    assert unpolarify(sin(p)) == sin(u)
    assert unpolarify(tanh(p)) == tanh(u)
    assert unpolarify(gamma(p)) == gamma(u)
    assert unpolarify(erf(p)) == erf(u)
    assert unpolarify(uppergamma(x, p)) == uppergamma(x, p)

    assert unpolarify(uppergamma(sin(p), sin(p + exp_polar(0)))) == \
        uppergamma(sin(u), sin(u + 1))
    assert unpolarify(uppergamma(polar_lift(0), 2*exp_polar(0))) == \
        uppergamma(0, 2)

    assert unpolarify(Eq(p, 0)) == Eq(u, 0)
    assert unpolarify(Ne(p, 0)) == Ne(u, 0)
    assert unpolarify(polar_lift(x) > 0) == (x > 0)

    # Test bools
    assert unpolarify(True) is True
Пример #15
0
    def eval(cls, arg, base=None):
        from sympy.functions.elementary.complexes import unpolarify
        from sympy.calculus import AccumBounds
        from sympy.functions.elementary.complexes import Abs

        arg = sympify(arg)

        if base is not None:
            base = sympify(base)
            if base == 1:
                if arg == 1:
                    return S.NaN
                else:
                    return S.ComplexInfinity
            try:
                # handle extraction of powers of the base now
                # or else expand_log in Mul would have to handle this
                n = multiplicity(base, arg)
                if n:
                    return n + log(arg / base**n) / log(base)
                else:
                    return log(arg) / log(base)
            except ValueError:
                pass
            if base is not S.Exp1:
                return cls(arg) / cls(base)
            else:
                return cls(arg)

        if arg.is_Number:
            if arg.is_zero:
                return S.ComplexInfinity
            elif arg is S.One:
                return S.Zero
            elif arg is S.Infinity:
                return S.Infinity
            elif arg is S.NegativeInfinity:
                return S.Infinity
            elif arg is S.NaN:
                return S.NaN
            elif arg.is_Rational and arg.p == 1:
                return -cls(arg.q)

        if arg.is_Pow and arg.base is S.Exp1 and arg.exp.is_extended_real:
            return arg.exp
        I = S.ImaginaryUnit
        if isinstance(arg, exp) and arg.exp.is_extended_real:
            return arg.exp
        elif isinstance(arg, exp) and arg.exp.is_number:
            r_, i_ = match_real_imag(arg.exp)
            if i_ and i_.is_comparable:
                i_ %= 2 * S.Pi
                if i_ > S.Pi:
                    i_ -= 2 * S.Pi
                return r_ + expand_mul(i_ * I, deep=False)
        elif isinstance(arg, exp_polar):
            return unpolarify(arg.exp)
        elif isinstance(arg, AccumBounds):
            if arg.min.is_positive:
                return AccumBounds(log(arg.min), log(arg.max))
            else:
                return
        elif isinstance(arg, SetExpr):
            return arg._eval_func(cls)

        if arg.is_number:
            if arg.is_negative:
                return S.Pi * I + cls(-arg)
            elif arg is S.ComplexInfinity:
                return S.ComplexInfinity
            elif arg is S.Exp1:
                return S.One

        if arg.is_zero:
            return S.ComplexInfinity

        # don't autoexpand Pow or Mul (see the issue 3351):
        if not arg.is_Add:
            coeff = arg.as_coefficient(I)

            if coeff is not None:
                if coeff is S.Infinity:
                    return S.Infinity
                elif coeff is S.NegativeInfinity:
                    return S.Infinity
                elif coeff.is_Rational:
                    if coeff.is_nonnegative:
                        return S.Pi * I * S.Half + cls(coeff)
                    else:
                        return -S.Pi * I * S.Half + cls(-coeff)

        if arg.is_number and arg.is_algebraic:
            # Match arg = coeff*(r_ + i_*I) with coeff>0, r_ and i_ real.
            coeff, arg_ = arg.as_independent(I, as_Add=False)
            if coeff.is_negative:
                coeff *= -1
                arg_ *= -1
            arg_ = expand_mul(arg_, deep=False)
            r_, i_ = arg_.as_independent(I, as_Add=True)
            i_ = i_.as_coefficient(I)
            if coeff.is_real and i_ and i_.is_real and r_.is_real:
                if r_.is_zero:
                    if i_.is_positive:
                        return S.Pi * I * S.Half + cls(coeff * i_)
                    elif i_.is_negative:
                        return -S.Pi * I * S.Half + cls(coeff * -i_)
                else:
                    from sympy.simplify import ratsimp
                    # Check for arguments involving rational multiples of pi
                    t = (i_ / r_).cancel()
                    t1 = (-t).cancel()
                    atan_table = {
                        # first quadrant only
                        sqrt(3):
                        S.Pi / 3,
                        1:
                        S.Pi / 4,
                        sqrt(5 - 2 * sqrt(5)):
                        S.Pi / 5,
                        sqrt(2) * sqrt(5 - sqrt(5)) / (1 + sqrt(5)):
                        S.Pi / 5,
                        sqrt(5 + 2 * sqrt(5)):
                        S.Pi * Rational(2, 5),
                        sqrt(2) * sqrt(sqrt(5) + 5) / (-1 + sqrt(5)):
                        S.Pi * Rational(2, 5),
                        sqrt(3) / 3:
                        S.Pi / 6,
                        sqrt(2) - 1:
                        S.Pi / 8,
                        sqrt(2 - sqrt(2)) / sqrt(sqrt(2) + 2):
                        S.Pi / 8,
                        sqrt(2) + 1:
                        S.Pi * Rational(3, 8),
                        sqrt(sqrt(2) + 2) / sqrt(2 - sqrt(2)):
                        S.Pi * Rational(3, 8),
                        sqrt(1 - 2 * sqrt(5) / 5):
                        S.Pi / 10,
                        (-sqrt(2) + sqrt(10)) / (2 * sqrt(sqrt(5) + 5)):
                        S.Pi / 10,
                        sqrt(1 + 2 * sqrt(5) / 5):
                        S.Pi * Rational(3, 10),
                        (sqrt(2) + sqrt(10)) / (2 * sqrt(5 - sqrt(5))):
                        S.Pi * Rational(3, 10),
                        2 - sqrt(3):
                        S.Pi / 12,
                        (-1 + sqrt(3)) / (1 + sqrt(3)):
                        S.Pi / 12,
                        2 + sqrt(3):
                        S.Pi * Rational(5, 12),
                        (1 + sqrt(3)) / (-1 + sqrt(3)):
                        S.Pi * Rational(5, 12)
                    }
                    if t in atan_table:
                        modulus = ratsimp(coeff * Abs(arg_))
                        if r_.is_positive:
                            return cls(modulus) + I * atan_table[t]
                        else:
                            return cls(modulus) + I * (atan_table[t] - S.Pi)
                    elif t1 in atan_table:
                        modulus = ratsimp(coeff * Abs(arg_))
                        if r_.is_positive:
                            return cls(modulus) + I * (-atan_table[t1])
                        else:
                            return cls(modulus) + I * (S.Pi - atan_table[t1])
Пример #16
0
 def eval(cls, ap, bq, z):
     if len(ap) <= len(bq) or (len(ap) == len(bq) + 1 and
                               (Abs(z) <= 1) == True):
         nz = unpolarify(z)
         if z != nz:
             return hyper(ap, bq, nz)
Пример #17
0
def test_issue_14216():
    from sympy.functions.elementary.complexes import unpolarify
    A = MatrixSymbol("A", 2, 2)
    assert unpolarify(A[0, 0]) == A[0, 0]
    assert unpolarify(A[0, 0] * A[1, 0]) == A[0, 0] * A[1, 0]
Пример #18
0
    def eval(cls, a, z):
        from sympy.functions.special.error_functions import expint
        if z.is_Number:
            if z is S.NaN:
                return S.NaN
            elif z is S.Infinity:
                return S.Zero
            elif z.is_zero:
                if re(a).is_positive:
                    return gamma(a)

        # We extract branching information here. C/f lowergamma.
        nx, n = z.extract_branch_factor()
        if a.is_integer and a.is_positive:
            nx = unpolarify(z)
            if z != nx:
                return uppergamma(a, nx)
        elif a.is_integer and a.is_nonpositive:
            if n != 0:
                return -2 * pi * I * n * S.NegativeOne**(
                    -a) / factorial(-a) + uppergamma(a, nx)
        elif n != 0:
            return gamma(a) * (1 - exp(2 * pi * I * n * a)) + exp(
                2 * pi * I * n * a) * uppergamma(a, nx)

        # Special values.
        if a.is_Number:
            if a is S.Zero and z.is_positive:
                return -Ei(-z)
            elif a is S.One:
                return exp(-z)
            elif a is S.Half:
                return sqrt(pi) * erfc(sqrt(z))
            elif a.is_Integer or (2 * a).is_Integer:
                b = a - 1
                if b.is_positive:
                    if a.is_integer:
                        return exp(-z) * factorial(b) * Add(
                            *[z**k / factorial(k) for k in range(a)])
                    else:
                        return (gamma(a) * erfc(sqrt(z)) +
                                S.NegativeOne**(a - S(3) / 2) * exp(-z) *
                                sqrt(z) * Add(*[
                                    gamma(-S.Half - k) * (-z)**k / gamma(1 - a)
                                    for k in range(a - S.Half)
                                ]))
                elif b.is_Integer:
                    return expint(-b, z) * unpolarify(z)**(b + 1)

                if not a.is_Integer:
                    return (S.NegativeOne**(S.Half - a) * pi * erfc(sqrt(z)) /
                            gamma(1 - a) - z**a * exp(-z) * Add(*[
                                z**k * gamma(a) / gamma(a + k + 1)
                                for k in range(S.Half - a)
                            ]))

        if a.is_zero and z.is_positive:
            return -Ei(-z)

        if z.is_zero and re(a).is_positive:
            return gamma(a)