src/forward_model.rs

branch
dev
changeset 61
4f468d35fa29
parent 49
6b0db7251ebe
child 63
7a8a55fd41c0
equal deleted inserted replaced
60:9738b51d90d7 61:4f468d35fa29
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 ///
52 /// This trait is supposed to be implemented by the data term $F$, in the basic case a
53 /// [`Mapping`] from [`RNDM<N, F>`] to a [`Float`] `F`.
54 /// The generic implementation for operators that satisfy [`BasicCurvatureBoundEstimates`]
55 /// uses Remark 5.15 and Example 5.16 for (4.2d) and (5.2a), and (5.2b);
56 /// and Lemma 3.8 for (3.8).
57 pub trait BoundedCurvature<F: Float = f64> {
58 /// Returns $(ℓ_F, Θ²)$ or individual errors for each.
59 fn curvature_bound_components(
51 &self, 60 &self,
52 other1: &D1, 61 guess: BoundedCurvatureGuess,
53 other_2: &D2, 62 ) -> (DynResult<F>, DynResult<F>);
54 ) -> Option<(Self::FloatType, Self::FloatType)>;
55 } 63 }
56 64
57 /* 65 /// 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. 66 /// for quadratic dataterms $F(μ) = \frac{1}{2}\|Aμ-b\|^2$.
59 pub trait LipschitzValues { 67 ///
60 type FloatType : Float; 68 /// 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 69 /// [`RNDM<N, F>`] to a an Euclidean space.
62 /// $z$ in the unit ball. 70 /// It is used by implementations of [`BoundedCurvature`] for $F$.
63 fn value_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { 71 ///
64 None 72 /// Based on Lemma 5.11 and Example 5.12, the helper bound for (5.15a) and (5.16a) is (3.8).
65 } 73 /// This trait provides the factor $θ²$ of (3.8) as determined by Lemma 3.8.
74 /// To aid in calculating (4.2d), (5.2a), (5.2b), motivated by Example 5.16, it also provides
75 /// $ℓ_F^0$ such that $∇v^k$ $ℓ_F^0 \|Aμ-b\|$-Lipschitz. Here $v^k := F'(∪^k)$.
76 pub trait BasicCurvatureBoundEstimates<F: Float = f64> {
77 /// Returns $(ℓ_F^0, Θ²)$ or individual errors for each.
78 fn basic_curvature_bound_components(&self) -> (DynResult<F>, DynResult<F>);
79 }
66 80
67 /// Return (if one exists) a factor $L$ such that $∇A_*z$ is $L$-Lipschitz for all 81 impl<F, A, Z, const N: usize> BoundedCurvature<F> for QuadraticDataTerm<F, RNDM<N, F>, A>
68 /// $z$ in the unit ball. 82 where
69 fn value_diff_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { 83 F: Float,
70 None 84 Z: Clone + Space + Euclidean<F>,
85 A: Mapping<RNDM<N, F>, Codomain = Z>,
86 A: BasicCurvatureBoundEstimates<F>,
87 {
88 fn curvature_bound_components(
89 &self,
90 guess: BoundedCurvatureGuess,
91 ) -> (DynResult<F>, DynResult<F>) {
92 match guess {
93 BoundedCurvatureGuess::BetterThanZero => {
94 let opA = self.operator();
95 let b = self.data();
96 let (ℓ_F0, θ2) = opA.basic_curvature_bound_components();
97 (ℓ_F0.map(|l| l * b.norm2()), θ2)
98 }
99 }
71 } 100 }
72 } 101 }
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