Beispiel #1
0
def jacobi_elliptic_cn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.2.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_cn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # cn collapses to cos(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 0'
        return cos(u)
    elif m == one:  # cn collapses to sech(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 1'
        return sech(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        v = (pi * u) / (two * ellipk(k**2))

    sum = zero
    term = zero  # series starts at zero

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_cn: calculating'
    while True:
        factor1 = (q**(term + onehalf)) / (one + q**(two * term + one))
        factor2 = cos((two * term + one) * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two * pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Beispiel #2
0
def cplot(f,
          re=[-5, 5],
          im=[-5, 5],
          points=2000,
          color=default_color_function,
          verbose=False,
          file=None,
          dpi=None):
    """
    Plots the given complex-valued function over a rectangular part
    of the complex plane given by the pairs of intervals re and im.
    For example:

        cplot(lambda z: z, [-2, 2], [-10, 10])
        cplot(exp)
        cplot(zeta, [0, 1], [0, 50])

    By default, the complex argument (phase) is shown as color and
    the magnitude is show as brightness. You can also supply a
    custom color function ('color'). This function should take a
    complex number as input and return an RGB 3-tuple containing
    floats in the range 0.0-1.0.

    To obtain a sharp image, the number of points may need to be
    increased to 100,000 or thereabout. Since evaluating the
    function that many times is likely to be slow, the 'verbose'
    option is useful to display progress.
    """
    import pylab
    pylab.clf()
    rea, reb = re
    ima, imb = im
    dre = reb - rea
    dim = imb - ima
    M = int(sqrt(points * dre / dim) + 1)
    N = int(sqrt(points * dim / dre) + 1)
    x = pylab.linspace(rea, reb, M)
    y = pylab.linspace(ima, imb, N)
    # Note: we have to be careful to get the right rotation.
    # Test with these plots:
    #   cplot(lambda z: z if z.real < 0 else 0)
    #   cplot(lambda z: z if z.imag < 0 else 0)
    w = pylab.zeros((N, M, 3))
    for n in xrange(N):
        for m in xrange(M):
            z = mpc(x[m], y[n])
            try:
                v = color(f(z))
            except plot_ignore:
                v = (0.5, 0.5, 0.5)
            w[n, m] = v
        if verbose:
            print n, "of", N
    pylab.imshow(w, extent=(rea, reb, ima, imb), origin='lower')
    pylab.xlabel('Re(z)')
    pylab.ylabel('Im(z)')
    if file:
        pylab.savefig(file, dpi=dpi)
    else:
        pylab.show()
Beispiel #3
0
def jacobi_elliptic_cn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.2.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_cn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:                   # cn collapses to cos(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 0'
        return cos(u)
    elif m == one:                  # cn collapses to sech(u)
        if verbose:
            print >> sys.stderr, 'cn: special case, m == 1'
        return sech(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        v = (pi * u) / (two*ellipk(k**2))

    sum = zero
    term = zero                     # series starts at zero

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_cn: calculating'
    while True:
        factor1 = (q**(term + onehalf)) / (one + q**(two*term + one))
        factor2 = cos((two*term + one)*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two*pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Beispiel #4
0
def _calc_spouge_coefficients(a, prec):
    """
    Calculate Spouge coefficients for approximation with parameter a.
    Return a list of big integers representing the coefficients in
    fixed-point form with a precision of prec bits.
    """

    # We'll store the coefficients as fixed-point numbers but calculate
    # them as Floats for convenience. The initial terms are huge, so we
    # need to allocate extra bits to ensure full accuracy. The integer
    # part of the largest term has size ~= exp(a) or 2**(1.4*a)
    floatprec = prec + int(a*1.4)
    Float.store()
    Float.setprec(floatprec)

    c = [0] * a
    b = exp(a-1)
    e = exp(1)
    c[0] = make_fixed(sqrt(2*pi_float()), prec)
    for k in range(1, a):
        # print "%02f" % (100.0 * k / a), "% done"
        c[k] = make_fixed(((-1)**(k-1) * (a-k)**k) * b / sqrt(a-k), prec)
        # Divide off e and k instead of computing exp and k! from scratch
        b = b / (e * k)

    Float.revert()
    return c
Beispiel #5
0
def cplot(f, re=[-5,5], im=[-5,5], points=2000, color=default_color_function,
    verbose=False, file=None, dpi=None):
    """
    Plots the given complex-valued function *f* over a rectangular part
    of the complex plane specified by the pairs of intervals *re* and *im*.
    For example::

        cplot(lambda z: z, [-2, 2], [-10, 10])
        cplot(exp)
        cplot(zeta, [0, 1], [0, 50])

    By default, the complex argument (phase) is shown as color (hue) and
    the magnitude is show as brightness. You can also supply a
    custom color function (*color*). This function should take a
    complex number as input and return an RGB 3-tuple containing
    floats in the range 0.0-1.0.

    To obtain a sharp image, the number of points may need to be
    increased to 100,000 or thereabout. Since evaluating the
    function that many times is likely to be slow, the 'verbose'
    option is useful to display progress.

    NOTE: This function requires matplotlib (pylab).
    """
    import pylab
    pylab.clf()
    rea, reb = re
    ima, imb = im
    dre = reb - rea
    dim = imb - ima
    M = int(sqrt(points*dre/dim)+1)
    N = int(sqrt(points*dim/dre)+1)
    x = pylab.linspace(rea, reb, M)
    y = pylab.linspace(ima, imb, N)
    # Note: we have to be careful to get the right rotation.
    # Test with these plots:
    #   cplot(lambda z: z if z.real < 0 else 0)
    #   cplot(lambda z: z if z.imag < 0 else 0)
    w = pylab.zeros((N, M, 3))
    for n in xrange(N):
        for m in xrange(M):
            z = mpc(x[m], y[n])
            try:
                v = color(f(z))
            except plot_ignore:
                v = (0.5, 0.5, 0.5)
            w[n,m] = v
        if verbose:
            print n, "of", N
    pylab.imshow(w, extent=(rea, reb, ima, imb), origin='lower')
    pylab.xlabel('Re(z)')
    pylab.ylabel('Im(z)')
    if file:
        pylab.savefig(file, dpi=dpi)
    else:
        pylab.show()
Beispiel #6
0
def quadraticstring(t, a, b, c):
    if c < 0:
        a, b, c = -a, -b, -c
    u1 = (-b + sqrt(b**2 - 4 * a * c)) / (2 * c)
    u2 = (-b - sqrt(b**2 - 4 * a * c)) / (2 * c)
    if abs(u1 - t) < abs(u2 - t):
        if b: s = '((%s+sqrt(%s))/%s)' % (-b, b**2 - 4 * a * c, 2 * c)
        else: s = '(sqrt(%s)/%s)' % (-4 * a * c, 2 * c)
    else:
        if b: s = '((%s-sqrt(%s))/%s)' % (-b, b**2 - 4 * a * c, 2 * c)
        else: s = '(-sqrt(%s)/%s)' % (-4 * a * c, 2 * c)
    return s
Beispiel #7
0
def quadraticstring(t,a,b,c):
    if c < 0:
        a,b,c = -a,-b,-c
    u1 = (-b+sqrt(b**2-4*a*c))/(2*c)
    u2 = (-b-sqrt(b**2-4*a*c))/(2*c)
    if abs(u1-t) < abs(u2-t):
        if b:  s = '((%s+sqrt(%s))/%s)' % (-b,b**2-4*a*c,2*c)
        else:  s = '(sqrt(%s)/%s)' % (-4*a*c,2*c)
    else:
        if b:  s = '((%s-sqrt(%s))/%s)' % (-b,b**2-4*a*c,2*c)
        else:  s = '(-sqrt(%s)/%s)' % (-4*a*c,2*c)
    return s
Beispiel #8
0
def jacobi_theta_3(z, m):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    delta_sum = 1
    term = 1                    # series starts at 1

    zero = mpf('0')
    sum = zero

    if z == zero:
        factor2 = mpf('1')
        while True:

            factor1 = q**(term*term)
            term_n = factor1                # suboptimal, kept for readability
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1

    else:
        while True:
            factor1 = q**(term*term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2*term*z)

            term_n = factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            if factor2 != mpf('0'):      # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2*sum
Beispiel #9
0
 def __pow__(s, n):
     """Calculate (man*2**exp)**n, currently for integral n only."""
     if isinstance(n, (int, long)):
         if n == 0: return Float((1, 0))
         if n == 1: return +s
         if n == 2: return s * s
         if n == -1: return Float(1) / s
         if n < 0:
             Float._prec += 2
             r = Float(1) / (s ** -n)
             Float._prec -= 2
             return +r
         else:
             prec2 = Float._prec + int(4*_clog(n, 2) + 4)
             man, exp, bc = normalize(s.man, s.exp, prec2, ROUND_FLOOR)
             pm, pe, bc = 1, 0, 1
             while n:
                 if n & 1:
                     pm, pe, bc = normalize(pm*man, pe+exp, prec2, ROUND_FLOOR)
                     n -= 1
                 man, exp, _ = normalize(man*man, exp+exp, prec2, ROUND_FLOOR)
                 n = n // 2
             #return Float((pm, pe))
             return makefloat(pm, pe)
     # TODO: support arbitrary powers through exp
     if n == 0.5:
         from functions import sqrt
         return sqrt(s)
     raise ValueError
Beispiel #10
0
def calculate_nome(k):
    """
    Calculate the nome, q, from the value for k.

    Useful factoids:

    k**2 = m;   m is used in Abramowitz
    """
    k = mpmathify(k)

    if abs(k) > one:             # range error
        raise ValueError

    if k == zero:
        return zero
    elif k == one:
        return one
    else:
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        top = ellipk(kprimesquared)
        bottom = ellipk(k**2)

        argument = -pi*top/bottom

        nome = exp(argument)
        return nome
Beispiel #11
0
def jacobi_theta_3(z, m):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    delta_sum = 1
    term = 1  # series starts at 1

    zero = mpf('0')
    sum = zero

    if z == zero:
        factor2 = mpf('1')
        while True:

            factor1 = q**(term * term)
            term_n = factor1  # suboptimal, kept for readability
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1

    else:
        while True:
            factor1 = q**(term * term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2 * term * z)

            term_n = factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            if factor2 != mpf('0'):  # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2 * sum
Beispiel #12
0
def calculate_nome(k):
    """
    Calculate the nome, q, from the value for k.

    Useful factoids:

    k**2 = m;   m is used in Abramowitz
    """
    k = convert_lossless(k)

    if k > mpf('1'):             # range error
        raise ValueError

    zero = mpf('0')
    one = mpf('1')

    if k == zero:
        return zero
    elif k == one:
        return one
    else:
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        top = ellipk(kprimesquared)
        bottom = ellipk(k**2)

        argument = mpf('-1')*pi*top/bottom

        nome = exp(argument)
        return nome
Beispiel #13
0
 def __iter__(self):
     f = self.f
     x0 = self.x0
     x1 = self.x1
     x2 = self.x2
     fx0 = f(x0)
     fx1 = f(x1)
     fx2 = f(x2)
     while True:
         # TODO: maybe refactoring with function for divided differences
         # calculate divided diffferences
         fx2x1 = (fx1 - fx2) / (x1 - x2)
         fx2x0 = (fx0 - fx2) / (x0 - x2)
         fx1x0 = (fx0 - fx1) / (x0 - x1)
         w = fx2x1 + fx2x0 - fx1x0
         fx2x1x0 = (fx1x0 - fx2x1) / (x0 - x2)
         if w == 0 and fx2x1x0 == 0:
             if self.verbose:
                 print 'canceled with'
                 print 'x0 =', x0, ', x1 =', x1, 'and x2 =', x2
             break
         x0 = x1
         fx0 = fx1
         x1 = x2
         fx1 = fx2
         # denominator should be as large as possible => choose sign
         r = sqrt(w**2 - 4*fx2*fx2x1x0)
         if abs(w - r) > abs(w + r):
             r = -r
         x2 -= 2*fx2 / (w + r)
         fx2 = f(x2)
         error = abs(x2 - x1)
         yield x2, error
Beispiel #14
0
 def __iter__(self):
     f = self.f
     x1 = self.x1
     fx1 = f(x1)
     x2 = self.x2
     fx2 = f(x2)
     while True:
         x3 = 0.5*(x1 + x2)
         fx3 = f(x3)
         x4 = x3 + (x3 - x1) * sign(fx1 - fx2) * fx3 / sqrt(fx3**2 - fx1*fx2)
         fx4 = f(x4)
         if abs(fx4) < self.tol:
             # TODO: better condition (when f is very flat)
             if self.verbose:
                 print 'canceled with f(x4) =', fx4
             yield x4, abs(x1 - x2)
             break
         if fx4 * fx2 < 0: # root in [x4, x2]
             x1 = x4
             fx1 = fx4
         else: # root in [x1, x4]
             x2 = x4
             fx2 = fx4
         error = abs(x1 - x2)
         yield (x1 + x2)/2, error
Beispiel #15
0
def calculate_nome(k):
    """
    Calculate the nome, q, from the value for k.

    Useful factoids:

    k**2 = m;   m is used in Abramowitz
    """
    k = convert_lossless(k)

    if k > mpf('1'):  # range error
        raise ValueError

    zero = mpf('0')
    one = mpf('1')

    if k == zero:
        return zero
    elif k == one:
        return one
    else:
        kprimesquared = one - k**2
        kprime = sqrt(kprimesquared)
        top = ellipk(kprimesquared)
        bottom = ellipk(k**2)

        argument = mpf('-1') * pi * top / bottom

        nome = exp(argument)
        return nome
Beispiel #16
0
def sqrt():
    num1 = request.args.get('num1')
    if num1 is None:
        num1 = 0

    return render_template('sqrt.html',
                           num1=num1,
                           sqrt=functions.sqrt(float(num1)))
Beispiel #17
0
def jacobi_elliptic_dn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.3.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_dn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # dn collapes to 1
        return one
    elif m == one:  # dn collapses to sech(u)
        return sech(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two * ellipk(k**2))

    sum = zero
    term = one  # series starts at one

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_dn: calculating'
    while True:
        factor1 = (q**term) / (one + q**(two * term))
        factor2 = cos(two * term * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    K = ellipk(k**2)
    answer = (pi / (two * K)) + (two * pi * sum) / (ellipk(k**2))

    return answer
Beispiel #18
0
def jacobi_elliptic_dn(u, m, verbose=False):
    """
    Implements the jacobi elliptic cn function, using the expansion in
    terms of q, from Abramowitz 16.23.3.
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_dn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:           # dn collapes to 1
        return one
    elif m == one:          # dn collapses to sech(u)
        return sech(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two*ellipk(k**2))

    sum = zero
    term = one                  # series starts at one

    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_elliptic_dn: calculating'
    while True:
        factor1 = (q**term) / (one + q**(two*term))
        factor2 = cos(two*term*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    K = ellipk(k**2)
    answer = (pi / (two*K)) + (two*pi*sum)/(ellipk(k**2))

    return answer
Beispiel #19
0
def erf(x):
    x = ComplexFloat(x)
    if x == 0: return Float(0)
    if x.real < 0: return -erf(-x)
    Float.store()
    Float._prec += 10
    y = lower_gamma(0.5, x**2) / sqrt(pi_float())
    if x.imag == 0:
        y = y.real
    Float.revert()
    return +y
Beispiel #20
0
def norm(x, p=2):
    r"""
    Gives the entrywise `p`-norm of an iterable *x*, i.e. the vector norm
    `\left(\sum_k |x_k|^p\right)^{1/p}`, for any given `1 \le p \le \infty`.

    Special cases:

    If *x* is not iterable, this just returns ``absmax(x)``.

    ``p=1`` gives the sum of absolute values.

    ``p=2`` is the standard Euclidean vector norm.

    ``p=inf`` gives the magnitude of the largest element.

    For *x* a matrix, ``p=2`` is the Frobenius norm.
    For operator matrix norms, use :func:`mnorm` instead.

    You can use the string 'inf' as well as float('inf') or mpf('inf')
    to specify the infinity norm.

    **Examples**

        >>> from mpmath import *
        >>> mp.dps = 15
        >>> x = matrix([-10, 2, 100])
        >>> norm(x, 1)
        mpf('112.0')
        >>> norm(x, 2)
        mpf('100.5186549850325')
        >>> norm(x, inf)
        mpf('100.0')

    """
    try:
        iter(x)
    except TypeError:
        return absmax(x)
    if type(p) is not int:
        p = mpmathify(p)
    if p == inf:
        return max(absmax(i) for i in x)
    elif p == 1:
        return fsum(x, absolute=1)
    elif p == 2:
        return sqrt(fsum(x, absolute=1, squared=1))
    elif p > 1:
        return nthroot(fsum(abs(i)**p for i in x), p)
    else:
        raise ValueError('p has to be >= 1')
Beispiel #21
0
def norm(x, p=2):
    r"""
    Gives the entrywise `p`-norm of an iterable *x*, i.e. the vector norm
    `\left(\sum_k |x_k|^p\right)^{1/p}`, for any given `1 \le p \le \infty`.

    Special cases:

    If *x* is not iterable, this just returns ``absmax(x)``.

    ``p=1`` gives the sum of absolute values.

    ``p=2`` is the standard Euclidean vector norm.

    ``p=inf`` gives the magnitude of the largest element.

    For *x* a matrix, ``p=2`` is the Frobenius norm.
    For operator matrix norms, use :func:`mnorm` instead.

    You can use the string 'inf' as well as float('inf') or mpf('inf')
    to specify the infinity norm.

    **Examples**

        >>> from mpmath import *
        >>> mp.dps = 15
        >>> x = matrix([-10, 2, 100])
        >>> norm(x, 1)
        mpf('112.0')
        >>> norm(x, 2)
        mpf('100.5186549850325')
        >>> norm(x, inf)
        mpf('100.0')

    """
    try:
        iter(x)
    except TypeError:
        return absmax(x)
    if type(p) is not int:
        p = mpmathify(p)
    if p == inf:
        return max(absmax(i) for i in x)
    elif p == 1:
        return fsum(x, absolute=1)
    elif p == 2:
        return sqrt(fsum(x, absolute=1, squared=1))
    elif p > 1:
        return nthroot(fsum(abs(i)**p for i in x), p)
    else:
        raise ValueError('p has to be >= 1')
Beispiel #22
0
def householder(A):
    """
    (A|b) -> H, p, x, res

    (A|b) is the coefficient matrix with left hand side of an optionally
    overdetermined linear equation system.
    H and p contain all information about the transformation matrices.
    x is the solution, res the residual.
    """
    assert isinstance(A, matrix)
    m = A.rows
    n = A.cols
    assert m >= n - 1
    # calculate Householder matrix
    p = []
    for j in xrange(0, n - 1):
        s = 0.
        for i in xrange(j, m):
            s += (A[i,j])**2
        if not abs(s) > eps:
            raise ValueError('matrix is numerically singular')
        p.append(-sign(A[j,j]) * sqrt(s))
        kappa = s - p[j] * A[j,j]
        A[j,j] -= p[j]
        for k in xrange(j+1, n):
            y = 0.
            for i in xrange(j, m):
                y += A[i,j] * A[i,k]
            y /= kappa
            for i in xrange(j, m):
                A[i,k] -= A[i,j] * y
    # solve Rx = c1
    x = []
    for i in xrange(n - 1):
        x.append(A[i,n - 1])
    for i in xrange(n - 2, -1, -1):
        for j in xrange(i + 1, n - 1):
            x[i] -= A[i,j] * x[j]
        x[i] /= p[i]
    # calculate residual
    if not m == n - 1:
        r = []
        for i in xrange(m - n + 1):
            r.append(A[m-1-i, n-1])
    else:
        # determined system, residual should be 0
        r = [0]*m
    return A, p, x, r
Beispiel #23
0
def householder(A):
    """
    (A|b) -> H, p, x, res

    (A|b) is the coefficient matrix with left hand side of an optionally
    overdetermined linear equation system.
    H and p contain all information about the transformation matrices.
    x is the solution, res the residual.
    """
    assert isinstance(A, matrix)
    m = A.rows
    n = A.cols
    assert m >= n - 1
    # calculate Householder matrix
    p = []
    for j in xrange(0, n - 1):
        s = 0.
        for i in xrange(j, m):
            s += (A[i, j])**2
        if not abs(s) > eps:
            raise ValueError('matrix is numerically singular')
        p.append(-sign(A[j, j]) * sqrt(s))
        kappa = s - p[j] * A[j, j]
        A[j, j] -= p[j]
        for k in xrange(j + 1, n):
            y = 0.
            for i in xrange(j, m):
                y += A[i, j] * A[i, k]
            y /= kappa
            for i in xrange(j, m):
                A[i, k] -= A[i, j] * y
    # solve Rx = c1
    x = []
    for i in xrange(n - 1):
        x.append(A[i, n - 1])
    for i in xrange(n - 2, -1, -1):
        for j in xrange(i + 1, n - 1):
            x[i] -= A[i, j] * x[j]
        x[i] /= p[i]
    # calculate residual
    if not m == n - 1:
        r = []
        for i in xrange(m - n + 1):
            r.append(A[m - 1 - i, n - 1])
    else:
        # determined system, residual should be 0
        r = [0] * m
    return A, p, x, r
Beispiel #24
0
def jcn(u, m):
    """
    Computes of the Jacobi elliptic cn function in terms
    of Jacobi theta functions.
    `u` is any complex number, `m` must be in the unit disk

    The cn-function is doubly periodic in the complex
    plane with periods `4 K(m)` and `4 i K(1-m)`
    (see :func:`ellipk`)::

        >>> from mpmath import *
        >>> mp.dps = 25
        >>> print jcn(2, 0.25)
        -0.2698649654510865792581416
        >>> print jcn(2+4*ellipk(0.25), 0.25)
        -0.2698649654510865792581416
        >>> print chop(jcn(2+4*j*ellipk(1-0.25), 0.25))
        -0.2698649654510865792581416

    """
    if abs(m) < eps:
        return cos(u)
    elif m == one:
        return sech(u)
    else:
        extra = 10
    try:
        mp.prec += extra
        q = calculate_nome(sqrt(m))

        v3 = jtheta(3, zero, q)
        v2 = jtheta(2, zero, q)
        v04 = jtheta(4, zero, q)

        arg1 = u / (v3*v3)

        v1 = jtheta(2, arg1, q)
        v4 = jtheta(4, arg1, q)

        cn = (v04/v2)*(v1/v4)
    finally:
        mp.prec -= extra
    return cn
Beispiel #25
0
def jdn(u, m):
    """
    Computes of the Jacobi elliptic dn function in terms
    of Jacobi theta functions.
    `u` is any complex number, `m` must be in the unit disk

    The dn-function is doubly periodic in the complex
    plane with periods `2 K(m)` and `4 i K(1-m)`
    (see :func:`ellipk`)::

        >>> from mpmath import *
        >>> mp.dps = 25
        >>> print jdn(2, 0.25)
        0.8764740583123262286931578
        >>> print jdn(2+2*ellipk(0.25), 0.25)
        0.8764740583123262286931578
        >>> print chop(jdn(2+4*j*ellipk(1-0.25), 0.25))
        0.8764740583123262286931578

    """
    if m == zero:
        return one
    elif m == one:
        return sech(u)
    else:
        extra = 10
    try:
        mp.prec += extra
        q = calculate_nome(sqrt(m))

        v3 = jtheta(3, zero, q)
        v2 = jtheta(2, zero, q)
        v04 = jtheta(4, zero, q)

        arg1 = u / (v3*v3)

        v1 = jtheta(3, arg1, q)
        v4 = jtheta(4, arg1, q)

        cn = (v04/v3)*(v1/v4)
    finally:
        mp.prec -= extra
    return cn
Beispiel #26
0
def jsn(u, m):
    """
    Computes of the Jacobi elliptic sn function in terms
    of Jacobi theta functions.
    `u` is any complex number, `m` must be in the unit disk

    The sn-function is doubly periodic in the complex
    plane with periods `4 K(m)` and `2 i K(1-m)`
    (see :func:`ellipk`)::

        >>> from mpmath import *
        >>> mp.dps = 25
        >>> print jsn(2, 0.25)
        0.9628981775982774425751399
        >>> print jsn(2+4*ellipk(0.25), 0.25)
        0.9628981775982774425751399
        >>> print chop(jsn(2+2*j*ellipk(1-0.25), 0.25))
        0.9628981775982774425751399

    """
    if abs(m) < eps:
        return sin(u)
    elif m == one:
        return tanh(u)
    else:
        extra = 10
    try:
        mp.prec += extra
        q = calculate_nome(sqrt(m))

        v3 = jtheta(3, zero, q)
        v2 = jtheta(2, zero, q)        # mathworld says v4
        arg1 = u / (v3*v3)
        v1 = jtheta(1, arg1, q)
        v4 = jtheta(4, arg1, q)

        sn = (v3/v2)*(v1/v4)
    finally:
        mp.prec -= extra

    return sn
Beispiel #27
0
def jacobian(f, x):
    """
    Calculate the Jacobian matrix of a function at the point x0.

    This is the first derivative of a vectorial function:

        f : R^m -> R^n with m >= n
    """
    x = matrix(x)
    h = sqrt(eps)
    fx = matrix(f(*x))
    m = len(fx)
    n = len(x)
    J = matrix(m, n)
    for j in xrange(n):
        xj = x.copy()
        xj[j] += h
        Jj = (matrix(f(*xj)) - fx) / h
        for i in xrange(m):
            J[i,j] = Jj[i]
    return J
def jacobian(f, x):
    """
    Calculate the Jacobian matrix of a function at the point x0.

    This is the first derivative of a vectorial function:

        f : R^m -> R^n with m >= n
    """
    x = matrix(x)
    h = sqrt(eps)
    fx = matrix(f(*x))
    m = len(fx)
    n = len(x)
    J = matrix(m, n)
    for j in xrange(n):
        xj = x.copy()
        xj[j] += h
        Jj = (matrix(f(*xj)) - fx) / h
        for i in xrange(m):
            J[i, j] = Jj[i]
    return J
Beispiel #29
0
def calc(func: str, variables: str):
    """evaluates simple mathematical equations"""
    func = func.lower()
    try:
        if func == "gcf":
            var1, var2 = variables.split(',')[:2]
            return f.gcf(int(var1), int(var2))

        elif func == "regular":
            return f.reg(variables)

        else:
            var = int(variables)
            if func == "abs":
                return f.absolute(var)
            if func == 'sqrt':
                return f.sqrt(var)
            if func == 'factors':
                return f.factors(var)

    except Exception:
        return "Invalid Function or Expression:", func
Beispiel #30
0
def cholesky(A):
    """
    Cholesky decompositon of a symmetric positive-definite matrix.

    Can be used to solve linear equation systems twice as efficient compared
    to LU decomposition or to test whether A is positive-definite.

    A = L * L.T
    Only L (the lower part) is returned.
    """
    assert isinstance(A, matrix)
    if not A.rows == A.cols:
        raise ValueError('need n*n matrix')
    n = A.rows
    L = matrix(n)
    for j in xrange(n):
        s = A[j,j] - fsum(L[j,k]**2 for k in xrange(j))
        if s < eps:
            raise ValueError('matrix not positive-definite')
        L[j,j] = sqrt(s)
        for i in xrange(j, n):
            L[i,j] = (A[i,j] - fsum(L[i,k] * L[j,k] for k in xrange(j))) \
                     / L[j,j]
    return L
Beispiel #31
0
def cholesky(A):
    """
    Cholesky decompositon of a symmetric positive-definite matrix.

    Can be used to solve linear equation systems twice as efficient compared
    to LU decomposition or to test whether A is positive-definite.

    A = L * L.T
    Only L (the lower part) is returned.
    """
    assert isinstance(A, matrix)
    if not A.rows == A.cols:
        raise ValueError('need n*n matrix')
    n = A.rows
    L = matrix(n)
    for j in xrange(n):
        s = A[j, j] - sum((L[j, k]**2 for k in xrange(j)))
        if s < eps:
            raise ValueError('matrix not positive-definite')
        L[j, j] = sqrt(s)
        for i in xrange(j, n):
            L[i,j] = (A[i,j] - sum((L[i,k] * L[j,k] for k in xrange(j)))) \
                     / L[j,j]
    return L
Beispiel #32
0
 def sqrt(self):
     return F.sqrt(self)
Beispiel #33
0
def jacobi_theta_4(z, m):
    """
    Implements the series expansion of the jacobi theta function
    1, where z == 0.

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    delta_sum = 1
    term = 1  # series starts at 1

    zero = mpf('0')

    if z == zero:
        factor2 = mpf('1')
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term * term)
            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1
    else:
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term * term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2 * term * z)

            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):  # all further terms will be zero
                break
            if factor2 != mpf('0'):  # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2 * sum
Beispiel #34
0
def jacobi_theta_2(z, m, verbose=False):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_theta_2'

    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if verbose:
        print >> sys.stderr, '\tk: %f ' % k
        print >> sys.stderr, '\tq: %f ' % q

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    term = 0  # series starts at zero

    zero = mpf('0')

    if q == zero:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: q == 0, return 0'
        return zero
    else:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: calculating'
        if z == zero:
            factor2 = mpf('1')
            while True:
                factor1 = q**(term * (term + 1))
                term_n = factor1  # suboptimal, kept for readability
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:  # all further terms will be zero
                    break
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

                term = term + 1
        else:
            while True:
                factor1 = q**(term * (term + 1))
                if z == zero:
                    factor2 = 1
                else:
                    factor2 = cos((2 * term + 1) * z)

                term_n = factor1 * factor2
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:  # all further terms will be zero
                    break
                if factor2 != zero:  # check precision iff cos != 0
                    #if log(term_n, '10') < -1*mpf.dps:
                    if abs(term_n) < eps:
                        break

                term = term + 1

        return (2 * q**(0.25)) * sum

    # can't get here
    print >> sys.stderr, 'elliptic.jacobi_theta_2 in impossible state'
    sys.exit(2)
Beispiel #35
0
 def sqrt(s):
     from functions import sqrt
     return sqrt(s)
Beispiel #36
0
 def sqrt(s):
     from functions import sqrt
     return sqrt(s)
Beispiel #37
0
def evalf(expr):
    """
    evalf(expr) attempts to evaluate a SymPy expression to a Float or
    ComplexFloat with an error smaller than 10**(-Float.getdps())
    """

    if isinstance(expr, (Float, ComplexFloat)):
        return expr
    elif isinstance(expr, (int, float)):
        return Float(expr)
    elif isinstance(expr, complex):
        return ComplexFloat(expr)

    expr = Basic.sympify(expr)

    if isinstance(expr, (Rational)):
        y = Float(expr)
    elif isinstance(expr, Real):
        y = Float(str(expr))

    elif expr is I:
        y = ComplexFloat(0,1)

    elif expr is pi:
        y = constants.pi_float()

    elif expr is E:
        y = functions.exp(1)

    elif isinstance(expr, Mul):
        factors = expr[:]
        workprec = Float.getprec() + 1 + len(factors)
        Float.store()
        Float.setprec(workprec)
        y = Float(1)
        for f in factors:
            y *= evalf(f)
        Float.revert()

    elif isinstance(expr, Pow):
        base, expt = expr[:]
        workprec = Float.getprec() + 8 # may need more
        Float.store()
        Float.setprec(workprec)
        base = evalf(base)
        expt = evalf(expt)
        if expt == 0.5:
            y = functions.sqrt(base)
        else:
            y = functions.exp(functions.log(base) * expt)
        Float.revert()

    elif isinstance(expr, Basic.exp):
        Float.store()
        Float.setprec(Float.getprec() + 3)
        #XXX: how is it possible, that this works:
        x = evalf(expr[0])
        #and this too:
        #x = evalf(expr[1])
        #?? (Try to uncomment it and you'll see)
        y = functions.exp(x)
        Float.revert()

    elif isinstance(expr, Add):
        # TODO: this doesn't yet work as it should.
        # We need some way to handle sums whose results are
        # very close to 0, and when necessary, repeat the
        # summation with higher precision
        reqprec = Float.getprec()
        Float.store()
        Float.setprec(10)
        terms = expr[:]
        approxterms = [abs(evalf(x)) for x in terms]
        min_mag = min(x.exp for x in approxterms)
        max_mag = max(x.exp+bitcount(x.man) for x in approxterms)
        Float.setprec(reqprec - 10 + max_mag - min_mag + 1 + len(terms))
        workprec = Float.getdps()
        y = 0
        for t in terms:
            y += evalf(t)
        Float.revert()

    else:
        # print expr, expr.__class__
        raise NotImplementedError

    # print expr, y

    return +y
Beispiel #38
0
def jacobi_theta_2(z, m, verbose=False):
    """
    Implements the jacobi theta function 2, using the series expansion
    found in Abramowitz & Stegun [4].

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    if verbose:
        print >> sys.stderr, 'elliptic.jacobi_theta_2'

    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if verbose:
        print >> sys.stderr, '\tk: %f ' % k
        print >> sys.stderr, '\tq: %f ' % q

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    term = 0                    # series starts at zero

    zero = mpf('0')

    if q == zero:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: q == 0, return 0'
        return zero
    else:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_theta_2: calculating'
        if z == zero:
            factor2 = mpf('1')
            while True:
                factor1 = q**(term*(term + 1))
                term_n = factor1            # suboptimal, kept for readability
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:         # all further terms will be zero
                    break
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

                term = term + 1
        else:
            while True:
                factor1 = q**(term*(term + 1))
                if z == zero:
                    factor2 = 1
                else:
                    factor2 = cos((2*term + 1)*z)

                term_n = factor1 * factor2
                sum = sum + term_n

                if verbose:
                    print >> sys.stderr, '\tTerm: %d' % term,
                    print >> sys.stderr, '\tterm_n: %e' % term_n,
                    print >> sys.stderr, '\tsum: %e' % sum

                if factor1 == zero:         # all further terms will be zero
                    break
                if factor2 != zero:         # check precision iff cos != 0
                    #if log(term_n, '10') < -1*mpf.dps:
                    if abs(term_n) < eps:
                        break

                term = term + 1

        return (2*q**(0.25))*sum

    # can't get here
    print >> sys.stderr, 'elliptic.jacobi_theta_2 in impossible state'
    sys.exit(2)
Beispiel #39
0

# Transformation y = f(x,c), with inverse function x = f(y,c)
# The third entry indicates whether the transformation is
# redundant when c = 1
transforms = [
    (lambda x, c: x * c, '$y/$c', 0),
    (lambda x, c: x / c, '$c*$y', 1),
    (lambda x, c: c / x, '$c/$y', 0),
    (lambda x, c: (x * c)**2, 'sqrt($y)/$c', 0),
    (lambda x, c: (x / c)**2, '$c*sqrt($y)', 1),
    (lambda x, c: (c / x)**2, '$c/sqrt($y)', 0),
    (lambda x, c: c * x**2, 'sqrt($y)/sqrt($c)', 1),
    (lambda x, c: x**2 / c, 'sqrt($c)*sqrt($y)', 1),
    (lambda x, c: c / x**2, 'sqrt($c)/sqrt($y)', 1),
    (lambda x, c: sqrt(x * c), '$y**2/$c', 0),
    (lambda x, c: sqrt(x / c), '$c*$y**2', 1),
    (lambda x, c: sqrt(c / x), '$c/$y**2', 0),
    (lambda x, c: c * sqrt(x), '$y**2/$c**2', 1),
    (lambda x, c: sqrt(x) / c, '$c**2*$y**2', 1),
    (lambda x, c: c / sqrt(x), '$c**2/$y**2', 1),
    (lambda x, c: exp(x * c), 'log($y)/$c', 0),
    (lambda x, c: exp(x / c), '$c*log($y)', 1),
    (lambda x, c: exp(c / x), '$c/log($y)', 0),
    (lambda x, c: c * exp(x), 'log($y/$c)', 1),
    (lambda x, c: exp(x) / c, 'log($c*$y)', 1),
    (lambda x, c: c / exp(x), 'log($c/$y)', 0),
    (lambda x, c: log(x * c), 'exp($y)/$c', 0),
    (lambda x, c: log(x / c), '$c*exp($y)', 1),
    (lambda x, c: log(c / x), '$c/exp($y)', 0),
    (lambda x, c: c * log(x), 'exp($y/$c)', 1),
Beispiel #40
0
def jacobi_theta_4(z, m):
    """
    Implements the series expansion of the jacobi theta function
    1, where z == 0.

    z is any complex number, but only reals here?
    m is the parameter, which must be converted to the nome
    """
    m = convert_lossless(m)
    z = convert_lossless(z)

    k = sqrt(m)
    q = calculate_nome(k)

    if abs(q) >= mpf('1'):
        raise ValueError

    sum = 0
    delta_sum = 1
    term = 1                    # series starts at 1

    zero = mpf('0')

    if z == zero:
        factor2 = mpf('1')
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term*term)
            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

            term = term + 1
    else:
        while True:
            if (term % 2) == 0:
                factor0 = 1
            else:
                factor0 = -1
            factor1 = q**(term*term)
            if z == zero:
                factor2 = 1
            else:
                factor2 = cos(2*term*z)

            term_n = factor0 * factor1 * factor2
            sum = sum + term_n

            if factor1 == mpf('0'):      # all further terms will be zero
                break
            if factor2 != mpf('0'):      # check precision iff cos != 0
                #if log(term_n, '10') < -1*mpf.dps:
                if abs(term_n) < eps:
                    break

            term = term + 1

    return 1 + 2*sum
Beispiel #41
0
def jacobi_elliptic_sn(u, m, verbose=False):
    """
    Implements the jacobi elliptic sn function, using the expansion in
    terms of q, from Abramowitz 16.23.1.

    u is any complex number, m is the parameter

    Alternative implementation:

    Expansion in terms of jacobi theta functions appears to fail with
    round off error, despite   I also think that the expansion in
    terms of q is much faster than four expansions in terms of q.

    **********************************
    Previous implementation kept here:

    if not isinstance(u, mpf):
        raise TypeError
    if not isinstance(m, mpf):
        raise TypeError

    zero = mpf('0')

    if u == zero and m == 0:
        return zero
    else:
        q = calculate_nome(sqrt(m))

        v3 = jacobi_theta_3(zero, q)
        v2 = jacobi_theta_2(zero, q)        # mathworld says v4

        arg1 = u / (v3*v3)

        v1 = jacobi_theta_1(arg1, q)
        v4 = jacobi_theta_4(arg1, q)

        sn = (v3/v2)*(v1/v4)

        return sn
    **********************************
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_sn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:  # sn collapes to sin(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 0'
        return sin(u)
    elif m == one:  # sn collapses to tanh(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 1'
        return tanh(u)
    else:
        k = sqrt(m)  # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two * ellipk(k**2))

    if v == pi or v == zero:  # sin factor always zero
        return zero

    sum = zero
    term = zero  # series starts at zero

    while True:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_elliptic_sn: calculating'
        factor1 = (q**(term + onehalf)) / (one - q**(two * term + one))
        factor2 = sin((two * term + one) * v)

        term_n = factor1 * factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two * pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Beispiel #42
0
def jacobi_elliptic_sn(u, m, verbose=False):
    """
    Implements the jacobi elliptic sn function, using the expansion in
    terms of q, from Abramowitz 16.23.1.

    u is any complex number, m is the parameter

    Alternative implementation:

    Expansion in terms of jacobi theta functions appears to fail with
    round off error, despite   I also think that the expansion in
    terms of q is much faster than four expansions in terms of q.

    **********************************
    Previous implementation kept here:

    if not isinstance(u, mpf):
        raise TypeError
    if not isinstance(m, mpf):
        raise TypeError

    zero = mpf('0')

    if u == zero and m == 0:
        return zero
    else:
        q = calculate_nome(sqrt(m))

        v3 = jacobi_theta_3(zero, q)
        v2 = jacobi_theta_2(zero, q)        # mathworld says v4

        arg1 = u / (v3*v3)

        v1 = jacobi_theta_1(arg1, q)
        v4 = jacobi_theta_4(arg1, q)

        sn = (v3/v2)*(v1/v4)

        return sn
    **********************************
    """
    u = convert_lossless(u)
    m = convert_lossless(m)

    if verbose:
        print >> sys.stderr, '\nelliptic.jacobi_elliptic_sn'
        print >> sys.stderr, '\tu: %1.12f' % u
        print >> sys.stderr, '\tm: %1.12f' % m

    zero = mpf('0')
    onehalf = mpf('0.5')
    one = mpf('1')
    two = mpf('2')

    if m == zero:           # sn collapes to sin(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 0'
        return sin(u)
    elif m == one:          # sn collapses to tanh(u)
        if verbose:
            print >> sys.stderr, '\nsn: special case, m == 1'
        return tanh(u)
    else:
        k = sqrt(m)                        # convert m to k
        q = calculate_nome(k)
        v = (pi * u) / (two*ellipk(k**2))

    if v == pi or v == zero:     # sin factor always zero
        return zero

    sum = zero
    term = zero                     # series starts at zero

    while True:
        if verbose:
            print >> sys.stderr, 'elliptic.jacobi_elliptic_sn: calculating'
        factor1 = (q**(term + onehalf)) / (one - q**(two*term + one))
        factor2 = sin((two*term + one)*v)

        term_n = factor1*factor2
        sum = sum + term_n

        if verbose:
            print >> sys.stderr, '\tTerm: %d' % term,
            print >> sys.stderr, '\tterm_n: %e' % term_n,
            print >> sys.stderr, '\tsum: %e' % sum

        if not factor2 == zero:
            #if log(term_n, '10') < -1*mpf.dps:
            if abs(term_n) < eps:
                break

        term = term + one

    answer = (two*pi) / (sqrt(m) * ellipk(k**2)) * sum

    return answer
Beispiel #43
0
### Dervla Candon
### Squareroot program using the function sqrt()

x = float(input("Please enter a positive number: "))
check1 = -1
##using a check value to allow for rerunning of the while loop
##in the event of user input of a negative number
import functions  ##for sqrt() function
while check1 < 0:
    if x < 0:
        print("This value is negative, please try again.")
        x = float(input("Please enter a positive number: "))
        ##no change to check value so that while loop will run again with new value for x
    else:
        print("\nThe squareroot of", x, "is", functions.sqrt(x), "\n")
        check1 = x  ##ends the while loop
Beispiel #44
0
    return s

# Transformation y = f(x,c), with inverse function x = f(y,c)
# The third entry indicates whether the transformation is
# redundant when c = 1
transforms = [
  (lambda x,c: x*c, '$y/$c', 0),
  (lambda x,c: x/c, '$c*$y', 1),
  (lambda x,c: c/x, '$c/$y', 0),
  (lambda x,c: (x*c)**2, 'sqrt($y)/$c', 0),
  (lambda x,c: (x/c)**2, '$c*sqrt($y)', 1),
  (lambda x,c: (c/x)**2, '$c/sqrt($y)', 0),
  (lambda x,c: c*x**2, 'sqrt($y)/sqrt($c)', 1),
  (lambda x,c: x**2/c, 'sqrt($c)*sqrt($y)', 1),
  (lambda x,c: c/x**2, 'sqrt($c)/sqrt($y)', 1),
  (lambda x,c: sqrt(x*c), '$y**2/$c', 0),
  (lambda x,c: sqrt(x/c), '$c*$y**2', 1),
  (lambda x,c: sqrt(c/x), '$c/$y**2', 0),
  (lambda x,c: c*sqrt(x), '$y**2/$c**2', 1),
  (lambda x,c: sqrt(x)/c, '$c**2*$y**2', 1),
  (lambda x,c: c/sqrt(x), '$c**2/$y**2', 1),
  (lambda x,c: exp(x*c), 'log($y)/$c', 0),
  (lambda x,c: exp(x/c), '$c*log($y)', 1),
  (lambda x,c: exp(c/x), '$c/log($y)', 0),
  (lambda x,c: c*exp(x), 'log($y/$c)', 1),
  (lambda x,c: exp(x)/c, 'log($c*$y)', 1),
  (lambda x,c: c/exp(x), 'log($c/$y)', 0),
  (lambda x,c: log(x*c), 'exp($y)/$c', 0),
  (lambda x,c: log(x/c), '$c*exp($y)', 1),
  (lambda x,c: log(c/x), '$c/exp($y)', 0),
  (lambda x,c: c*log(x), 'exp($y/$c)', 1),
Beispiel #45
0
def test_sqrt(x, decimals):
    import functions
    tol = 10**(-decimals)
    assert_almost_equal(functions.sqrt(x, tol=tol),
                        np.sqrt(x),
                        decimal=decimals - 1)
Beispiel #46
0
def test_sqrt():
    assert functions.sqrt(4) == 2
    assert functions.sqrt(4) != 4