src/prox_penalty.rs

changeset 89
8d1c959432c8
parent 78
2a122736e91c
child 90
b471a13e3136
--- 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

mercurial