src/measures/delta.rs

branch
dev
changeset 61
4f468d35fa29
parent 60
9738b51d90d7
child 62
32328a74c790
child 63
7a8a55fd41c0
equal deleted inserted replaced
60:9738b51d90d7 61:4f468d35fa29
1 /*!
2 This module implementes delta measures, i.e., single spikes $\alpha \delta_x$ for some
3 location $x$ and mass $\alpha$.
4 */
5
6 use super::base::*;
7 use crate::types::*;
8 use std::ops::{Div, Mul, DivAssign, MulAssign, Neg};
9 use serde::ser::{Serialize, Serializer, SerializeStruct};
10 use alg_tools::norms::Norm;
11 use alg_tools::linops::{Mapping, Linear};
12 use alg_tools::instance::{Instance, Space};
13
14 /// Representation of a delta measure.
15 ///
16 /// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and
17 /// a mass $\alpha$ in `F`.
18 #[derive(Clone,Copy,Debug)]
19 pub struct DeltaMeasure<Domain, F : Num> {
20 // This causes [`csv`] to crash.
21 //#[serde(flatten)]
22 /// Location of the spike
23 pub x : Domain,
24 /// Mass of the spike
25 pub α : F
26 }
27
28 const COORDINATE_NAMES : &'static [&'static str] = &[
29 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7"
30 ];
31
32 // Need to manually implement serialisation as [`csv`] writer fails on
33 // structs with nested arrays as well as with #[serde(flatten)].
34 impl<F : Num, const N : usize> Serialize for DeltaMeasure<Loc<F, N>, F>
35 where
36 F: Serialize,
37 {
38 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 S: Serializer,
41 {
42 assert!(N <= COORDINATE_NAMES.len());
43
44 let mut s = serializer.serialize_struct("DeltaMeasure", N+1)?;
45 for (i, e) in (0..).zip(self.x.iter()) {
46 s.serialize_field(COORDINATE_NAMES[i], e)?;
47 }
48 s.serialize_field("weight", &self.α)?;
49 s.end()
50 }
51 }
52
53
54 impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> {
55 type Domain = Domain;
56 }
57
58 impl<Domain, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> {
59 #[inline]
60 fn norm(&self, _ : Radon) -> F {
61 self.α.abs()
62 }
63 }
64
65 // impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> {
66 // #[inline]
67 // fn dist(&self, other : &Self, _ : Radon) -> F {
68 // if self.x == other. x {
69 // (self.α - other.α).abs()
70 // } else {
71 // self.α.abs() + other.α.abs()
72 // }
73 // }
74 // }
75
76 impl<Domain, G, F : Num> Mapping<G> for DeltaMeasure<Domain, F>
77 where
78 Domain : Space,
79 G::Codomain : Mul<F, Output=G::Codomain>,
80 G : Mapping<Domain> + Clone + Space,
81 for<'b> &'b Domain : Instance<Domain>,
82 {
83 type Codomain = G::Codomain;
84
85 #[inline]
86 fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain {
87 g.eval(|g̃| g̃.apply(&self.x) * self.α)
88 }
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 { }
98
99 // /// Partial blanket implementation of [`DeltaMeasure`] as a linear functional of [`Mapping`]s.
100 // /// A full blanket implementation is not possible due to annoying Rust limitations: only [`Apply`]
101 // /// on a reference is implemented, but a consuming [`Apply`] has to be implemented on a case-by-case
102 // /// basis, not because an implementation could not be written, but because the Rust trait system
103 // /// chokes up.
104 // impl<Domain, G, F : Num, V> Linear<G> for DeltaMeasure<Domain, F>
105 // where G: for<'a> Apply<&'a Domain, Output = V>,
106 // V : Mul<F>,
107 // Self: Apply<G, Output = <V as Mul<F>>::Output> {
108 // type Codomain = <V as Mul<F>>::Output;
109 // }
110
111 // impl<'b, Domain, G, F : Num, V> Apply<&'b G> for DeltaMeasure<Domain, F>
112 // where G: for<'a> Apply<&'a Domain, Output = V>,
113 // V : Mul<F> {
114 // type Output = <V as Mul<F>>::Output;
115
116 // #[inline]
117 // fn apply(&self, g : &'b G) -> Self::Output {
118 // g.apply(&self.x) * self.α
119 // }
120 // }
121
122 // /// Implementation of the necessary apply for BTFNs
123 // mod btfn_apply {
124 // use super::*;
125 // use alg_tools::bisection_tree::{BTFN, BTImpl, SupportGenerator, LocalAnalysis};
126
127 // impl<F : Float, BT, G, V, const N : usize> Apply<BTFN<F, G, BT, N>>
128 // for DeltaMeasure<Loc<F, N>, F>
129 // where BT : BTImpl<F, N>,
130 // G : SupportGenerator<F, N, Id=BT::Data>,
131 // G::SupportType : LocalAnalysis<F, BT::Agg, N> + for<'a> Apply<&'a Loc<F, N>, Output = V>,
132 // V : std::iter::Sum + Mul<F> {
133
134 // type Output = <V as Mul<F>>::Output;
135
136 // #[inline]
137 // fn apply(&self, g : BTFN<F, G, BT, N>) -> Self::Output {
138 // g.apply(&self.x) * self.α
139 // }
140 // }
141 // }
142
143
144 impl<D, Domain, F : Num> From<(D, F)> for DeltaMeasure<Domain, F>
145 where D : Into<Domain> {
146 #[inline]
147 fn from((x, α) : (D, F)) -> Self {
148 DeltaMeasure{x: x.into(), α: α}
149 }
150 }
151
152 impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> for DeltaMeasure<Domain, F> {
153 #[inline]
154 fn from(d : &'a DeltaMeasure<Domain, F>) -> Self {
155 d.clone()
156 }
157 }
158
159
160 impl<Domain, F : Num> DeltaMeasure<Domain, F> {
161 /// Set the mass of the spike.
162 #[inline]
163 pub fn set_mass(&mut self, α : F) {
164 self.α = α
165 }
166
167 /// Set the location of the spike.
168 #[inline]
169 pub fn set_location(&mut self, x : Domain) {
170 self.x = x
171 }
172
173 /// Get the mass of the spike.
174 #[inline]
175 pub fn get_mass(&self) -> F {
176 self.α
177 }
178
179 /// Get a mutable reference to the mass of the spike.
180 #[inline]
181 pub fn get_mass_mut(&mut self) -> &mut F {
182 &mut self.α
183 }
184
185 /// Get a reference to the location of the spike.
186 #[inline]
187 pub fn get_location(&self) -> &Domain {
188 &self.x
189 }
190
191 /// Get a mutable reference to the location of the spike.
192 #[inline]
193 pub fn get_location_mut(&mut self) -> &mut Domain {
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)
215 }
216 }
217
218
219 macro_rules! make_delta_scalarop_rhs {
220 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
221 impl<F : Num, Domain> $trait<F> for DeltaMeasure<Domain, F> {
222 type Output = Self;
223 fn $fn(mut self, b : F) -> Self {
224 self.α.$fn_assign(b);
225 self
226 }
227 }
228
229 impl<'a, F : Num, Domain> $trait<&'a F> for DeltaMeasure<Domain, F> {
230 type Output = Self;
231 fn $fn(mut self, b : &'a F) -> Self {
232 self.α.$fn_assign(*b);
233 self
234 }
235 }
236
237 impl<'b, F : Num, Domain : Clone> $trait<F> for &'b DeltaMeasure<Domain, F> {
238 type Output = DeltaMeasure<Domain, F>;
239 fn $fn(self, b : F) -> Self::Output {
240 DeltaMeasure { α : self.α.$fn(b), x : self.x.clone() }
241 }
242 }
243
244 impl<'a, 'b, F : Num, Domain : Clone> $trait<&'a F> for &'b DeltaMeasure<Domain, F> {
245 type Output = DeltaMeasure<Domain, F>;
246 fn $fn(self, b : &'a F) -> Self::Output {
247 DeltaMeasure { α : self.α.$fn(*b), x : self.x.clone() }
248 }
249 }
250
251 impl<F : Num, Domain> $trait_assign<F> for DeltaMeasure<Domain, F> {
252 fn $fn_assign(&mut self, b : F) {
253 self.α.$fn_assign(b)
254 }
255 }
256
257 impl<'a, F : Num, Domain> $trait_assign<&'a F> for DeltaMeasure<Domain, F> {
258 fn $fn_assign(&mut self, b : &'a F) {
259 self.α.$fn_assign(*b)
260 }
261 }
262 }
263 }
264
265 make_delta_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
266 make_delta_scalarop_rhs!(Div, div, DivAssign, div_assign);
267
268 macro_rules! make_delta_scalarop_lhs {
269 ($trait:ident, $fn:ident; $($f:ident)+) => { $(
270 impl<Domain> $trait<DeltaMeasure<Domain, $f>> for $f {
271 type Output = DeltaMeasure<Domain, $f>;
272 fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
273 δ.α = self.$fn(δ.α);
274 δ
275 }
276 }
277
278 impl<'a, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for $f {
279 type Output = DeltaMeasure<Domain, $f>;
280 fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
281 DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
282 }
283 }
284
285 impl<'b, Domain> $trait<DeltaMeasure<Domain, $f>> for &'b $f {
286 type Output = DeltaMeasure<Domain, $f>;
287 fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
288 δ.α = self.$fn(δ.α);
289 δ
290 }
291 }
292
293 impl<'a, 'b, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for &'b $f {
294 type Output = DeltaMeasure<Domain, $f>;
295 fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
296 DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
297 }
298 }
299 )+ }
300 }
301
302 make_delta_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
303 make_delta_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
304
305 macro_rules! make_delta_unary {
306 ($trait:ident, $fn:ident, $type:ty) => {
307 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type {
308 type Output = DeltaMeasure<Domain, F>;
309 fn $fn(self) -> Self::Output {
310 let mut tmp = self.clone();
311 tmp.α = tmp.α.$fn();
312 tmp
313 }
314 }
315 }
316 }
317
318 make_delta_unary!(Neg, neg, DeltaMeasure<Domain, F>);
319 make_delta_unary!(Neg, neg, &'a DeltaMeasure<Domain, F>);
320

mercurial