Skip to main content

TrustRegionProblem

Trait TrustRegionProblem 

pub trait TrustRegionProblem {
    // Required methods
    fn n_residuals(&self) -> usize;
    fn n_params(&self) -> usize;
    fn params(&self) -> Vec<f64>;
    fn set_params(&mut self, p: &[f64]);
    fn residuals_into(&mut self, r: Mat<Mut<'_, f64>>) -> Result<(), CoreError>;
    fn jacobian_into(&mut self, jac: Mat<Mut<'_, f64>>) -> Result<(), CoreError>;

    // Provided methods
    fn apply_jacobian(
        &mut self,
        v: &[f64],
        out: &mut [f64],
    ) -> Result<(), CoreError> { ... }
    fn apply_jacobian_transpose(
        &mut self,
        u: &[f64],
        out: &mut [f64],
    ) -> Result<(), CoreError> { ... }
    fn scales(&self) -> Vec<f64> { ... }
    fn trust_scaling(&self, _grad: &[f64]) -> Option<Vec<f64>> { ... }
}
Expand description

A weighted nonlinear least-squares problem driven by the trust-region core.

Conventions:

  • “weighted” means residuals and Jacobian already carry the per-point 1/σ factor, so the driver minimises ½‖r‖² directly.
  • n_params is the number of free parameters (tied/fixed excluded).
  • Bounds reflection and tied-parameter application live in set_params; the driver never sees them, it only proposes raw steps.

Required Methods§

fn n_residuals(&self) -> usize

Number of residual rows m (total points across datasets).

fn n_params(&self) -> usize

Number of free parameters p.

fn params(&self) -> Vec<f64>

Current free-parameter vector (length p).

Called after set_params so the driver can read back the value the problem actually applied (e.g. after bounds reflection).

fn set_params(&mut self, p: &[f64])

Install a proposed free-parameter vector p (length n_params).

The implementor applies any reflection / tied-plan here, so a subsequent params may differ from p.

fn residuals_into(&mut self, r: Mat<Mut<'_, f64>>) -> Result<(), CoreError>

Write the weighted residual vector r (shape m × 1) for the current parameters into r.

fn jacobian_into(&mut self, jac: Mat<Mut<'_, f64>>) -> Result<(), CoreError>

Write the weighted Jacobian J (shape m × p) for the current parameters into jac.

Provided Methods§

fn apply_jacobian( &mut self, v: &[f64], out: &mut [f64], ) -> Result<(), CoreError>

Apply the weighted Jacobian as a linear operator: write out = J·v (length m) for the current parameters, where v has length p.

This is the matrix-free half of the problem contract, intended for Krylov subproblem solvers (truncated-CG / Steihaug) that need only Jacobian–vector products, never the dense J. The default materializes J via jacobian_into and multiplies — correct but O(m·p) storage per call; a matrix-free implementor overrides both operators to avoid forming J. Implementations must stay consistent with jacobian_into: apply_jacobian(v) == J·v.

Reserved API — no driver in this workspace calls it today. The Newton-CG method works on the dense scaled J through Subproblem::hvec, not through these operators, so the only exercise the default implementations get is the framework’s own contract test. It is kept because it is the seam a future matrix-free implementor needs, not because something behind it is already wired up.

fn apply_jacobian_transpose( &mut self, u: &[f64], out: &mut [f64], ) -> Result<(), CoreError>

Apply the transposed weighted Jacobian: write out = Jᵀ·u (length p) for the current parameters, where u has length m.

The transpose-multiply companion to apply_jacobian (forms the Krylov normal-equation operator v ↦ Jᵀ(J·v) without JᵀJ). The default materializes J and multiplies; matrix-free implementors override it. Must satisfy apply_jacobian_transpose(u) == Jᵀ·u.

Reserved API on the same terms as apply_jacobian: no driver calls it today and the default is exercised only by tests.

fn scales(&self) -> Vec<f64>

Per-parameter scale factors (length p) used for column scaling of the damping diagonal. Defaults to all-ones (Levenberg damping).

This trait method itself has no callers in the workspace today — Parameter.scale is already wired, but through a different path: spectrafit-solver’s LmProblem (lm_problem.rs) holds its own scales field and applies it directly when assembling the scaled working-variable Jacobian, rather than by overriding this method.

fn trust_scaling(&self, _grad: &[f64]) -> Option<Vec<f64>>

Coleman–Li trust-region scaling v ∈ (0, 1] per free parameter for the current point and gradient grad, or None when the problem is unbounded. v_i → 0 as parameter i approaches the active bound; the driver folds D_i ← D_i / √v_i, so the trust region shrinks near bounds (the “reflective” part of Trust-Region-Reflective). Default: None.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§