Skip to content

Parameter Estimation

Parameter estimation fits an ODE model to experimental data by finding the parameter values that minimize the discrepancy between model predictions and observations.

Given a model:

dydt=f(t,y;p),y(t0)=y0\frac{dy}{dt} = f(t, y; p), \quad y(t_0) = y_0

and observed data (ti,y^i)(t_i, \hat{y}_i) for i=1,,Mi = 1, \ldots, M, find:

p=argminpi=1My(ti;p)y^i2p^* = \arg\min_p \sum_{i=1}^{M} \|y(t_i; p) - \hat{y}_i\|^2
use numra::ocp::{ParamEstProblem, ParamEstResult};
// Exponential decay: dy/dt = -k*y, true k = 0.5
let t_data = vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0];
let y_data = vec![1.0, 0.607, 0.368, 0.223, 0.135, 0.082];
let result = ParamEstProblem::<f64>::new(1, 1) // 1 param, 1 state
.model(|t, y, dydt, p| {
dydt[0] = -p[0] * y[0];
})
.initial_state(&[1.0])
.initial_params(&[1.0]) // initial guess for k
.data(&t_data, &y_data)
.param_bounds(0, (0.01, 10.0))
.solve()
.unwrap();
println!("Estimated k = {:.4}", result.params[0]); // should be ~0.5
println!("Residual: {:.6e}", result.residual_norm);
println!("Converged: {}", result.converged);
println!("ODE integrations: {}", result.n_integrations);

When the ODE has multiple states but you only observe some of them:

let result = ParamEstProblem::<f64>::new(2, 3) // 2 params, 3 states
.model(|t, y, dydt, p| {
dydt[0] = -p[0] * y[0] + p[1] * y[1];
dydt[1] = p[0] * y[0] - p[1] * y[1];
dydt[2] = p[1] * y[1]; // cumulative output
})
.initial_state(&[1.0, 0.0, 0.0])
.initial_params(&[1.0, 0.5])
.data(&t_data, &y_observed)
.observed_indices(&[0, 2]) // only observe states 0 and 2
.solve()
.unwrap();
FieldDescription
paramsEstimated parameters
residual_normL2 norm of residuals
iterationsOptimizer iterations
convergedConvergence flag
predictedModel predictions at data times
n_integrationsTotal ODE solves performed
wall_time_secsComputation time
  1. Initial guess: Provide a reasonable initial guess. The optimizer may converge to a local minimum if started too far from the truth.

  2. Parameter bounds: Always bound parameters to physically meaningful ranges. This prevents the optimizer from exploring regions where the ODE becomes stiff or unstable.

  3. Data quality: More data points and less noise improve identifiability. If parameters are structurally unidentifiable (the model cannot distinguish between different parameter combinations), no amount of data will help.

  4. Scaling: If parameters differ by orders of magnitude (e.g., one is 0.001 and another is 1000), consider scaling them to be O(1) before estimation.

  5. Multi-start: Run the estimation from several random initial guesses and pick the solution with the lowest residual to avoid local minima.

FeatureParameter Estimationcurve_fit
Model typeODE-basedAlgebraic function
RequiresODE integrationDirect function call
Cost per callExpensive (full ODE solve)Cheap
Best forDynamic modelsStatic models

Use ParamEstProblem when your model is defined by a differential equation. Use curve_fit when you have a direct formula y=f(x;p)y = f(x; p).