src/measures/delta.rs

changeset 0
eb3c7813b67a
equal deleted inserted replaced
-1:000000000000 0:eb3c7813b67a
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, Dist};
11 use alg_tools::linops::{Apply, Linear};
12
13 /// Representation of a delta measure.
14 ///
15 /// This is a single spike $\alpha \delta\_x$ for some location $x$ in `Domain` and
16 /// a mass $\alpha$ in `F`.
17 #[derive(Clone,Copy,Debug)]
18 pub struct DeltaMeasure<Domain, F : Num> {
19 // This causes [`csv`] to crash.
20 //#[serde(flatten)]
21 /// Location of the spike
22 pub x : Domain,
23 /// Mass of the spike
24 pub α : F
25 }
26
27 const COORDINATE_NAMES : &'static [&'static str] = &[
28 "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7"
29 ];
30
31 // Need to manually implement serialisation as [`csv`] writer fails on
32 // structs with nested arrays as well as with #[serde(flatten)].
33 impl<F : Num, const N : usize> Serialize for DeltaMeasure<Loc<F, N>, F>
34 where
35 F: Serialize,
36 {
37 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38 where
39 S: Serializer,
40 {
41 assert!(N <= COORDINATE_NAMES.len());
42
43 let mut s = serializer.serialize_struct("DeltaMeasure", N+1)?;
44 for (i, e) in (0..).zip(self.x.iter()) {
45 s.serialize_field(COORDINATE_NAMES[i], e)?;
46 }
47 s.serialize_field("weight", &self.α)?;
48 s.end()
49 }
50 }
51
52
53 impl<Domain : PartialEq, F : Float> Measure<F> for DeltaMeasure<Domain, F> {
54 type Domain = Domain;
55 }
56
57 impl<Domain : PartialEq, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> {
58 #[inline]
59 fn norm(&self, _ : Radon) -> F {
60 self.α.abs()
61 }
62 }
63
64 impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> {
65 #[inline]
66 fn dist(&self, other : &Self, _ : Radon) -> F {
67 if self.x == other. x {
68 (self.α - other.α).abs()
69 } else {
70 self.α.abs() + other.α.abs()
71 }
72 }
73 }
74
75 impl<'b, Domain, G, F : Num, V : Mul<F, Output=V>> Apply<G> for DeltaMeasure<Domain, F>
76 where G: for<'a> Apply<&'a Domain, Output = V>,
77 V : Mul<F> {
78 type Output = V;
79
80 #[inline]
81 fn apply(&self, g : G) -> Self::Output {
82 g.apply(&self.x) * self.α
83 }
84 }
85
86 impl<Domain, G, F : Num, V : Mul<F, Output=V>> Linear<G> for DeltaMeasure<Domain, F>
87 where G: for<'a> Apply<&'a Domain, Output = V> {
88 type Codomain = V;
89 }
90
91 // /// 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`]
93 // /// 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
95 // /// chokes up.
96 // impl<Domain, G, F : Num, V> Linear<G> for DeltaMeasure<Domain, F>
97 // where G: for<'a> Apply<&'a Domain, Output = V>,
98 // V : Mul<F>,
99 // Self: Apply<G, Output = <V as Mul<F>>::Output> {
100 // type Codomain = <V as Mul<F>>::Output;
101 // }
102
103 // impl<'b, Domain, G, F : Num, V> Apply<&'b G> for DeltaMeasure<Domain, F>
104 // where G: for<'a> Apply<&'a Domain, Output = V>,
105 // V : Mul<F> {
106 // type Output = <V as Mul<F>>::Output;
107
108 // #[inline]
109 // fn apply(&self, g : &'b G) -> Self::Output {
110 // g.apply(&self.x) * self.α
111 // }
112 // }
113
114 // /// Implementation of the necessary apply for BTFNs
115 // mod btfn_apply {
116 // use super::*;
117 // use alg_tools::bisection_tree::{BTFN, BTImpl, SupportGenerator, LocalAnalysis};
118
119 // impl<F : Float, BT, G, V, const N : usize> Apply<BTFN<F, G, BT, N>>
120 // for DeltaMeasure<Loc<F, N>, F>
121 // where BT : BTImpl<F, N>,
122 // G : SupportGenerator<F, N, Id=BT::Data>,
123 // G::SupportType : LocalAnalysis<F, BT::Agg, N> + for<'a> Apply<&'a Loc<F, N>, Output = V>,
124 // V : std::iter::Sum + Mul<F> {
125
126 // type Output = <V as Mul<F>>::Output;
127
128 // #[inline]
129 // fn apply(&self, g : BTFN<F, G, BT, N>) -> Self::Output {
130 // g.apply(&self.x) * self.α
131 // }
132 // }
133 // }
134
135
136 impl<D, Domain, F : Num> From<(D, F)> for DeltaMeasure<Domain, F>
137 where D : Into<Domain> {
138 #[inline]
139 fn from((x, α) : (D, F)) -> Self {
140 DeltaMeasure{x: x.into(), α: α}
141 }
142 }
143
144 /*impl<F : Num> From<(F, F)> for DeltaMeasure<Loc<F, 1>, F> {
145 #[inline]
146 fn from((x, α) : (F, F)) -> Self {
147 DeltaMeasure{x: Loc([x]), α: α}
148 }
149 }*/
150
151 impl<Domain, F : Num> DeltaMeasure<Domain, F> {
152 /// Set the mass of the spike.
153 #[inline]
154 pub fn set_mass(&mut self, α : F) {
155 self.α = α
156 }
157
158 /// Set the location of the spike.
159 #[inline]
160 pub fn set_location(&mut self, x : Domain) {
161 self.x = x
162 }
163
164 /// Get the mass of the spike.
165 #[inline]
166 pub fn get_mass(&self) -> F {
167 self.α
168 }
169
170 /// Get a mutable reference to the mass of the spike.
171 #[inline]
172 pub fn get_mass_mut(&mut self) -> &mut F {
173 &mut self.α
174 }
175
176 /// Get a reference to the location of the spike.
177 #[inline]
178 pub fn get_location(&self) -> &Domain {
179 &self.x
180 }
181
182 /// Get a mutable reference to the location of the spike.
183 #[inline]
184 pub fn get_location_mut(&mut self) -> &mut Domain {
185 &mut self.x
186 }
187 }
188
189
190 macro_rules! make_delta_scalarop_rhs {
191 ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => {
192 impl<F : Num, Domain> $trait<F> for DeltaMeasure<Domain, F> {
193 type Output = Self;
194 fn $fn(mut self, b : F) -> Self {
195 self.α.$fn_assign(b);
196 self
197 }
198 }
199
200 impl<'a, F : Num, Domain> $trait<&'a F> for DeltaMeasure<Domain, F> {
201 type Output = Self;
202 fn $fn(mut self, b : &'a F) -> Self {
203 self.α.$fn_assign(*b);
204 self
205 }
206 }
207
208 impl<'b, F : Num, Domain : Clone> $trait<F> for &'b DeltaMeasure<Domain, F> {
209 type Output = DeltaMeasure<Domain, F>;
210 fn $fn(self, b : F) -> Self::Output {
211 DeltaMeasure { α : self.α.$fn(b), x : self.x.clone() }
212 }
213 }
214
215 impl<'a, 'b, F : Num, Domain : Clone> $trait<&'a F> for &'b DeltaMeasure<Domain, F> {
216 type Output = DeltaMeasure<Domain, F>;
217 fn $fn(self, b : &'a F) -> Self::Output {
218 DeltaMeasure { α : self.α.$fn(*b), x : self.x.clone() }
219 }
220 }
221
222 impl<F : Num, Domain> $trait_assign<F> for DeltaMeasure<Domain, F> {
223 fn $fn_assign(&mut self, b : F) {
224 self.α.$fn_assign(b)
225 }
226 }
227
228 impl<'a, F : Num, Domain> $trait_assign<&'a F> for DeltaMeasure<Domain, F> {
229 fn $fn_assign(&mut self, b : &'a F) {
230 self.α.$fn_assign(*b)
231 }
232 }
233 }
234 }
235
236 make_delta_scalarop_rhs!(Mul, mul, MulAssign, mul_assign);
237 make_delta_scalarop_rhs!(Div, div, DivAssign, div_assign);
238
239 macro_rules! make_delta_scalarop_lhs {
240 ($trait:ident, $fn:ident; $($f:ident)+) => { $(
241 impl<Domain> $trait<DeltaMeasure<Domain, $f>> for $f {
242 type Output = DeltaMeasure<Domain, $f>;
243 fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
244 δ.α = self.$fn(δ.α);
245 δ
246 }
247 }
248
249 impl<'a, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for $f {
250 type Output = DeltaMeasure<Domain, $f>;
251 fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
252 DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
253 }
254 }
255
256 impl<'b, Domain> $trait<DeltaMeasure<Domain, $f>> for &'b $f {
257 type Output = DeltaMeasure<Domain, $f>;
258 fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output {
259 δ.α = self.$fn(δ.α);
260 δ
261 }
262 }
263
264 impl<'a, 'b, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for &'b $f {
265 type Output = DeltaMeasure<Domain, $f>;
266 fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output {
267 DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) }
268 }
269 }
270 )+ }
271 }
272
273 make_delta_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
274 make_delta_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
275
276 macro_rules! make_delta_unary {
277 ($trait:ident, $fn:ident, $type:ty) => {
278 impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type {
279 type Output = DeltaMeasure<Domain, F>;
280 fn $fn(self) -> Self::Output {
281 let mut tmp = self.clone();
282 tmp.α = tmp.α.$fn();
283 tmp
284 }
285 }
286 }
287 }
288
289 make_delta_unary!(Neg, neg, DeltaMeasure<Domain, F>);
290 make_delta_unary!(Neg, neg, &'a DeltaMeasure<Domain, F>);
291

mercurial