12 use std::marker::PhantomData; |
12 use std::marker::PhantomData; |
13 |
13 |
14 pub use alg_tools::linops::*; |
14 pub use alg_tools::linops::*; |
15 use alg_tools::euclidean::Euclidean; |
15 use alg_tools::euclidean::Euclidean; |
16 use alg_tools::norms::{ |
16 use alg_tools::norms::{ |
17 L1, Linfinity, Norm |
17 L1, Linfinity, L2, Norm |
18 }; |
18 }; |
19 use alg_tools::bisection_tree::*; |
19 use alg_tools::bisection_tree::*; |
20 use alg_tools::mapping::RealMapping; |
20 use alg_tools::mapping::RealMapping; |
21 use alg_tools::lingrid::*; |
21 use alg_tools::lingrid::*; |
22 use alg_tools::iter::{MapX, Mappable}; |
22 use alg_tools::iter::{MapX, Mappable}; |
25 use alg_tools::error::DynError; |
25 use alg_tools::error::DynError; |
26 |
26 |
27 use crate::types::*; |
27 use crate::types::*; |
28 use crate::measures::*; |
28 use crate::measures::*; |
29 use crate::seminorms::{ |
29 use crate::seminorms::{ |
30 Lipschitz, |
|
31 ConvolutionOp, |
30 ConvolutionOp, |
32 SimpleConvolutionKernel, |
31 SimpleConvolutionKernel, |
33 }; |
32 }; |
34 use crate::kernels::{ |
33 use crate::kernels::{ |
35 Convolution, |
34 Convolution, |
36 AutoConvolution, |
35 AutoConvolution, |
37 BoundedBy, |
36 BoundedBy, |
38 }; |
37 }; |
|
38 use crate::types::L2Squared; |
|
39 use crate::transport::TransportLipschitz; |
39 |
40 |
40 pub type RNDM<F, const N : usize> = DiscreteMeasure<Loc<F,N>, F>; |
41 pub type RNDM<F, const N : usize> = DiscreteMeasure<Loc<F,N>, F>; |
41 |
42 |
42 /// `ForwardeModel`s are bounded preadjointable linear operators $A ∈ 𝕃(𝒵(Ω); E)$ |
43 /// `ForwardeModel`s are bounded preadjointable linear operators $A ∈ 𝕃(𝒵(Ω); E)$ |
43 /// where $𝒵(Ω) ⊂ ℳ(Ω)$ is the space of sums of delta measures, presented by |
44 /// where $𝒵(Ω) ⊂ ℳ(Ω)$ is the space of sums of delta measures, presented by |
556 /// Implements the calculation a factor $L$ such that $A_*A ≤ L 𝒟$ for $A$ the forward model |
557 /// Implements the calculation a factor $L$ such that $A_*A ≤ L 𝒟$ for $A$ the forward model |
557 /// and $𝒟$ a seminorm of suitable form. |
558 /// and $𝒟$ a seminorm of suitable form. |
558 /// |
559 /// |
559 /// **This assumes (but does not check) that the sensors are not overlapping.** |
560 /// **This assumes (but does not check) that the sensors are not overlapping.** |
560 #[replace_float_literals(F::cast_from(literal))] |
561 #[replace_float_literals(F::cast_from(literal))] |
561 impl<F, BT, S, P, K, const N : usize> Lipschitz<ConvolutionOp<F, K, BT, N>> |
562 impl<'a, F, BT, S, P, K, const N : usize> Lipschitz<&'a ConvolutionOp<F, K, BT, N>> |
562 for SensorGrid<F, S, P, BT, N> |
563 for SensorGrid<F, S, P, BT, N> |
563 where F : Float + nalgebra::RealField + ToNalgebraRealField, |
564 where F : Float + nalgebra::RealField + ToNalgebraRealField, |
564 BT : SensorGridBT<F, S, P, N>, |
565 BT : SensorGridBT<F, S, P, N>, |
565 S : Sensor<F, N>, |
566 S : Sensor<F, N>, |
566 P : Spread<F, N>, |
567 P : Spread<F, N>, |
568 K : SimpleConvolutionKernel<F, N>, |
569 K : SimpleConvolutionKernel<F, N>, |
569 AutoConvolution<P> : BoundedBy<F, K> { |
570 AutoConvolution<P> : BoundedBy<F, K> { |
570 |
571 |
571 type FloatType = F; |
572 type FloatType = F; |
572 |
573 |
573 fn lipschitz_factor(&self, seminorm : &ConvolutionOp<F, K, BT, N>) -> Option<F> { |
574 fn lipschitz_factor(&self, seminorm : &'a ConvolutionOp<F, K, BT, N>) -> Option<F> { |
574 // Sensors should not take on negative values to allow |
575 // Sensors should not take on negative values to allow |
575 // A_*A to be upper bounded by a simple convolution of `spread`. |
576 // A_*A to be upper bounded by a simple convolution of `spread`. |
576 if self.sensor.bounds().lower() < 0.0 { |
577 if self.sensor.bounds().lower() < 0.0 { |
577 return None |
578 return None |
578 } |
579 } |
587 |
588 |
588 // The final transition factor is: |
589 // The final transition factor is: |
589 Some(l0 * l1) |
590 Some(l0 * l1) |
590 } |
591 } |
591 } |
592 } |
|
593 |
|
594 #[replace_float_literals(F::cast_from(literal))] |
|
595 impl<F, BT, S, P, const N : usize> TransportLipschitz<L2Squared> |
|
596 for SensorGrid<F, S, P, BT, N> |
|
597 where F : Float + nalgebra::RealField + ToNalgebraRealField, |
|
598 BT : SensorGridBT<F, S, P, N>, |
|
599 S : Sensor<F, N>, |
|
600 P : Spread<F, N>, |
|
601 Convolution<S, P> : Spread<F, N> + Lipschitz<L2> { |
|
602 type FloatType = F; |
|
603 |
|
604 fn transport_lipschitz_factor(&self, L2Squared : L2Squared) -> Self::FloatType { |
|
605 todo!("Unimplemented") |
|
606 } |
|
607 } |
|
608 |
592 |
609 |
593 macro_rules! make_sensorgridsupportgenerator_scalarop_rhs { |
610 macro_rules! make_sensorgridsupportgenerator_scalarop_rhs { |
594 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
611 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { |
595 impl<F, S, P, const N : usize> |
612 impl<F, S, P, const N : usize> |
596 std::ops::$trait_assign<F> |
613 std::ops::$trait_assign<F> |