Esempio n. 1
0
        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
Esempio n. 2
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)
Esempio n. 3
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)
Esempio n. 4
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_negative:
                return -cls(-arg)
        else:
            i_coeff = arg.as_coefficient(S.ImaginaryUnit)

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

                if pi_coeff is not None:
                    if pi_coeff.is_integer:
                        return S.Zero
                    elif pi_coeff.is_Rational:
                        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_Mul and arg.args[0].is_negative:
                    return -cls(-arg)
                if arg.is_Add:
                    x, m = arg.as_independent(S.Pi)
                    if m in [S.Pi / 2, S.Pi]:
                        return sin(m) * cos(x) + cos(m) * sin(x)
                    # normalize sin(-x-y) to -sin(x+y)
                    if arg.args[0].is_Mul:
                        if arg.args[0].args[0].is_negative:
                            # e.g. arg = -x - y
                            if (-arg).args[0].is_Mul:
                                if (-arg).args[0].args[0].is_negative:
                                    # This is to prevent infinite recursion in
                                    # the case sin(-x+y), for which
                                    # -arg = -y + x. See also #838 for the
                                    # root of the problem here.
                                    return
                            # convert sin(-x-y) to -sin(x+y)
                            return -cls(-arg)
                    if arg.args[0].is_negative:
                        if (-arg).args[0].is_negative:
                            # This is to avoid infinite recursion in the case
                            # sin(-x-1)
                            return
                        return -cls(-arg)

            if isinstance(arg, asin):
                return arg.args[0]

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

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

            if isinstance(arg, acot):
                x = arg.args[0]
                return 1 / (sqrt(1 + 1 / x**2) * x)
Esempio n. 5
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 = -int(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
Esempio n. 6
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)
Esempio n. 7
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(C.Rational(q - p, q)*S.Pi)
                    return cls(C.Rational(p, q)*S.Pi)
                else:
                    newarg = pi_coeff*S.Pi
                    if newarg != arg:
                        return cls(newarg)
                    return None

        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 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)