Sat, 01 Feb 2025 16:47:11 -0500
Parameter adjustments
| 35 | 1 | /*! |
| 2 | Simple parametric forward model. | |
| 3 | */ | |
| 4 | ||
| 5 | use numeric_literals::replace_float_literals; | |
| 6 | use alg_tools::types::{Float, ClosedAdd}; | |
| 7 | use alg_tools::mapping::Space; | |
| 8 | use alg_tools::direct_product::Pair; | |
| 44 | 9 | use alg_tools::linops::{Linear, RowOp, IdOp, ZeroOp, AXPY}; |
| 35 | 10 | use alg_tools::error::DynError; |
| 11 | use alg_tools::norms::{L2, Norm, PairNorm, NormExponent}; | |
| 12 | use crate::measures::RNDM; | |
| 44 | 13 | use super::{ForwardModel, AdjointProductBoundedBy, AdjointProductPairBoundedBy, BoundedCurvature}; |
| 35 | 14 | |
| 15 | impl<Domain, F, A, E> ForwardModel<Pair<Domain, A::Observable>, F, PairNorm<E, L2, L2>> | |
| 16 | for RowOp<A, IdOp<A::Observable>> | |
| 17 | where | |
| 18 | E : NormExponent, | |
| 19 | Domain : Space + Norm<F, E>, | |
| 20 | F : Float, | |
| 21 | A::Observable : ClosedAdd + Norm<F, L2> + 'static, | |
| 22 | A : ForwardModel<Domain, F, E> + 'static | |
| 23 | { | |
| 24 | type Observable = A::Observable; | |
| 25 | ||
| 26 | fn write_observable(&self, b : &Self::Observable, prefix : String) -> DynError { | |
| 27 | self.0.write_observable(b, prefix) | |
| 28 | } | |
| 29 | ||
| 30 | /// Returns a zero observable | |
| 31 | fn zero_observable(&self) -> Self::Observable { | |
| 32 | self.0.zero_observable() | |
| 33 | } | |
| 34 | } | |
| 35 | ||
| 36 | #[replace_float_literals(F::cast_from(literal))] | |
| 37 | impl<Domain, F, A, D, Z> AdjointProductPairBoundedBy<Pair<Domain, Z>, D, IdOp<Z>> | |
| 38 | for RowOp<A, IdOp<Z>> | |
| 39 | where | |
| 40 | Domain : Space, | |
| 41 | F : Float, | |
| 42 | Z : Clone + Space + ClosedAdd, | |
| 43 | A : AdjointProductBoundedBy<Domain, D, FloatType=F, Codomain = Z>, | |
| 44 | A::Codomain : ClosedAdd, | |
| 45 | { | |
| 46 | type FloatType = F; | |
| 47 | ||
| 48 | fn adjoint_product_pair_bound(&self, d : &D, _ : &IdOp<Z>) -> Option<(F, F)> { | |
| 49 | self.0.adjoint_product_bound(d).map(|l_0| { | |
| 50 | // [A_*; B_*][A, B] = [A_*A, A_* B; B_* A, B_* B] ≤ diag(2A_*A, 2B_*B) | |
| 51 | // ≤ diag(2l_A𝒟_A, 2l_B𝒟_B), where now 𝒟_B=Id and l_B=1. | |
| 52 | (2.0 * l_0, 2.0) | |
| 53 | }) | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 44 | 57 | /* |
| 35 | 58 | /// This `impl` is bit of an abuse as the codomain of `Apre` is a [`Pair`] of a measure predual, |
| 59 | /// to which this `impl` applies, and another space. | |
| 60 | impl<F, Apre, Z> LipschitzValues | |
| 61 | for ColOp<Apre, IdOp<Z>> | |
| 62 | where | |
| 63 | F : Float, | |
| 64 | Z : Clone + Space + ClosedAdd, | |
| 65 | Apre : LipschitzValues<FloatType = F>, | |
| 66 | { | |
| 67 | type FloatType = F; | |
| 68 | /// Return (if one exists) a factor $L$ such that $A_*z$ is $L$-Lipschitz for all | |
| 69 | /// $z$ in the unit ball. | |
| 70 | fn value_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { | |
| 71 | self.0.value_unit_lipschitz_factor() | |
| 72 | } | |
| 73 | ||
| 74 | /// Return (if one exists) a factor $L$ such that $∇A_*z$ is $L$-Lipschitz for all | |
| 75 | /// $z$ in the unit ball. | |
| 76 | fn value_diff_unit_lipschitz_factor(&self) -> Option<Self::FloatType> { | |
| 77 | self.0.value_diff_unit_lipschitz_factor() | |
| 78 | } | |
| 79 | } | |
| 44 | 80 | */ |
| 35 | 81 | |
| 44 | 82 | impl<F, A, Z> BoundedCurvature |
| 83 | for RowOp<A, IdOp<Z>> | |
| 84 | where | |
| 85 | F : Float, | |
| 86 | Z : Clone + Space + ClosedAdd, | |
| 87 | A : BoundedCurvature<FloatType = F>, | |
| 88 | { | |
| 35 | 89 | type FloatType = F; |
| 90 | ||
| 44 | 91 | fn curvature_bound_components(&self) -> (Option<Self::FloatType>, Option<Self::FloatType>) { |
| 92 | self.0.curvature_bound_components() | |
| 35 | 93 | } |
| 94 | } | |
| 95 | ||
| 96 | #[replace_float_literals(F::cast_from(literal))] | |
| 97 | impl<'a, F, D, XD, Y, const N : usize> AdjointProductBoundedBy<RNDM<F, N>, D> | |
| 98 | for ZeroOp<'a, RNDM<F, N>, XD, Y, F> | |
| 99 | where | |
| 100 | F : Float, | |
| 101 | Y : AXPY<F> + Clone, | |
| 102 | D : Linear<RNDM<F, N>>, | |
| 103 | { | |
| 104 | type FloatType = F; | |
| 105 | /// Return $L$ such that $A_*A ≤ L𝒟$ is bounded by some `other` operator $𝒟$. | |
| 106 | fn adjoint_product_bound(&self, _ : &D) -> Option<F> { | |
| 107 | Some(0.0) | |
| 108 | } | |
| 109 | } | |
| 110 |