src/forward_model.rs

changeset 70
ed16d0f10d08
parent 63
7a8a55fd41c0
equal deleted inserted replaced
58:6099ba025aac 70:ed16d0f10d08
1 /*! 1 /*!
2 Forward models from discrete measures to observations. 2 Forward models from discrete measures to observations.
3 */ 3 */
4 4
5 use alg_tools::error::DynError; 5 use crate::dataterm::QuadraticDataTerm;
6 use alg_tools::euclidean::Euclidean; 6 use crate::measures::{Radon, RNDM};
7 use alg_tools::instance::Instance; 7 use crate::types::*;
8 use alg_tools::error::{DynError, DynResult};
9 use alg_tools::euclidean::{ClosedEuclidean, Euclidean};
8 pub use alg_tools::linops::*; 10 pub use alg_tools::linops::*;
9 use alg_tools::norms::{Norm, NormExponent, L2}; 11 use alg_tools::norms::{Norm, NormExponent, L2};
12 use serde::{Deserialize, Serialize};
10 13
11 use crate::measures::Radon;
12 use crate::types::*;
13 pub mod bias; 14 pub mod bias;
14 pub mod sensor_grid; 15 pub mod sensor_grid;
15 16
16 /// `ForwardeModel`s are bounded preadjointable linear operators $A ∈ 𝕃(𝒵(Ω); E)$ 17 /// `ForwardeModel`s are bounded preadjointable linear operators $A ∈ 𝕃(𝒵(Ω); E)$
17 /// where $𝒵(Ω) ⊂ ℳ(Ω)$ is the space of sums of delta measures, presented by 18 /// where $𝒵(Ω) ⊂ ℳ(Ω)$ is the space of sums of delta measures, presented by
19 pub trait ForwardModel<Domain: Space, F: Float = f64, E: NormExponent = Radon>: 20 pub trait ForwardModel<Domain: Space, F: Float = f64, E: NormExponent = Radon>:
20 BoundedLinear<Domain, E, L2, F, Codomain = Self::Observable> 21 BoundedLinear<Domain, E, L2, F, Codomain = Self::Observable>
21 + GEMV<F, Domain, Self::Observable> 22 + GEMV<F, Domain, Self::Observable>
22 + Preadjointable<Domain, Self::Observable> 23 + Preadjointable<Domain, Self::Observable>
23 where 24 where
24 for<'a> Self::Observable: Instance<Self::Observable>, 25 Domain: Norm<E, F>,
25 Domain: Norm<F, E>,
26 { 26 {
27 /// The codomain or value space (of “observables”) for this operator. 27 /// The codomain or value space (of “observables”) for this operator.
28 /// It is assumed to be a [`Euclidean`] space, and therefore also (identified with) 28 /// It is assumed to be a [`Euclidean`] space, and therefore also (identified with)
29 /// the domain of the preadjoint. 29 /// the domain of the preadjoint.
30 type Observable: Euclidean<F, Output = Self::Observable> + AXPY<F> + Space + Clone; 30 type Observable: ClosedEuclidean<F> + Clone;
31 31
32 /// Write an observable into a file. 32 /// Write an observable into a file.
33 fn write_observable(&self, b: &Self::Observable, prefix: String) -> DynError; 33 fn write_observable(&self, b: &Self::Observable, prefix: String) -> DynError;
34 34
35 /// Returns a zero observable 35 /// Returns a zero observable
36 fn zero_observable(&self) -> Self::Observable; 36 fn zero_observable(&self) -> Self::Observable;
37 } 37 }
38 38
39 /// Trait for operators $A$ for which $A_*A$ is bounded by some other operator. 39 /// Guess for [`BoundedCurvature`] calculations.
40 pub trait AdjointProductBoundedBy<Domain: Space, D>: Linear<Domain> { 40 #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
41 type FloatType: Float; 41 pub enum BoundedCurvatureGuess {
42 /// Return $L$ such that $A_*A ≤ LD$. 42 /// No iterate $μ^k$ is worse than $μ=0$.
43 fn adjoint_product_bound(&self, other: &D) -> Option<Self::FloatType>; 43 BetterThanZero,
44 } 44 }
45 45
46 /// Trait for operators $A$ for which $A_*A$ is bounded by a diagonal operator. 46 /// Curvature error control: helper bounds for (4.2d), (5.2a), (5.2b), (5.15a), and (5.16a).
47 pub trait AdjointProductPairBoundedBy<Domain: Space, D1, D2>: Linear<Domain> { 47 ///
48 type FloatType: Float; 48 /// Based on Lemma 5.11 and Example 5.12, the helper bound for (5.15a) and (5.16a) is (3.8).
49 /// Return $(L, L_z)$ such that $A_*A ≤ (L_1 D_1, L_2 D_2)$. 49 /// Thus, subject to `guess` being correct, returns factor $(ℓ_F, Θ²)$ such that
50 fn adjoint_product_pair_bound( 50 /// $B_{F'(μ)} dγ ≤ ℓ_F c_2$ and $⟨F'(μ+Δ)-F'(μ)|Δ⟩ ≤ Θ²|γ|(c_2)$, where $Δ=(π_♯^1-π_♯^0)γ$.
51 /// The latter is the firm transport Lipshitz property of (3.8b) and Lemma 5.11.
52 ///
53 /// This trait is supposed to be implemented by the data term $F$, in the basic case a
54 /// [`Mapping`] from [`RNDM<N, F>`] to a [`Float`] `F`.
55 /// The generic implementation for operators that satisfy [`BasicCurvatureBoundEstimates`]
56 /// uses Remark 5.15 and Example 5.16 for (4.2d) and (5.2a), and (5.2b);
57 /// and Lemma 3.8 for (3.8).
58 pub trait BoundedCurvature<F: Float = f64> {
59 /// Returns $(ℓ_F, Θ²)$ or individual errors for each.
60 fn curvature_bound_components(
51 &self, 61 &self,
52 other1: &D1, 62 guess: BoundedCurvatureGuess,
53 other_2: &D2, 63 ) -> (DynResult<F>, DynResult<F>);
54 ) -> Option<(Self::FloatType, Self::FloatType)>;
55 } 64 }
56 65
57 /* 66 /// Curvature error control: helper bounds for (4.2d), (5.2a), (5.2b), (5.15a), and (5.16a)
58 /// Trait for [`ForwardModel`]s whose preadjoint has Lipschitz values. 67 /// for quadratic dataterms $F(μ) = \frac{1}{2}\|Aμ-b\|^2$.
59 pub trait LipschitzValues { 68 ///
60 type FloatType : Float; 69 /// This trait is to be implemented by the [`Linear`] operator $A$, in the basic from
61 /// Return (if one exists) a factor $L$ such that $A_*z$ is $L$-Lipschitz for all 70 /// [`RNDM<N, F>`] to a an Euclidean space.
62 /// $z$ in the unit ball. 71 /// It is used by implementations of [`BoundedCurvature`] for $F$.
63 fn value_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { 72 ///
64 None 73 /// Based on Lemma 5.11 and Example 5.12, the helper bound for (5.15a) and (5.16a) is (3.8).
65 } 74 /// This trait provides the factor $θ²$ of (3.8) as determined by Lemma 3.8.
75 /// To aid in calculating (4.2d), (5.2a), (5.2b), motivated by Example 5.16, it also provides
76 /// $ℓ_F^0$ such that $∇v^k$ $ℓ_F^0 \|Aμ-b\|$-Lipschitz. Here $v^k := F'(∪^k)$.
77 pub trait BasicCurvatureBoundEstimates<F: Float = f64> {
78 /// Returns $(ℓ_F^0, Θ²)$ or individual errors for each.
79 fn basic_curvature_bound_components(&self) -> (DynResult<F>, DynResult<F>);
80 }
66 81
67 /// Return (if one exists) a factor $L$ such that $∇A_*z$ is $L$-Lipschitz for all 82 impl<F, A, Z, const N: usize> BoundedCurvature<F> for QuadraticDataTerm<F, RNDM<N, F>, A>
68 /// $z$ in the unit ball. 83 where
69 fn value_diff_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { 84 F: Float,
70 None 85 Z: Clone + Space + Euclidean<F>,
86 A: Mapping<RNDM<N, F>, Codomain = Z>,
87 A: BasicCurvatureBoundEstimates<F>,
88 {
89 fn curvature_bound_components(
90 &self,
91 guess: BoundedCurvatureGuess,
92 ) -> (DynResult<F>, DynResult<F>) {
93 match guess {
94 BoundedCurvatureGuess::BetterThanZero => {
95 let opA = self.operator();
96 let b = self.data();
97 let (ℓ_F0, θ2) = opA.basic_curvature_bound_components();
98 (ℓ_F0.map(|l| l * b.norm2()), θ2)
99 }
100 }
71 } 101 }
72 } 102 }
73 */
74
75 /// Trait for [`ForwardModel`]s that satisfy bounds on curvature.
76 pub trait BoundedCurvature {
77 type FloatType: Float;
78
79 /// Returns factor $ℓ_F$ and $ℓ_r$ such that
80 /// $B_{F'(μ)} dγ ≤ ℓ_F c_2$ and $⟨F'(μ)+F'(μ+Δ)|Δ⟩ ≤ ℓ_r|γ|(c_2)$,
81 /// where $Δ=(π_♯^1-π_♯^0)γ$.
82 fn curvature_bound_components(&self) -> (Option<Self::FloatType>, Option<Self::FloatType>);
83 }

mercurial