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 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
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. CmaEsState’s CountsMirror folds every
kind of work into the outer’s single cost_evals via
delta.total_work() — CMA-ES outer state has no gradient_evals
field, so a derivative-based inner (LM, L-BFGS-B) has its gradient
work honestly collapse into cost_evals with no per-trait cross-type
fold. See CONTRIBUTING.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, 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 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_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 termination criterion on the inner loop.
Criteria are reused across every outer iteration’s inner run, but
each is reset at the start of every run, so stateful criteria —
including MaxTime — are safe.
See CONTRIBUTING.md “Solver composition” rule 2.
Trait Implementations§
Source§impl<P, I, V, M, F> Solver<P, CmaEsState<V, M, F>> for CmaInject<I, V, M, F>where
F: Scalar,
P: CostFunction<Param = V, Output = F>,
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, CmaEsState<V, M, F>, Error = P::Error>,
impl<P, I, V, M, F> Solver<P, CmaEsState<V, M, F>> for CmaInject<I, V, M, F>where
F: Scalar,
P: CostFunction<Param = V, Output = F>,
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, CmaEsState<V, M, 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: CmaEsState<V, M, F>,
) -> Result<CmaEsState<V, M, F>, Self::Error>
fn init( &mut self, problem: &mut Problem<P>, state: CmaEsState<V, M, F>, ) -> Result<CmaEsState<V, M, F>, Self::Error>
Source§fn next_iter(
&mut self,
problem: &mut Problem<P>,
state: CmaEsState<V, M, F>,
) -> Result<(CmaEsState<V, M, F>, Option<TerminationReason>), Self::Error>
fn next_iter( &mut self, problem: &mut Problem<P>, state: CmaEsState<V, M, F>, ) -> Result<(CmaEsState<V, M, F>, Option<TerminationReason>), Self::Error>
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
I: UnsafeUnpin,
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, 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.