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
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()
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
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
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()
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
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
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
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
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
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
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
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
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
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
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)))
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
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
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
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')
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
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
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
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
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
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
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
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
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
def sqrt(self): return F.sqrt(self)
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
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)
def sqrt(s): from functions import sqrt return sqrt(s)
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
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)
# 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),
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
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
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
### 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
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),
def test_sqrt(x, decimals): import functions tol = 10**(-decimals) assert_almost_equal(functions.sqrt(x, tol=tol), np.sqrt(x), decimal=decimals - 1)
def test_sqrt(): assert functions.sqrt(4) == 2 assert functions.sqrt(4) != 4