Пример #1
0
def mpf_asin(x, prec, rnd=round_fast):
    sign, man, exp, bc = x
    if bc+exp > 0 and x not in (fone, fnone):
        raise ComplexResult("asin(x) is real only for -1 <= x <= 1")
    flag_nr = True
    if prec < 1000 or exp+bc < -13:
        flag_nr = False
    else:
        ebc = exp + bc
        if ebc < -13:
            flag_nr = False
        elif ebc < -3:
            if prec < 3000:
                flag_nr = False
    if not flag_nr:
        # asin(x) = 2*atan(x/(1+sqrt(1-x**2)))
        wp = prec + 15
        a = mpf_mul(x, x)
        b = mpf_add(fone, mpf_sqrt(mpf_sub(fone, a, wp), wp), wp)
        c = mpf_div(x, b, wp)
        return mpf_shift(mpf_atan(c, prec, rnd), 1)
    # use Newton's method
    extra = 10
    extra_p = 10
    prec2 = prec + extra
    r = math.asin(to_float(x))
    r = from_float(r, 50, rnd)
    for p in giant_steps(50, prec2):
        wp = p + extra_p
        c, s = cos_sin(r, wp, rnd)
        tmp = mpf_sub(x, s, wp, rnd)
        tmp = mpf_div(tmp, c, wp, rnd)
        r = mpf_add(r, tmp, wp, rnd)
    sign, man, exp, bc = r
    return normalize(sign, man, exp, bc, prec, rnd)
Пример #2
0
def try_convert_mpf_value(x, prec, rounding):
    if isinstance(x, float): return from_float(x)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = mpmathify(x._mpmath_(prec, rounding))
        if isinstance(t, mpf):
            return t._mpf_
    return NotImplemented
Пример #3
0
def try_convert_mpf_value(x, prec, rounding):
    if isinstance(x, float): return from_float(x)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = convert_lossless(x._mpmath_(prec, rounding))
        if isinstance(t, mpf):
            return t._mpf_
    return NotImplemented
Пример #4
0
def mpf_convert_rhs(x):
    if isinstance(x, int_types): return from_int(x)
    if isinstance(x, float): return from_float(x)
    if isinstance(x, complex_types): return mpc(x)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = mpmathify(x._mpmath_(*prec_rounding))
        if isinstance(t, mpf):
            return t._mpf_
        return t
    return NotImplemented
Пример #5
0
def mpf_convert_arg(x, prec, rounding):
    if isinstance(x, int_types): return from_int(x)
    if isinstance(x, float): return from_float(x)
    if isinstance(x, basestring): return from_str(x, prec, rounding)
    if isinstance(x, constant): return x.func(prec, rounding)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = mpmathify(x._mpmath_(prec, rounding))
        if isinstance(t, mpf):
            return t._mpf_
    raise TypeError("cannot create mpf from " + repr(x))
Пример #6
0
def mpf_convert_rhs(x):
    if isinstance(x, int_types): return from_int(x)
    if isinstance(x, float): return from_float(x)
    if isinstance(x, complex_types): return mpc(x)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = convert_lossless(x._mpmath_(*prec_rounding))
        if isinstance(t, mpf):
            return t._mpf_
        return t
    return NotImplemented
Пример #7
0
def mpf_convert_arg(x, prec, rounding):
    if isinstance(x, int_types): return from_int(x)
    if isinstance(x, float): return from_float(x)
    if isinstance(x, basestring): return from_str(x, prec, rounding)
    if isinstance(x, constant): return x.func(prec, rounding)
    if hasattr(x, '_mpf_'): return x._mpf_
    if hasattr(x, '_mpmath_'):
        t = convert_lossless(x._mpmath_(prec, rounding))
        if isinstance(t, mpf):
            return t._mpf_
    raise TypeError("cannot create mpf from " + repr(x))
Пример #8
0
def convert_lossless(x, strings=True):
    """Attempt to convert x to an mpf or mpc losslessly. If x is an
    mpf or mpc, return it unchanged. If x is an int, create an mpf with
    sufficient precision to represent it exactly. If x is a str, just
    convert it to an mpf with the current working precision (perhaps
    this should be done differently...)"""
    if isinstance(x, mpnumeric): return x
    if isinstance(x, int_types): return make_mpf(from_int(x))
    if isinstance(x, float): return make_mpf(from_float(x))
    if isinstance(x, complex): return mpc(x)
    if strings and isinstance(x, basestring): return make_mpf(from_str(x, *prec_rounding))
    if hasattr(x, '_mpf_'): return make_mpf(x._mpf_)
    if hasattr(x, '_mpc_'): return make_mpc(x._mpc_)
    if hasattr(x, '_mpmath_'): return convert_lossless(x._mpmath_(*prec_rounding))
    raise TypeError("cannot create mpf from " + repr(x))
Пример #9
0
def mpmathify(x, strings=True):
    """
    Converts *x* to an ``mpf`` or ``mpc``. If *x* is of type ``mpf``,
    ``mpc``, ``int``, ``float``, ``complex``, the conversion
    will be performed losslessly.

    If *x* is a string, the result will be rounded to the present
    working precision. Strings representing fractions or complex
    numbers are permitted.

        >>> from sympy.mpmath import *
        >>> mp.dps = 15
        >>> mpmathify(3.5)
        mpf('3.5')
        >>> mpmathify('2.1')
        mpf('2.1000000000000001')
        >>> mpmathify('3/4')
        mpf('0.75')
        >>> mpmathify('2+3j')
        mpc(real='2.0', imag='3.0')

    """
    if isinstance(x, mpnumeric): return x
    if isinstance(x, int_types): return make_mpf(from_int(x))
    if isinstance(x, float): return make_mpf(from_float(x))
    if isinstance(x, complex): return mpc(x)
    if strings and isinstance(x, basestring):
        try:
            return make_mpf(from_str(x, *prec_rounding))
        except Exception, e:
            if '/' in x:
                fract = x.split('/')
                assert len(fract) == 2
                return mpmathify(fract[0]) / mpmathify(fract[1])
            if 'j' in x.lower():
                x = x.lower().replace(' ', '')
                match = get_complex.match(x)
                re = match.group('re')
                if not re:
                    re = 0
                im = match.group('im').rstrip('j')
                return mpc(mpmathify(re),
                           mpmathify(im))
            raise e
Пример #10
0
    wp = prec + 15
    x = mpf_add(fone, b, wp), mpf_neg(a)
    y = mpf_sub(fone, b, wp), a
    l1 = mpc_log(x, wp)
    l2 = mpc_log(y, wp)
    a, b = mpc_sub(l1, l2, prec, rnd)
    # (I/2) * (a+b*I) = (-b/2 + a/2*I)
    v = mpf_neg(mpf_shift(b, -1)), mpf_shift(a, -1)
    # Subtraction at infinity gives correct real part but
    # wrong imaginary part (should be zero)
    if v[1] == fnan and mpc_is_inf(z):
        v = (v[0], fzero)
    return v


beta_crossover = from_float(0.6417)
alpha_crossover = from_float(1.5)


def acos_asin(z, prec, rnd, n):
    """ complex acos for n = 0, asin for n = 1
    The algorithm is described in
    T.E. Hull, T.F. Fairgrieve and P.T.P. Tang
    'Implementing the Complex Arcsine and Arcosine Functions
    using Exception Handling',
    ACM Trans. on Math. Software Vol. 23 (1997), p299
    The complex acos and asin can be defined as
    acos(z) = acos(beta) - I*sign(a)* log(alpha + sqrt(alpha**2 -1))
    asin(z) = asin(beta) + I*sign(a)* log(alpha + sqrt(alpha**2 -1))
    where z = a + I*b
    alpha = (1/2)*(r + s); beta = (1/2)*(r - s) = a/alpha
Пример #11
0
# TODO: avoid loss of accuracy
def mpc_atan((a, b), prec, rnd=round_fast):
    # atan(z) = (I/2)*(log(1-I*z) - log(1+I*z))
    # x = 1-I*z = 1 + b - I*a
    # y = 1+I*z = 1 - b + I*a
    wp = prec + 15
    x = mpf_add(fone, b, wp), mpf_neg(a)
    y = mpf_sub(fone, b, wp), a
    l1 = mpc_log(x, wp)
    l2 = mpc_log(y, wp)
    a, b = mpc_sub(l1, l2, prec, rnd)
    # (I/2) * (a+b*I) = (-b/2 + a/2*I)
    return mpf_neg(mpf_shift(b, -1)), mpf_shift(a, -1)


beta_crossover = from_float(0.6417)
alpha_crossover = from_float(1.5)


def acos_asin(z, prec, rnd, n):
    """ complex acos for n = 0, asin for n = 1
    The algorithm is described in
    T.E. Hull, T.F. Fairgrieve and P.T.P. Tang
    'Implementing the Complex Arcsine and Arcosine Functions
    using Exception Handling',
    ACM Trans. on Math. Software Vol. 23 (1997), p299
    The complex acos and asin can be defined as
    acos(z) = acos(beta) - I*sign(a)* log(alpha + sqrt(alpha**2 -1))
    asin(z) = asin(beta) + I*sign(a)* log(alpha + sqrt(alpha**2 -1))
    where z = a + I*b
    alpha = (1/2)*(r + s); beta = (1/2)*(r - s) = a/alpha
Пример #12
0
    if n == 1:
        return mpci_pos(x, prec)
    if n == 2:
        return mpci_square(x, prec)
    wp = prec + 20
    result = (mpi_one, mpi_zero)
    while n:
        if n & 1:
            result = mpci_mul(result, x, wp)
            n -= 1
        x = mpci_square(x, wp)
        n >>= 1
    return mpci_pos(result, prec)


gamma_min_a = from_float(1.46163214496)
gamma_min_b = from_float(1.46163214497)
gamma_min = (gamma_min_a, gamma_min_b)
gamma_mono_imag_a = from_float(-1.1)
gamma_mono_imag_b = from_float(1.1)


def mpi_overlap(x, y):
    a, b = x
    c, d = y
    if mpf_lt(d, a): return False
    if mpf_gt(c, b): return False
    return True


# type = 0 -- gamma
Пример #13
0
        return mpi_one, mpi_zero
    if n == 1:
        return mpci_pos(x, prec)
    if n == 2:
        return mpci_square(x, prec)
    wp = prec + 20
    result = (mpi_one, mpi_zero)
    while n:
        if n & 1:
            result = mpci_mul(result, x, wp)
            n -= 1
        x = mpci_square(x, wp)
        n >>= 1
    return mpci_pos(result, prec)

gamma_min_a = from_float(1.46163214496)
gamma_min_b = from_float(1.46163214497)
gamma_min = (gamma_min_a, gamma_min_b)
gamma_mono_imag_a = from_float(-1.1)
gamma_mono_imag_b = from_float(1.1)

def mpi_overlap(x, y):
    a, b = x
    c, d = y
    if mpf_lt(d, a): return False
    if mpf_gt(c, b): return False
    return True

# type = 0 -- gamma
# type = 1 -- factorial
# type = 2 -- 1/gamma