|
1 /*! |
|
2 Basid definitions for data terms |
|
3 */ |
|
4 |
|
5 use numeric_literals::replace_float_literals; |
|
6 |
|
7 use alg_tools::euclidean::Euclidean; |
|
8 use alg_tools::linops::GEMV; |
|
9 pub use alg_tools::norms::L1; |
|
10 use alg_tools::norms::Norm; |
|
11 use alg_tools::instance::{Instance, Space}; |
|
12 |
|
13 use crate::types::*; |
|
14 pub use crate::types::L2Squared; |
|
15 use crate::measures::RNDM; |
|
16 |
|
17 /// Calculates the residual $Aμ-b$. |
|
18 #[replace_float_literals(F::cast_from(literal))] |
|
19 pub(crate) fn calculate_residual< |
|
20 X : Space, |
|
21 I : Instance<X>, |
|
22 F : Float, |
|
23 V : Euclidean<F> + Clone, |
|
24 A : GEMV<F, X, Codomain = V>, |
|
25 >( |
|
26 μ : I, |
|
27 opA : &A, |
|
28 b : &V |
|
29 ) -> V { |
|
30 let mut r = b.clone(); |
|
31 opA.gemv(&mut r, 1.0, μ, -1.0); |
|
32 r |
|
33 } |
|
34 |
|
35 /// Calculates the residual $A(μ+μ_delta)-b$. |
|
36 #[replace_float_literals(F::cast_from(literal))] |
|
37 pub(crate) fn calculate_residual2< |
|
38 F : Float, |
|
39 X : Space, |
|
40 I : Instance<X>, |
|
41 J : Instance<X>, |
|
42 V : Euclidean<F> + Clone, |
|
43 A : GEMV<F, X, Codomain = V>, |
|
44 >( |
|
45 μ : I, |
|
46 μ_delta : J, |
|
47 opA : &A, |
|
48 b : &V |
|
49 ) -> V { |
|
50 let mut r = b.clone(); |
|
51 opA.gemv(&mut r, 1.0, μ, -1.0); |
|
52 opA.gemv(&mut r, 1.0, μ_delta, 1.0); |
|
53 r |
|
54 } |
|
55 |
|
56 |
|
57 /// Trait for data terms |
|
58 #[replace_float_literals(F::cast_from(literal))] |
|
59 pub trait DataTerm<F : Float, V, const N : usize> { |
|
60 /// Calculates $F(y)$, where $F$ is the data fidelity. |
|
61 fn calculate_fit(&self, _residual : &V) -> F; |
|
62 |
|
63 /// Calculates $F(Aμ-b)$, where $F$ is the data fidelity. |
|
64 fn calculate_fit_op<I, A : GEMV<F, RNDM<F, N>, Codomain = V>>( |
|
65 &self, |
|
66 μ : I, |
|
67 opA : &A, |
|
68 b : &V |
|
69 ) -> F |
|
70 where |
|
71 V : Euclidean<F> + Clone, |
|
72 I : Instance<RNDM<F, N>>, |
|
73 { |
|
74 let r = calculate_residual(μ, opA, b); |
|
75 self.calculate_fit(&r) |
|
76 } |
|
77 } |
|
78 |
|
79 impl<F : Float, V : Euclidean<F>, const N : usize> |
|
80 DataTerm<F, V, N> |
|
81 for L2Squared { |
|
82 fn calculate_fit(&self, residual : &V) -> F { |
|
83 residual.norm2_squared_div2() |
|
84 } |
|
85 } |
|
86 |
|
87 |
|
88 impl<F : Float, V : Euclidean<F> + Norm<F, L1>, const N : usize> |
|
89 DataTerm<F, V, N> |
|
90 for L1 { |
|
91 fn calculate_fit(&self, residual : &V) -> F { |
|
92 residual.norm(L1) |
|
93 } |
|
94 } |