src/forward_model.rs

branch
dev
changeset 34
efa60bc4f743
parent 32
56c8adc32b09
child 35
b087e3eab191
--- a/src/forward_model.rs	Tue Aug 01 10:32:12 2023 +0300
+++ b/src/forward_model.rs	Thu Aug 29 00:00:00 2024 -0500
@@ -23,6 +23,7 @@
 use alg_tools::nalgebra_support::ToNalgebraRealField;
 use alg_tools::tabledump::write_csv;
 use alg_tools::error::DynError;
+use alg_tools::maputil::map2;
 
 use crate::types::*;
 use crate::measures::*;
@@ -594,15 +595,25 @@
 #[replace_float_literals(F::cast_from(literal))]
 impl<F, BT, S, P, const N : usize> TransportLipschitz<L2Squared>
 for SensorGrid<F, S, P, BT, N>
-where F : Float + nalgebra::RealField + ToNalgebraRealField,
+where F : Float + ToNalgebraRealField,
       BT : SensorGridBT<F, S, P, N>,
       S : Sensor<F, N>,
       P : Spread<F, N>,
-      Convolution<S, P> : Spread<F, N> + Lipschitz<L2> {
+      Convolution<S, P> : Spread<F, N> + Lipschitz<L2, FloatType = F> {
     type FloatType = F;
 
     fn transport_lipschitz_factor(&self, L2Squared : L2Squared) -> Self::FloatType {
-        todo!("Unimplemented")
+        // We estimate the factor by N_ψL^2, where L is the 2-norm Lipschitz factor of
+        // the base sensor (sensor * base_spread), and N_ψ the maximum overlap.
+        let l = self.base_sensor.lipschitz_factor(L2).unwrap();
+        let w = self.base_sensor.support_hint().width();
+        let d = map2(self.domain.width(), &self.sensor_count, |wi, &i| wi/F::cast_from(i));
+        let n = w.iter()
+                 .zip(d.iter())
+                 .map(|(&wi, &di)| (wi/di).ceil())
+                 .reduce(F::mul)
+                 .unwrap();
+        2.0 * n * l.powi(2)
     }
 }
 

mercurial