| 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 } |
|