--- a/src/forward_model/sensor_grid.rs Thu Jan 23 23:35:28 2025 +0100 +++ b/src/forward_model/sensor_grid.rs Thu Jan 23 23:34:05 2025 +0100 @@ -94,7 +94,8 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N>, - BT : SensorGridBT<F, S, P, N>, { + BT : SensorGridBT<F, S, P, N>, +{ domain : Cube<F, N>, sensor_count : [usize; N], sensor : S, @@ -109,7 +110,7 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>*/ { +{ /// Create a new sensor grid. /// @@ -148,7 +149,8 @@ BT : SensorGridBT<F, S, P, N>, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> { + Convolution<S, P> : Spread<F, N> +{ /// Return the grid of sensor locations. pub fn grid(&self) -> LinGrid<F, N> { @@ -190,7 +192,6 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N>, - //ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, { type Codomain = DVector<F>; @@ -211,7 +212,6 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N>, - //ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N> { } @@ -222,7 +222,6 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N>, - //ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N> { fn gemv<I : Instance<RNDM<F, N>>>( @@ -268,8 +267,8 @@ BT : SensorGridBT<F, S, P, N, Agg=Bounds<F>>, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N>, - ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N> { + Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N> +{ /// An estimate on the operator norm in $𝕃(ℳ(Ω); ℝ^n)$ with $ℳ(Ω)$ equipped /// with the Radon norm, and $ℝ^n$ with the Euclidean norm. @@ -278,11 +277,14 @@ // |Aμ|_2 = sup_{|z|_2 ≤ 1} ⟨z,Αμ⟩ = sup_{|z|_2 ≤ 1} ⟨A^*z|μ⟩ // ≤ sup_{|z|_2 ≤ 1} |A^*z|_∞ |μ|_ℳ // = sup_{|z|_2 ≤ 1} |∑ φ(· - x_i)z_i|_∞ |μ|_ℳ - // ≤ sup_{|z|_2 ≤ 1} |φ|_∞ ∑ |z_i| |μ|_ℳ - // ≤ sup_{|z|_2 ≤ 1} |φ|_∞ √n |z|_2 |μ|_ℳ - // = |φ|_∞ √n |μ|_ℳ. + // ≤ sup_{|z|_2 ≤ 1} |φ(y)| ∑_{i:th sensor active at y}|z_i| |μ|_ℳ + // where the supremum of |∑ φ(· - x_i)z_i|_∞ is reached at y + // ≤ sup_{|z|_2 ≤ 1} |φ|_∞ √N_ψ |z|_2 |μ|_ℳ + // where N_ψ is the maximum number of sensors that overlap, and + // |z|_2 is restricted to the active sensors. + // = |φ|_∞ √N_ψ |μ|_ℳ. // Hence - let n = F::cast_from(self.n_sensors()); + let n = self.max_overlapping(); self.base_sensor.bounds().uniform() * n.sqrt() } } @@ -297,9 +299,8 @@ BT : SensorGridBT<F, S, P, N>, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { + Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N> +{ type PreadjointCodomain = BTFN<F, SensorGridSupportGenerator<F, S, P, N>, BT, N>; type Preadjoint<'a> = SensorGridPreadjoint<'a, Self, F, N> where Self : 'a; @@ -317,8 +318,7 @@ P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + Lipschitz<L2, FloatType=F> + DifferentiableMapping<Loc<F,N>> + LocalAnalysis<F, BT::Agg, N>, for<'b> <Convolution<S, P> as DifferentiableMapping<Loc<F,N>>>::Differential<'b> : Lipschitz<L2, FloatType=F>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { +{ type FloatType = F; @@ -345,7 +345,8 @@ pub struct SensorGridSupportGenerator<F, S, P, const N : usize> where F : Float, S : Sensor<F, N>, - P : Spread<F, N> { + P : Spread<F, N> +{ base_sensor : Convolution<S, P>, grid : LinGrid<F, N>, weights : DVector<F> @@ -355,7 +356,8 @@ where F : Float, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> { + Convolution<S, P> : Spread<F, N> +{ #[inline] fn construct_sensor(&self, id : usize, w : F) -> Weighted<ShiftedSensor<F, S, P, N>, F> { @@ -375,7 +377,8 @@ where F : Float, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> { + Convolution<S, P> : Spread<F, N> +{ type Id = usize; type SupportType = Weighted<ShiftedSensor<F, S, P, N>, F>; type AllDataIter<'a> = MapX<'a, Zip<RangeFrom<usize>, @@ -407,8 +410,7 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { +{ type Observable = DVector<F>; fn write_observable(&self, b : &Self::Observable, prefix : String) -> DynError { @@ -428,9 +430,8 @@ BT : SensorGridBT<F, S, P, N>, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { + Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, BT::Agg, N> +{ fn findim_quadratic_model( &self, @@ -465,7 +466,8 @@ P : Spread<F, N>, Convolution<S, P> : Spread<F, N>, K : SimpleConvolutionKernel<F, N>, - AutoConvolution<P> : BoundedBy<F, K> { + AutoConvolution<P> : BoundedBy<F, K> +{ type FloatType = F; @@ -496,7 +498,8 @@ BT : SensorGridBT<F, S, P, N>, S : Sensor<F, N>, P : Spread<F, N>, - Convolution<S, P> : Spread<F, N> + Lipschitz<L2, FloatType = F> { + Convolution<S, P> : Spread<F, N> + Lipschitz<L2, FloatType = F> +{ type FloatType = F; fn transport_lipschitz_factor(&self, L2Squared : L2Squared) -> Self::FloatType { @@ -604,8 +607,7 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, Bounds<F>, N>, - //ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - /*Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { +{ type Codomain = SensorGridBTFN<F, S, P, BT, N>; @@ -627,8 +629,4 @@ S : Sensor<F, N>, P : Spread<F, N>, Convolution<S, P> : Spread<F, N> + LocalAnalysis<F, Bounds<F>, N>, - /*ShiftedSensor<F, S, P, N> : LocalAnalysis<F, BT::Agg, N>, - Weighted<ShiftedSensor<F, S, P, N>, F> : LocalAnalysis<F, BT::Agg, N>*/ { - -} - +{ }