Crates.io | errorfunctions |
lib.rs | errorfunctions |
version | 0.2.0 |
source | src |
created_at | 2022-10-14 14:24:39.811109 |
updated_at | 2022-10-25 09:53:09.078434 |
description | Pure Rust package to compute the error function, Dawson's function, and Faddeeva's function for real and complex arguments. |
homepage | |
repository | https://github.com/JorisDeRidder/errorfunctions |
max_upload_size | |
id | 688215 |
size | 143,765 |
This crate allows to compute:
erf(z)
for complex and real arguments z
:$$ {\rm erf}(z) = \frac{2}{\sqrt{\pi}} \int_0^z e^{-t^2} dt $$
erfc(z)
for complex and real arguments z
:$$ {\rm erfc}(z) = 1 - {\rm erf}(z) $$
erfi(z)
for complex and real arguments z
:$$ {\rm erfi}(z) = -i\ {\rm erf}(i z) = \frac{2}{\sqrt{\pi}} \int_0^z e^{t^2} dt $$
dawson(z)
for complex and real arguments z
:$$ {\rm dawson}(z) = \frac{\sqrt{\pi}}{2} \ e^{-z^2} \ {\rm erfi}(z) = e^{-z^2} \int_0^z e^{t^2} dt $$
w(z)
for complex and real arguments z
:$$ {\rm w}(z) = e^{-z^2}\ {\rm erfc}(-i z) = e^{-z^2} \ \left(1 + \frac{2i}{\sqrt{\pi}} \int_0^z e^{t^2} dt \right) $$
erfcx(z)
for complex and real arguments z
:$$ {\rm erfcx}(z) = e^{z^2} \ {\rm erfc}(z) = {\rm w}(i z) $$
w_im(x)
for real arguments x
:$$ {\rm w}\_{\rm im}(x) = {\rm Im}({\rm w}(x)) = e^{-x^2} {\rm erfi}(x) $$
The implementation of this crate is a port of Steven G. Johnson's
Faddeeva C/C++ library in Rust.
The functions are computed in an efficient way up to machine precision for Complex<f64>
or f64
arguments.
The functions handle NaN and infinite (positive and negative) arguments correctly.
Computing the error functions for a complex argument can be done as in the following example:
use num::complex::Complex;
use errorfunctions::ComplexErrorFunctions;
fn main() {
let z = Complex::<f64>::new(1.21, -0.93);
println!("z = {}", z);
println!("erf(z) = {}", z.erf());
println!("erfc(z) = {}", z.erfc());
println!("erfcx(z) = {}", z.erfcx());
println!("erfi(z) = {}", z.erfi());
println!("w(z) = {}", z.w());
println!("dawson(z) = {}", z.dawson());
}
Computing the error functions for a real argument can be done as in the following example:
use errorfunctions::RealErrorFunctions;
fn main() {
let x: f64 = 0.934;
println!("x = {}", x);
println!("erf(x) = {}", x.erf());
println!("erfc(x) = {}", x.erfc());
println!("erfcx(x) = {}", x.erfcx());
println!("erfi(x) = {}", x.erfi());
println!("Im(w(x)) = {}", x.w_im());
println!("dawson(x) = {}", x.dawson());
}
If, for some reason, you don't need machine precision, you can specify the desired relative error as follows:
use num::complex::Complex;
use errorfunctions::*;
fn main() {
let z = Complex::<f64>::new(1.21, -0.93);
let relerror = 1.0e-3;
println!("z = {}", z);
println!("erf(z) = {}", erf_with_relerror(z, relerror));
println!("erfc(z) = {}", erfc_with_relerror(z, relerror));
println!("erfcx(z) = {}", erfcx_with_relerror(z, relerror));
println!("erfi(z) = {}", erfi_with_relerror(z, relerror));
println!("w(z) = {}", w_with_relerror(z, relerror));
println!("dawson(z) = {}", dawson_with_relerror(z, relerror));
}
Setting relerror=0.0
returns machine precision.
Include the following lines in your Cargo.toml file:
[dependencies]
num = "0.4.0"
errorfunctions = "*"
where *
is the latest version of this errorfunctions
package.
The extenstive set of unit tests in the original Faddeeva code was also ported to Rust and is included in this crate.
Since this is a close to literal translation in Rust of Steven G. Johnson's C++ code, credit should go to him.