pub struct Bfgs<ObjFn> { /* private fields */ }Expand description
A configurable BFGS solver.
Implementations§
Source§impl<ObjFn> Bfgs<ObjFn>where
ObjFn: FirstOrderObjective,
impl<ObjFn> Bfgs<ObjFn>where
ObjFn: FirstOrderObjective,
Sourcepub fn new(x0: Array1<f64>, obj_fn: ObjFn) -> Self
pub fn new(x0: Array1<f64>, obj_fn: ObjFn) -> Self
Creates a new BFGS solver.
§Arguments
x0- The initial guess for the minimum.obj_fn- First-order objective.
Sourcepub fn with_tolerance(self, tolerance: Tolerance) -> Self
pub fn with_tolerance(self, tolerance: Tolerance) -> Self
Sets the convergence tolerance (default: 1e-5).
Sourcepub fn with_max_iterations(self, max_iterations: MaxIterations) -> Self
pub fn with_max_iterations(self, max_iterations: MaxIterations) -> Self
Sets the maximum number of iterations (default: 100).
Sourcepub fn with_bounds(self, bounds: Bounds) -> Self
pub fn with_bounds(self, bounds: Bounds) -> Self
Provides simple box bounds for each coordinate (lower <= x <= upper). Points are projected by coordinate clamping, and the gradient is projected by zeroing active constraints during direction updates.
pub fn with_profile(self, profile: Profile) -> Self
Sourcepub fn with_initial_sample(
self,
x0: Array1<f64>,
sample: FirstOrderSample,
) -> Self
pub fn with_initial_sample( self, x0: Array1<f64>, sample: FirstOrderSample, ) -> Self
Hand the solver a precomputed (x0, sample) pair so its first
internal evaluation is served from cache instead of re-running
the objective. Use this when the caller has already evaluated
the seed (e.g. for routing decisions or seed-validation).
The validation of sample shape and finiteness is deferred to
run(); calling with_initial_sample itself never fails. If
the seed point does not match the constructor’s x0 (after
projection onto bounds), the cache is silently bypassed.
Sourcepub fn with_gradient_tolerance(self, tol: GradientTolerance) -> Self
pub fn with_gradient_tolerance(self, tol: GradientTolerance) -> Self
Use a scale-aware stopping criterion. Takes precedence over
with_tolerance for the final threshold computation; the
tolerance value (if set) becomes the absolute floor.
Sourcepub fn with_initial_metric(self, metric: InitialMetric) -> Self
pub fn with_initial_metric(self, metric: InitialMetric) -> Self
Seed the BFGS inverse-Hessian approximation. Default
(InitialMetric::Identity, equivalent to not calling this) is
the historical scaled-identity reset. Pass Diagonal(d) when
you have per-coordinate curvature (e.g. from a penalty
matrix’s diagonal); DenseInverseHessian(M) for a full seed.
Sourcepub fn with_observer<O>(self, observer: O) -> Selfwhere
O: OptimizerObserver + 'static,
pub fn with_observer<O>(self, observer: O) -> Selfwhere
O: OptimizerObserver + 'static,
Install an observer for accepted-step / iteration-start events.
The observer is called from inside run(); only one observer
is supported per solver (later calls replace earlier ones).
Sourcepub fn with_axis_step_caps(self, caps: Array1<f64>) -> Self
pub fn with_axis_step_caps(self, caps: Array1<f64>) -> Self
Cap the BFGS search direction component-wise. At the start of each
iteration, after the descent direction d = -B_inv · g is computed
(and any bound-active components are zeroed), if any axis with a
finite cap has |d[i]| > caps[i] the direction is uniformly scaled
by the tightest binding ratio so every per-axis budget is respected.
The line search consumes the shortened direction; α can still
backtrack further if Wolfe / cost conditions need it.
Pass f64::INFINITY (or any non-finite value) on axes that should
not be capped. Calling this method twice replaces the previous caps;
the array length is validated lazily during run() against the
parameter dimension.
Use this when different parameter blocks have very different natural step magnitudes — e.g. a joint solver over log-λ (natural step ≈ 5) and log-κ (natural step ≈ ln 2): a single isotropic trust radius can’t simultaneously give λ headroom while keeping κ from oscillating across orders of magnitude per iter. This is the principled replacement for “objective-side fake-finite-cost on overreach” patterns: shortening the BFGS direction up front keeps the line search honest (no sentinel costs poisoning Wolfe brackets).
Sourcepub fn run(&mut self) -> Result<Solution, BfgsError>
pub fn run(&mut self) -> Result<Solution, BfgsError>
Executes the BFGS algorithm with the adaptive hybrid line search.
Requires &mut self to support stateful FnMut objectives.
Sourcepub fn run_report(&mut self) -> OptimizationReport
pub fn run_report(&mut self) -> OptimizationReport
Run the solver and return a structured report instead of a
Result<Solution, _>. The report distinguishes convergence
from budget exhaustion, line-search failure, and numerical
failure without forcing the caller to pattern-match BfgsError.
run_report is infallible: every termination path produces a
report whose status indicates the outcome and whose
solution is the best point seen during the run (or, on early
numerical failure, a placeholder built from the initial point).