src/prox_penalty.rs

changeset 78
2a122736e91c
parent 75
677a5fd1b014
--- 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 }
     }
 }
 

mercurial