rgsl/
elliptic.rs

1//
2// A rust binding for the GSL library by Guillaume Gomez (guillaume1.gomez@gmail.com)
3//
4
5//! Further information about the elliptic integrals can be found in Abramowitz & Stegun, Chapter 17.
6
7/// The Legendre forms of elliptic integrals F(\phi,k), E(\phi,k) and \Pi(\phi,k,n) are defined by,
8///
9/// F(\phi,k) = \int_0^\phi dt 1/\sqrt((1 - k^2 \sin^2(t)))
10///
11/// E(\phi,k) = \int_0^\phi dt   \sqrt((1 - k^2 \sin^2(t)))
12///
13/// Pi(\phi,k,n) = \int_0^\phi dt 1/((1 + n \sin^2(t))\sqrt(1 - k^2 \sin^2(t)))
14///
15/// The complete Legendre forms are denoted by K(k) = F(\pi/2, k) and E(k) = E(\pi/2, k).
16///
17/// The notation used here is based on Carlson, Numerische Mathematik 33 (1979) 1 and differs slightly from that used by Abramowitz & Stegun, where the functions are given in terms of the parameter m = k^2 and n is replaced by -n.
18pub mod legendre {
19    pub mod complete {
20        use crate::{types, Value};
21        use std::mem::MaybeUninit;
22
23        /// This routine computes the complete elliptic integral K(k) to the accuracy specified by the mode variable mode.
24        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
25        #[doc(alias = "gsl_sf_ellint_Kcomp")]
26        pub fn ellint_Kcomp(k: f64, mode: crate::Mode) -> f64 {
27            unsafe { sys::gsl_sf_ellint_Kcomp(k, mode.into()) }
28        }
29
30        /// This routine computes the complete elliptic integral K(k) to the accuracy specified by the mode variable mode.
31        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
32        #[doc(alias = "gsl_sf_ellint_Kcomp_e")]
33        pub fn ellint_Kcomp_e(k: f64, mode: crate::Mode) -> Result<types::Result, Value> {
34            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
35            let ret = unsafe { ::sys::gsl_sf_ellint_Kcomp_e(k, mode.into(), result.as_mut_ptr()) };
36
37            result_handler!(ret, unsafe { result.assume_init() }.into())
38        }
39
40        /// This routine computes the complete elliptic integral E(k) to the accuracy specified by the mode variable mode.
41        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
42        #[doc(alias = "gsl_sf_ellint_Ecomp")]
43        pub fn ellint_Ecomp(k: f64, mode: crate::Mode) -> f64 {
44            unsafe { sys::gsl_sf_ellint_Ecomp(k, mode.into()) }
45        }
46
47        /// This routine computes the complete elliptic integral E(k) to the accuracy specified by the mode variable mode.
48        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
49        #[doc(alias = "gsl_sf_ellint_Ecomp_e")]
50        pub fn ellint_Ecomp_e(k: f64, mode: crate::Mode) -> Result<types::Result, Value> {
51            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
52            let ret = unsafe { ::sys::gsl_sf_ellint_Ecomp_e(k, mode.into(), result.as_mut_ptr()) };
53
54            result_handler!(ret, unsafe { result.assume_init() }.into())
55        }
56
57        /// This routine computes the complete elliptic integral \Pi(k,n) to the accuracy specified by the mode variable mode.
58        /// Note that Abramowitz & Stegun define this function in terms of the parameters m = k^2 and \sin^2(\alpha) = k^2, with the change of sign n \to -n.
59        #[doc(alias = "gsl_sf_ellint_Pcomp")]
60        pub fn ellint_Pcomp(k: f64, n: f64, mode: crate::Mode) -> f64 {
61            unsafe { sys::gsl_sf_ellint_Pcomp(k, n, mode.into()) }
62        }
63
64        /// This routine computes the complete elliptic integral \Pi(k,n) to the accuracy specified by the mode variable mode.
65        /// Note that Abramowitz & Stegun define this function in terms of the parameters m = k^2 and \sin^2(\alpha) = k^2, with the change of sign n \to -n.
66        #[doc(alias = "gsl_sf_ellint_Pcomp_e")]
67        pub fn ellint_Pcomp_e(k: f64, n: f64, mode: crate::Mode) -> Result<types::Result, Value> {
68            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
69            let ret =
70                unsafe { ::sys::gsl_sf_ellint_Pcomp_e(k, n, mode.into(), result.as_mut_ptr()) };
71
72            result_handler!(ret, unsafe { result.assume_init() }.into())
73        }
74    }
75
76    pub mod incomplete {
77        use crate::{types, Value};
78        use std::mem::MaybeUninit;
79
80        /// This routine computes the incomplete elliptic integral F(\phi,k) to the accuracy specified by the mode variable mode.
81        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
82        #[doc(alias = "gsl_sf_ellint_F")]
83        pub fn ellint_F(phi: f64, k: f64, mode: crate::Mode) -> f64 {
84            unsafe { sys::gsl_sf_ellint_F(phi, k, mode.into()) }
85        }
86
87        /// This routine computes the incomplete elliptic integral F(\phi,k) to the accuracy specified by the mode variable mode.
88        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
89        #[doc(alias = "gsl_sf_ellint_F_e")]
90        pub fn ellint_F_e(phi: f64, k: f64, mode: crate::Mode) -> Result<types::Result, Value> {
91            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
92            let ret = unsafe { ::sys::gsl_sf_ellint_F_e(phi, k, mode.into(), result.as_mut_ptr()) };
93
94            result_handler!(ret, unsafe { result.assume_init() }.into())
95        }
96
97        /// This routine computes the incomplete elliptic integral E(\phi,k) to the accuracy specified by the mode variable mode.
98        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
99        #[doc(alias = "gsl_sf_ellint_E")]
100        pub fn ellint_E(phi: f64, k: f64, mode: crate::Mode) -> f64 {
101            unsafe { sys::gsl_sf_ellint_E(phi, k, mode.into()) }
102        }
103
104        /// This routine computes the incomplete elliptic integral E(\phi,k) to the accuracy specified by the mode variable mode.
105        /// Note that Abramowitz & Stegun define this function in terms of the parameter m = k^2.
106        #[doc(alias = "gsl_sf_ellint_E_e")]
107        pub fn ellint_E_e(phi: f64, k: f64, mode: crate::Mode) -> Result<types::Result, Value> {
108            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
109            let ret = unsafe { ::sys::gsl_sf_ellint_E_e(phi, k, mode.into(), result.as_mut_ptr()) };
110
111            result_handler!(ret, unsafe { result.assume_init() }.into())
112        }
113
114        /// This routine computes the incomplete elliptic integral \Pi(\phi,k,n) to the accuracy specified by the mode variable mode.
115        /// Note that Abramowitz & Stegun define this function in terms of the parameters m = k^2 and \sin^2(\alpha) = k^2, with the change of sign n \to -n.
116        #[doc(alias = "gsl_sf_ellint_P")]
117        pub fn ellint_P(phi: f64, k: f64, n: f64, mode: crate::Mode) -> f64 {
118            unsafe { sys::gsl_sf_ellint_P(phi, k, n, mode.into()) }
119        }
120
121        /// This routine computes the incomplete elliptic integral \Pi(\phi,k,n) to the accuracy specified by the mode variable mode.
122        /// Note that Abramowitz & Stegun define this function in terms of the parameters m = k^2 and \sin^2(\alpha) = k^2, with the change of sign n \to -n.
123        #[doc(alias = "gsl_sf_ellint_P_e")]
124        pub fn ellint_P_e(
125            phi: f64,
126            k: f64,
127            n: f64,
128            mode: crate::Mode,
129        ) -> Result<types::Result, Value> {
130            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
131            let ret =
132                unsafe { ::sys::gsl_sf_ellint_P_e(phi, k, n, mode.into(), result.as_mut_ptr()) };
133
134            result_handler!(ret, unsafe { result.assume_init() }.into())
135        }
136
137        /// This routine computes the incomplete elliptic integral D(\phi,k) which is defined through the Carlson form RD(x,y,z) by the following relation,
138        ///
139        /// D(\phi,k,n) = (1/3)(\sin(\phi))^3 RD (1-\sin^2(\phi), 1-k^2 \sin^2(\phi), 1).
140        #[doc(alias = "gsl_sf_ellint_D")]
141        pub fn ellint_D(phi: f64, k: f64, mode: crate::Mode) -> f64 {
142            unsafe { sys::gsl_sf_ellint_D(phi, k, mode.into()) }
143        }
144
145        /// This routine computes the incomplete elliptic integral D(\phi,k) which is defined through the Carlson form RD(x,y,z) by the following relation,
146        ///
147        /// D(\phi,k,n) = (1/3)(\sin(\phi))^3 RD (1-\sin^2(\phi), 1-k^2 \sin^2(\phi), 1).
148        ///
149        /// The argument n is not used and will be removed in a future release.
150        #[doc(alias = "gsl_sf_ellint_D_e")]
151        pub fn ellint_D_e(phi: f64, k: f64, mode: crate::Mode) -> Result<types::Result, Value> {
152            let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
153            let ret = unsafe { ::sys::gsl_sf_ellint_D_e(phi, k, mode.into(), result.as_mut_ptr()) };
154
155            result_handler!(ret, unsafe { result.assume_init() }.into())
156        }
157    }
158}
159
160/// The Carlson symmetric forms of elliptical integrals RC(x,y), RD(x,y,z), RF(x,y,z) and RJ(x,y,z,p) are defined by,
161///
162/// RC(x,y) = 1/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1)
163///
164/// RD(x,y,z) = 3/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-3/2)
165///
166/// RF(x,y,z) = 1/2 \int_0^\infty dt (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2)
167///
168/// RJ(x,y,z,p) = 3/2 \int_0^\infty dt
169///                (t+x)^(-1/2) (t+y)^(-1/2) (t+z)^(-1/2) (t+p)^(-1)
170pub mod carlson {
171    use crate::{types, Value};
172    use std::mem::MaybeUninit;
173
174    /// This routine computes the incomplete elliptic integral RC(x,y) to the accuracy specified by the mode variable mode.
175    #[doc(alias = "gsl_sf_ellint_RC")]
176    pub fn ellint_RC(x: f64, y: f64, mode: crate::Mode) -> f64 {
177        unsafe { sys::gsl_sf_ellint_RC(x, y, mode.into()) }
178    }
179
180    /// This routine computes the incomplete elliptic integral RC(x,y) to the accuracy specified by the mode variable mode.
181    #[doc(alias = "gsl_sf_ellint_RC_e")]
182    pub fn ellint_RC_e(x: f64, y: f64, mode: crate::Mode) -> Result<types::Result, Value> {
183        let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
184        let ret = unsafe { ::sys::gsl_sf_ellint_RC_e(x, y, mode.into(), result.as_mut_ptr()) };
185
186        result_handler!(ret, unsafe { result.assume_init() }.into())
187    }
188
189    /// This routine computes the incomplete elliptic integral RD(x,y,z) to the accuracy specified by the mode variable mode.
190    #[doc(alias = "gsl_sf_ellint_RD")]
191    pub fn ellint_RD(x: f64, y: f64, z: f64, mode: crate::Mode) -> f64 {
192        unsafe { sys::gsl_sf_ellint_RD(x, y, z, mode.into()) }
193    }
194
195    /// This routine computes the incomplete elliptic integral RD(x,y,z) to the accuracy specified by the mode variable mode.
196    #[doc(alias = "gsl_sf_ellint_RD_e")]
197    pub fn ellint_RD_e(x: f64, y: f64, z: f64, mode: crate::Mode) -> Result<types::Result, Value> {
198        let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
199        let ret = unsafe { ::sys::gsl_sf_ellint_RD_e(x, y, z, mode.into(), result.as_mut_ptr()) };
200
201        result_handler!(ret, unsafe { result.assume_init() }.into())
202    }
203
204    /// This routine computes the incomplete elliptic integral RF(x,y,z) to the accuracy specified by the mode variable mode.
205    #[doc(alias = "gsl_sf_ellint_RF")]
206    pub fn ellint_RF(x: f64, y: f64, z: f64, mode: crate::Mode) -> f64 {
207        unsafe { sys::gsl_sf_ellint_RF(x, y, z, mode.into()) }
208    }
209
210    /// This routine computes the incomplete elliptic integral RF(x,y,z) to the accuracy specified by the mode variable mode.
211    #[doc(alias = "gsl_sf_ellint_RF_e")]
212    pub fn ellint_RF_e(x: f64, y: f64, z: f64, mode: crate::Mode) -> Result<types::Result, Value> {
213        let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
214        let ret = unsafe { ::sys::gsl_sf_ellint_RF_e(x, y, z, mode.into(), result.as_mut_ptr()) };
215
216        result_handler!(ret, unsafe { result.assume_init() }.into())
217    }
218
219    /// This routine computes the incomplete elliptic integral RJ(x,y,z,p) to the accuracy specified by the mode variable mode.
220    #[doc(alias = "gsl_sf_ellint_RJ")]
221    pub fn ellint_RJ(x: f64, y: f64, z: f64, p: f64, mode: crate::Mode) -> f64 {
222        unsafe { sys::gsl_sf_ellint_RJ(x, y, z, p, mode.into()) }
223    }
224
225    /// This routine computes the incomplete elliptic integral RJ(x,y,z,p) to the accuracy specified by the mode variable mode.
226    #[doc(alias = "gsl_sf_ellint_RJ_e")]
227    pub fn ellint_RJ_e(
228        x: f64,
229        y: f64,
230        z: f64,
231        p: f64,
232        mode: crate::Mode,
233    ) -> Result<types::Result, Value> {
234        let mut result = MaybeUninit::<sys::gsl_sf_result>::uninit();
235        let ret =
236            unsafe { ::sys::gsl_sf_ellint_RJ_e(x, y, z, p, mode.into(), result.as_mut_ptr()) };
237
238        result_handler!(ret, unsafe { result.assume_init() }.into())
239    }
240}