This crate allows to compute:
- The error function
erf(z)
for complex and real argumentsz
:
- The complementary error function
erfc(z)
for complex and real argumentsz
:
- The imaginary error function
erfi(z)
for complex and real argumentsz
:
- Dawson's function
dawson(z)
for complex and real argumentsz
:
- The Faddeeva function
w(z)
for complex and real argumentsz
:
- The scaled complementary error function
erfcx(z)
for complex and real argumentsz
:
- The imaginary part of the Faddeeva function
w_im(x)
for real argumentsx
:
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.