pub struct CmaInject<I, V, M>where
I: MemeticInner<V>,{ /* 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 normalised 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
The outer’s state.cost_evals aggregates total inner work units
per I::work_units(state). For derivative-based inners (LM,
L-BFGS-B) the impl sums cost_evals + gradient_evals; CMA-ES
outer state has no gradient_evals field
(BasicPopulationState extends State, not GradientState), so
derivative-eval counts collapse into cost_evals honestly per
AGENTS.md “Solver composition” rule 1.
§Backends
Same coverage as CmaEs: nalgebra (DVector / DMatrix) and
faer (Col / Mat). Vec<f64> and ndarray produce a
compile-time error per tenet 5.
§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> CmaInject<I, V, M>where
I: MemeticInner<V>,
impl<I, V, M> CmaInject<I, V, M>where
I: MemeticInner<V>,
Sourcepub fn with_inner_solver(cma: CmaEs<V, M>, inner: I) -> Self
pub fn with_inner_solver(cma: CmaEs<V, M>, 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 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: f64) -> Self
pub fn with_c_y(self, c_y: f64) -> Self
Override the Hansen-2011 clipping threshold c_y (default
√n + 2n/(n+2)).
§Panics
Panics if c_y <= 0.
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 inner_terminate_on<C>(self, criterion: C) -> Selfwhere
C: TerminationCriterion<I::State> + 'static,
pub fn inner_terminate_on<C>(self, criterion: C) -> Selfwhere
C: TerminationCriterion<I::State> + 'static,
Register a stateless termination criterion on the inner loop.
Criteria are reused across every outer iteration’s inner run,
so they MUST be stateless across calls — MaxIter, the
*Tolerance family, and MaxCostEvals are safe;
MaxTime is not.
See AGENTS.md “Solver composition” rule 2.
Trait Implementations§
Source§impl<P, I, V, M> Solver<P, BasicPopulationState<V>> for CmaInject<I, V, M>where
P: CostFunction<Param = V, Output = f64>,
I: MemeticInner<V> + Solver<P, <I as WarmStart<V>>::State>,
I::State: State<Param = V, Float = f64>,
V: VectorLen + Clone + ScaledAdd<f64> + ScaleInPlace + ComponentMulAssign + NormSquared + SampleStandardNormal + Index<usize, Output = f64> + IndexMut<usize, Output = f64>,
M: MatrixIdentity + MatrixFromDiagonal<V> + MatVec<V> + MatTransposeVec<V> + ScaleInPlace + RankOneUpdate<V> + SymmetricEigen<V> + Clone,
impl<P, I, V, M> Solver<P, BasicPopulationState<V>> for CmaInject<I, V, M>where
P: CostFunction<Param = V, Output = f64>,
I: MemeticInner<V> + Solver<P, <I as WarmStart<V>>::State>,
I::State: State<Param = V, Float = f64>,
V: VectorLen + Clone + ScaledAdd<f64> + ScaleInPlace + ComponentMulAssign + NormSquared + SampleStandardNormal + Index<usize, Output = f64> + IndexMut<usize, Output = f64>,
M: MatrixIdentity + MatrixFromDiagonal<V> + MatVec<V> + MatTransposeVec<V> + ScaleInPlace + RankOneUpdate<V> + SymmetricEigen<V> + Clone,
Source§fn init(
&mut self,
problem: &P,
state: BasicPopulationState<V>,
) -> BasicPopulationState<V>
fn init( &mut self, problem: &P, state: BasicPopulationState<V>, ) -> BasicPopulationState<V>
Source§fn next_iter(
&mut self,
problem: &P,
state: BasicPopulationState<V>,
) -> (BasicPopulationState<V>, Option<TerminationReason>)
fn next_iter( &mut self, problem: &P, state: BasicPopulationState<V>, ) -> (BasicPopulationState<V>, Option<TerminationReason>)
Source§fn terminate(
&self,
state: &BasicPopulationState<V>,
) -> Option<TerminationReason>
fn terminate( &self, state: &BasicPopulationState<V>, ) -> Option<TerminationReason>
Auto Trait Implementations§
impl<I, V, M> Freeze for CmaInject<I, V, M>
impl<I, V, M> !RefUnwindSafe for CmaInject<I, V, M>
impl<I, V, M> !Send for CmaInject<I, V, M>
impl<I, V, M> !Sync for CmaInject<I, V, M>
impl<I, V, M> Unpin for CmaInject<I, V, M>
impl<I, V, M> UnsafeUnpin for CmaInject<I, V, M>
impl<I, V, M> !UnwindSafe for CmaInject<I, V, M>
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
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
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.