src/dataterm.rs

changeset 52
f0e8704d3f0e
parent 35
b087e3eab191
equal deleted inserted replaced
31:6105b5cd8d89 52:f0e8704d3f0e
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 }

mercurial