errorfunctions

Crates.ioerrorfunctions
lib.rserrorfunctions
version0.2.0
sourcesrc
created_at2022-10-14 14:24:39.811109
updated_at2022-10-25 09:53:09.078434
descriptionPure Rust package to compute the error function, Dawson's function, and Faddeeva's function for real and complex arguments.
homepage
repositoryhttps://github.com/JorisDeRidder/errorfunctions
max_upload_size
id688215
size143,765
Joris De Ridder (JorisDeRidder)

documentation

README

This crate allows to compute:

  1. The error function erf(z) for complex and real arguments z:

$$ {\rm erf}(z) = \frac{2}{\sqrt{\pi}} \int_0^z e^{-t^2} dt $$

  1. The complementary error function erfc(z)for complex and real arguments z:

$$ {\rm erfc}(z) = 1 - {\rm erf}(z) $$

  1. The imaginary error function 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 $$

  1. Dawson's function 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 $$

  1. The Faddeeva function 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) $$

  1. The scaled complementary error function erfcx(z) for complex and real arguments z:

$$ {\rm erfcx}(z) = e^{z^2} \ {\rm erfc}(z) = {\rm w}(i z) $$

  1. The imaginary part of the Faddeeva function 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.

Examples

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.

Toml file

Include the following lines in your Cargo.toml file:

[dependencies]
num = "0.4.0"
errorfunctions = "*"

where * is the latest version of this errorfunctions package.

Tests

The extenstive set of unit tests in the original Faddeeva code was also ported to Rust and is included in this crate.

Credits

Since this is a close to literal translation in Rust of Steven G. Johnson's C++ code, credit should go to him.

Commit count: 15

cargo fmt