5 |
5 |
6 use super::base::*; |
6 use super::base::*; |
7 use crate::types::*; |
7 use crate::types::*; |
8 use std::ops::{Div, Mul, DivAssign, MulAssign, Neg}; |
8 use std::ops::{Div, Mul, DivAssign, MulAssign, Neg}; |
9 use serde::ser::{Serialize, Serializer, SerializeStruct}; |
9 use serde::ser::{Serialize, Serializer, SerializeStruct}; |
10 use alg_tools::norms::{Norm, Dist}; |
10 use alg_tools::norms::Norm; |
11 use alg_tools::linops::{Apply, Linear}; |
11 use alg_tools::linops::{Mapping, Linear}; |
|
12 use alg_tools::instance::{Instance, Space}; |
12 |
13 |
13 /// Representation of a delta measure. |
14 /// Representation of a delta measure. |
14 /// |
15 /// |
15 /// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and |
16 /// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and |
16 /// a mass $\alpha$ in `F`. |
17 /// a mass $\alpha$ in `F`. |
48 s.end() |
49 s.end() |
49 } |
50 } |
50 } |
51 } |
51 |
52 |
52 |
53 |
53 impl<Domain : PartialEq, F : Float> Measure<F> for DeltaMeasure<Domain, F> { |
54 impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> { |
54 type Domain = Domain; |
55 type Domain = Domain; |
55 } |
56 } |
56 |
57 |
57 impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> { |
58 impl<Domain, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> { |
58 #[inline] |
59 #[inline] |
59 fn norm(&self, _ : Radon) -> F { |
60 fn norm(&self, _ : Radon) -> F { |
60 self.α.abs() |
61 self.α.abs() |
61 } |
62 } |
62 } |
63 } |
63 |
64 |
64 impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> { |
65 // impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> { |
65 #[inline] |
66 // #[inline] |
66 fn dist(&self, other : &Self, _ : Radon) -> F { |
67 // fn dist(&self, other : &Self, _ : Radon) -> F { |
67 if self.x == other. x { |
68 // if self.x == other. x { |
68 (self.α - other.α).abs() |
69 // (self.α - other.α).abs() |
69 } else { |
70 // } else { |
70 self.α.abs() + other.α.abs() |
71 // self.α.abs() + other.α.abs() |
71 } |
72 // } |
72 } |
73 // } |
73 } |
74 // } |
74 |
75 |
75 impl<'b, Domain, G, F : Num, V : Mul<F, Output=V>> Apply<G> for DeltaMeasure<Domain, F> |
76 impl<Domain, G, F : Num> Mapping<G> for DeltaMeasure<Domain, F> |
76 where G: for<'a> Apply<&'a Domain, Output = V>, |
77 where |
77 V : Mul<F> { |
78 Domain : Space, |
78 type Output = V; |
79 G::Codomain : Mul<F, Output=G::Codomain>, |
79 |
80 G : Mapping<Domain> + Clone + Space, |
80 #[inline] |
81 for<'b> &'b Domain : Instance<Domain>, |
81 fn apply(&self, g : G) -> Self::Output { |
82 { |
82 g.apply(&self.x) * self.α |
83 type Codomain = G::Codomain; |
83 } |
84 |
84 } |
85 #[inline] |
85 |
86 fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain { |
86 impl<Domain, G, F : Num, V : Mul<F, Output=V>> Linear<G> for DeltaMeasure<Domain, F> |
87 g.eval(|g̃| g̃.apply(&self.x) * self.α) |
87 where G: for<'a> Apply<&'a Domain, Output = V> { |
88 } |
88 type Codomain = V; |
89 } |
89 } |
90 |
|
91 impl<Domain, G, F : Num> Linear<G> for DeltaMeasure<Domain, F> |
|
92 where |
|
93 Domain : Space, |
|
94 G::Codomain : Mul<F, Output=G::Codomain>, |
|
95 G : Mapping<Domain> + Clone + Space, |
|
96 for<'b> &'b Domain : Instance<Domain>, |
|
97 { } |
90 |
98 |
91 // /// Partial blanket implementation of [`DeltaMeasure`] as a linear functional of [`Mapping`]s. |
99 // /// Partial blanket implementation of [`DeltaMeasure`] as a linear functional of [`Mapping`]s. |
92 // /// A full blanket implementation is not possible due to annoying Rust limitations: only [`Apply`] |
100 // /// A full blanket implementation is not possible due to annoying Rust limitations: only [`Apply`] |
93 // /// on a reference is implemented, but a consuming [`Apply`] has to be implemented on a case-by-case |
101 // /// on a reference is implemented, but a consuming [`Apply`] has to be implemented on a case-by-case |
94 // /// basis, not because an implementation could not be written, but because the Rust trait system |
102 // /// basis, not because an implementation could not be written, but because the Rust trait system |
139 fn from((x, α) : (D, F)) -> Self { |
147 fn from((x, α) : (D, F)) -> Self { |
140 DeltaMeasure{x: x.into(), α: α} |
148 DeltaMeasure{x: x.into(), α: α} |
141 } |
149 } |
142 } |
150 } |
143 |
151 |
144 /*impl<F : Num> From<(F, F)> for DeltaMeasure<Loc<F, 1>, F> { |
152 impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> for DeltaMeasure<Domain, F> { |
145 #[inline] |
153 #[inline] |
146 fn from((x, α) : (F, F)) -> Self { |
154 fn from(d : &'a DeltaMeasure<Domain, F>) -> Self { |
147 DeltaMeasure{x: Loc([x]), α: α} |
155 d.clone() |
148 } |
156 } |
149 }*/ |
157 } |
|
158 |
150 |
159 |
151 impl<Domain, F : Num> DeltaMeasure<Domain, F> { |
160 impl<Domain, F : Num> DeltaMeasure<Domain, F> { |
152 /// Set the mass of the spike. |
161 /// Set the mass of the spike. |
153 #[inline] |
162 #[inline] |
154 pub fn set_mass(&mut self, α : F) { |
163 pub fn set_mass(&mut self, α : F) { |
181 |
190 |
182 /// Get a mutable reference to the location of the spike. |
191 /// Get a mutable reference to the location of the spike. |
183 #[inline] |
192 #[inline] |
184 pub fn get_location_mut(&mut self) -> &mut Domain { |
193 pub fn get_location_mut(&mut self) -> &mut Domain { |
185 &mut self.x |
194 &mut self.x |
|
195 } |
|
196 } |
|
197 |
|
198 impl<Domain, F : Num> IntoIterator for DeltaMeasure<Domain, F> { |
|
199 type Item = Self; |
|
200 type IntoIter = std::iter::Once<Self>; |
|
201 |
|
202 #[inline] |
|
203 fn into_iter(self) -> Self::IntoIter { |
|
204 std::iter::once(self) |
|
205 } |
|
206 } |
|
207 |
|
208 impl<'a, Domain, F : Num> IntoIterator for &'a DeltaMeasure<Domain, F> { |
|
209 type Item = Self; |
|
210 type IntoIter = std::iter::Once<Self>; |
|
211 |
|
212 #[inline] |
|
213 fn into_iter(self) -> Self::IntoIter { |
|
214 std::iter::once(self) |
186 } |
215 } |
187 } |
216 } |
188 |
217 |
189 |
218 |
190 macro_rules! make_delta_scalarop_rhs { |
219 macro_rules! make_delta_scalarop_rhs { |