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