--- a/src/prox_penalty.rs Tue Aug 04 13:46:29 2026 -0500 +++ b/src/prox_penalty.rs Tue Aug 04 14:12:18 2026 -0500 @@ -66,9 +66,12 @@ /// Iterations between merging heuristic tries pub merge_every: usize, - /// Additional weight optimisation steps + /// Additional weight optimisation steps after merge and random insertion pub extra_weight_optimisation_steps: usize, + /// Random insertion after merge + pub random_insertions: bool, + /// Maximum iteration for scaling hack, zero if no maximum. pub max_scaling_iter: usize, } @@ -91,16 +94,45 @@ merge_tolerance_mult: 2.0, extra_weight_optimisation_steps: 0, max_scaling_iter: 0, + random_insertions: false, } } } impl<F: Float> InsertionConfig<F> { - /// Check if merging should be attempted this iteration + /// Check if merging should be attempted this iteration. + /// Wrapped in a possible error, returns [`Some`] of the return value of `f`, if merging should + /// be performed. pub fn if_merge_now<I: AlgIterator, A>( &self, state: &AlgIteratorIteration<I>, - mut f: impl FnMut(&Self) -> A, + mut f: impl FnMut(&Self) -> DynResult<A>, + ) -> DynResult<Option<A>> { + if (self.merging.enabled || self.merging.scaling.is_some()) + && state.iteration() % self.merge_every == 0 + { + if self.max_scaling_iter != 0 && state.iteration() > self.max_scaling_iter { + if !self.merging.enabled { + Ok(None) + } else { + Ok(Some(f(&InsertionConfig { + merging: SpikeMergingMethod { scaling: None, ..self.merging }, + ..*self + })?)) + } + } else { + Ok(Some(f(self)?)) + } + } else { + Ok(None) + } + } + + // Lightweight version of [`Self::if_merge_now`]. + pub fn if_merge_now_check<I: AlgIterator, A>( + &self, + state: &AlgIteratorIteration<I>, + mut f: impl FnMut() -> A, ) -> Option<A> { if (self.merging.enabled || self.merging.scaling.is_some()) && state.iteration() % self.merge_every == 0 @@ -109,13 +141,10 @@ if !self.merging.enabled { None } else { - Some(f(&InsertionConfig { - merging: SpikeMergingMethod { scaling: None, ..self.merging }, - ..*self - })) + Some(f()) } } else { - Some(f(self)) + Some(f()) } } else { None