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