{-| module : Data.Number.Flint.Acb.Elliptic.FFI copyright : (c) 2022 Hartmut Monien license : GNU GPL, version 2 or above (see LICENSE) maintainer : hmonien@uni-bonn.de -} module Data.Number.Flint.Acb.Elliptic.FFI ( -- * Elliptic integrals and functions of complex variables -- * Complete elliptic integrals acb_elliptic_k , acb_elliptic_k_jet , _acb_elliptic_k_series , acb_elliptic_k_series , acb_elliptic_e , acb_elliptic_pi -- * Legendre incomplete elliptic integrals , acb_elliptic_f , acb_elliptic_e_inc , acb_elliptic_pi_inc -- * Carlson symmetric elliptic integrals , acb_elliptic_rf , acb_elliptic_rg , acb_elliptic_rj , acb_elliptic_rj_carlson , acb_elliptic_rj_integration , acb_elliptic_rc1 -- * Weierstrass elliptic functions , acb_elliptic_p , acb_elliptic_p_prime , acb_elliptic_p_jet , _acb_elliptic_p_series , acb_elliptic_p_series , acb_elliptic_invariants , acb_elliptic_roots , acb_elliptic_inv_p , acb_elliptic_zeta , acb_elliptic_sigma ) where -- Elliptic integrals and functions of complex variables ----------------------- import Foreign.Ptr import Foreign.C.Types import Foreign.C.String import Data.Number.Flint.Arb.Types import Data.Number.Flint.Acb.Types import Data.Number.Flint.Acb.Poly -- Complete elliptic integrals ------------------------------------------------- -- | /acb_elliptic_k/ /res/ /m/ /prec/ -- -- Computes the complete elliptic integral of the first kind -- -- \[`\] -- \[K(m) = \int_0^{\pi/2} \frac{dt}{\sqrt{1-m \sin^2 t}} -- = \int_0^1 -- \frac{dt}{\left(\sqrt{1-t^2}\right)\left(\sqrt{1-mt^2}\right)}\] -- -- using the arithmetic-geometric mean: \(K(m) = \pi / (2 M(\sqrt{1-m}))\). foreign import ccall "acb_elliptic.h acb_elliptic_k" acb_elliptic_k :: Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_k_jet/ /res/ /m/ /len/ /prec/ -- -- Sets the coefficients in the array /res/ to the power series expansion -- of the complete elliptic integral of the first kind at the point /m/ -- truncated to length /len/, i.e. \(K(m+x) \in \mathbb{C}[[x]]\). foreign import ccall "acb_elliptic.h acb_elliptic_k_jet" acb_elliptic_k_jet :: Ptr CAcb -> Ptr CAcb -> CLong -> CLong -> IO () foreign import ccall "acb_elliptic.h _acb_elliptic_k_series" _acb_elliptic_k_series :: Ptr CAcb -> Ptr CAcb -> CLong -> CLong -> CLong -> IO () -- | /acb_elliptic_k_series/ /res/ /m/ /len/ /prec/ -- -- Sets /res/ to the complete elliptic integral of the first kind of the -- power series /m/, truncated to length /len/. foreign import ccall "acb_elliptic.h acb_elliptic_k_series" acb_elliptic_k_series :: Ptr CAcbPoly -> Ptr CAcbPoly -> CLong -> CLong -> IO () -- | /acb_elliptic_e/ /res/ /m/ /prec/ -- -- Computes the complete elliptic integral of the second kind -- -- \[`\] -- \[E(m) = \int_0^{\pi/2} \sqrt{1-m \sin^2 t} \, dt = -- \int_0^1 -- \frac{\sqrt{1-mt^2}}{\sqrt{1-t^2}} \, dt\] -- -- using \(E(m) = (1-m)(2m K'(m) + K(m))\) (where the prime denotes a -- derivative, not a complementary integral). foreign import ccall "acb_elliptic.h acb_elliptic_e" acb_elliptic_e :: Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_pi/ /res/ /n/ /m/ /prec/ -- -- Evaluates the complete elliptic integral of the third kind -- -- \[`\] -- \[\Pi(n, m) = \int_0^{\pi/2} -- \frac{dt}{(1-n \sin^2 t) \sqrt{1-m \sin^2 t}} = -- \int_0^1 -- \frac{dt}{(1-nt^2) \sqrt{1-t^2} \sqrt{1-mt^2}}.\] -- -- This implementation currently uses the same algorithm as the -- corresponding incomplete integral. It is therefore less efficient than -- the implementations of the first two complete elliptic integrals which -- use the AGM. foreign import ccall "acb_elliptic.h acb_elliptic_pi" acb_elliptic_pi :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- Legendre incomplete elliptic integrals -------------------------------------- -- | /acb_elliptic_f/ /res/ /phi/ /m/ /pi/ /prec/ -- -- Evaluates the Legendre incomplete elliptic integral of the first kind, -- given by -- -- \[`\] -- \[F(\phi,m) = \int_0^{\phi} \frac{dt}{\sqrt{1-m \sin^2 t}} -- = \int_0^{\sin \phi} -- \frac{dt}{\left(\sqrt{1-t^2}\right)\left(\sqrt{1-mt^2}\right)}\] -- -- on the standard strip \(-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2\). -- Outside this strip, the function extends quasiperiodically as -- -- \[`\] -- \[F(\phi + n \pi, m) = 2 n K(m) + F(\phi,m), n \in \mathbb{Z}.\] -- -- Inside the standard strip, the function is computed via the symmetric -- integral \(R_F\). -- -- If the flag /pi/ is set to 1, the variable \(\phi\) is replaced by -- \(\pi \phi\), changing the quasiperiod to 1. -- -- The function reduces to a complete elliptic integral of the first kind -- when \(\phi = \frac{\pi}{2}\); that is, -- \(F\left(\frac{\pi}{2}, m\right) = K(m)\). foreign import ccall "acb_elliptic.h acb_elliptic_f" acb_elliptic_f :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- | /acb_elliptic_e_inc/ /res/ /phi/ /m/ /pi/ /prec/ -- -- Evaluates the Legendre incomplete elliptic integral of the second kind, -- given by -- -- \[`\] -- \[E(\phi,m) = \int_0^{\phi} \sqrt{1-m \sin^2 t} \, dt = -- \int_0^{\sin \phi} -- \frac{\sqrt{1-mt^2}}{\sqrt{1-t^2}} \, dt\] -- -- on the standard strip \(-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2\). -- Outside this strip, the function extends quasiperiodically as -- -- \[`\] -- \[E(\phi + n \pi, m) = 2 n E(m) + E(\phi,m), n \in \mathbb{Z}.\] -- -- Inside the standard strip, the function is computed via the symmetric -- integrals \(R_F\) and \(R_D\). -- -- If the flag /pi/ is set to 1, the variable \(\phi\) is replaced by -- \(\pi \phi\), changing the quasiperiod to 1. -- -- The function reduces to a complete elliptic integral of the second kind -- when \(\phi = \frac{\pi}{2}\); that is, -- \(E\left(\frac{\pi}{2}, m\right) = E(m)\). foreign import ccall "acb_elliptic.h acb_elliptic_e_inc" acb_elliptic_e_inc :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- | /acb_elliptic_pi_inc/ /res/ /n/ /phi/ /m/ /pi/ /prec/ -- -- Evaluates the Legendre incomplete elliptic integral of the third kind, -- given by -- -- \[`\] -- \[\Pi(n, \phi, m) = \int_0^{\phi} -- \frac{dt}{(1-n \sin^2 t) \sqrt{1-m \sin^2 t}} = -- \int_0^{\sin \phi} -- \frac{dt}{(1-nt^2) \sqrt{1-t^2} \sqrt{1-mt^2}}\] -- -- on the standard strip \(-\pi/2 \le \operatorname{Re}(\phi) \le \pi/2\). -- Outside this strip, the function extends quasiperiodically as -- -- \[`\] -- \[\Pi(n, \phi + k \pi, m) = 2 k \Pi(n,m) + \Pi(n,\phi,m), k \in \mathbb{Z}.\] -- -- Inside the standard strip, the function is computed via the symmetric -- integrals \(R_F\) and \(R_J\). -- -- If the flag /pi/ is set to 1, the variable \(\phi\) is replaced by -- \(\pi \phi\), changing the quasiperiod to 1. -- -- The function reduces to a complete elliptic integral of the third kind -- when \(\phi = \frac{\pi}{2}\); that is, -- \(\Pi\left(n, \frac{\pi}{2}, m\right) = \Pi(n, m)\). foreign import ccall "acb_elliptic.h acb_elliptic_pi_inc" acb_elliptic_pi_inc :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- Carlson symmetric elliptic integrals ---------------------------------------- -- Carlson symmetric forms are the preferred form of incomplete elliptic -- integrals, due to their neat properties and relatively simple -- computation based on duplication theorems. There are five named -- functions: \(R_F, R_G, R_J\), and \(R_C\), \(R_D\) which are special -- cases of \(R_F\) and \(R_J\) respectively. We largely follow the -- definitions and algorithms in < [Car1995]> and chapter 19 in -- < [NIST2012]>. -- -- | /acb_elliptic_rf/ /res/ /x/ /y/ /z/ /flags/ /prec/ -- -- Evaluates the Carlson symmetric elliptic integral of the first kind -- -- \[`\] -- \[R_F(x,y,z) = \frac{1}{2} -- \int_0^{\infty} \frac{dt}{\sqrt{(t+x)(t+y)(t+z)}}\] -- -- where the square root extends continuously from positive infinity. The -- integral is well-defined for \(x,y,z \notin (-\infty,0)\), and with at -- most one of \(x,y,z\) being zero. When some parameters are negative real -- numbers, the function is still defined by analytic continuation. -- -- In general, one or more duplication steps are applied until \(x,y,z\) -- are close enough to use a multivariate Taylor series. -- -- The special case -- \(R_C(x, y) = R_F(x, y, y) = \frac{1}{2} \int_0^{\infty} (t+x)^{-1/2} (t+y)^{-1} dt\) -- may be computed by setting /y/ and /z/ to the same variable. (This case -- is not yet handled specially, but might be optimized in the future.) -- -- The /flags/ parameter is reserved for future use and currently does -- nothing. Passing 0 results in default behavior. foreign import ccall "acb_elliptic.h acb_elliptic_rf" acb_elliptic_rf :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- | /acb_elliptic_rg/ /res/ /x/ /y/ /z/ /flags/ /prec/ -- -- Evaluates the Carlson symmetric elliptic integral of the second kind -- -- \[`\] -- \[R_G(x,y,z) = \frac{1}{4} \int_0^{\infty} -- \frac{t}{\sqrt{(t+x)(t+y)(t+z)}} -- \left( \frac{x}{t+x} + \frac{y}{t+y} + \frac{z}{t+z}\right) dt\] -- -- where the square root is taken continuously as in \(R_F\). The -- evaluation is done by expressing \(R_G\) in terms of \(R_F\) and -- \(R_D\). There are no restrictions on the variables. foreign import ccall "acb_elliptic.h acb_elliptic_rg" acb_elliptic_rg :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () foreign import ccall "acb_elliptic.h acb_elliptic_rj" acb_elliptic_rj :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () foreign import ccall "acb_elliptic.h acb_elliptic_rj_carlson" acb_elliptic_rj_carlson :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- | /acb_elliptic_rj_integration/ /res/ /x/ /y/ /z/ /p/ /flags/ /prec/ -- -- Evaluates the Carlson symmetric elliptic integral of the third kind -- -- \[`\] -- \[R_J(x,y,z,p) = \frac{3}{2} -- \int_0^{\infty} \frac{dt}{(t+p)\sqrt{(t+x)(t+y)(t+z)}}\] -- -- where the square root is taken continuously as in \(R_F\). -- -- Three versions of this function are available: the /carlson/ version -- applies one or more duplication steps until \(x,y,z,p\) are close enough -- to use a multivariate Taylor series. -- -- The duplication algorithm is not correct for all possible combinations -- of complex variables, since the square roots taken during the -- computation can introduce spurious branch cuts. According to -- < [Car1995]>, a sufficient (but not necessary) condition for correctness -- is that /x/, /y/, /z/ have nonnegative real part and that /p/ has -- positive real part. -- -- In other cases, the algorithm /might/ still be correct, but no attempt -- is made to check this; it is up to the user to verify that the -- duplication algorithm is appropriate for the given parameters before -- calling this function. -- -- The /integration/ algorithm uses explicit numerical integration to -- translate the parameters to the right half-plane. This is reliable but -- can be slow. -- -- The default method uses the /carlson/ algorithm when it is certain to be -- correct, and otherwise falls back to the slow /integration/ algorithm. -- -- The special case \(R_D(x, y, z) = R_J(x, y, z, z)\) may be computed by -- setting /z/ and /p/ to the same variable. This case is handled specially -- to avoid redundant arithmetic operations. In this case, the /carlson/ -- algorithm is correct for all /x/, /y/ and /z/. -- -- The /flags/ parameter is reserved for future use and currently does -- nothing. Passing 0 results in default behavior. foreign import ccall "acb_elliptic.h acb_elliptic_rj_integration" acb_elliptic_rj_integration :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CInt -> CLong -> IO () -- | /acb_elliptic_rc1/ /res/ /x/ /prec/ -- -- This helper function computes the special case -- \(R_C(1, 1+x) = \operatorname{atan}(\sqrt{x})/\sqrt{x} = {}_2F_1(1,1/2,3/2,-x)\), -- which is needed in the evaluation of \(R_J\). foreign import ccall "acb_elliptic.h acb_elliptic_rc1" acb_elliptic_rc1 :: Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- Weierstrass elliptic functions ---------------------------------------------- -- Elliptic functions may be defined on a general lattice Lambda = {m -- 2omega_1 + n 2omega_2: m, n in mathbb{Z}} with half-periods -- \(\omega_1, \omega_2\). We simplify by setting 2omega_1 = 1, 2omega_2 = -- tau with \(\operatorname{im}(\tau) > 0\). To evaluate the functions on a -- general lattice, it is enough to make a linear change of variables. The -- main reference is chapter 23 in < [NIST2012]>. -- -- | /acb_elliptic_p/ /res/ /z/ /tau/ /prec/ -- -- Computes Weierstrass\'s elliptic function -- -- \[`\] -- \[\wp(z, \tau) = \frac{1}{z^2} + \sum_{n^2+m^2 \ne 0} -- \left[ \frac{1}{(z+m+n\tau)^2} - \frac{1}{(m+n\tau)^2} \right]\] -- -- which satisfies -- \(\wp(z, \tau) = \wp(z + 1, \tau) = \wp(z + \tau, \tau)\). To evaluate -- the function efficiently, we use the formula -- -- \[`\] -- \[\wp(z, \tau) = \pi^2 \theta_2^2(0,\tau) \theta_3^2(0,\tau) -- \frac{\theta_4^2(z,\tau)}{\theta_1^2(z,\tau)} - -- \frac{\pi^2}{3} \left[ \theta_2^4(0,\tau) + \theta_3^4(0,\tau)\right].\] foreign import ccall "acb_elliptic.h acb_elliptic_p" acb_elliptic_p :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_p_prime/ /res/ /z/ /tau/ /prec/ -- -- Computes the derivative \(\wp'(z, \tau)\) of Weierstrass\'s elliptic -- function \(\wp(z, \tau)\). foreign import ccall "acb_elliptic.h acb_elliptic_p_prime" acb_elliptic_p_prime :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_p_jet/ /res/ /z/ /tau/ /len/ /prec/ -- -- Computes the formal power series -- \(\wp(z + x, \tau) \in \mathbb{C}[[x]]\), truncated to length /len/. In -- particular, with /len/ = 2, simultaneously computes -- \(\wp(z, \tau), \wp'(z, \tau)\) which together generate the field of -- elliptic functions with periods 1 and \(\tau\). foreign import ccall "acb_elliptic.h acb_elliptic_p_jet" acb_elliptic_p_jet :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> CLong -> IO () foreign import ccall "acb_elliptic.h _acb_elliptic_p_series" _acb_elliptic_p_series :: Ptr CAcb -> Ptr CAcb -> CLong -> Ptr CAcb -> CLong -> CLong -> IO () -- | /acb_elliptic_p_series/ /res/ /z/ /tau/ /len/ /prec/ -- -- Sets /res/ to the Weierstrass elliptic function of the power series /z/, -- with periods 1 and /tau/, truncated to length /len/. foreign import ccall "acb_elliptic.h acb_elliptic_p_series" acb_elliptic_p_series :: Ptr CAcbPoly -> Ptr CAcbPoly -> Ptr CAcb -> CLong -> CLong -> IO () -- | /acb_elliptic_invariants/ /g2/ /g3/ /tau/ /prec/ -- -- Computes the lattice invariants \(g_2, g_3\). The Weierstrass elliptic -- function satisfies the differential equation -- \([\wp'(z, \tau)]^2 = 4 [\wp(z,\tau)]^3 - g_2 \wp(z,\tau) - g_3\). Up to -- constant factors, the lattice invariants are the first two Eisenstein -- series (see @acb_modular_eisenstein@). foreign import ccall "acb_elliptic.h acb_elliptic_invariants" acb_elliptic_invariants :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_roots/ /e1/ /e2/ /e3/ /tau/ /prec/ -- -- Computes the lattice roots \(e_1, e_2, e_3\), which are the roots of the -- polynomial \(4z^3 - g_2 z - g_3\). foreign import ccall "acb_elliptic.h acb_elliptic_roots" acb_elliptic_roots :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_inv_p/ /res/ /z/ /tau/ /prec/ -- -- Computes the inverse of the Weierstrass elliptic function, which -- satisfies \(\wp(\wp^{-1}(z, \tau), \tau) = z\). This function is given -- by the elliptic integral -- -- \[`\] -- \[\wp^{-1}(z, \tau) = \frac{1}{2} \int_z^{\infty} \frac{dt}{\sqrt{(t-e_1)(t-e_2)(t-e_3)}} -- = R_F(z-e_1,z-e_2,z-e_3).\] foreign import ccall "acb_elliptic.h acb_elliptic_inv_p" acb_elliptic_inv_p :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_zeta/ /res/ /z/ /tau/ /prec/ -- -- Computes the Weierstrass zeta function -- -- \[`\] -- \[\zeta(z, \tau) = \frac{1}{z} + \sum_{n^2+m^2 \ne 0} -- \left[ \frac{1}{z-m-n\tau} + \frac{1}{m+n\tau} + \frac{z}{(m+n\tau)^2} \right]\] -- -- which is quasiperiodic with -- \(\zeta(z + 1, \tau) = \zeta(z, \tau) + \zeta(1/2, \tau)\) and -- \(\zeta(z + \tau, \tau) = \zeta(z, \tau) + \zeta(\tau/2, \tau)\). foreign import ccall "acb_elliptic.h acb_elliptic_zeta" acb_elliptic_zeta :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO () -- | /acb_elliptic_sigma/ /res/ /z/ /tau/ /prec/ -- -- Computes the Weierstrass sigma function -- -- \[`\] -- \[\sigma(z, \tau) = z \prod_{n^2+m^2 \ne 0} -- \left[ \left(1-\frac{z}{m+n\tau}\right) -- \exp\left(\frac{z}{m+n\tau} + \frac{z^2}{2(m+n\tau)^2} \right) \right]\] -- -- which is quasiperiodic with -- \(\sigma(z + 1, \tau) = -e^{2 \zeta(1/2, \tau) (z+1/2)} \sigma(z, \tau)\) -- and -- \(\sigma(z + \tau, \tau) = -e^{2 \zeta(\tau/2, \tau) (z+\tau/2)} \sigma(z, \tau)\). foreign import ccall "acb_elliptic.h acb_elliptic_sigma" acb_elliptic_sigma :: Ptr CAcb -> Ptr CAcb -> Ptr CAcb -> CLong -> IO ()