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}