pub trait Model: Send + Sync {
// Required methods
fn eval(&self, x: &[f64], params: &[f64]) -> f64;
fn param_names(&self) -> Vec<Cow<'static, str>>;
// Provided methods
fn jacobian(&self, x: &[f64], params: &[f64]) -> Vec<f64> { ... }
fn jacobian_into(&self, x: &[f64], params: &[f64], out: &mut [f64]) { ... }
fn eval_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64]) { ... }
fn jac_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64]) { ... }
fn n_dims(&self) -> usize { ... }
}Expand description
Core model trait implemented by every built-in kernel.
Convention: x is a coordinate slice.
- 1-D models expect
x.len() == 1(i.e.x[0]is the scalar coordinate). - n-D models declare
n_dims() > 1.
Required Methods§
Sourcefn eval(&self, x: &[f64], params: &[f64]) -> f64
fn eval(&self, x: &[f64], params: &[f64]) -> f64
Evaluate the model at coordinate x with the given params.
§Preconditions
Implementations index params and x by raw position and assume the
caller has already validated arity (this keeps the per-point evaluation
branch-free on the hot path). The caller MUST guarantee:
params.len() == self.param_names().len()x.len() >= self.n_dims()
§Panics
Panics (index-out-of-bounds) if params.len() < self.param_names().len()
or x.len() < self.n_dims(). Because the pyo3 binding crate calls these
kernels on the hot path, a panic here would unwind across the FFI
boundary — validate param/coordinate arity at graph-compile time so the
kernel is only ever invoked well-formed.
Sourcefn param_names(&self) -> Vec<Cow<'static, str>>
fn param_names(&self) -> Vec<Cow<'static, str>>
Ordered parameter names, matching the layout expected by eval and jacobian.
Returns an owned Vec of Cow<'static, str> so that runtime-generated
models (e.g. GaussianND{d} with dynamic center_0..center_{d-1}) can
produce their parameter names without requiring compile-time-static slices.
For all built-in kernels with static names, every element is
Cow::Borrowed(&'static str) — zero extra heap allocation.
Provided Methods§
Sourcefn jacobian(&self, x: &[f64], params: &[f64]) -> Vec<f64>
fn jacobian(&self, x: &[f64], params: &[f64]) -> Vec<f64>
Jacobian — one derivative per parameter, in the same order as
param_names().
The default implementation uses forward-difference finite differences
with step h = 1e-7 * |p[i]|.max(1e-7) (relative + absolute floor).
Override with an analytical formula when possible for best performance.
§Preconditions / Panics
Same arity contract as eval: the caller MUST ensure
params.len() == self.param_names().len() and x.len() >= self.n_dims().
A short slice panics with an index-out-of-bounds rather than returning an
error; the same FFI-unwind hazard applies, so validate arity upstream.
Sourcefn jacobian_into(&self, x: &[f64], params: &[f64], out: &mut [f64])
fn jacobian_into(&self, x: &[f64], params: &[f64], out: &mut [f64])
Fill a pre-allocated slice with Jacobian values (one entry per parameter).
This is the hot-path companion to [jacobian]. The caller provides a
scratch buffer (out) of length ≥ param_names().len(); the method
writes derivatives into out[0..n_params] without any heap allocation.
The default falls back to [jacobian] and copies the result. Models
with analytical Jacobians should override this to compute values
directly into out, sharing intermediate calculations across parameters.
Sourcefn eval_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64])
fn eval_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64])
Batch evaluation of a 1-D model: fill out[i] = eval([xs[i]], params).
Only called when n_dims() == 1.
Default: per-point loop calling eval(). Override to hoist
loop-invariant constants (e.g. precompute 1/(2σ²) once) and let LLVM
eliminate redundant arithmetic across the slice.
Sourcefn jac_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64])
fn jac_slice_into(&self, xs: &[f64], params: &[f64], out: &mut [f64])
Batch Jacobian for a 1-D model: fill out in row-major layout
[i * params.len() + j] = d(model)/d(params[j]) at xs[i].
Only called when n_dims() == 1.
Default: per-point loop calling jacobian_into(). Override to hoist
invariants (avoids recomputing σ² and the exp() argument for every
point call).
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".