pub fn derivative_batch<F>(
points: &[f64],
settings: DiffSettings,
backend: ComputeBackend,
f: F,
) -> DerivativeBatchExpand description
Differentiate N independent scalar functions at N points, on the chosen
backend.
This is the batched, GPU-shaped form: lane i differentiates f(i, .) at
points[i], and no arithmetic crosses lanes.
§Arguments
points— one abscissa per lane, in the caller’s own units.settings— scheme and step-size policy, shared by every lane.backend— requested execution backend. What actually runs isderivative_backend_forapplied to it. None of the degradations changes the answer.f—f(i, x)is lanei’s function evaluated atx. It must be a pure deterministic function of its arguments — see the module-level “Determinism” section. TheSyncbound is present in both feature builds so enablingparallelnever changes a public signature.
§Returns
A DerivativeBatch with one solution per point, in point order. An empty
points slice returns an empty batch and calls f zero times.
§Cost
DiffScheme::evaluations_per_derivative calls to f per lane — 2 for the
three second-order-or-lower schemes, 4 for DiffScheme::Central4th.
§Example
use outram_foam_basic_lib::compute::ComputeBackend;
use outram_foam_basic_lib::math::differentiate::{
derivative_batch, DiffSettings,
};
// Lane i differentiates x^(i+1) at x = 2; the answer is (i+1) * 2^i.
let points = vec![2.0_f64; 4];
let batch = derivative_batch(
&points,
DiffSettings::central(),
ComputeBackend::CpuMulti,
|i, x: f64| x.powi(i as i32 + 1),
);
let d = batch.values().expect("all lanes finite");
for (i, got) in d.iter().enumerate() {
let want = (i as f64 + 1.0) * 2.0_f64.powi(i as i32);
assert!((got - want).abs() < 1e-6 * want.abs().max(1.0), "lane {i}: {got} vs {want}");
}