Skip to main content

central_difference

Function central_difference 

Source
pub fn central_difference(
    base: &ResolvedSolveRequestV1,
    axis: InputAxis,
    ranges_m: &[f64],
    step: Option<f64>,
) -> Result<Vec<Derivative>, KernelError>
Expand description

Central difference: (f(x+h) - f(x-h)) / 2h, covering every range in ranges_m with exactly two solves total (one per side) in the common case – see the module doc’s “Cost” section. The step follows the crate convention h = (|x| * default_rel_step).max(min_abs_step) (axis_meta, taxonomy.rs) unless the caller supplies an explicit step. When one perturbed side leaves the axis’s physical domain, falls back to a one-sided difference – see the module doc’s “One-sided fallback” section and Derivative::scheme.

§Errors

  • KernelError::CategoricalAxis if axis_meta(axis).kind is AxisKind::Categorical (spec D7: categorical axes are never differentiated).
  • KernelError::AxisAbsent if axis has no value on baseread_axis returns None here directly, without ever reaching with_axis – most notably the three wind axes under segmented wind.
  • KernelError::TypeMismatch if read_axis ever returns a non-Scalar value for a continuous axis. Not reachable with the current taxonomy (every Continuous axis reads back as Scalar or None; Flag/DragModel/TwistDirection only ever come from Categorical axes, already rejected above), kept as a defensive catch-all so a future axis added under the wrong AxisKind fails loudly here instead of miscomputing silently.
  • KernelError::NonFinite if the computed or caller-supplied step is not a finite positive number, or if either resulting derivative is not finite.
  • KernelError::AxisUnsupportedForRequest or KernelError::AxisAbsent, propagated unchanged from with_axis – these depend only on axis/base, never on the perturbed value, so they surface immediately with no fallback attempted (see the module doc).
  • KernelError::StepOutOfDomain if BOTH perturbed sides fail with a domain rejection (KernelError::is_domain_rejection) – there is no data left to build even a one-sided difference from.
  • KernelError::Solve or KernelError::Observation, propagated unchanged from evaluate, for any failure that is NOT a domain rejection on either perturbed side (see the module doc’s “One-sided fallback” – this is the case the fallback must NOT swallow), or if the UNPERTURBED value at x itself also fails to evaluate during a one-sided fallback – a degenerate case distinct from StepOutOfDomain in that even the base value is unusable, not just the step.