pub struct FiniteDiff<P> { /* private fields */ }Expand description
Wraps a problem to synthesize its derivatives by finite differences.
Construct with FiniteDiff::new (central gradient/Hessian, forward
Jacobian — see the module docs) and adjust with the builder
methods. The wrapper delegates CostFunction / Residual /
BoxConstraints to the inner problem and implements Gradient /
Jacobian / Hessian via finite differences.
§Backends
Gradient is backend-generic (any V: Clone + VectorLen + VectorIndex). Jacobian and Hessian additionally require
V: DenseMatrixFromFn, so they are available only for the matrix
backends (nalgebra DVector → DMatrix, faer Col → Mat) — Vec<f64>
and ndarray produce a compile-time error, mirroring the analytic
Jacobian / Hessian coverage (tenet 5).
§Examples
Run a gradient solver against a problem that only implements
CostFunction: wrapping it in FiniteDiff synthesizes the
Gradient by central differences.
use basin::{BasicState, CostFunction, Executor, FiniteDiff, GradientDescent, GradientTolerance};
struct Sphere;
impl CostFunction for Sphere {
type Param = Vec<f64>;
type Output = f64;
type Error = std::convert::Infallible;
fn cost(&self, x: &Vec<f64>) -> Result<f64, std::convert::Infallible> {
Ok(x.iter().map(|xi| xi * xi).sum())
}
}
let result = Executor::new(
FiniteDiff::new(Sphere),
GradientDescent::new(0.1),
BasicState::new(vec![1.0, 1.0]),
)
.max_iter(1_000)
.terminate_on(GradientTolerance(1e-8))
.run()
.unwrap();
assert!(result.cost() < 1e-10);Implementations§
Source§impl<P> FiniteDiff<P>
impl<P> FiniteDiff<P>
Sourcepub fn new(problem: P) -> Self
pub fn new(problem: P) -> Self
Wrap problem with default settings: central-difference gradient
and Hessian, forward-difference (MINPACK fdjac2) Jacobian,
function_precision = f64::EPSILON, adaptive step sizes.
Sourcepub fn gradient_method(self, method: Method) -> Self
pub fn gradient_method(self, method: Method) -> Self
Set the stencil used for the gradient (default Method::Central).
Sourcepub fn jacobian_method(self, method: Method) -> Self
pub fn jacobian_method(self, method: Method) -> Self
Set the stencil used for the Jacobian (default Method::Forward,
the MINPACK fdjac2 parity choice).
Sourcepub fn hessian_method(self, method: Method) -> Self
pub fn hessian_method(self, method: Method) -> Self
Set the stencil used for the Hessian (default Method::Central).
Sourcepub fn function_precision(self, epsfcn: f64) -> Self
pub fn function_precision(self, epsfcn: f64) -> Self
Set the assumed relative accuracy of the wrapped function (MINPACK’s
epsfcn). Larger values widen the step, which helps when the
function is noisy. Floored at f64::EPSILON. Default f64::EPSILON.
Sourcepub fn with_step(self, h: f64) -> Self
pub fn with_step(self, h: f64) -> Self
Override the adaptive step rule with a fixed absolute step h used
for every coordinate. Escape hatch — most callers should leave the
adaptive |xⱼ|-scaled rule in place.
Sourcepub fn into_inner(self) -> P
pub fn into_inner(self) -> P
Unwrap and return the inner problem.
Trait Implementations§
Source§impl<P: BoxConstraints> BoxConstraints for FiniteDiff<P>
impl<P: BoxConstraints> BoxConstraints for FiniteDiff<P>
Source§impl<P: Clone> Clone for FiniteDiff<P>
impl<P: Clone> Clone for FiniteDiff<P>
Source§fn clone(&self) -> FiniteDiff<P>
fn clone(&self) -> FiniteDiff<P>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl<P: Copy> Copy for FiniteDiff<P>
Source§impl<P: CostFunction> CostFunction for FiniteDiff<P>
impl<P: CostFunction> CostFunction for FiniteDiff<P>
Source§type Param = <P as CostFunction>::Param
type Param = <P as CostFunction>::Param
Source§type Output = <P as CostFunction>::Output
type Output = <P as CostFunction>::Output
f64 (see CONTRIBUTING.md’s
provisional choices).Source§type Error = <P as CostFunction>::Error
type Error = <P as CostFunction>::Error
std::convert::Infallible when the cost cannot fail — its
niche optimization keeps Result<f64, Infallible> the same
layout as bare f64 on the happy path.Source§impl<P: Debug> Debug for FiniteDiff<P>
impl<P: Debug> Debug for FiniteDiff<P>
Source§impl<P, V> Gradient for FiniteDiff<P>where
P: CostFunction<Param = V, Output = f64> + MaybeSync,
V: Clone + VectorLen + VectorIndex + MaybeSync,
<P as CostFunction>::Error: MaybeSend,
impl<P, V> Gradient for FiniteDiff<P>where
P: CostFunction<Param = V, Output = f64> + MaybeSync,
V: Clone + VectorLen + VectorIndex + MaybeSync,
<P as CostFunction>::Error: MaybeSend,
Source§type Gradient = V
type Gradient = V
CostFunction::Param.Source§fn cost_and_gradient(
&self,
param: &Self::Param,
) -> Result<(Self::Output, Self::Gradient), Self::Error>
fn cost_and_gradient( &self, param: &Self::Param, ) -> Result<(Self::Output, Self::Gradient), Self::Error>
param in one call. The default
body delegates to CostFunction::cost and
Gradient::gradient; override when shared intermediate work
can be amortized across the two. Read moreSource§impl<P, V> Hessian for FiniteDiff<P>where
P: CostFunction<Param = V, Output = f64> + MaybeSync,
V: Clone + VectorLen + VectorIndex + DenseMatrixFromFn + MaybeSync,
<P as CostFunction>::Error: MaybeSend,
impl<P, V> Hessian for FiniteDiff<P>where
P: CostFunction<Param = V, Output = f64> + MaybeSync,
V: Clone + VectorLen + VectorIndex + DenseMatrixFromFn + MaybeSync,
<P as CostFunction>::Error: MaybeSend,
Source§type Hessian = <V as DenseMatrixFromFn>::Matrix
type Hessian = <V as DenseMatrixFromFn>::Matrix
n × n and symmetric.Source§fn hessian(&self, param: &V) -> Result<Self::Hessian, P::Error>
fn hessian(&self, param: &V) -> Result<Self::Hessian, P::Error>
param.Source§fn cost_and_gradient_and_hessian(
&self,
param: &Self::Param,
) -> Result<(<Self as CostFunction>::Output, <Self as Gradient>::Gradient, Self::Hessian), <Self as CostFunction>::Error>
fn cost_and_gradient_and_hessian( &self, param: &Self::Param, ) -> Result<(<Self as CostFunction>::Output, <Self as Gradient>::Gradient, Self::Hessian), <Self as CostFunction>::Error>
param in one call.
The default body delegates to Gradient::cost_and_gradient
followed by Hessian::hessian; override when all three share
intermediate work. Read moreSource§impl<P, V> Jacobian for FiniteDiff<P>where
P: Residual<Param = V, Output = V> + MaybeSync,
V: Clone + VectorLen + VectorIndex + DenseMatrixFromFn + MaybeSync + MaybeSend,
<P as Residual>::Error: MaybeSend,
impl<P, V> Jacobian for FiniteDiff<P>where
P: Residual<Param = V, Output = V> + MaybeSync,
V: Clone + VectorLen + VectorIndex + DenseMatrixFromFn + MaybeSync + MaybeSend,
<P as Residual>::Error: MaybeSend,
Source§type Jacobian = <V as DenseMatrixFromFn>::Matrix
type Jacobian = <V as DenseMatrixFromFn>::Matrix
m × n.Source§fn jacobian(&self, param: &V) -> Result<Self::Jacobian, P::Error>
fn jacobian(&self, param: &V) -> Result<Self::Jacobian, P::Error>
param.Source§fn residual_and_jacobian(
&self,
param: &Self::Param,
) -> Result<(<Self as Residual>::Output, Self::Jacobian), <Self as Residual>::Error>
fn residual_and_jacobian( &self, param: &Self::Param, ) -> Result<(<Self as Residual>::Output, Self::Jacobian), <Self as Residual>::Error>
param in one call. The
default body delegates to Residual::residual and
Jacobian::jacobian; override when shared intermediate work
can be amortized across the two — common in NLLS where r(x)
reuses forward-mode AD state that J(x) continues from. Read moreSource§impl<P: Residual> Residual for FiniteDiff<P>
impl<P: Residual> Residual for FiniteDiff<P>
Source§type Param = <P as Residual>::Param
type Param = <P as Residual>::Param
CostFunction::Param).Source§type Output = <P as Residual>::Output
type Output = <P as Residual>::Output
m,
independent of param.len() = n.Auto Trait Implementations§
impl<P> Freeze for FiniteDiff<P>where
P: Freeze,
impl<P> RefUnwindSafe for FiniteDiff<P>where
P: RefUnwindSafe,
impl<P> Send for FiniteDiff<P>where
P: Send,
impl<P> Sync for FiniteDiff<P>where
P: Sync,
impl<P> Unpin for FiniteDiff<P>where
P: Unpin,
impl<P> UnsafeUnpin for FiniteDiff<P>where
P: UnsafeUnpin,
impl<P> UnwindSafe for FiniteDiff<P>where
P: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.