use crate::numerical_integration::mode::*;
use crate::numerical_integration::gaussian_integration;
use crate::numerical_integration::integrator::*;
use crate::numerical_integration::iterative_integration;
use crate::utils::error_codes::*;
#[test]
fn test_booles_integration_1() {
let func = |args: f64| -> f64 { 2.0 * args };
let integration_limit = [0.0, 2.0];
let integrator =
iterative_integration::IterativeSingle::from_parameters(100, IterativeMethod::Booles);
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 4.0) < 1e-14);
}
#[test]
fn test_booles_integration_2() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limit = [0.0, 1.0];
let point = [1.0, 2.0, 3.0];
let integrator =
iterative_integration::IterativeMulti::from_parameters(100, IterativeMethod::Booles);
let val = integrator
.get_single_partial(&func, 0, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 7.0) < 1e-25);
let integration_limit = [0.0, 2.0];
let val = integrator
.get_single_partial(&func, 1, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 10.0) < 0.00001);
let integration_limit = [0.0, 3.0];
let val = integrator
.get_single_partial(&func, 2, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 15.0) < 0.00001);
}
#[test]
fn test_booles_integration_3() {
let func = |args: f64| -> f64 { 6.0 * args };
let integration_limits = [[0.0, 2.0], [0.0, 2.0]];
let integrator =
iterative_integration::IterativeSingle::from_parameters(20, IterativeMethod::Booles);
let val = integrator.get_double(&func, &integration_limits).unwrap();
assert!(f64::abs(val - 24.0) < 0.00001);
}
#[test]
fn test_gauss_legendre_quadrature_integration_1() {
let func = |args: f64| -> f64 { 4.0 * args * args * args - 3.0 * args * args };
let integration_limit = [0.0, 2.0];
let integrator = gaussian_integration::GaussianSingle::from_parameters(
4,
GaussianQuadratureMethod::GaussLegendre,
);
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 8.0) < 1e-14);
}
#[test]
fn test_gauss_legendre_quadrature_integration_2() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limit = [0.0, 1.0];
let point = [1.0, 2.0, 3.0];
let integrator = gaussian_integration::GaussianMulti::from_parameters(
2,
GaussianQuadratureMethod::GaussLegendre,
);
let val = integrator
.get_single_partial(&func, 0, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 7.0) < 1e-14);
let integration_limit = [0.0, 2.0];
let val = integrator
.get_single_partial(&func, 1, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 10.0) < 1e-14);
let integration_limit = [0.0, 3.0];
let val = integrator
.get_single_partial(&func, 2, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 15.0) < 1e-14);
}
#[test]
fn test_gauss_legendre_quadrature_integration_3() {
let func = |args: f64| -> f64 { 6.0 * args };
let integration_limits = [[0.0, 2.0], [0.0, 2.0]];
let integrator = gaussian_integration::GaussianSingle::from_parameters(
2,
GaussianQuadratureMethod::GaussLegendre,
);
let val = integrator.get_double(&func, &integration_limits).unwrap();
assert!(f64::abs(val - 24.0) < 1e-14);
}
#[test]
fn test_simpsons_integration_1() {
let func = |args: f64| -> f64 { 2.0 * args };
let integration_limit = [0.0, 2.0];
let integrator =
iterative_integration::IterativeSingle::from_parameters(200, IterativeMethod::Simpsons);
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 4.0) < 0.05);
}
#[test]
fn test_simpsons_integration_2() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limit = [0.0, 1.0];
let point = [1.0, 2.0, 3.0];
let integrator =
iterative_integration::IterativeMulti::from_parameters(200, IterativeMethod::Simpsons);
let val = integrator
.get_single_partial(&func, 0, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 7.0) < 0.05);
let integration_limit = [0.0, 2.0];
let val = integrator
.get_single_partial(&func, 1, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 10.0) < 0.05);
let integration_limit = [0.0, 3.0];
let val = integrator
.get_single_partial(&func, 2, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 15.0) < 0.05);
}
#[test]
fn test_simpsons_integration_3() {
let func = |args: f64| -> f64 { 6.0 * args };
let integration_limits = [[0.0, 2.0], [0.0, 2.0]];
let integrator =
iterative_integration::IterativeSingle::from_parameters(200, IterativeMethod::Simpsons);
let val = integrator.get_double(&func, &integration_limits).unwrap();
assert!(f64::abs(val - 24.0) < 0.05);
}
#[test]
fn test_simpsons_integration_4() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limits = [[0.0, 1.0], [0.0, 1.0]];
let point = [1.0, 1.0, 1.0];
let integrator =
iterative_integration::IterativeMulti::from_parameters(200, IterativeMethod::Simpsons);
let val = integrator
.get_double_partial(&func, [0, 1], &integration_limits, &point)
.unwrap();
assert!(f64::abs(val - 1.50) < 0.05);
}
#[test]
fn test_trapezoidal_integration_1() {
let func = |args: f64| -> f64 { 2.0 * args };
let integration_limit = [0.0, 2.0];
let iterator =
iterative_integration::IterativeSingle::from_parameters(100, IterativeMethod::Trapezoidal);
let val = iterator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 4.0) < 0.00001);
}
#[test]
fn test_trapezoidal_integration_2() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limit = [0.0, 1.0];
let point = [1.0, 2.0, 3.0];
let iterator =
iterative_integration::IterativeMulti::from_parameters(100, IterativeMethod::Trapezoidal);
let val = iterator
.get_single_partial(&func, 0, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 7.0) < 0.00001);
let integration_limit = [0.0, 2.0];
let val = iterator
.get_single_partial(&func, 1, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 10.0) < 0.00001);
let integration_limit = [0.0, 3.0];
let val = iterator
.get_single_partial(&func, 2, &integration_limit, &point)
.unwrap();
assert!(f64::abs(val - 15.0) < 0.00001);
}
#[test]
fn test_trapezoidal_integration_3() {
let func = |args: f64| -> f64 { 6.0 * args };
let integration_limits = [[0.0, 2.0], [0.0, 2.0]];
let integrator =
iterative_integration::IterativeSingle::from_parameters(10, IterativeMethod::Trapezoidal);
let val = integrator.get_double(&func, &integration_limits).unwrap();
assert!(f64::abs(val - 24.0) < 0.00001);
}
#[test]
fn test_trapezoidal_integration_4() {
let func = |args: &[f64; 3]| -> f64 { 2.0 * args[0] + args[1] * args[2] };
let integration_limits = [[0.0, 1.0], [0.0, 2.0]];
let point = [1.0, 2.0, 3.0];
let integrator =
iterative_integration::IterativeMulti::from_parameters(10, IterativeMethod::Trapezoidal);
let val = integrator
.get_double_partial(&func, [0, 1], &integration_limits, &point)
.unwrap();
assert!(f64::abs(val - 8.0) < 0.00001);
}
#[test]
fn test_error_checking_1() {
let func = |args: f64| -> f64 { 2.0 * args };
let integration_limit = [10.0, 1.0];
let integrator = iterative_integration::IterativeSingle::default();
let result = integrator.get_single(&func, &integration_limit);
assert!(result.is_err());
assert!(result.unwrap_err() == CalcError::IntegrationLimitsIllDefined);
}
#[test]
fn test_error_checking_2() {
let func = |args: f64| -> f64 { 2.0 * args };
let integration_limit = [0.0, 1.0];
let integrator =
iterative_integration::IterativeSingle::from_parameters(0, IterativeMethod::Booles);
let result = integrator.get_single(&func, &integration_limit);
assert!(result.is_err());
assert!(result.unwrap_err() == CalcError::IterationsZero);
}
#[test]
fn test_error_checking_3() {
let func = |args: f64| -> f64 { 4.0 * args * args * args - 3.0 * args * args };
let integration_limit = [0.0, 2.0];
let integrator = gaussian_integration::GaussianSingle::from_parameters(
0,
GaussianQuadratureMethod::GaussLegendre,
);
let result = integrator.get_single(&func, &integration_limit);
assert!(result.is_err());
assert!(result.unwrap_err() == CalcError::QuadratureOrderOutOfRange);
}
#[test]
fn test_error_checking_4() {
let func = |args: f64| -> f64 { 4.0 * args * args * args - 3.0 * args * args };
let integration_limit = [0.0, 2.0];
let integrator = gaussian_integration::GaussianSingle::from_parameters(
31,
GaussianQuadratureMethod::GaussLegendre,
);
let result = integrator.get_single(&func, &integration_limit);
assert!(result.is_err());
assert!(result.unwrap_err() == CalcError::QuadratureOrderOutOfRange);
}
#[test]
fn test_gauss_hermite_single() {
let func = |x: f64| -> f64 { x * x };
let integrator = gaussian_integration::GaussianSingle::from_parameters(
5,
GaussianQuadratureMethod::GaussHermite,
);
let integration_limit = [f64::NEG_INFINITY, f64::INFINITY];
let val = integrator.get_single(&func, &integration_limit).unwrap();
let expected = core::f64::consts::PI.sqrt() / 2.0;
assert!(f64::abs(val - expected) < 1e-10);
}
#[test]
fn test_gauss_laguerre_single() {
let func = |x: f64| -> f64 { x * x };
let integrator = gaussian_integration::GaussianSingle::from_parameters(
5,
GaussianQuadratureMethod::GaussLaguerre,
);
let integration_limit = [0.0, f64::INFINITY];
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 2.0) < 1e-9);
}
#[test]
fn test_gauss_hermite_multivariable() {
let func = |args: &[f64; 2]| -> f64 { args[0] * args[0] * args[1] * args[1] };
let integrator = gaussian_integration::GaussianMulti::from_parameters(
5,
GaussianQuadratureMethod::GaussHermite,
);
let integration_limits = [
[f64::NEG_INFINITY, f64::INFINITY],
[f64::NEG_INFINITY, f64::INFINITY],
];
let point = [0.0, 0.0];
let val = integrator
.get([0, 1], &func, &integration_limits, &point)
.unwrap();
let sqrt_pi_half = core::f64::consts::PI.sqrt() / 2.0;
assert!(f64::abs(val - sqrt_pi_half * sqrt_pi_half) < 1e-10);
}
#[test]
fn test_gauss_laguerre_multivariable() {
let func = |args: &[f64; 2]| -> f64 { args[0] * args[0] * args[1] * args[1] };
let integrator = gaussian_integration::GaussianMulti::from_parameters(
5,
GaussianQuadratureMethod::GaussLaguerre,
);
let integration_limits = [[0.0, f64::INFINITY], [0.0, f64::INFINITY]];
let point = [0.0, 0.0];
let val = integrator
.get([0, 1], &func, &integration_limits, &point)
.unwrap();
assert!(f64::abs(val - 4.0) < 1e-8);
}
#[test]
fn test_iterative_infinite_gaussian() {
let func = |x: f64| -> f64 { f64::exp(-x * x) };
let integrator = iterative_integration::IterativeSingle::default();
let integration_limit = [f64::NEG_INFINITY, f64::INFINITY];
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - core::f64::consts::PI.sqrt()) < 1e-3);
}
#[test]
fn test_iterative_semi_infinite_exp() {
let func = |x: f64| -> f64 { f64::exp(-x) };
let integrator = iterative_integration::IterativeSingle::default();
let integration_limit = [0.0, f64::INFINITY];
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 1.0) < 1e-3);
}
#[test]
fn test_iterative_semi_infinite_inverse_square() {
let func = |x: f64| -> f64 { 1.0 / (x * x) };
let integrator = iterative_integration::IterativeSingle::default();
let integration_limit = [1.0, f64::INFINITY];
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 1.0) < 1e-3);
}
#[test]
fn test_iterative_negative_limits() {
let func = |x: f64| -> f64 { 2.0 * x };
let integrator = iterative_integration::IterativeSingle::default();
let integration_limit = [-2.0, 1.0];
let val = integrator.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - (-3.0)) < 1e-9);
}
#[test]
fn test_composite_rule_degree_3_polynomial() {
let func = |x: f64| -> f64 { x * x * x };
let integration_limit = [0.0, 2.0];
let simpson =
iterative_integration::IterativeSingle::from_parameters(120, IterativeMethod::Simpsons);
let val = simpson.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 4.0) < 1e-9);
let boole =
iterative_integration::IterativeSingle::from_parameters(120, IterativeMethod::Booles);
let val = boole.get_single(&func, &integration_limit).unwrap();
assert!(f64::abs(val - 4.0) < 1e-9);
}