src/measures/merging.rs

branch
dev
changeset 39
6316d68b58af
parent 34
efa60bc4f743
child 51
0693cc9ba9f0
--- a/src/measures/merging.rs	Thu Jan 23 23:35:28 2025 +0100
+++ b/src/measures/merging.rs	Thu Jan 23 23:34:05 2025 +0100
@@ -19,63 +19,24 @@
 /// Spike merging heuristic selection
 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
 #[allow(dead_code)]
-pub enum SpikeMergingMethod<F> {
-    /// Try to merge spikes within a given radius of each other, averaging the location
-    HeuristicRadius(F),
-    /// Try to merge spikes within a given radius of each other, attempting original locations
-    HeuristicRadiusNoInterp(F),
-    /// No merging
-    None,
+pub struct SpikeMergingMethod<F> {
+    // Merging radius
+    pub(crate) radius : F,
+    // Enabled
+    pub(crate) enabled : bool,
+    // Interpolate merged points
+    pub(crate) interp : bool,
 }
 
-// impl<F : Float> SpikeMergingMethod<F> {
-//     /// This is for [`clap`] to display command line help.
-//     pub fn value_parser() -> PossibleValuesParser {
-//         PossibleValuesParser::new([
-//             PossibleValue::new("none").help("No merging"),
-//             PossibleValue::new("<radius>").help("Heuristic merging within indicated radius")
-//         ])
-//     }
-// }
-
-impl<F : ClapFloat> std::fmt::Display for SpikeMergingMethod<F> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
-        match self {
-            Self::None => write!(f, "none"),
-            Self::HeuristicRadius(r) => write!(f, "i:{}", r),
-            Self::HeuristicRadiusNoInterp(r) => write!(f, "n:{}", r),
-        }
-    }
-}
-
-impl<F : ClapFloat> std::str::FromStr for SpikeMergingMethod<F> {
-    type Err = F::Err;
-
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        if s == "none" {
-            Ok(Self::None)
-        } else {
-            let mut subs = s.split(':');
-            match subs.next() {
-                None =>  Ok(Self::HeuristicRadius(F::from_str(s)?)),
-                Some(t) if t == "n" => match subs.next() {
-                    None => Err(core::num::dec2flt::pfe_invalid()),
-                    Some(v) => Ok(Self::HeuristicRadiusNoInterp(F::from_str(v)?))
-                },
-                Some(t) if t == "i" => match subs.next() {
-                    None => Err(core::num::dec2flt::pfe_invalid()),
-                    Some(v) => Ok(Self::HeuristicRadius(F::from_str(v)?))
-                },
-                Some(v) => Ok(Self::HeuristicRadius(F::from_str(v)?))
-            }
-        }
-    }
-}
 
 #[replace_float_literals(F::cast_from(literal))]
 impl<F : Float> Default for SpikeMergingMethod<F> {
     fn default() -> Self {
-        SpikeMergingMethod::HeuristicRadius(0.02)
+        SpikeMergingMethod{
+            radius : 0.01,
+            enabled : false,
+            interp : true,
+        }
     }
 }
 
@@ -90,16 +51,16 @@
     /// an arbitrary value. This method will return that value for the *last* accepted merge, or
     /// [`None`] if no merge was accepted.
     ///
-    /// This method is stable with respect to spike locations:  on merge, the weight of existing
-    /// spikes is set to zero, and a new one inserted at the end of the spike vector.
+    /// This method is stable with respect to spike locations:  on merge, the weights of existing
+    /// removed spikes is set to zero, new ones inserted at the end of the spike vector.
+    /// They merge may also be performed by increasing the weights of the existing spikes,
+    /// without inserting new spikes.
     fn merge_spikes<G>(&mut self, method : SpikeMergingMethod<F>, accept : G) -> usize
     where G : FnMut(&'_ Self) -> bool {
-        match method {
-            SpikeMergingMethod::HeuristicRadius(ρ) =>
-                self.do_merge_spikes_radius(ρ, true, accept),
-            SpikeMergingMethod::HeuristicRadiusNoInterp(ρ) =>
-                self.do_merge_spikes_radius(ρ, false, accept),
-            SpikeMergingMethod::None => 0,
+        if method.enabled {
+            self.do_merge_spikes_radius(method.radius, method.interp, accept)
+        } else {
+            0
         }
     }
 

mercurial