use multicalc::numerical_integration::integrator::{
IntegratorMultiVariable, IntegratorSingleVariable,
};
use multicalc::numerical_integration::iterative_integration::{IterativeMulti, IterativeSingle};
use multicalc::numerical_integration::mode::IterativeMethod;
fn report(label: &str, value: f64, exact: f64) {
println!(
" {label:<13} = {value:>12.8} (exact {exact:>9.6}, |err| {:.0e})",
(value - exact).abs()
);
}
fn main() {
let f = |x: f64| 2.0 * x;
let integrator = IterativeSingle::default(); println!(
"int_0^2 2x dx = {:.8} (exact 4)",
integrator.get_single(&f, &[0.0, 2.0]).unwrap()
);
let g = |v: &[f64; 3]| v[1] * v[2] * v[0] * v[0] * v[0].exp();
let exact = 6.0 * (std::f64::consts::E - 2.0);
let point = [1.0, 2.0, 3.0];
println!("\nint int int (yz x^2 e^x) dx dx dx (default 120 intervals):");
for (name, method) in [
("Boole", IterativeMethod::Booles),
("Simpson", IterativeMethod::Simpsons),
("Trapezoid", IterativeMethod::Trapezoidal),
] {
let solver = IterativeMulti::from_parameters(120, method);
let val = solver.get([0, 0, 0], &g, &[[0.0, 1.0]; 3], &point).unwrap();
report(name, val, exact);
}
println!("\ninfinite limits (Boole):");
let bell = |x: f64| (-x * x).exp();
report(
"e^(-x^2)",
integrator
.get_single(&bell, &[f64::NEG_INFINITY, f64::INFINITY])
.unwrap(),
std::f64::consts::PI.sqrt(),
);
report(
"e^(-x)",
integrator
.get_single(&|x| (-x).exp(), &[0.0, f64::INFINITY])
.unwrap(),
1.0,
);
report(
"x^(-2)",
integrator
.get_single(&|x| 1.0 / (x * x), &[1.0, f64::INFINITY])
.unwrap(),
1.0,
);
let h = |v: &[f64; 3]| 2.0 * v[0] + v[1] * v[2];
let multi = IterativeMulti::default();
println!("\nint_0^1 (2x + yz) dx at (1, 2, 3):");
report(
"partial",
multi
.get_single_partial(&h, 0, &[0.0, 1.0], &point)
.unwrap(),
7.0,
);
}