Exemple #1
0
    def _eval_expand_trig(self, **hints):
        arg = self.args[0]
        x = None
        if arg.is_Add:
            from sympy import symmetric_poly

            n = len(arg.args)
            CX = []
            for x in arg.args:
                cx = cot(x, evaluate=False)._eval_expand_trig()
                CX.append(cx)

            Yg = numbered_symbols("Y")
            Y = [Yg.next() for i in xrange(n)]

            p = [0, 0]
            for i in xrange(n, -1, -1):
                p[(n - i) % 2] += symmetric_poly(i, Y) * (-1) ** (((n - i) % 4) // 2)
            return (p[0] / p[1]).subs(zip(Y, CX))
        else:
            coeff, terms = arg.as_coeff_Mul(rational=True)
            if coeff.is_Integer and coeff > 1:
                I = S.ImaginaryUnit
                z = C.Symbol("dummy", real=True)
                P = ((z + I) ** coeff).expand()
                return (C.re(P) / C.im(P)).subs([(z, cot(terms))])
        return cot(arg)
Exemple #2
0
def solve_ODE_first_order(eq, f):
    """
    solves many kinds of first order odes, different methods are used
    depending on the form of the given equation. Now the linear
    and Bernoulli cases are implemented.
    """
    from sympy.integrals.integrals import integrate
    x = f.args[0]
    f = f.func

    #linear case: a(x)*f'(x)+b(x)*f(x)+c(x) = 0
    a = Wild('a', exclude=[f(x)])
    b = Wild('b', exclude=[f(x)])
    c = Wild('c', exclude=[f(x)])

    r = eq.match(a*diff(f(x),x) + b*f(x) + c)
    if r:
        t = C.exp(integrate(r[b]/r[a], x))
        tt = integrate(t*(-r[c]/r[a]), x)
        return (tt + Symbol("C1"))/t

    #Bernoulli case: a(x)*f'(x)+b(x)*f(x)+c(x)*f(x)^n = 0
    n = Wild('n', exclude=[f(x)])

    r = eq.match(a*diff(f(x),x) + b*f(x) + c*f(x)**n)
    if r:
        t = C.exp((1-r[n])*integrate(r[b]/r[a],x))
        tt = (r[n]-1)*integrate(t*r[c]/r[a],x)
        return ((tt + Symbol("C1"))/t)**(1/(1-r[n]))

    #other cases of first order odes will be implemented here

    raise NotImplementedError("solve_ODE_first_order: Cannot solve " + str(eq))
 def _eval_expand_complex(self, deep=True, **hints):
     re, im = self.args[0].as_real_imag()
     if deep:
         re = re.expand(deep, **hints)
         im = im.expand(deep, **hints)
     cos, sin = C.cos(im), C.sin(im)
     return exp(re) * cos + S.ImaginaryUnit * exp(re) * sin
Exemple #4
0
    def _eval_expand_trig(self, **hints):
        from sympy import expand_mul
        arg = self.args[0]
        x = None
        if arg.is_Add:  # TODO, implement more if deep stuff here
            # TODO: Do this more efficiently for more than two terms
            x, y = arg.as_two_terms()
            sx = sin(x, evaluate=False)._eval_expand_trig()
            sy = sin(y, evaluate=False)._eval_expand_trig()
            cx = cos(x, evaluate=False)._eval_expand_trig()
            cy = cos(y, evaluate=False)._eval_expand_trig()
            return sx*cy + sy*cx
        else:
            n, x = arg.as_coeff_Mul(rational=True)
            if n.is_Integer:  # n will be positive because of .eval
                # canonicalization

                # See http://mathworld.wolfram.com/Multiple-AngleFormulas.html
                if n.is_odd:
                    return (-1)**((n - 1)/2)*C.chebyshevt(n, sin(x))
                else:
                    return expand_mul((-1)**(n/2 - 1)*cos(x)*C.chebyshevu(n -
                        1, sin(x)), deep=False)
            pi_coeff = _pi_coeff(arg)
            if pi_coeff is not None:
                if pi_coeff.is_Rational:
                    return self.rewrite(sqrt)
        return sin(arg)
Exemple #5
0
 def vertices(self):
     points = []
     c, r, n = self
     v = 2*S.Pi/n
     for k in xrange(0, n):
         points.append( Point(c[0] + r*C.cos(k*v), c[1] + r*C.sin(k*v)) )
     return points
Exemple #6
0
    def eval(cls, arg):
        arg = sympify(arg)

        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Infinity:
                return S.Infinity
            elif arg is S.NegativeInfinity:
                return S.NegativeInfinity
            elif arg is S.Zero:
                return S.Zero
            elif arg is S.One:
                return C.log(2 ** S.Half + 1)
            elif arg is S.NegativeOne:
                return C.log(2 ** S.Half - 1)
            elif arg.is_negative:
                return -cls(-arg)
        else:
            i_coeff = arg.as_coefficient(S.ImaginaryUnit)

            if i_coeff is not None:
                return S.ImaginaryUnit * C.asin(i_coeff)
            else:
                coeff, terms = arg.as_coeff_terms()

                if coeff.is_negative:
                    return -cls(-arg)
Exemple #7
0
    def _eval_expand_trig(self, **hints):
        arg = self.args[0]
        x = None
        if arg.is_Add:
            from sympy import symmetric_poly
            n = len(arg.args)
            TX = []
            for x in arg.args:
                tx = tan(x, evaluate=False)._eval_expand_trig()
                TX.append(tx)

            Yg = numbered_symbols('Y')
            Y = [ Yg.next() for i in xrange(n) ]

            p = [0,0]
            for i in xrange(n+1):
                p[1-i%2] += symmetric_poly(i,Y)*(-1)**((i%4)//2)
            return (p[0]/p[1]).subs(zip(Y,TX))

        else:
            coeff, terms = arg.as_coeff_Mul(rational=True)
            if coeff.is_Integer and coeff > 1:
                I = S.ImaginaryUnit
                z = C.Symbol('dummy',real=True)
                P = ((1+I*z)**coeff).expand()
                return (C.im(P)/C.re(P)).subs([(z,tan(terms))])
        return tan(arg)
def monomial_count(V, N):
    r"""
    Computes the number of monomials.

    The number of monomials is given by the following formula:

    .. math::

        \frac{(\#V + N)!}{\#V! N!}

    where `N` is a total degree and `V` is a set of variables.

    **Examples**

    >>> from sympy import monomials, monomial_count
    >>> from sympy.abc import x, y

    >>> monomial_count(2, 2)
    6

    >>> M = monomials([x, y], 2)

    >>> sorted(M)
    [1, x, y, x**2, y**2, x*y]
    >>> len(M)
    6

    """
    return C.factorial(V + N) / C.factorial(V) / C.factorial(N)
 def _eval_expand_complex(self, *args):
     if self.args[0].is_real:
         return self
     re, im = self.args[0].as_real_imag()
     denom = sin(re)**2 + C.sinh(im)**2
     return (sin(re)*cos(re) - \
         S.ImaginaryUnit*C.sinh(im)*C.cosh(im))/denom
Exemple #10
0
 def _eval_rewrite_as_polynomial(self, n, m, x):
     k = C.Dummy("k")
     kern = (
         C.factorial(2 * n - 2 * k)
         / (2 ** n * C.factorial(n - k) * C.factorial(k) * C.factorial(n - 2 * k - m))
         * (-1) ** k
         * x ** (n - m - 2 * k)
     )
     return (1 - x ** 2) ** (m / 2) * C.Sum(kern, (k, 0, C.floor((n - m) * S.Half)))
Exemple #11
0
 def _eval_expand_func(self, **hints):
     n, m, theta, phi = self.args
     rv = (
         sqrt((2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m))
         * C.exp(I * m * phi)
         * assoc_legendre(n, m, C.cos(theta))
     )
     # We can do this because of the range of theta
     return rv.subs(sqrt(-cos(theta) ** 2 + 1), sin(theta))
Exemple #12
0
def solve_ODE_second_order(eq, f):
    """
    solves many kinds of second order odes, different methods are used
    depending on the form of the given equation. So far the constants
    coefficients case and a special case are implemented.
    """
    x = f.args[0]
    f = f.func

    #constant coefficients case: af''(x)+bf'(x)+cf(x)=0
    a = Wild('a', exclude=[x])
    b = Wild('b', exclude=[x])
    c = Wild('c', exclude=[x])

    r = eq.match(a*f(x).diff(x,x) + c*f(x))
    if r:
        return Symbol("C1")*C.sin(sqrt(r[c]/r[a])*x)+Symbol("C2")*C.cos(sqrt(r[c]/r[a])*x)

    r = eq.match(a*f(x).diff(x,x) + b*diff(f(x),x) + c*f(x))
    if r:
        r1 = solve(r[a]*x**2 + r[b]*x + r[c], x)
        if r1[0].is_real:
            if len(r1) == 1:
                return (Symbol("C1") + Symbol("C2")*x)*exp(r1[0]*x)
            else:
                return Symbol("C1")*exp(r1[0]*x) + Symbol("C2")*exp(r1[1]*x)
        else:
            r2 = abs((r1[0] - r1[1])/(2*S.ImaginaryUnit))
            return (Symbol("C2")*C.cos(r2*x) + Symbol("C1")*C.sin(r2*x))*exp((r1[0] + r1[1])*x/2)

    #other cases of the second order odes will be implemented here

    #special equations, that we know how to solve
    a = Wild('a')
    t = x*exp(f(x))
    tt = a*t.diff(x, x)/t
    r = eq.match(tt.expand())
    if r:
        return -solve_ODE_1(f(x), x)

    t = x*exp(-f(x))
    tt = a*t.diff(x, x)/t
    r = eq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t)
        return solve_ODE_1(f(x), x)

    neq = eq*exp(f(x))/exp(-f(x))
    r = neq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( t.diff(x,2)*r[a]/t ).expand() == eq
        return solve_ODE_1(f(x), x)

    raise NotImplementedError("solve_ODE_second_order: cannot solve " + str(eq))
Exemple #13
0
    def eval(cls, r, k):
        r, k = map(sympify, (r, k))

        if k.is_Number:
            if k is S.Zero:
                return S.One
            elif k.is_Integer:
                if k.is_negative:
                    return S.Zero
                else:
                    if r.is_Integer and r.is_nonnegative:
                        r, k = int(r), int(k)

                        if k > r:
                            return S.Zero
                        elif k > r // 2:
                            k = r - k

                        M, result = int(sqrt(r)), 1

                        for prime in sieve.primerange(2, r+1):
                            if prime > r - k:
                                result *= prime
                            elif prime > r // 2:
                                continue
                            elif prime > M:
                                if r % prime < k % prime:
                                    result *= prime
                            else:
                                R, K = r, k
                                exp = a = 0

                                while R > 0:
                                    a = int((R % prime) < (K % prime + a))
                                    R, K = R // prime, K // prime
                                    exp = a + exp

                                if exp > 0:
                                    result *= prime**exp

                        return C.Integer(result)
                    else:
                        result = r - k + 1

                        for i in xrange(2, k+1):
                            result *= r-k+i
                            result /= i

                        return result

        if k.is_integer:
            if k.is_negative:
                return S.Zero
        else:
            return C.gamma(r+1)/(C.gamma(r-k+1)*C.gamma(k+1))
Exemple #14
0
 def _eval_rewrite_as_polynomial(self, n, a, b, x):
     # TODO: Make sure n \in N
     k = C.Dummy("k")
     kern = (
         C.RisingFactorial(-n, k)
         * C.RisingFactorial(a + b + n + 1, k)
         * C.RisingFactorial(a + k + 1, n - k)
         / C.factorial(k)
         * ((1 - x) / 2) ** k
     )
     return 1 / C.factorial(n) * C.Sum(kern, (k, 0, n))
Exemple #15
0
 def as_real_imag(self, deep=True, **hints):
     if self.args[0].is_real:
         if deep:
             hints['complex'] = False
             return (self.expand(deep, **hints), S.Zero)
         else:
             return (self, S.Zero)
     if deep:
         re, im = self.args[0].expand(deep, **hints).as_real_imag()
     else:
         re, im = self.args[0].as_real_imag()
     return (cos(re)*C.cosh(im), -sin(re)*C.sinh(im))
Exemple #16
0
    def taylor_term(n, x, *previous_terms):
        if n == 0:
            return 1 / sympify(x)
        elif n < 0 or n % 2 == 0:
            return S.Zero
        else:
            x = sympify(x)

            B = C.bernoulli(n+1)
            F = C.factorial(n+1)

            return (-1)**((n+1)//2) * 2**(n+1) * B/F * x**n
Exemple #17
0
 def as_real_imag(self, deep=True, **hints):
     if self.args[0].is_real:
         if deep:
             return (self.expand(deep, **hints), S.Zero)
         else:
             return (self, S.Zero)
     if deep:
         re, im = self.args[0].expand(deep, **hints).as_real_imag()
     else:
         re, im = self.args[0].as_real_imag()
     denom = sinh(re) ** 2 + C.sin(im) ** 2
     return (sinh(re) * cosh(re) / denom, -C.sin(im) * C.cos(im) / denom)
 def _eval_expand_complex(self, deep=True, **hints):
     if deep:
         abs = C.abs(self.args[0].expand(deep, **hints))
         arg = C.arg(self.args[0].expand(deep, **hints))
     else:
         abs = C.abs(self.args[0])
         arg = C.arg(self.args[0])
     if hints['log']: # Expand the log
         hints['complex'] = False
         return log(abs).expand(deep, **hints) + S.ImaginaryUnit * arg
     else:
         return log(abs) + S.ImaginaryUnit * arg
Exemple #19
0
    def taylor_term(n, x, *previous_terms):
        if n < 0 or n % 2 == 0:
            return S.Zero
        else:
            x = sympify(x)

            a, b = ((n-1)//2), 2**(n+1)

            B = C.bernoulli(n+1)
            F = C.factorial(n+1)

            return (-1)**a * b*(b-1) * B/F * x**n
 def _eval_expand_complex(self, deep=True, **hints):
     if self.args[0].is_real:
         if deep:
             hints['complex'] = False
             return self.expand(deep, **hints)
         else:
             return self
     if deep:
         re, im = self.args[0].expand(deep, **hints).as_real_imag()
     else:
         re, im = self.args[0].as_real_imag()
     return sin(re)*C.cosh(im) + S.ImaginaryUnit*cos(re)*C.sinh(im)
Exemple #21
0
 def _eval_expand_complex(self, deep=True, **hints):
     if self.args[0].is_real:
         if deep:
             return self.expand(deep, **hints)
         else:
             return self
     if deep:
         re, im = self.args[0].expand(deep, **hints).as_real_imag()
     else:
         re, im = self.args[0].as_real_imag()
     denom = sinh(re)**2 + C.sin(im)**2
     return (sinh(re)*cosh(re) - \
         S.ImaginaryUnit*C.sin(im)*C.cos(im))/denom
    def eval(cls, n, m, theta, phi):
        n, m, theta, phi = [sympify(x) for x in (n, m, theta, phi)]

        # Handle negative index m and arguments theta, phi
        if m.could_extract_minus_sign():
            m = -m
            return S.NegativeOne**m * C.exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
        if theta.could_extract_minus_sign():
            theta = -theta
            return Ynm(n, m, theta, phi)
        if phi.could_extract_minus_sign():
            phi = -phi
            return C.exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
Exemple #23
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))
Exemple #24
0
    def eval(cls, n, m, x):
        if n.is_integer and n >= 0 and m.is_integer and abs(m) <= n:
            assoc = cls.calc(int(n), abs(int(m)))

            if m < 0:
                assoc *= (-1)**(-m) * (C.factorial(n + m)/C.factorial(n - m))

            return assoc.subs(_x, x)

        if n.is_negative:
            raise ValueError("%s : 1st index must be nonnegative integer (got %r)" % (cls, n))

        if abs(m) > n:
            raise ValueError("%s : abs('2nd index') must be <= '1st index' (got %r, %r)" % (cls, n, m))
Exemple #25
0
    def eval(cls, arg):
        if arg.is_integer:
            return arg
        if arg.is_imaginary or (S.ImaginaryUnit*arg).is_real:
            i = C.im(arg)
            if not i.has(S.ImaginaryUnit):
                return cls(i)*S.ImaginaryUnit
            return cls(arg, evaluate=False)

        v = cls._eval_number(arg)
        if v is not None:
            return v

        # Integral, numerical, symbolic part
        ipart = npart = spart = S.Zero

        # Extract integral (or complex integral) terms
        terms = Add.make_args(arg)

        for t in terms:
            if t.is_integer or (t.is_imaginary and C.im(t).is_integer):
                ipart += t
            elif t.has(C.Symbol):
                spart += t
            else:
                npart += t

        if not (npart or spart):
            return ipart

        # Evaluate npart numerically if independent of spart
        if npart and (
            not spart or
            npart.is_real and (spart.is_imaginary or (S.ImaginaryUnit*spart).is_real) or
                npart.is_imaginary and spart.is_real):
            try:
                re, im = get_integer_part(
                    npart, cls._dir, {}, return_ints=True)
                ipart += C.Integer(re) + C.Integer(im)*S.ImaginaryUnit
                npart = S.Zero
            except (PrecisionExhausted, NotImplementedError):
                pass

        spart += npart
        if not spart:
            return ipart
        elif spart.is_imaginary or (S.ImaginaryUnit*spart).is_real:
            return ipart + cls(C.im(spart), evaluate=False)*S.ImaginaryUnit
        else:
            return ipart + cls(spart, evaluate=False)
Exemple #26
0
 def eval(cls, n, m, x):
     if m.could_extract_minus_sign():
         # P^{-m}_n  --->  F * P^m_n
         return S.NegativeOne**(-m) * (C.factorial(m + n)/C.factorial(n - m)) * assoc_legendre(n, -m, x)
     if m == 0:
         # P^0_n  --->  L_n
         return legendre(n, x)
     if x == 0:
         return 2**m*sqrt(S.Pi) / (C.gamma((1 - m - n)/2)*C.gamma(1 - (m - n)/2))
     if n.is_Number and m.is_Number and n.is_integer and m.is_integer:
         if n.is_negative:
             raise ValueError("%s : 1st index must be nonnegative integer (got %r)" % (cls, n))
         if abs(m) > n:
             raise ValueError("%s : abs('2nd index') must be <= '1st index' (got %r, %r)" % (cls, n, m))
         return cls._eval_at_order(int(n), abs(int(m))).subs(_x, x)
 def as_real_imag(self, deep=True, **hints):
     # TODO: Handle deep and hints
     n, m, theta, phi = self.args
     re = (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) *
           C.cos(m*phi) * assoc_legendre(n, m, C.cos(theta)))
     im = (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) *
           C.sin(m*phi) * assoc_legendre(n, m, C.cos(theta)))
     return (re, im)
Exemple #28
0
    def canonize(cls, arg):
        if arg.is_integer:
            return arg
        if arg.is_imaginary:
            return cls(C.im(arg))*S.ImaginaryUnit

        v = cls._eval_number(arg)
        if v is not None:
            return v

        # Integral, numerical, symbolic part
        ipart = npart = spart = S.Zero

        # Extract integral (or complex integral) terms
        if arg.is_Add:
            terms = arg.args
        else:
            terms = [arg]

        for t in terms:
            if t.is_integer or (t.is_imaginary and C.im(t).is_integer):
                ipart += t
            elif t.atoms(C.Symbol):
                spart += t
            else:
                npart += t

        if not (npart or spart):
            return ipart

        # Evaluate npart numerically if independent of spart
        orthogonal = (npart.is_real and spart.is_imaginary) or \
            (npart.is_imaginary and spart.is_real)
        if npart and ((not spart) or orthogonal):
            try:
                re, im = get_integer_part(npart, cls._dir, {}, return_ints=True)
                ipart += C.Integer(re) + C.Integer(im)*S.ImaginaryUnit
                npart = S.Zero
            except (PrecisionExhausted, NotImplementedError):
                pass

        spart = npart + spart
        if not spart:
            return ipart
        elif spart.is_imaginary:
            return ipart + cls(C.im(spart),evaluate=False)*S.ImaginaryUnit
        else:
            return ipart + cls(spart, evaluate=False)
Exemple #29
0
    def eval(cls, arg):
        arg = sympify(arg)

        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Infinity:
                return S.Infinity
            elif arg is S.NegativeInfinity:
                return S.Infinity
            elif arg is S.Zero:
                return S.One
            elif arg.is_negative:
                return cls(-arg)
        else:
            i_coeff = arg.as_coefficient(S.ImaginaryUnit)

            if i_coeff is not None:
                return C.cos(i_coeff)
            else:
                coeff, terms = arg.as_coeff_terms()

                if coeff.is_negative:
                    return cls(-arg)

            if arg.func == asinh:
                return sqrt(1 + arg.args[0] ** 2)

            if arg.func == acosh:
                return arg.args[0]

            if arg.func == atanh:
                return 1 / sqrt(1 - arg.args[0] ** 2)
Exemple #30
0
    def eval(cls, arg):
        arg = sympify(arg)

        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Infinity:
                return S.Infinity
            elif arg is S.NegativeInfinity:
                return S.NegativeInfinity
            elif arg is S.Zero:
                return S.Zero
            elif arg.is_negative:
                return -cls(-arg)
        else:
            i_coeff = arg.as_coefficient(S.ImaginaryUnit)

            if i_coeff is not None:
                return S.ImaginaryUnit * C.sin(i_coeff)
            else:
                coeff, terms = arg.as_coeff_terms()

                if coeff.is_negative:
                    return -cls(-arg)

            if arg.func == asinh:
                return arg.args[0]

            if arg.func == acosh:
                x = arg.args[0]
                return sqrt(x - 1) * sqrt(x + 1)

            if arg.func == atanh:
                x = arg.args[0]
                return x / sqrt(1 - x ** 2)
Exemple #31
0
 def plot_interval(self, parameter_name='t'):
     t = C.Symbol(parameter_name, real=True)
     return [t, 0, 1]
Exemple #32
0
 def _eval_rewrite_as_polynomial(self, n, x):
     k = C.Dummy("k")
     kern = C.binomial(n, 2 * k) * (x**2 - 1)**k * x**(n - 2 * k)
     return C.Sum(kern, (k, 0, C.floor(n / 2)))
Exemple #33
0
 def _eval_rewrite_as_polynomial(self, n, x):
     k = C.Dummy("k")
     kern = S.NegativeOne**k * C.factorial(n - k) * (2 * x)**(n - 2 * k) / (
         C.factorial(k) * C.factorial(n - 2 * k))
     return C.Sum(kern, (k, 0, C.floor(n / 2)))
Exemple #34
0
 def _eval_expand_complex(self, *args):
     if self.args[0].is_real:
         return self
     re, im = self.args[0].as_real_imag()
     return sinh(re) * C.cos(im) + cosh(re) * C.sin(im) * S.ImaginaryUnit
Exemple #35
0
"""
This module mainly implements special orthogonal polynomials.

See also functions.combinatorial.numbers which contains some
combinatorial polynomials.

"""

from sympy.core.basic import S, C
from sympy.core import Rational
from sympy.core.function import Function
from sympy.utilities.memoization import recurrence_memo, assoc_recurrence_memo

_x = C.Symbol('x', dummy=True)


class PolynomialSequence(Function):
    """Polynomial sequence with 1 index

       n >= 0
    """

    nargs = 2

    @classmethod
    def eval(cls, n, x):
        if n.is_integer and n >= 0:
            return cls.calc(int(n)).subs(_x, x)
        if n.is_negative:
            raise ValueError("%s index must be nonnegative integer (got %r)" %
                             (cls, n))
Exemple #36
0
from sympy.core.basic import C
from sympy.core.singleton import S
from sympy.core import Rational
from sympy.core.function import Function
from sympy.functions.combinatorial.factorials import factorial

from sympy.polys.orthopolys import (
    chebyshevt_poly,
    chebyshevu_poly,
    laguerre_poly,
    hermite_poly,
    legendre_poly,
)

_x = C.Dummy('x')

class PolynomialSequence(Function):
    """Polynomial sequence with one index and n >= 0. """

    nargs = 2

    @classmethod
    def eval(cls, n, x):
        if n.is_integer and n >= 0:
            return cls._ortho_poly(int(n), _x).subs(_x, x)
        if n.is_negative:
            raise ValueError("%s index must be nonnegative integer (got %r)" % (cls, n))

#----------------------------------------------------------------------------
# Chebyshev polynomials of first and second kind
Exemple #37
0
 def eval(cls, n, k):
     if not 0 <= k < n:
         raise ValueError("must have 0 <= k < n")
     return C.cos(S.Pi*(k+1)/(n+1))
Exemple #38
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            if arg is S.Zero:
                return S.ComplexInfinity

        if arg.could_extract_minus_sign():
            return -cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return -S.ImaginaryUnit * C.coth(i_coeff)

        pi_coeff = _pi_coeff(arg, 2)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return S.ComplexInfinity

            if not pi_coeff.is_Rational:
                narg = pi_coeff*S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            cst_table = {
                2 : S.Zero,
                3 : 1 / sqrt(3),
                4 : S.One,
                6 : sqrt(3)
            }

            try:
                result = cst_table[pi_coeff.q]

                if (2*pi_coeff.p // pi_coeff.q) % 4 in (1, 3):
                    return -result
                else:
                    return result
            except KeyError:
                if pi_coeff.p > pi_coeff.q:
                    p, q = pi_coeff.p % pi_coeff.q, pi_coeff.q
                    if 2 * p > q:
                        return -cls(Rational(q - p, q)*S.Pi)
                    return cls(Rational(p, q)*S.Pi)

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                if (m*2/S.Pi) % 2 == 0:
                    return cot(x)
                else:
                    return -tan(x)

        if arg.func is acot:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return 1 / x

        if arg.func is asin:
            x = arg.args[0]
            return sqrt(1 - x**2) / x

        if arg.func is acos:
            x = arg.args[0]
            return x / sqrt(1 - x**2)
Exemple #39
0
 def _eval_rewrite_as_log(self, x):
     return S.ImaginaryUnit/2 * \
            (C.log((S(1) - S.ImaginaryUnit * x)/(S(1) + S.ImaginaryUnit * x)))
Exemple #40
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Zero:
                return S.Zero
            elif arg is S.Infinity or arg is S.NegativeInfinity:
                return

        if arg.could_extract_minus_sign():
            return -cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return S.ImaginaryUnit * C.sinh(i_coeff)

        pi_coeff = _pi_coeff(arg)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return S.Zero

            if not pi_coeff.is_Rational:
                narg = pi_coeff * S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            # http://code.google.com/p/sympy/issues/detail?id=2949
            # transform a sine to a cosine, to avoid redundant code
            if pi_coeff.is_Rational:
                x = pi_coeff % 2
                if x > 1:
                    return -cls((x % 1) * S.Pi)
                if 2 * x > 1:
                    return cls((1 - x) * S.Pi)
                narg = ((pi_coeff + C.Rational(3, 2)) % 2) * S.Pi
                result = cos(narg)
                if not isinstance(result, cos):
                    return result
                if pi_coeff * S.Pi != arg:
                    return cls(pi_coeff * S.Pi)
                return None

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                return sin(m) * cos(x) + cos(m) * sin(x)

        if arg.func is asin:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return x / sqrt(1 + x**2)

        if arg.func is atan2:
            y, x = arg.args
            return y / sqrt(x**2 + y**2)

        if arg.func is acos:
            x = arg.args[0]
            return sqrt(1 - x**2)

        if arg.func is acot:
            x = arg.args[0]
            return 1 / (sqrt(1 + 1 / x**2) * x)
Exemple #41
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Zero:
                return S.One
            elif arg is S.Infinity or arg is S.NegativeInfinity:
                # In this cases, it is unclear if we should
                # return S.NaN or leave un-evaluated.  One
                # useful test case is how "limit(sin(x)/x,x,oo)"
                # is handled.
                # See test_sin_cos_with_infinity() an
                # Test for issue 209
                # http://code.google.com/p/sympy/issues/detail?id=2097
                # For now, we return un-evaluated.
                return

        if arg.could_extract_minus_sign():
            return cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return C.cosh(i_coeff)

        pi_coeff = _pi_coeff(arg)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return (S.NegativeOne)**pi_coeff
            if not pi_coeff.is_Rational:
                narg = pi_coeff * S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            # cosine formula #####################
            # http://code.google.com/p/sympy/issues/detail?id=2949
            # explicit calculations are preformed for
            # cos(k pi / 8), cos(k pi /10), and cos(k pi / 12)
            # Some other exact values like cos(k pi/15) can be
            # calculated using a partial-fraction decomposition
            # by calling cos( X ).rewrite(sqrt)
            cst_table_some = {
                3: S.Half,
                5: (sqrt(5) + 1) / 4,
            }
            if pi_coeff.is_Rational:
                q = pi_coeff.q
                p = pi_coeff.p % (2 * q)
                if p > q:
                    narg = (pi_coeff - 1) * S.Pi
                    return -cls(narg)
                if 2 * p > q:
                    narg = (1 - pi_coeff) * S.Pi
                    return -cls(narg)

                # If nested sqrt's are worse than un-evaluation
                # you can require q in (1, 2, 3, 4, 6)
                # q <= 12 returns expressions with 2 or fewer nestings.
                if q > 12:
                    return None

                if q in cst_table_some:
                    cts = cst_table_some[pi_coeff.q]
                    return C.chebyshevt(pi_coeff.p, cts).expand()

                if 0 == q % 2:
                    narg = (pi_coeff * 2) * S.Pi
                    nval = cls(narg)
                    if None == nval:
                        return None
                    x = (2 * pi_coeff + 1) / 2
                    sign_cos = (-1)**((-1 if x < 0 else 1) * int(abs(x)))
                    return sign_cos * sqrt((1 + nval) / 2)
            return None

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                return cos(m) * cos(x) - sin(m) * sin(x)

        if arg.func is acos:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return 1 / sqrt(1 + x**2)

        if arg.func is atan2:
            y, x = arg.args
            return x / sqrt(x**2 + y**2)

        if arg.func is asin:
            x = arg.args[0]
            return sqrt(1 - x**2)

        if arg.func is acot:
            x = arg.args[0]
            return 1 / sqrt(1 + 1 / x**2)
Exemple #42
0
def _pi_coeff(arg, cycles=1):
    """
    When arg is a Number times pi (e.g. 3*pi/2) then return the Number
    normalized to be in the range [0, 2], else None.

    When an even multiple of pi is encountered, if it is multiplying
    something with known parity then the multiple is returned as 0 otherwise
    as 2.

    Examples:
    >>> from sympy.functions.elementary.trigonometric import _pi_coeff as coeff
    >>> from sympy import pi
    >>> from sympy.abc import x, y
    >>> coeff(3*x*pi)
    3*x
    >>> coeff(11*pi/7)
    11/7
    >>> coeff(-11*pi/7)
    3/7
    >>> coeff(4*pi)
    0
    >>> coeff(5*pi)
    1
    >>> coeff(5.0*pi)
    1
    >>> coeff(5.5*pi)
    3/2
    >>> coeff(2 + pi)

    """
    arg = sympify(arg)
    if arg is S.Pi:
        return S.One
    elif not arg:
        return S.Zero
    elif arg.is_Mul:
        cx = arg.coeff(S.Pi)
        if cx:
            c, x = cx.as_coeff_Mul()  # pi is not included as coeff
            if c.is_Float:
                # recast exact binary fractions to Rationals
                f = abs(c) % 1
                if f != 0:
                    p = -round(log(f, 2).evalf())
                    m = 2**p
                    cm = c * m
                    i = int(cm)
                    if i == cm:
                        c = C.Rational(i, m)
                        cx = c * x
                else:
                    c = C.Rational(int(c))
                    cx = c * x
            if x.is_integer:
                c2 = c % 2
                if c2 == 1:
                    return x
                elif not c2:
                    if x.is_even is not None:  # known parity
                        return S.Zero
                    return 2 * x
                else:
                    return c2 * x
            return cx
Exemple #43
0
 def arbitrary_point(self, parameter_name='t'):
     """Returns a symbolic point that is on this line segment."""
     t = C.Symbol(parameter_name, real=True)
     x = simplify(self.p1[0] + t * (self.p2[0] - self.p1[0]))
     y = simplify(self.p1[1] + t * (self.p2[1] - self.p1[1]))
     return Point(x, y)
Exemple #44
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            if arg is S.Zero:
                return S.ComplexInfinity

        if arg.could_extract_minus_sign():
            return -cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return -S.ImaginaryUnit * C.coth(i_coeff)

        pi_coeff = _pi_coeff(arg, 2)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return S.ComplexInfinity

            if not pi_coeff.is_Rational:
                narg = pi_coeff * S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            if pi_coeff.is_Rational:
                narg = (((pi_coeff + S.Half) % 1) - S.Half) * S.Pi
                # see cos() to specify which expressions should be
                # expanded automatically in terms of radicals
                cresult, sresult = cos(narg), cos(narg - S.Pi / 2)
                if not isinstance(cresult, cos) \
                        and not isinstance(sresult, cos):
                    if sresult == 0:
                        return S.ComplexInfinity
                    return cresult / sresult
                if narg != arg:
                    return cls(narg)

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                cotm = cot(m)
                if cotm == 0:
                    return -tan(x)
                cotx = cot(x)
                if cotm is S.ComplexInfinity:
                    return cotx
                if cotm.is_Rational:
                    return (cotm * cotx - 1) / (cotm + cotx)
            return None

        if arg.func is acot:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return 1 / x

        if arg.func is atan2:
            y, x = arg.args
            return x / y

        if arg.func is asin:
            x = arg.args[0]
            return sqrt(1 - x**2) / x

        if arg.func is acos:
            x = arg.args[0]
            return x / sqrt(1 - x**2)
Exemple #45
0
 def plot_interval(self, parameter_name='t'):
     """Returns the plot interval for the default geometric plot of line"""
     t = C.Symbol(parameter_name, real=True)
     return [t, -5, 5]
Exemple #46
0
 def _eval_rewrite_as_polynomial(self, n, x):
     k = C.Dummy("k")
     kern = (-1)**k * C.binomial(n, k)**2 * ((1 + x) / 2)**(n - k) * (
         (1 - x) / 2)**k
     return C.Sum(kern, (k, 0, n))
Exemple #47
0
 def _eval_rewrite_as_polynomial(self, n, a, x):
     k = C.Dummy("k")
     kern = ((-1)**k * C.RisingFactorial(a, n - k) * (2 * x)**(n - 2 * k) /
             (C.factorial(k) * C.factorial(n - 2 * k)))
     return C.Sum(kern, (k, 0, C.floor(n / 2)))
Exemple #48
0
 def eval(cls, n, k):
     if not ((0 <= k) and (k < n)):
         raise ValueError("must have 0 <= k < n, "
                          "got k = %s and n = %s" % (k, n))
     return C.cos(S.Pi * (k + 1) / (n + 1))
Exemple #49
0
 def _eval_rewrite_as_polynomial(self, n, x):
     # TODO: Should make sure n is in N_0
     k = C.Dummy("k")
     kern = C.RisingFactorial(
         -n, k) / (C.gamma(k + alpha + 1) * C.factorial(k)) * x**k
     return C.gamma(n + alpha + 1) / C.factorial(n) * C.Sum(kern, (k, 0, n))
Exemple #50
0
 def _eval_rewrite_as_log(self, x):
     return S.Pi/2 + S.ImaginaryUnit * C.log(S.ImaginaryUnit * x + sqrt(1 - x**2))
Exemple #51
0
    def eval(cls, n, a, b, x):
        # Simplify to other polynomials
        # P^{a, a}_n(x)
        if a == b:
            if a == -S.Half:
                return C.RisingFactorial(
                    S.Half, n) / C.factorial(n) * chebyshevt(n, x)
            elif a == S.Zero:
                return legendre(n, x)
            elif a == S.Half:
                return C.RisingFactorial(
                    3 * S.Half, n) / C.factorial(n + 1) * chebyshevu(n, x)
            else:
                return C.RisingFactorial(a + 1, n) / C.RisingFactorial(
                    2 * a + 1, n) * gegenbauer(n, a + S.Half, x)
        elif b == -a:
            # P^{a, -a}_n(x)
            return C.gamma(n + a + 1) / C.gamma(n + 1) * (1 + x)**(a / 2) / (
                1 - x)**(a / 2) * assoc_legendre(n, -a, x)
        elif a == -b:
            # P^{-b, b}_n(x)
            return C.gamma(n - b + 1) / C.gamma(n + 1) * (1 - x)**(b / 2) / (
                1 + x)**(b / 2) * assoc_legendre(n, b, x)

        if not n.is_Number:
            # Symbolic result P^{a,b}_n(x)
            # P^{a,b}_n(-x)  --->  (-1)**n * P^{b,a}_n(-x)
            if x.could_extract_minus_sign():
                return S.NegativeOne**n * jacobi(n, b, a, -x)
            # We can evaluate for some special values of x
            if x == S.Zero:
                return (2**(-n) * C.gamma(a + n + 1) /
                        (C.gamma(a + 1) * C.factorial(n)) *
                        C.hyper([-b - n, -n], [a + 1], -1))
            if x == S.One:
                return C.RisingFactorial(a + 1, n) / C.factorial(n)
            elif x == S.Infinity:
                if n.is_positive:
                    # TODO: Make sure a+b+2*n \notin Z
                    return C.RisingFactorial(a + b + n + 1, n) * S.Infinity
        else:
            # n is a given fixed integer, evaluate into polynomial
            return jacobi_poly(n, a, b, x)
Exemple #52
0
 def _eval_rewrite_as_log(self, x):
     return S.ImaginaryUnit/2 * \
            (C.log((x - S.ImaginaryUnit)/(x + S.ImaginaryUnit)))
Exemple #53
0
 def _eval_rewrite_as_polynomial(self, n, x):
     k = C.Dummy("k")
     kern = (-1)**k / (C.factorial(k) *
                       C.factorial(n - 2 * k)) * (2 * x)**(n - 2 * k)
     return C.factorial(n) * C.Sum(kern, (k, 0, C.floor(n / 2)))
Exemple #54
0
    def _eval_integral(self,
                       f,
                       x,
                       meijerg=None,
                       risch=None,
                       manual=None,
                       conds='piecewise'):
        """
        Calculate the anti-derivative to the function f(x).

        The following algorithms are applied (roughly in this order):

        1. Simple heuristics (based on pattern matching and integral table):

           - most frequently used functions (e.g. polynomials, products of trig functions)

        2. Integration of rational functions:

           - A complete algorithm for integrating rational functions is
             implemented (the Lazard-Rioboo-Trager algorithm).  The algorithm
             also uses the partial fraction decomposition algorithm
             implemented in apart() as a preprocessor to make this process
             faster.  Note that the integral of a rational function is always
             elementary, but in general, it may include a RootSum.

        3. Full Risch algorithm:

           - The Risch algorithm is a complete decision
             procedure for integrating elementary functions, which means that
             given any elementary function, it will either compute an
             elementary antiderivative, or else prove that none exists.
             Currently, part of transcendental case is implemented, meaning
             elementary integrals containing exponentials, logarithms, and
             (soon!) trigonometric functions can be computed.  The algebraic
             case, e.g., functions containing roots, is much more difficult
             and is not implemented yet.

           - If the routine fails (because the integrand is not elementary, or
             because a case is not implemented yet), it continues on to the
             next algorithms below.  If the routine proves that the integrals
             is nonelementary, it still moves on to the algorithms below,
             because we might be able to find a closed-form solution in terms
             of special functions.  If risch=True, however, it will stop here.

        4. The Meijer G-Function algorithm:

           - This algorithm works by first rewriting the integrand in terms of
             very general Meijer G-Function (meijerg in SymPy), integrating
             it, and then rewriting the result back, if possible.  This
             algorithm is particularly powerful for definite integrals (which
             is actually part of a different method of Integral), since it can
             compute closed-form solutions of definite integrals even when no
             closed-form indefinite integral exists.  But it also is capable
             of computing many indefinite integrals as well.

           - Another advantage of this method is that it can use some results
             about the Meijer G-Function to give a result in terms of a
             Piecewise expression, which allows to express conditionally
             convergent integrals.

           - Setting meijerg=True will cause integrate() to use only this
             method.

        5. The "manual integration" algorithm:

           - This algorithm tries to mimic how a person would find an
             antiderivative by hand, for example by looking for a
             substitution or applying integration by parts. This algorithm
             does not handle as many integrands but can return results in a
             more familiar form.

           - Sometimes this algorithm can evaluate parts of an integral; in
             this case integrate() will try to evaluate the rest of the
             integrand using the other methods here.

           - Setting manual=True will cause integrate() to use only this
             method.

        6. The Heuristic Risch algorithm:

           - This is a heuristic version of the Risch algorithm, meaning that
             it is not deterministic.  This is tried as a last resort because
             it can be very slow.  It is still used because not enough of the
             full Risch algorithm is implemented, so that there are still some
             integrals that can only be computed using this method.  The goal
             is to implement enough of the Risch and Meijer G methods so that
             this can be deleted.

        """
        from sympy.integrals.risch import risch_integrate

        if risch:
            try:
                return risch_integrate(f, x, conds=conds)
            except NotImplementedError:
                return None

        if manual:
            try:
                result = manualintegrate(f, x)
                if result is not None and result.func != Integral:
                    return result
            except (ValueError, PolynomialError):
                pass

        # if it is a poly(x) then let the polynomial integrate itself (fast)
        #
        # It is important to make this check first, otherwise the other code
        # will return a sympy expression instead of a Polynomial.
        #
        # see Polynomial for details.
        if isinstance(f, Poly) and not meijerg:
            return f.integrate(x)

        # Piecewise antiderivatives need to call special integrate.
        if f.func is Piecewise:
            return f._eval_integral(x)

        # let's cut it short if `f` does not depend on `x`
        if not f.has(x):
            return f * x

        # try to convert to poly(x) and then integrate if successful (fast)
        poly = f.as_poly(x)

        if poly is not None and not meijerg:
            return poly.integrate().as_expr()

        if risch is not False:
            try:
                result, i = risch_integrate(f,
                                            x,
                                            separate_integral=True,
                                            conds=conds)
            except NotImplementedError:
                pass
            else:
                if i:
                    # There was a nonelementary integral. Try integrating it.
                    return result + i.doit(risch=False)
                else:
                    return result

        # since Integral(f=g1+g2+...) == Integral(g1) + Integral(g2) + ...
        # we are going to handle Add terms separately,
        # if `f` is not Add -- we only have one term

        # Note that in general, this is a bad idea, because Integral(g1) +
        # Integral(g2) might not be computable, even if Integral(g1 + g2) is.
        # For example, Integral(x**x + x**x*log(x)).  But many heuristics only
        # work term-wise.  So we compute this step last, after trying
        # risch_integrate.  We also try risch_integrate again in this loop,
        # because maybe the integral is a sum of an elementary part and a
        # nonelementary part (like erf(x) + exp(x)).  risch_integrate() is
        # quite fast, so this is acceptable.
        parts = []
        args = Add.make_args(f)
        for g in args:
            coeff, g = g.as_independent(x)

            # g(x) = const
            if g is S.One and not meijerg:
                parts.append(coeff * x)
                continue

            # g(x) = expr + O(x**n)
            order_term = g.getO()

            if order_term is not None:
                h = self._eval_integral(g.removeO(), x)

                if h is not None:
                    h_order_expr = self._eval_integral(order_term.expr, x)

                    if h_order_expr is not None:
                        h_order_term = order_term.func(h_order_expr,
                                                       *order_term.variables)
                        parts.append(coeff * (h + h_order_term))
                        continue

                # NOTE: if there is O(x**n) and we fail to integrate then there is
                # no point in trying other methods because they will fail anyway.
                return None

            #               c
            # g(x) = (a*x+b)
            if g.is_Pow and not g.exp.has(x) and not meijerg:
                a = Wild('a', exclude=[x])
                b = Wild('b', exclude=[x])

                M = g.base.match(a * x + b)

                if M is not None:
                    if g.exp == -1:
                        h = C.log(g.base)
                    elif conds != 'piecewise':
                        h = g.base**(g.exp + 1) / (g.exp + 1)
                    else:
                        h1 = C.log(g.base)
                        h2 = g.base**(g.exp + 1) / (g.exp + 1)
                        h = Piecewise((h1, Eq(g.exp, -1)), (h2, True))

                    parts.append(coeff * h / M[a])
                    continue

            #        poly(x)
            # g(x) = -------
            #        poly(x)
            if g.is_rational_function(x) and not meijerg:
                parts.append(coeff * ratint(g, x))
                continue

            if not meijerg:
                # g(x) = Mul(trig)
                h = trigintegrate(g, x, conds=conds)
                if h is not None:
                    parts.append(coeff * h)
                    continue

                # g(x) has at least a DiracDelta term
                h = deltaintegrate(g, x)
                if h is not None:
                    parts.append(coeff * h)
                    continue

                # Try risch again.
                if risch is not False:
                    try:
                        h, i = risch_integrate(g,
                                               x,
                                               separate_integral=True,
                                               conds=conds)
                    except NotImplementedError:
                        h = None
                    else:
                        if i:
                            h = h + i.doit(risch=False)

                        parts.append(coeff * h)
                        continue

                # fall back to heurisch
                try:
                    if conds == 'piecewise':
                        h = heurisch_wrapper(g, x, hints=[])
                    else:
                        h = heurisch(g, x, hints=[])
                except PolynomialError:
                    # XXX: this exception means there is a bug in the
                    # implementation of heuristic Risch integration
                    # algorithm.
                    h = None
            else:
                h = None

            if meijerg is not False and h is None:
                # rewrite using G functions
                try:
                    h = meijerint_indefinite(g, x)
                except NotImplementedError:
                    from sympy.integrals.meijerint import _debug
                    _debug('NotImplementedError from meijerint_definite')
                    res = None
                if h is not None:
                    parts.append(coeff * h)
                    continue

            if h is None and manual is not False:
                try:
                    result = manualintegrate(g, x)
                    if result is not None and not isinstance(result, Integral):
                        if result.has(Integral):
                            # try to have other algorithms do the integrals
                            # manualintegrate can't handle
                            result = result.func(*[
                                arg.doit(
                                    manual=False) if arg.has(Integral) else arg
                                for arg in result.args
                            ]).expand(multinomial=False,
                                      log=False,
                                      power_exp=False,
                                      power_base=False)
                        if not result.has(Integral):
                            parts.append(coeff * result)
                            continue
                except (ValueError, PolynomialError):
                    # can't handle some SymPy expressions
                    pass

            # if we failed maybe it was because we had
            # a product that could have been expanded,
            # so let's try an expansion of the whole
            # thing before giving up; we don't try this
            # at the outset because there are things
            # that cannot be solved unless they are
            # NOT expanded e.g., x**x*(1+log(x)). There
            # should probably be a checker somewhere in this
            # routine to look for such cases and try to do
            # collection on the expressions if they are already
            # in an expanded form
            if not h and len(args) == 1:
                f = f.expand(mul=True, deep=False)
                if f.is_Add:
                    # Note: risch will be identical on the expanded
                    # expression, but maybe it will be able to pick out parts,
                    # like x*(exp(x) + erf(x)).
                    return self._eval_integral(f,
                                               x,
                                               meijerg=meijerg,
                                               risch=risch,
                                               conds=conds)

            if h is not None:
                parts.append(coeff * h)
            else:
                return None

        return Add(*parts)
Exemple #55
0
 def _eval_rewrite_as_polynomial(self, n, x):
     # TODO: Should make sure n is in N_0
     k = C.Dummy("k")
     kern = C.RisingFactorial(-n, k) / C.factorial(k)**2 * x**k
     return C.Sum(kern, (k, 0, n))
Exemple #56
0
def sqrt(arg):
    # arg = sympify(arg) is handled by Pow
    return C.Pow(arg, S.Half)
Exemple #57
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Zero:
                return S.Zero
            elif arg is S.Infinity:
                return

        if arg.could_extract_minus_sign():
            return -cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return S.ImaginaryUnit * C.sinh(i_coeff)

        pi_coeff = _pi_coeff(arg)
        if pi_coeff is not None:
            if pi_coeff.is_integer:
                return S.Zero

            if not pi_coeff.is_Rational:
                narg = pi_coeff*S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            cst_table_some = {
                2 : S.One,
                3 : S.Half*sqrt(3),
                4 : S.Half*sqrt(2),
                6 : S.Half,
            }

            cst_table_more = {
                (1, 5) : sqrt((5 - sqrt(5)) / 8),
                (2, 5) : sqrt((5 + sqrt(5)) / 8)
            }

            p = pi_coeff.p
            q = pi_coeff.q

            Q, P = p // q, p % q

            try:
                result = cst_table_some[q]
            except KeyError:
                if abs(P) > q // 2:
                    P = q - P

                try:
                    result = cst_table_more[(P, q)]
                except KeyError:
                    if P != p:
                        result = cls(C.Rational(P, q)*S.Pi)
                    else:
                        return None

            if Q % 2 == 1:
                return -result
            else:
                return result

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                return sin(m)*cos(x)+cos(m)*sin(x)

        if arg.func is asin:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return x / sqrt(1 + x**2)

        if arg.func is acos:
            x = arg.args[0]
            return sqrt(1 - x**2)

        if arg.func is acot:
            x = arg.args[0];
            return 1 / (sqrt(1 + 1 / x**2) * x)
Exemple #58
0
    def _eval_rewrite_as_sqrt(self, arg):
        _EXPAND_INTS = False

        def migcdex(x):
            # recursive calcuation of gcd and linear combination
            # for a sequence of integers.
            # Given  (x1, x2, x3)
            # Returns (y1, y1, y3, g)
            # such that g is the gcd and x1*y1+x2*y2+x3*y3 - g = 0
            # Note, that this is only one such linear combination.
            if len(x) == 1:
                return (1, x[0])
            if len(x) == 2:
                return igcdex(x[0], x[-1])
            g = migcdex(x[1:])
            u, v, h = igcdex(x[0], g[-1])
            return tuple([u] + [v * i for i in g[0:-1]] + [h])

        def ipartfrac(r, factors=None):
            if isinstance(r, int):
                return r
            assert isinstance(r, C.Rational)
            n = r.q
            if 2 > r.q * r.q:
                return r.q

            if None == factors:
                a = [n / x**y for x, y in factorint(r.q).iteritems()]
            else:
                a = [n / x for x in factors]
            if len(a) == 1:
                return [r]
            h = migcdex(a)
            ans = [r.p * C.Rational(i * j, r.q) for i, j in zip(h[:-1], a)]
            assert r == sum(ans)
            return ans

        pi_coeff = _pi_coeff(arg)
        if pi_coeff is None:
            return None

        assert not pi_coeff.is_integer, "should have been simplified already"

        if not pi_coeff.is_Rational:
            return None

        cst_table_some = {
            3:
            S.Half,
            5: (sqrt(5) + 1) / 4,
            17:
            sqrt((15 + sqrt(17)) / 32 + sqrt(2) * (sqrt(17 - sqrt(17)) + sqrt(
                sqrt(2) *
                (-8 * sqrt(17 + sqrt(17)) -
                 (1 - sqrt(17)) * sqrt(17 - sqrt(17))) + 6 * sqrt(17) + 34)) /
                 32)
            # 65537 and 257 are the only other known Fermat primes
            # Please add if you would like them
        }

        def fermatCoords(n):
            assert isinstance(n, int)
            assert n > 0
            if n == 1 or 0 == n % 2:
                return False
            primes = dict([(p, 0) for p in cst_table_some])
            assert 1 not in primes
            for p_i in primes:
                while 0 == n % p_i:
                    n = n / p_i
                    primes[p_i] += 1
            if 1 != n:
                return False
            if max(primes.values()) > 1:
                return False
            return tuple([p for p in primes if primes[p] == 1])

        if pi_coeff.q in cst_table_some:
            return C.chebyshevt(pi_coeff.p,
                                cst_table_some[pi_coeff.q]).expand()

        if 0 == pi_coeff.q % 2:  # recursively remove powers of 2
            narg = (pi_coeff * 2) * S.Pi
            nval = cos(narg)
            if None == nval:
                return None
            nval = nval.rewrite(sqrt)
            if not _EXPAND_INTS:
                if (isinstance(nval, cos) or isinstance(-nval, cos)):
                    return None
            x = (2 * pi_coeff + 1) / 2
            sign_cos = (-1)**((-1 if x < 0 else 1) * int(abs(x)))
            return sign_cos * sqrt((1 + nval) / 2)

        FC = fermatCoords(pi_coeff.q)
        if FC:
            decomp = ipartfrac(pi_coeff, FC)
            X = [(x[1], x[0] * S.Pi)
                 for x in zip(decomp, numbered_symbols('z'))]
            pcls = cos(sum([x[0] for x in X]))._eval_expand_trig().subs(X)
            return pcls.rewrite(sqrt)
        if _EXPAND_INTS:
            decomp = ipartfrac(pi_coeff)
            X = [(x[1], x[0] * S.Pi)
                 for x in zip(decomp, numbered_symbols('z'))]
            pcls = cos(sum([x[0] for x in X]))._eval_expand_trig().subs(X)
            return pcls
        return None
Exemple #59
0
    def eval(cls, arg):
        if arg.is_Number:
            if arg is S.NaN:
                return S.NaN
            elif arg is S.Zero:
                return S.One
            elif arg is S.Infinity:
                return

        if arg.could_extract_minus_sign():
            return cls(-arg)

        i_coeff = arg.as_coefficient(S.ImaginaryUnit)
        if i_coeff is not None:
            return C.cosh(i_coeff)

        pi_coeff = _pi_coeff(arg)
        if pi_coeff is not None:
            if not pi_coeff.is_Rational:
                if pi_coeff.is_integer:
                    even = pi_coeff.is_even
                    if even:
                        return S.One
                    elif even is False:
                        return S.NegativeOne
                narg = pi_coeff*S.Pi
                if narg != arg:
                    return cls(narg)
                return None

            cst_table_some = {
                1 : S.One,
                2 : S.Zero,
                3 : S.Half,
                4 : S.Half*sqrt(2),
                6 : S.Half*sqrt(3),
            }

            cst_table_more = {
                (1, 5) : (sqrt(5) + 1)/4,
                (2, 5) : (sqrt(5) - 1)/4
            }

            p = pi_coeff.p
            q = pi_coeff.q

            Q, P = 2*p // q, p % q

            try:
                result = cst_table_some[q]
            except KeyError:
                if abs(P) > q // 2:
                    P = q - P

                try:
                    result = cst_table_more[(P, q)]
                except KeyError:
                    if P != p:
                        result = cls(C.Rational(P, q)*S.Pi)
                    else:
                        return None

            if Q % 4 in (1, 2):
                return -result
            else:
                return result

        if arg.is_Add:
            x, m = _peeloff_pi(arg)
            if m:
                return cos(m)*cos(x)-sin(m)*sin(x)

        if arg.func is acos:
            return arg.args[0]

        if arg.func is atan:
            x = arg.args[0]
            return 1 / sqrt(1 + x**2)

        if arg.func is asin:
            x = arg.args[0]
            return sqrt(1 - x ** 2)

        if arg.func is acot:
            x = arg.args[0]
            return 1 / sqrt(1 + 1 / x**2)
Exemple #60
0
 def fdiff(self, argindex=1):
     if argindex == 1:
         return 2 * C.exp(-self.args[0]**2) / sqrt(S.Pi)
     else:
         raise ArgumentIndexError(self, argindex)