def Pinv(self, P): from mpmath import ellipf, sqrt, asin, acos, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: P = -P if Delta > 0: m = (e2 - e3) / (e1 - e3) retval = (1 / sqrt(e1 - e3)) * ellipf( asin(sqrt((e1 - e3) / (P - e3))), m=m) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert (H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) retval = 1 / (2 * sqrt(H2)) * ellipf(acos( (e2 - P + H2) / (e2 - P - H2)), m=m) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / sqrt(P) else: c = e1 / 2 retval = (1 / sqrt(3 * c)) * asin(sqrt((3 * c) / (P + c))) if self.__ng3: retval /= mpc(0, 1) alpha, beta, _, _ = self.reduce_to_fpp(retval) T1, T2 = self.periods return T1 * alpha + T2 * beta
def Pinv(self,P): from mpmath import ellipf, sqrt, asin, acos, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: P = -P if Delta > 0: m = (e2 - e3) / (e1 - e3) retval = (1 / sqrt(e1 - e3)) * ellipf(asin(sqrt((e1 - e3)/(P - e3))),m=m) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) retval = 1 / (2 * sqrt(H2)) * ellipf(acos((e2-P+H2)/(e2-P-H2)),m=m) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / sqrt(P) else: c = e1 / 2 retval = (1 / sqrt(3 * c)) * asin(sqrt((3 * c)/(P + c))) if self.__ng3: retval /= mpc(0,1) alpha, beta, _, _ = self.reduce_to_fpp(retval) T1, T2 = self.periods return T1 * alpha + T2 * beta
def phi_inf(P, M): Qvar = Q(P, M) ksq = (Qvar - P + 6. * M) / (2. * Qvar) zinf = zeta_inf(P, M) phi = 2. * (mpmath.sqrt( P / Qvar)) * (mpmath.ellipk(ksq) - mpmath.ellipf(zinf, ksq)) return phi
def calc_lambda_0(chi, zp, zm, En, Lz, aa, slr, x): """ Mino time as a function of polar angle, chi Parameters: chi (float): polar angle zp (float): polar root zm (float): polar root En (float): energy Lz (float): angular momentum aa (float): spin slr (float): semi-latus rectum x (float): inclination Returns: lambda_0 (float) """ pi = mp.pi beta = aa * aa * (1 - En * En) k = sqrt(zm / zp) k2 = k * k prefactor = 1 / sqrt(beta * zp) ellipticK_k = ellipk(k2) ellipticF = ellipf(pi / 2 - chi, k2) return prefactor * (ellipticK_k - ellipticF)
def z_Zolotarev(N, x, m): r""" Function to evaluate the Zolotarev polynomial (eq 1, [McNamara93]_). :param N: Order of the Zolotarev polynomial :param x: The argument at which one would like to evaluate the Zolotarev polynomial :param m: m is the elliptic parameter (not the modulus k and not the nome q) :rtype: Returns a float, the value of Zolotarev polynomial at x """ M = -ellipk(m) / N x3 = ellipfun('sn', u=-M, m=m) xbar = x3 * mp.sqrt( (x**2 - 1) / (x**2 - x3**2)) # rearranged eq 21, [Levy70]_ u = ellipf(mp.asin(xbar), m) # rearranged eq 20, [Levy70]_, asn(x) = F(asin(x)|m) f = mp.cosh((N / 2) * mp.log(z_eta(M + u, m) / z_eta(M - u, m))) if f.imag / f.real > 1e-10: print("imaginary part of the Zolotarev function is not negligible!") print("f_imaginary = ", f.imag) else: if (x > 0): # no idea why I am doing this ... anyhow, it seems working f = -f.real else: f = f.real return f
def param_position(self, x, y, z): """ see: https://www.wolframalpha.com/input/?i=integral+sqrt(+1%2B(3nx%5E2)%5E2+) """ from mpmath import ellipf x = x.reshape(-1).astype(numpy.complex) # coefs shortcut n = self.coef ni = numpy.sqrt(n * 1j) sq3 = numpy.sqrt(3) sq9n2x4 = numpy.sqrt(9 * (n**2) * (x**4) + 1) # calculation num1 = 27 * (n**3) * (x**5) num2 = 2 * sq3 * sq9n2x4 num3 = 1j * numpy.arcsinh(sq3 * ni * x) for i, n in enumerate(num3): num3[i] = ellipf(n, -1) num4 = 3 * n * x den = 9 * n * sq9n2x4 x = (num1 - num2 * num3 + num4) / den x = numpy.real(x) return numpy.hstack([x.reshape(-1, 1), y.reshape(-1, 1)])
def __compute_t_r(self,n_lobes,lobe_idx,H_in,Hr,d_eval,p4roots,lead_cf): from pyranha import math from mpmath import asin, sqrt, ellipf, mpf assert(n_lobes == 1 or n_lobes == 2) C = -lead_cf assert(C > 0) # First determine if we are integrating in the upper or lower plane. # NOTE: we don't care about eps, we are only interested in the sign. if (self.__F1 * math.sin(pt('h_\\ast'))).trim().evaluate(d_eval) > 0: sign = 1 else: sign = -1 if n_lobes == 2: assert(lobe_idx == 0 or lobe_idx == 1) r0,r1,r2,r3 = p4roots # k is the same in both cases. k = sqrt(((r3-r2)*(r1-r0))/((r3-r1)*(r2-r0))) if lobe_idx == 0: assert(Hr == r0) phi = asin(sqrt(((r3-r1)*(H_in-r0))/((r1-r0)*(r3-H_in)))) else: assert(Hr == r2) phi = asin(sqrt(((r3-r1)*(H_in-r2))/((H_in-r1)*(r3-r2)))) return -sign * mpf(2) / sqrt(C * (r3 - r1) * (r2 - r0)) * ellipf(phi,k**2) else: # TODO: single lobe case. assert(False) pass
def do_approximation(self): epsilonp = np.sqrt(np.power(10, self.Ap / 10) - 1) gp = np.power(10, -self.Ap / 20) k1 = np.sqrt((np.power(10, self.Ap / 10) - 1) / (np.power(10, self.Ao / 10) - 1)) k = 1 / self.wan a = mp.asin(1j / epsilonp) vo = mp.ellipf(1j / epsilonp, k1) / (1j * self.n) self.n = np.ceil( special.ellipk(np.sqrt(1 - np.power(k1, 2))) * special.ellipk(k) / (special.ellipk(k1) * special.ellipk(np.sqrt(1 - np.power(k, 2))))) for i in range(1, int(np.floor(self.n / 2)) + 1): cd = mp.ellipfun('cd', (2 * i - 1) / self.n, k) zero = (1j / (float(k * cd.real) + 1j * float(k * cd.imag))) self.num = self.num * np.poly1d([1 / zero, 1]) self.num = self.num * np.poly1d([1 / np.conj(zero), 1]) cd = mp.ellipfun('cd', (2 * i - 1) / self.n - 1j * vo, k) pole = 1j * (float(cd.real) + 1j * float(cd.imag)) if np.real(pole) <= 0: self.den = self.den * np.poly1d([-1 / pole, 1]) self.den = self.den * np.poly1d([-1 / np.conj(pole), 1]) if np.mod(self.n, 2) == 1: sn = 1j * mp.ellipfun('sn', 1j * vo, k) pole = 1j * (float(sn.real) + 1j * float(sn.imag)) if np.real(pole) <= 0: self.den = self.den * np.poly1d([-1 / pole, 1]) self.den = self.den * np.poly1d([-1 / np.conj(pole), 1]) self.zeroes = np.roots(self.num) self.poles = np.roots(self.den) self.aprox_gain = np.power(gp, 1 - (self.n - 2 * np.floor(self.n / 2))) self.num = self.num * self.aprox_gain self.norm_sys = signal.TransferFunction( self.num, self.den) #Filter system is obtained
def F(zeta: float, m): """Calculates the incomplete elliptic integral of argument zeta and mod m = k² Args: zeta: the argument of the elliptic integral m: the modulus of the elliptic integral. mpmath takes m=k² as modulus Returns: float: the value of the elliptic integral of argument zeta and modulus m=k²""" return mpmath.ellipf(zeta, m) # takes k**2 as mod, not k
def one_side(x,y): m = ((-1 + x)*(1 + y))/((1 + x)*(-1 + y)) k = sqrt(m) u = asin(1/k) EE = ellipe(m) EF = re(ellipf(u,m)) n = (-1 + x)/(-1 + y) EPI = ellippi(n/m,1/m)/k #EPI = ellippi(n,u,m) return re(-(EE*(1 + x)*(-1 + y) + (x - y)*(EF + EPI*(x-y) + EF*y))/sqrt(((1 + x)*(1 - y))))
def __compute_tau_eta(self): # Gradshtein 3.131.5. from mpmath import sqrt, asin, ellipf u = self.__init_coordinates[1]**2 / 2 c,b,a = self.__roots_eta k = asin(sqrt(((a - c) * (u - b)) / ((a - b) * (u - c)))) p = sqrt((a - b) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(k,p**2) if self.__init_momenta[1] >= 0: return -abs(retval) else: return abs(retval)
def psi_x(z, x, beta): """ Eq.(24) from Ref[1] with argument zeta=0 and no constant factor e*beta**2/2/rho**2. Note that 'x' here corresponds to 'chi = x/rho', and 'z' here corresponds to 'xi = z/2/rho' in the paper. """ kap = kappa(z, x, beta) alp = alpha(z, x, beta) arg2 = -4 * (1 + x) / x**2 T1 = (1 / fabs(x) / (1 + x) * ((2 + 2 * x + x**2) * ellipf(alp, arg2) - x**2 * ellipe(alp, arg2))) D = kap**2 - beta**2 * (1 + x)**2 * sin(2 * alp)**2 T2 = ((kap**2 - 2 * beta**2 * (1 + x)**2 + beta**2 * (1 + x) * (2 + 2 * x + x**2) * cos(2 * alp)) / beta / (1 + x) / D) T3 = -kap * sin(2 * alp) / D T4 = kap * beta**2 * (1 + x) * sin(2 * alp) * cos(2 * alp) / D T5 = 1 / fabs(x) * ellipf(alp, arg2) # psi_phi without e/rho**2 factor out = re((T1 + T2 + T3 + T4) - 2 / beta**2 * T5) return out
def __compute_tau_eta(self): # Gradshtein 3.131.5. from mpmath import sqrt, asin, ellipf u = self.__init_coordinates[1]**2 / 2 c, b, a = self.__roots_eta k = asin(sqrt(((a - c) * (u - b)) / ((a - b) * (u - c)))) p = sqrt((a - b) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(k, p**2) if self.__init_momenta[1] >= 0: return -abs(retval) else: return abs(retval)
def __compute_tau_xi(self): from mpmath import sqrt, asin, ellipf, mpc, atan if self.bound: # Gradshtein 3.131.3. u = self.__init_coordinates[0]**2 / 2 c, b, a = self.__roots_xi gamma = asin(sqrt((u - c) / (b - c))) q = sqrt((b - c) / (a - c)) # NOTE: here it's q**2 instead of q because of the difference in # convention between G and mpmath :( # NOTE: the external factor 1 / sqrt(8 * self.eps) comes from the fact # that G gives the formula for a polynomial normalised by its leading coefficient. retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf( gamma, q**2) else: # Here we will need two cases: one for when the other two roots are real # but negative, one for when the other two roots are imaginary. if isinstance(self.__roots_xi[1], mpc): # G 3.138.7. m = self.__roots_xi[1].real n = abs(self.__roots_xi[1].imag) # Only real root is the first one. a = self.__roots_xi[0] u = self.__init_coordinates[0]**2 / 2 p = sqrt((m - a)**2 + n**2) retval = 1 / sqrt(8 * self.eps) * (1 / sqrt(p)) * ellipf( 2 * atan(sqrt((u - a) / p)), (p + m - a) / (2 * p)) else: # G 3.131.7. u = self.__init_coordinates[0]**2 / 2 c, b, a = self.__roots_xi mu = asin(sqrt((u - a) / (u - b))) q = sqrt((b - c) / (a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf( mu, q**2) # Fix the sign according to the initial momentum. if self.__init_momenta[0] >= 0: return -abs(retval) else: return abs(retval)
def xtau(phi): out = np.zeros((6, )) s, c, A, B = consts(phi) E = ellipe(asin(w * c), 1 / w) F = ellipf(asin(w * c), 1 / w) out[0] = -2 * A * (s**2 * B + w * s**3) # x_D1 out[1] = A * (w * E + 3 * w * c + 2 * s * c * B - 2 * w * c**3) # y_D1 out[3] = 2 * l * F / w - 3 * w * E * A - 3 * w * c * A # y_D2 out[4] = A * (B * (2 * w**2 * c**2 - w**2 - 1) - 2 * w**3 * s**3 + 2 * w * (w**2 - 1) * s) # x_I out[5] = A * (w * E + 2 * w**2 * s * c * B - 2 * w**3 * c**3 + w * c * (2 + w**2)) # y_I return out
def __compute_tau_xi(self): from mpmath import sqrt, asin, ellipf, mpc, atan if self.bound: # Gradshtein 3.131.3. u = self.__init_coordinates[0]**2 / 2 c,b,a = self.__roots_xi gamma = asin(sqrt((u - c)/(b - c))) q = sqrt((b - c)/(a - c)) # NOTE: here it's q**2 instead of q because of the difference in # convention between G and mpmath :( # NOTE: the external factor 1 / sqrt(8 * self.eps) comes from the fact # that G gives the formula for a polynomial normalised by its leading coefficient. retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(gamma,q**2) else: # Here we will need two cases: one for when the other two roots are real # but negative, one for when the other two roots are imaginary. if isinstance(self.__roots_xi[1],mpc): # G 3.138.7. m = self.__roots_xi[1].real n = abs(self.__roots_xi[1].imag) # Only real root is the first one. a = self.__roots_xi[0] u = self.__init_coordinates[0]**2 / 2 p = sqrt((m - a)**2 + n**2) retval = 1 / sqrt(8 * self.eps) * (1 / sqrt(p)) * ellipf(2 * atan(sqrt((u - a) / p)),(p + m - a) / (2*p)) else: # G 3.131.7. u = self.__init_coordinates[0]**2 / 2 c,b,a = self.__roots_xi mu = asin(sqrt((u - a)/(u - b))) q = sqrt((b - c)/(a - c)) retval = 1 / sqrt(8 * self.eps) * (2 / sqrt(a - c)) * ellipf(mu,q**2) # Fix the sign according to the initial momentum. if self.__init_momenta[0] >= 0: return -abs(retval) else: return abs(retval)
def elliptic_core_g(x,y): x = x/2 y = y/2 factor = (cos(x)/sin(y) + sin(y)/cos(x) - (cos(y)/tan(y)/cos(x) + sin(x)*tan(x)/sin(y)))/pi k = tan(x)/tan(y) m = k*k n = (sin(x)/sin(y))*(sin(x)/sin(y)) u = asin(tan(y)/tan(x)) complete = ellipk(m) - ellippi(n, m) incomplete = ellipf(u,m) - ellippi(n/k/k,1/m)/k #incomplete = ellipf(u,m) - ellippi(n,u,m) return re(1.0 - factor*(incomplete + complete))
def z_Zolotarev(N, x, m): """Function to evaluate the Zolotarev polynomial (eq 1, [McNamara93]_).""" M = -ellipk(m) / N x3 = ellipfun('sn', u= -M, m=m) xbar = x3 * mp.sqrt((x ** 2 - 1) / (x ** 2 - x3 ** 2)) # rearranged eq 21, [Levy70]_ u = ellipf(mp.asin(xbar), m) # rearranged eq 20, [Levy70]_, asn(x) = F(asin(x)|m) f = mp.cosh((N / 2) * mp.log(z_eta(M + u, m) / z_eta(M - u, m))) if (f.imag / f.real > 1e-10): print "imaginary part of the Zolotarev function is not negligible!" print "f_imaginary = ", f.imag else: if (x > 0): # no idea why I am doing this ... anyhow, it seems working f = -f.real else: f = f.real return f
def calc_abel(k, zeta, eta): k1 = sqrt(1 - k**2) a = k1 + complex(0, 1) * k b = k1 - complex(0, 1) * k abel_tmp = map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) abel = [] for i in range(0, 4, 1): abel.append(abel_select(k, abel_tmp[i], eta[i])) return abel
def calc_abel(k, zeta, eta): k1 = sqrt(1-k**2) a=k1+complex(0, 1)*k b=k1-complex(0, 1)*k abel_tmp = map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) abel = [] for i in range(0, 4, 1): abel.append(abel_select(k, abel_tmp[i], eta[i])) return abel
def z_Zolotarev(N, x, m): """Function to evaluate the Zolotarev polynomial (eq 1, [McNamara93]_).""" M = -ellipk(m) / N x3 = ellipfun('sn', u=-M, m=m) xbar = x3 * mp.sqrt( (x**2 - 1) / (x**2 - x3**2)) # rearranged eq 21, [Levy70]_ u = ellipf(mp.asin(xbar), m) # rearranged eq 20, [Levy70]_, asn(x) = F(asin(x)|m) f = mp.cosh((N / 2) * mp.log(z_eta(M + u, m) / z_eta(M - u, m))) if (f.imag / f.real > 1e-10): print("imaginary part of the Zolotarev function is not negligible!") print("f_imaginary = ", f.imag) else: if (x > 0): # no idea why I am doing this ... anyhow, it seems working f = -f.real else: f = f.real return f
def test_on_line(k, x0, x1, y, z, partition_size): k1 = sqrt(1 - k**2) a = k1 + complex(0, 1) * k b = k1 - complex(0, 1) * k x_step = (x1 - x0) / partition_size for i in range(0, partition_size): x = x0 + i * x_step zeta = calc_zeta(k, x, y, z) eta = calc_eta(k, x, y, z) abel = calc_abel(k, zeta, eta) mu = calc_mu(k, x, y, z, zeta, abel) print "zeta/a", zeta[0] / a, zeta[1] / a, zeta[2] / a, zeta[3] / a, '\n' print "eta", eta[0], eta[1], eta[2], eta[3], '\n' print "abel", abel[0], abel[1], abel[2], abel[3], '\n' abel_tmp= map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) print "abel_tmp", abel_tmp[0], abel_tmp[1], abel_tmp[2], abel_tmp[ 3], '\n' print abel[0] + conj(abel[2]), abel[1] + conj(abel[3]), '\n' print -taufrom(k=k) / 2, '\n' for l in range(0, 4): tmp = abs(complex64(calc_eta_by_theta(k, abel[l])) - eta[l]) print tmp value = higgs_squared(k, x, y, z) print "higgs", higgs_squared(k, x, y, z) if (value > 1.0 or value < 0.0): print "Exception" print '\n' # print mu[0]+mu[2], mu[1]+mu[3], '\n' return
def test_on_line(k, x0, x1, y, z, partition_size): k1 = sqrt(1-k**2) a=k1+complex(0, 1)*k b=k1-complex(0, 1)*k x_step = (x1 - x0) / partition_size for i in range(0, partition_size): x=x0+i*x_step zeta = calc_zeta(k ,x, y, z) eta = calc_eta(k, x, y, z) abel = calc_abel(k, zeta, eta) mu = calc_mu(k, x, y, z, zeta, abel) print "zeta/a", zeta[0]/a, zeta[1]/a, zeta[2]/a, zeta[3]/a, '\n' print "eta", eta[0], eta[1], eta[2], eta[3], '\n' print "abel", abel[0], abel[1],abel[2],abel[3],'\n' abel_tmp= map(lambda zetai : \ complex(0, 1) * 1/(complex64(ellipk(k**2))*2*b) \ * complex64(ellipf( asin( (zetai )/a), mfrom(k=a/b))) \ - taufrom(k=k)/2, zeta) print "abel_tmp", abel_tmp[0], abel_tmp[1],abel_tmp[2],abel_tmp[3],'\n' print abel[0]+conj(abel[2]), abel[1]+conj(abel[3]), '\n' print - taufrom(k=k)/2, '\n' for l in range(0,4): tmp= abs(complex64(calc_eta_by_theta(k, abel[l])) - eta[l]) print tmp value = higgs_squared(k, x, y, z) print "higgs", higgs_squared(k,x,y,z) if (value > 1.0 or value <0.0): print "Exception" print '\n' # print mu[0]+mu[2], mu[1]+mu[3], '\n' return
def calc_lambda_r(r, r1, r2, r3, r4, En): """ Mino time as a function of r (which in turn is a function of psi) Parameters: r (float): radius r1 (float): radial root r2 (float): radial root r3 (float): radial root r4 (float): radial root En (float): energy Returns: lambda (float) """ kr = ((r1 - r2) * (r3 - r4)) / ((r1 - r3) * (r2 - r4)) # if r1 == r2: # # circular orbit # print('Circular orbits currently do not work.') # return 0 yr = sqrt(((r - r2) * (r1 - r3)) / ((r1 - r2) * (r - r3))) F_asin = ellipf(asin(yr), kr) return (2 * F_asin) / (sqrt(1 - En * En) * sqrt((r1 - r3) * (r2 - r4)))
def calc_wr(psi, ups_r, En, Lz, Q, aa, slr, ecc, x): """ Computes wr by analytic evaluation of the integral in Drasco and Hughes (2005) """ a1 = (1 - ecc**2) * (1 - En**2) b1 = 2 * (1 - En**2 - (1 - ecc**2) / slr) c1 = (((3 + ecc**2) * (1 - En**2)) / (1 - ecc**2) - 4 / slr + ((1 - ecc**2) * (aa**2 * (1 - En**2) + Lz**2 + Q)) / slr**2) if psi == mp.pi: # the closed form function has a singularity at psi = pi # but it can be evaluated in integral form to be pi return mp.pi else: return ((-2j * (1 - ecc**2) * ups_r * cos(psi / 2.)**2 * ellipf( 1j * asinh( sqrt((a1 - (-1 + ecc) * (b1 + c1 - c1 * ecc)) / (a1 + b1 + c1 - c1 * ecc**2 + sqrt( (b1**2 - 4 * a1 * c1) * ecc**2))) * tan(psi / 2.)), (a1 + b1 + c1 - c1 * ecc**2 + sqrt( (b1**2 - 4 * a1 * c1) * ecc**2)) / (a1 + b1 + c1 - c1 * ecc**2 - sqrt( (b1**2 - 4 * a1 * c1) * ecc**2))) * sqrt(2 + (2 * (a1 - (-1 + ecc) * (b1 + c1 - c1 * ecc)) * tan(psi / 2.)**2) / (a1 + b1 + c1 - c1 * ecc**2 - sqrt( (b1**2 - 4 * a1 * c1) * ecc**2))) * sqrt(1 + ((a1 - (-1 + ecc) * (b1 + c1 - c1 * ecc)) * tan(psi / 2.)**2) / (a1 + b1 + c1 - c1 * ecc**2 + sqrt( (b1**2 - 4 * a1 * c1) * ecc**2)))) / (sqrt((a1 - (-1 + ecc) * (b1 + c1 - c1 * ecc)) / (a1 + b1 + c1 - c1 * ecc**2 + sqrt( (b1**2 - 4 * a1 * c1) * ecc**2))) * slr * sqrt(2 * a1 + 2 * b1 + 2 * c1 + c1 * ecc**2 + 2 * (b1 + 2 * c1) * ecc * cos(psi) + c1 * ecc**2 * cos(2 * psi))))
def z_Zolotarev(N, x, m): r""" Function to evaluate the Zolotarev polynomial (eq 1, [McNamara93]_). :param N: Order of the Zolotarev polynomial :param x: The argument at which one would like to evaluate the Zolotarev polynomial :param m: m is the elliptic parameter (not the modulus k and not the nome q) :rtype: Returns a float, the value of Zolotarev polynomial at x """ M = -ellipk(m) / N x3 = ellipfun('sn', u= -M, m=m) xbar = x3 * mp.sqrt((x ** 2 - 1) / (x ** 2 - x3 ** 2)) # rearranged eq 21, [Levy70]_ u = ellipf(mp.asin(xbar), m) # rearranged eq 20, [Levy70]_, asn(x) = F(asin(x)|m) f = mp.cosh((N / 2) * mp.log(z_eta(M + u, m) / z_eta(M - u, m))) if (f.imag / f.real > 1e-10): print "imaginary part of the Zolotarev function is not negligible!" print "f_imaginary = ", f.imag else: if (x > 0): # no idea why I am doing this ... anyhow, it seems working f = -f.real else: f = f.real return f
def K(m): """Calculates the complete elliptic integral of mod m=k²""" return mpmath.ellipf(np.pi / 2, m)
def fermat_length(a,x): F = mp.ellipf(mp.acos((0.5-x) / (0.5+x)), 0.5) return a*(F + sqrt(2*x*(4*x**2+1))) / sqrt(18)