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. 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: the default Vec<f64> (via
DenseMatrix), nalgebra, ndarray, and faer. The
matrix bound is SymmetricEigen, which every backend satisfies, 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> 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.