pub struct CmaInject<I, V, M, F = f64>where
F: Scalar,
I: MemeticInner<V, F>,{ /* private fields */ }Expand description
Memetic CMA-ES with Hansen (2011) injection: outer CMA-ES proposes
λ candidates per generation, an inner local solver
(MemeticInner) refines the best k, and the refined points are
Mahalanobis-clipped and injected back into the population for the
next CMA update.
The only departure from the standard
CmaEs update is clipping each
injected point’s normalized step in Mahalanobis distance:
y_i ← min(1, c_y / ‖C^{-1/2} y_i‖) · y_i (Hansen 2011 eq. 4)
c_y = √n + 2n/(n+2) (Table 1 default)with y_i = (x_i − m)/σ and C^{-1/2} = B D^{-1} Bᵀ from the
post-update eigendecomposition CMA-ES already maintains. After
clipping, replaced candidates re-enter the population on equal
footing with regular samples; all subsequent CMA updates
(m, p_σ, p_c, C, σ) run the standard equations unchanged. Lamarckian
by construction; no Baldwinian mode in the paper.
§Inner solver
Generic over any I: MemeticInner<V>. The associated I::State
determines the inner state shape. Shipped impls cover
NelderMead, LevenbergMarquardt, and Lbfgsb. For
L-BFGS-B inner with consistent bound flow, use the bounded sibling
BoundedCmaInject over
BoundedCmaEs.
§Eval aggregation
Same-problem composition: the inner shares the outer’s
Problem wrapper, so every inner cost/gradient/Jacobian/
Hessian call bumps the same
EvalCounts as the outer’s own
evaluations. PopulationProgress preserves all six categories without
folding derivative work into cost_evals. Use counts().total_work() for
an explicit aggregate. Exact checkpoints retain the outer distribution,
inner solver, progress, and counts together. With serde, these serialize
when their constituent types do; application hooks cannot be serialized.
§Backends
Same coverage as CmaEs: Vec<F> for F = f32 or f64 (via
DenseMatrix), nalgebra, ndarray, and faer. The
matrix capabilities are those of CmaEs, and the
shipped MemeticInner inners are
backend-generic.
§Examples
See CmaEs for the base population-based Executor pattern;
CmaInject adds a local-search inner via Hansen-2011 injection.
Implementations§
Source§impl<I, V, M, F: Scalar> CmaInject<I, V, M, F>where
I: MemeticInner<V, F>,
impl<I, V, M, F: Scalar> CmaInject<I, V, M, F>where
I: MemeticInner<V, F>,
Sourcepub fn with_absolute_cost_change_tolerance<Q: Scalar>(
self,
value: impl Into<Option<Q>>,
) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), (), CostChecks<Q>, ()>
pub fn with_absolute_cost_change_tolerance<Q: Scalar>( self, value: impl Into<Option<Q>>, ) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), (), CostChecks<Q>, ()>
Stop when the absolute change between consecutive observed costs is at most the tolerance.
Disabled by default. None disables; zero requests an exact-zero
threshold. Values must be finite and nonnegative. Distinct enabled tests combine with OR.
Evaluated at initialized iteration boundaries; repeated calls replace
this setting. Change tests need two observed iterates. Trust-region
solvers skip rejected iterations and compare accepted iterates.
Sourcepub fn with_relative_cost_change_tolerance<Q: Scalar>(
self,
value: impl Into<Option<Q>>,
) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), (), CostChecks<Q>, ()>
pub fn with_relative_cost_change_tolerance<Q: Scalar>( self, value: impl Into<Option<Q>>, ) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), (), CostChecks<Q>, ()>
Stop when the observed cost change is at most the tolerance times the previous absolute cost.
Disabled by default. None disables; zero requests an exact-zero
threshold. Values must be finite and nonnegative. Distinct enabled tests combine with OR.
Evaluated at initialized iteration boundaries; repeated calls replace
this setting. Change tests need two observed iterates. Trust-region
solvers skip rejected iterations and compare accepted iterates.
Source§impl<I, V, M, F: Scalar> CmaInject<I, V, M, F>where
I: MemeticInner<V, F>,
impl<I, V, M, F: Scalar> CmaInject<I, V, M, F>where
I: MemeticInner<V, F>,
Sourcepub fn with_absolute_step_tolerance<Param, Q: Scalar>(
self,
value: impl Into<Option<Q>>,
) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), StepChecks<Param, Q>, (), ()>
pub fn with_absolute_step_tolerance<Param, Q: Scalar>( self, value: impl Into<Option<Q>>, ) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), StepChecks<Param, Q>, (), ()>
Stop when the Euclidean distance between consecutive observed iterates is at most the tolerance.
Disabled by default. None disables; zero requests an exact-zero
threshold. Values must be finite and nonnegative. Distinct enabled tests combine with OR.
Evaluated at initialized iteration boundaries; repeated calls replace
this setting. Change tests need two observed iterates. Trust-region
solvers skip rejected iterations and compare accepted iterates.
Sourcepub fn with_relative_step_tolerance<Param, Q: Scalar>(
self,
value: impl Into<Option<Q>>,
) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), StepChecks<Param, Q>, (), ()>
pub fn with_relative_step_tolerance<Param, Q: Scalar>( self, value: impl Into<Option<Q>>, ) -> ConfiguredSolver<CmaInject<I, V, M, F>, (), StepChecks<Param, Q>, (), ()>
Stop when the Euclidean iterate change is at most the tolerance times the current iterate norm.
Disabled by default. None disables; zero requests an exact-zero
threshold. Values must be finite and nonnegative. Distinct enabled tests combine with OR.
Evaluated at initialized iteration boundaries; repeated calls replace
this setting. Change tests need two observed iterates. Trust-region
solvers skip rejected iterations and compare accepted iterates.
Source§impl<I, V, M, F> CmaInject<I, V, M, F>
impl<I, V, M, F> CmaInject<I, V, M, F>
Sourcepub fn with_inner_solver(cma: CmaEs<V, M, F>, inner: I) -> Self
pub fn with_inner_solver(cma: CmaEs<V, M, F>, inner: I) -> Self
Wrap a configured CmaEs with inner as the local
refinement step. Defaults: k = 1 refinement per generation,
inner max_iter = 50, c_y = Hansen-2011 Table 1 default.
Sourcepub fn cma(&self) -> &CmaEs<V, M, F>
pub fn cma(&self) -> &CmaEs<V, M, F>
Inspect the outer distribution model without transferring its ownership.
Sourcepub fn with_k(self, k: usize) -> Self
pub fn with_k(self, k: usize) -> Self
Number of best-ranked candidates to refine and inject each
generation. Default 1.
§Panics
Panics if k == 0. k > λ is silently clamped at runtime.
Sourcepub fn with_c_y(self, c_y: F) -> Self
pub fn with_c_y(self, c_y: F) -> Self
Override the Hansen-2011 clipping threshold c_y (default
√n + 2n/(n+2)).
§Panics
Panics if c_y <= 0.
Sourcepub fn with_inner_diagnostics(self, enabled: bool) -> Self
pub fn with_inner_diagnostics(self, enabled: bool) -> Self
Enable owned inner stopping reports and count snapshots. Disabled by default. Fresh initialization clears records; exact continuation retains them.
Sourcepub fn inner_diagnostics(&self) -> &[Record<F>]
pub fn inner_diagnostics(&self) -> &[Record<F>]
Inner reports consumed during this outer run, in dispatch order. A callback error retains counts and has no returned report.
Sourcepub fn with_inner_max_iter(self, n: u64) -> Self
pub fn with_inner_max_iter(self, n: u64) -> Self
Inner solver iteration budget per outer generation (default 50).
Sourcepub fn with_absolute_distribution_size_tolerance(
self,
value: impl Into<Option<F>>,
) -> Self
pub fn with_absolute_distribution_size_tolerance( self, value: impl Into<Option<F>>, ) -> Self
Configure the outer CMA distribution-size tolerance; None disables it.
Sourcepub fn inner_stop_when_factory<Mk, CheckFn>(self, make: Mk) -> Selfwhere
Mk: FnMut() -> CheckFn + 'static,
CheckFn: FnMut(&I::State) -> Option<ApplicationStop> + 'static,
pub fn inner_stop_when_factory<Mk, CheckFn>(self, make: Mk) -> Selfwhere
Mk: FnMut() -> CheckFn + 'static,
CheckFn: FnMut(&I::State) -> Option<ApplicationStop> + 'static,
Add a factory creating fresh application-stop history for each inner run.
Trait Implementations§
Source§impl<'de, I, V, M, F> Deserialize<'de> for CmaInject<I, V, M, F>where
F: Scalar + Deserialize<'de>,
I: MemeticInner<V, F> + Deserialize<'de>,
V: Deserialize<'de>,
M: Deserialize<'de>,
Available on crate feature serde only.
impl<'de, I, V, M, F> Deserialize<'de> for CmaInject<I, V, M, F>where
F: Scalar + Deserialize<'de>,
I: MemeticInner<V, F> + Deserialize<'de>,
V: Deserialize<'de>,
M: Deserialize<'de>,
serde only.Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<P, I, V, M, F> Solver<P, PopulationProgress<V, F>> for CmaInject<I, V, M, F>where
F: Scalar,
P: CostFunction<Param = V, Output = F> + ProblemConstraints<Constraints = NoConstraints>,
I: MemeticInner<V, F> + Solver<P, <I as InitialState<V>>::State, Error = P::Error>,
I::State: State<Param = V, Float = F> + CountsMirror,
V: VectorLen + Clone + ScaledAdd<F> + ScaleInPlace<F> + ComponentMulAssign + NormSquared<F> + SampleStandardNormal + Index<usize, Output = F> + IndexMut<usize, Output = F>,
M: MatrixIdentity + MatrixFromDiagonal<V> + MatVec<V> + MatTransposeVec<V> + ScaleInPlace<F> + RankOneUpdate<V, F> + SymmetricEigen<V> + Clone,
CmaEs<V, M, F>: Solver<P, PopulationProgress<V, F>, Error = P::Error>,
impl<P, I, V, M, F> Solver<P, PopulationProgress<V, F>> for CmaInject<I, V, M, F>where
F: Scalar,
P: CostFunction<Param = V, Output = F> + ProblemConstraints<Constraints = NoConstraints>,
I: MemeticInner<V, F> + Solver<P, <I as InitialState<V>>::State, Error = P::Error>,
I::State: State<Param = V, Float = F> + CountsMirror,
V: VectorLen + Clone + ScaledAdd<F> + ScaleInPlace<F> + ComponentMulAssign + NormSquared<F> + SampleStandardNormal + Index<usize, Output = F> + IndexMut<usize, Output = F>,
M: MatrixIdentity + MatrixFromDiagonal<V> + MatVec<V> + MatTransposeVec<V> + ScaleInPlace<F> + RankOneUpdate<V, F> + SymmetricEigen<V> + Clone,
CmaEs<V, M, F>: Solver<P, PopulationProgress<V, F>, Error = P::Error>,
Source§type Error = <P as CostFunction>::Error
type Error = <P as CostFunction>::Error
type Error. See the trait docs.Source§fn init(
&mut self,
problem: &mut Problem<P>,
state: PopulationProgress<V, F>,
) -> Result<PopulationProgress<V, F>, Self::Error>
fn init( &mut self, problem: &mut Problem<P>, state: PopulationProgress<V, F>, ) -> Result<PopulationProgress<V, F>, Self::Error>
Source§fn next_iter(
&mut self,
problem: &mut Problem<P>,
state: PopulationProgress<V, F>,
) -> Result<SolverStep<PopulationProgress<V, F>>, Self::Error>
fn next_iter( &mut self, problem: &mut Problem<P>, state: PopulationProgress<V, F>, ) -> Result<SolverStep<PopulationProgress<V, F>>, Self::Error>
Source§fn terminate(&self, state: &PopulationProgress<V, F>) -> Option<Termination<F>>
fn terminate(&self, state: &PopulationProgress<V, F>) -> Option<Termination<F>>
Source§fn reset_convergence(&mut self)
fn reset_convergence(&mut self)
Source§fn should_check_iterate_change(&self) -> bool
fn should_check_iterate_change(&self) -> bool
Source§fn check_convergence(
&mut self,
_problem: &Problem<P>,
state: &S,
) -> Option<Termination<S::Float>>
fn check_convergence( &mut self, _problem: &Problem<P>, state: &S, ) -> Option<Termination<S::Float>>
Auto Trait Implementations§
impl<I, V, M, F = f64> !RefUnwindSafe for CmaInject<I, V, M, F>
impl<I, V, M, F = f64> !Send for CmaInject<I, V, M, F>
impl<I, V, M, F = f64> !Sync for CmaInject<I, V, M, F>
impl<I, V, M, F = f64> !UnwindSafe for CmaInject<I, V, M, F>
impl<I, V, M, F> Freeze for CmaInject<I, V, M, F>
impl<I, V, M, F> Unpin for CmaInject<I, V, M, F>
impl<I, V, M, F> UnsafeUnpin for CmaInject<I, V, M, F>where
CmaEs<V, M, F>: UnsafeUnpin,
InnerExecutor<<I as InitialState<V>>::State, I>: UnsafeUnpin,
Option<Vec<Record<F>>>: UnsafeUnpin,
Option<F>: UnsafeUnpin,
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
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
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.