--- a/src/prox_penalty.rs Wed Jul 22 16:48:22 2026 -0500 +++ b/src/prox_penalty.rs Sun Jul 26 17:30:51 2026 -0500 @@ -68,6 +68,9 @@ /// Additional weight optimisation steps pub extra_weight_optimisation_steps: usize, + + /// Maximum iteration for scaling hack, zero if no maximum. + pub max_scaling_iter: usize, } #[replace_float_literals(F::cast_from(literal))] @@ -87,19 +90,41 @@ merge_every: 10, merge_tolerance_mult: 2.0, extra_weight_optimisation_steps: 0, + max_scaling_iter: 0, } } } impl<F: Float> InsertionConfig<F> { /// Check if merging should be attempted this iteration - pub fn merge_now<I: AlgIterator>(&self, state: &AlgIteratorIteration<I>) -> bool { - self.merging.enabled && state.iteration() % self.merge_every == 0 + pub fn if_merge_now<I: AlgIterator, A>( + &self, + state: &AlgIteratorIteration<I>, + mut f: impl FnMut(&Self) -> A, + ) -> 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 { + None + } else { + Some(f(&InsertionConfig { + merging: SpikeMergingMethod { scaling: None, ..self.merging }, + ..*self + })) + } + } else { + Some(f(self)) + } + } else { + None + } } /// Returns the final merging method pub fn final_merging_method(&self) -> SpikeMergingMethod<F> { - SpikeMergingMethod { enabled: self.final_merging, ..self.merging } + SpikeMergingMethod { enabled: self.final_merging, scaling: None, ..self.merging } } }