-
Notifications
You must be signed in to change notification settings - Fork 38
Open
Description
Description
When using the higher-order adaptive Gauss-Kronrod integrators (G10K21*, G20K41*, G30K61* and their R versions), the adaptive subdivision loop never stops early even on functions that the rule should integrate exactly in the first step (e.g. any polynomial of degree ≤ 9 for G10K21, ≤ 19 for G20K41, ≤ 59 for G30K61).
Instead, it keeps subdividing all the way to max_iter, causing the integration to take seconds instead of microseconds.
Lower-order rules and non-adaptive methods work fine still.
Reproduction
use peroxide::fuga::*;
use std::time::Instant;
fn main() {
let f = |x: f64| 3.0 * x.powi(2) + 2.0 * x + 5.0;
let tol = 1.0e-4;
let max_iter = 24u32;
let methods = vec![
("G10K21 ", Integral::G10K21(tol, max_iter)),
("G20K41 ", Integral::G20K41(tol, max_iter)),
("G30K61 ", Integral::G30K61(tol, max_iter)),
("G10K21R", Integral::G10K21R(tol, max_iter)),
("G20K41R", Integral::G20K41R(tol, max_iter)),
("G30K61R", Integral::G30K61R(tol, max_iter)),
];
for (name, method) in methods {
let start = Instant::now();
let res = integrate(f, (5.0, 10.0), method);
let ms = start.elapsed().as_secs_f64() * 1000.0;
println!("{} | {:.3} ms | {:.6}", name, ms, res);
}
}Output of code:
| Method | Time (ms) | Result |
|---|---|---|
| G10K21 | 2424.726 | 975.000000 |
| G20K41 | 3540.177 | 975.000000 |
| G30K61 | 4663.384 | 975.000000 |
| G10K21R | 2438.282 | 975.000000 |
| G20K41R | 3583.130 | 975.000000 |
| G30K61R | 4864.546 | 975.000000 |
Expected behavior
The algorithm should detect that |G - K| ≈ 0 on the first interval and return immediately (exact integration).
Actual behavior
Error estimate never falls below tolerance → full subdivision to max_iter.
Environment
Peroxide: 0.41.0
Rust: stable, tested on 1.85+
OS: Windows 11
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels