Skip to main content

ellip/
lib.rs

1/*
2 * Ellip is licensed under The 3-Clause BSD, see LICENSE.
3 * Copyright 2025 Sira Pornsiriprasert <code@psira.me>
4 */
5
6#![cfg_attr(not(any(test, feature = "std")), no_std)]
7#![cfg_attr(feature = "test_force_fail", allow(unused))]
8#![allow(clippy::excessive_precision)]
9//! # Ellip - Elliptic integrals for Rust
10//!
11//! **Ellip** is a pure-Rust implementation of [elliptic integrals](https://dlmf.nist.gov/19).
12//! This means there is no dependence on C++ libraries. Ellip also provides less common
13//! functions like Bulirsch's `cel` and `el`. Some applications of elliptic integrals include
14//! computing the [lengths of plane curves](https://dlmf.nist.gov/19.30), magnetic field from
15//! magnets of various shapes (e.g., [cylindrical](https://doi.org/10.1016/j.jmmm.2018.02.003)),
16//! [astrophysics](https://dx.doi.org/10.1088/0004-637X/696/2/1616), and [string theory](https://dx.doi.org/10.1088/1126-6708/2004/03/004).
17//!
18//! Use [Ellip-Rayon](https://github.com/p-sira/ellip/tree/main/ellip-rayon) to parallelize and improve
19//! performance for large inputs. Ellip is also available for Python via [EllipPy](https://github.com/p-sira/ellippy).
20//!
21//! ## Example
22//! Calculating the perimeter of an ellipse.
23//! ```
24//! use ellip::*;
25//!
26//! fn ellipse_perimeter(a: f64, b: f64) -> Result<f64, StrErr> {
27//!     Ok(8.0 * elliprg(0.0, a * a, b * b)?)
28//! }
29//!
30//! // Example: ellipse with semi-major axis 5, semi-minor axis 3
31//! println!("{}", ellipse_perimeter(5.0, 3.0).unwrap()); // 25.526998863398124
32//! ```
33//!
34//! # Features
35//! ## Legendre's complete integrals
36//! - [fn@ellipk]: Complete elliptic integral of the first kind (K).
37//! - [fn@ellipe]: Complete elliptic integral of the second kind (E).
38//! - [fn@ellippi]: Complete elliptic integral of the third kind (Π).
39//! - [fn@ellipd]: Complete elliptic integral of Legendre's type (D).
40//! ## Legendre's incomplete integrals
41//! - [fn@ellipf]: Incomplete elliptic integral of the first kind (F).
42//! - [fn@ellipeinc]: Incomplete elliptic integral of the second kind (E).
43//! - [fn@ellippiinc]: Incomplete elliptic integral of the third kind (Π).
44//! - [fn@ellippiinc_bulirsch]: Faster implementation of [fn@ellippiinc].
45//! - [fn@ellipdinc]: Incomplete elliptic integral of Legendre's type (D).
46//! ## Bulirsch's integrals
47//! - [fn@cel]: General complete elliptic integral in Bulirsch's form.
48//! - [fn@cel1]: Complete elliptic integral of the first kind in Bulirsch's form.
49//! - [fn@cel2]: Complete elliptic integral of the second kind in Bulirsch's form.
50//! - [fn@el1]: Incomplete elliptic integral of the first kind in Bulirsch's form.
51//! - [fn@el2]: Incomplete elliptic integral of the second kind in Bulirsch's form.
52//! - [fn@el3]: Incomplete elliptic integral of the third kind in Bulirsch's form.
53//! ## Carlson's symmetric integrals
54//! - [fn@elliprf]: Symmetric elliptic integral of the first kind (RF).
55//! - [fn@elliprg]: Symmetric elliptic integral of the second kind (RG).
56//! - [fn@elliprj]: Symmetric elliptic integral of the third kind (RJ).
57//! - [fn@elliprc]: Degenerate elliptic integral of RF (RC).
58//! - [fn@elliprd]: Degenerate elliptic integral of the third kind (RD).
59//! ## Miscellaneous functions
60//! - [fn@jacobi_zeta]: Jacobi Zeta function (Z).
61//! - [fn@heuman_lambda]: Heuman Lambda function (Λ0).
62//! ## Feature Flags
63//! - `unstable`: Enable unstable or untested features that might be changed without notice in the future.
64//! - `test_force_fail`: Used for testing only. Force tests to reach code unreachable under normal circumstances.
65//!
66//! # Testing
67//! The function results are compared with Boost Math test data and Wolfram Engine test data.
68//! The accuracy report and the test data along with the test generation scripts can
69//! be found [here](https://github.com/p-sira/ellip/blob/main/tests).
70//!
71//! # Acknowledgment
72//! Ellip is derived from multiple mathematic libraries. We thank
73//! the opensource contributors for making mathematic libraries free for all.
74//! Following are the main original works used in the development of Ellip.
75//! Detailed credits are available in the source code.
76//! - [SciPy](https://github.com/scipy/scipy/)
77//! - [Cephes Math Library](https://netlib.org/cephes/)
78//! - [Boost Math Library](https://www.boost.org/doc/libs/release/libs/math/)
79//! - [Russell Lab](https://github.com/cpmech/russell)
80//!
81//! References for original implementations are:
82//! - NIST Digital Library, [Chapter 19: Elliptic Integrals](https://dlmf.nist.gov/19) (Carlson, 2025).
83//! - Numerical calculation of elliptic integrals and elliptic functions [I](https://link.springer.com/article/10.1007/BF01397975) (Bulirsch, 1965), [II](https://doi.org/10.1007/BF01436529) (Bulirsch, 1965), and [III](https://doi.org/10.1007/BF02165405) (Bulirsch, 1969).
84//! - NIST Digital Library, [Chapter 22 Jacobian Elliptic Functions](https://dlmf.nist.gov/22) (Reinhardt and Walker, 2025).
85//!
86//! Unicode-style mathematical notation are created using [Diagon](https://github.com/ArthurSonzogni/Diagon).
87//!
88//! # Citation
89//! The paper describing Ellip is published in the [Journal of Open Source Software](https://joss.theoj.org/papers/10.21105/joss.09386). If Ellip is helpful to your work, please consider citing it:
90//!
91//! ```text
92//! Pornsiriprasert, S., (2026). Ellip: An Elliptic Integral Library for Rust. Journal of Open Source Software, 11(118), 9386, https://doi.org/10.21105/joss.09386
93//! ```
94//!
95//! Bibtex format:
96//!
97//! ```bibtex
98//! @article{Pornsiriprasert2026,
99//!     doi = {10.21105/joss.09386},
100//!    url = {https://doi.org/10.21105/joss.09386},
101//!    year = {2026},
102//!    publisher = {The Open Journal},
103//!    volume = {11}, number = {118}, pages = {9386},
104//!    author = {Pornsiriprasert, Sira},
105//!    title = {Ellip: An Elliptic Integral Library for Rust},
106//!    journal = {Journal of Open Source Software} }
107//! ```
108
109num_lazy::declare_nums! {@constant T}
110num_lazy::declare_nums! {@special T}
111
112mod crate_util;
113
114/// Static error str
115pub type StrErr = &'static str;
116
117pub mod legendre;
118// Legendre's complete integrals
119pub use legendre::ellipd;
120pub use legendre::ellipe;
121pub use legendre::ellipk;
122pub use legendre::ellippi;
123
124// Legendre's incomplete integrals
125pub use legendre::ellipdinc;
126pub use legendre::ellipeinc;
127pub use legendre::ellipf;
128pub use legendre::ellippiinc;
129pub use legendre::ellippiinc_bulirsch;
130
131// Bulirsch's integrals
132pub mod bulirsch;
133pub use bulirsch::cel;
134pub use bulirsch::cel1;
135pub use bulirsch::cel2;
136pub use bulirsch::el1;
137pub use bulirsch::el2;
138pub use bulirsch::el3;
139
140// Carlson's symmetric integrals
141pub mod carlson;
142pub use carlson::elliprc;
143pub use carlson::elliprd;
144pub use carlson::elliprf;
145pub use carlson::elliprg;
146pub use carlson::elliprj;
147
148// Miscellaneous functions
149pub mod misc;
150pub use misc::heuman_lambda;
151pub use misc::jacobi_zeta;
152
153// Utilities
154mod polyeval;
155use polyeval::polyeval;
156pub mod util;
157
158#[cfg(test)]
159mod test_util;