Mon, 06 Jan 2025 21:37:03 -0500
Attempt to do more Serialize / Deserialize but run into csv problems
0 | 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}; | |
38
0f59c0d02e13
Attempt to do more Serialize / Deserialize but run into csv problems
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
9 | use serde::{Serialize, Deserialize}; |
35 | 10 | use alg_tools::norms::Norm; |
11 | use alg_tools::linops::{Mapping, Linear}; | |
12 | use alg_tools::instance::{Instance, Space}; | |
0 | 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`. | |
38
0f59c0d02e13
Attempt to do more Serialize / Deserialize but run into csv problems
Tuomo Valkonen <tuomov@iki.fi>
parents:
35
diff
changeset
|
18 | #[derive(Clone,Copy,Debug,Serialize,Deserialize)] |
0 | 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 | ||
35 | 28 | impl<Domain, F : Float> Measure<F> for DeltaMeasure<Domain, F> { |
0 | 29 | type Domain = Domain; |
30 | } | |
31 | ||
35 | 32 | impl<Domain, F : Float> Norm<F, Radon> for DeltaMeasure<Domain, F> { |
0 | 33 | #[inline] |
34 | fn norm(&self, _ : Radon) -> F { | |
35 | self.α.abs() | |
36 | } | |
37 | } | |
38 | ||
35 | 39 | // impl<Domain : PartialEq, F : Float> Dist<F, Radon> for DeltaMeasure<Domain, F> { |
40 | // #[inline] | |
41 | // fn dist(&self, other : &Self, _ : Radon) -> F { | |
42 | // if self.x == other. x { | |
43 | // (self.α - other.α).abs() | |
44 | // } else { | |
45 | // self.α.abs() + other.α.abs() | |
46 | // } | |
47 | // } | |
48 | // } | |
49 | ||
50 | impl<Domain, G, F : Num> Mapping<G> for DeltaMeasure<Domain, F> | |
51 | where | |
52 | Domain : Space, | |
53 | G::Codomain : Mul<F, Output=G::Codomain>, | |
54 | G : Mapping<Domain> + Clone + Space, | |
55 | for<'b> &'b Domain : Instance<Domain>, | |
56 | { | |
57 | type Codomain = G::Codomain; | |
58 | ||
0 | 59 | #[inline] |
35 | 60 | fn apply<I : Instance<G>>(&self, g : I) -> Self::Codomain { |
61 | g.eval(|g̃| g̃.apply(&self.x) * self.α) | |
0 | 62 | } |
63 | } | |
64 | ||
35 | 65 | impl<Domain, G, F : Num> Linear<G> for DeltaMeasure<Domain, F> |
66 | where | |
67 | Domain : Space, | |
68 | G::Codomain : Mul<F, Output=G::Codomain>, | |
69 | G : Mapping<Domain> + Clone + Space, | |
70 | for<'b> &'b Domain : Instance<Domain>, | |
71 | { } | |
0 | 72 | |
73 | // /// Partial blanket implementation of [`DeltaMeasure`] as a linear functional of [`Mapping`]s. | |
74 | // /// A full blanket implementation is not possible due to annoying Rust limitations: only [`Apply`] | |
75 | // /// on a reference is implemented, but a consuming [`Apply`] has to be implemented on a case-by-case | |
76 | // /// basis, not because an implementation could not be written, but because the Rust trait system | |
77 | // /// chokes up. | |
78 | // impl<Domain, G, F : Num, V> Linear<G> for DeltaMeasure<Domain, F> | |
79 | // where G: for<'a> Apply<&'a Domain, Output = V>, | |
80 | // V : Mul<F>, | |
81 | // Self: Apply<G, Output = <V as Mul<F>>::Output> { | |
82 | // type Codomain = <V as Mul<F>>::Output; | |
83 | // } | |
84 | ||
85 | // impl<'b, Domain, G, F : Num, V> Apply<&'b G> for DeltaMeasure<Domain, F> | |
86 | // where G: for<'a> Apply<&'a Domain, Output = V>, | |
87 | // V : Mul<F> { | |
88 | // type Output = <V as Mul<F>>::Output; | |
89 | ||
90 | // #[inline] | |
91 | // fn apply(&self, g : &'b G) -> Self::Output { | |
92 | // g.apply(&self.x) * self.α | |
93 | // } | |
94 | // } | |
95 | ||
96 | // /// Implementation of the necessary apply for BTFNs | |
97 | // mod btfn_apply { | |
98 | // use super::*; | |
99 | // use alg_tools::bisection_tree::{BTFN, BTImpl, SupportGenerator, LocalAnalysis}; | |
100 | ||
101 | // impl<F : Float, BT, G, V, const N : usize> Apply<BTFN<F, G, BT, N>> | |
102 | // for DeltaMeasure<Loc<F, N>, F> | |
103 | // where BT : BTImpl<F, N>, | |
104 | // G : SupportGenerator<F, N, Id=BT::Data>, | |
105 | // G::SupportType : LocalAnalysis<F, BT::Agg, N> + for<'a> Apply<&'a Loc<F, N>, Output = V>, | |
106 | // V : std::iter::Sum + Mul<F> { | |
107 | ||
108 | // type Output = <V as Mul<F>>::Output; | |
109 | ||
110 | // #[inline] | |
111 | // fn apply(&self, g : BTFN<F, G, BT, N>) -> Self::Output { | |
112 | // g.apply(&self.x) * self.α | |
113 | // } | |
114 | // } | |
115 | // } | |
116 | ||
117 | ||
118 | impl<D, Domain, F : Num> From<(D, F)> for DeltaMeasure<Domain, F> | |
119 | where D : Into<Domain> { | |
120 | #[inline] | |
121 | fn from((x, α) : (D, F)) -> Self { | |
122 | DeltaMeasure{x: x.into(), α: α} | |
123 | } | |
124 | } | |
125 | ||
35 | 126 | impl<'a, Domain : Clone, F : Num> From<&'a DeltaMeasure<Domain, F>> for DeltaMeasure<Domain, F> { |
0 | 127 | #[inline] |
35 | 128 | fn from(d : &'a DeltaMeasure<Domain, F>) -> Self { |
129 | d.clone() | |
0 | 130 | } |
35 | 131 | } |
132 | ||
0 | 133 | |
134 | impl<Domain, F : Num> DeltaMeasure<Domain, F> { | |
135 | /// Set the mass of the spike. | |
136 | #[inline] | |
137 | pub fn set_mass(&mut self, α : F) { | |
138 | self.α = α | |
139 | } | |
140 | ||
141 | /// Set the location of the spike. | |
142 | #[inline] | |
143 | pub fn set_location(&mut self, x : Domain) { | |
144 | self.x = x | |
145 | } | |
146 | ||
147 | /// Get the mass of the spike. | |
148 | #[inline] | |
149 | pub fn get_mass(&self) -> F { | |
150 | self.α | |
151 | } | |
152 | ||
153 | /// Get a mutable reference to the mass of the spike. | |
154 | #[inline] | |
155 | pub fn get_mass_mut(&mut self) -> &mut F { | |
156 | &mut self.α | |
157 | } | |
158 | ||
159 | /// Get a reference to the location of the spike. | |
160 | #[inline] | |
161 | pub fn get_location(&self) -> &Domain { | |
162 | &self.x | |
163 | } | |
164 | ||
165 | /// Get a mutable reference to the location of the spike. | |
166 | #[inline] | |
167 | pub fn get_location_mut(&mut self) -> &mut Domain { | |
168 | &mut self.x | |
169 | } | |
170 | } | |
171 | ||
35 | 172 | impl<Domain, F : Num> IntoIterator for DeltaMeasure<Domain, F> { |
173 | type Item = Self; | |
174 | type IntoIter = std::iter::Once<Self>; | |
175 | ||
176 | #[inline] | |
177 | fn into_iter(self) -> Self::IntoIter { | |
178 | std::iter::once(self) | |
179 | } | |
180 | } | |
181 | ||
182 | impl<'a, Domain, F : Num> IntoIterator for &'a DeltaMeasure<Domain, F> { | |
183 | type Item = Self; | |
184 | type IntoIter = std::iter::Once<Self>; | |
185 | ||
186 | #[inline] | |
187 | fn into_iter(self) -> Self::IntoIter { | |
188 | std::iter::once(self) | |
189 | } | |
190 | } | |
191 | ||
0 | 192 | |
193 | macro_rules! make_delta_scalarop_rhs { | |
194 | ($trait:ident, $fn:ident, $trait_assign:ident, $fn_assign:ident) => { | |
195 | impl<F : Num, Domain> $trait<F> for DeltaMeasure<Domain, F> { | |
196 | type Output = Self; | |
197 | fn $fn(mut self, b : F) -> Self { | |
198 | self.α.$fn_assign(b); | |
199 | self | |
200 | } | |
201 | } | |
202 | ||
203 | impl<'a, F : Num, Domain> $trait<&'a F> for DeltaMeasure<Domain, F> { | |
204 | type Output = Self; | |
205 | fn $fn(mut self, b : &'a F) -> Self { | |
206 | self.α.$fn_assign(*b); | |
207 | self | |
208 | } | |
209 | } | |
210 | ||
211 | impl<'b, F : Num, Domain : Clone> $trait<F> for &'b DeltaMeasure<Domain, F> { | |
212 | type Output = DeltaMeasure<Domain, F>; | |
213 | fn $fn(self, b : F) -> Self::Output { | |
214 | DeltaMeasure { α : self.α.$fn(b), x : self.x.clone() } | |
215 | } | |
216 | } | |
217 | ||
218 | impl<'a, 'b, F : Num, Domain : Clone> $trait<&'a F> for &'b DeltaMeasure<Domain, F> { | |
219 | type Output = DeltaMeasure<Domain, F>; | |
220 | fn $fn(self, b : &'a F) -> Self::Output { | |
221 | DeltaMeasure { α : self.α.$fn(*b), x : self.x.clone() } | |
222 | } | |
223 | } | |
224 | ||
225 | impl<F : Num, Domain> $trait_assign<F> for DeltaMeasure<Domain, F> { | |
226 | fn $fn_assign(&mut self, b : F) { | |
227 | self.α.$fn_assign(b) | |
228 | } | |
229 | } | |
230 | ||
231 | impl<'a, F : Num, Domain> $trait_assign<&'a F> for DeltaMeasure<Domain, F> { | |
232 | fn $fn_assign(&mut self, b : &'a F) { | |
233 | self.α.$fn_assign(*b) | |
234 | } | |
235 | } | |
236 | } | |
237 | } | |
238 | ||
239 | make_delta_scalarop_rhs!(Mul, mul, MulAssign, mul_assign); | |
240 | make_delta_scalarop_rhs!(Div, div, DivAssign, div_assign); | |
241 | ||
242 | macro_rules! make_delta_scalarop_lhs { | |
243 | ($trait:ident, $fn:ident; $($f:ident)+) => { $( | |
244 | impl<Domain> $trait<DeltaMeasure<Domain, $f>> for $f { | |
245 | type Output = DeltaMeasure<Domain, $f>; | |
246 | fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output { | |
247 | δ.α = self.$fn(δ.α); | |
248 | δ | |
249 | } | |
250 | } | |
251 | ||
252 | impl<'a, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for $f { | |
253 | type Output = DeltaMeasure<Domain, $f>; | |
254 | fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output { | |
255 | DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) } | |
256 | } | |
257 | } | |
258 | ||
259 | impl<'b, Domain> $trait<DeltaMeasure<Domain, $f>> for &'b $f { | |
260 | type Output = DeltaMeasure<Domain, $f>; | |
261 | fn $fn(self, mut δ : DeltaMeasure<Domain, $f>) -> Self::Output { | |
262 | δ.α = self.$fn(δ.α); | |
263 | δ | |
264 | } | |
265 | } | |
266 | ||
267 | impl<'a, 'b, Domain : Clone> $trait<&'a DeltaMeasure<Domain, $f>> for &'b $f { | |
268 | type Output = DeltaMeasure<Domain, $f>; | |
269 | fn $fn(self, δ : &'a DeltaMeasure<Domain, $f>) -> Self::Output { | |
270 | DeltaMeasure{ x : δ.x.clone(), α : self.$fn(δ.α) } | |
271 | } | |
272 | } | |
273 | )+ } | |
274 | } | |
275 | ||
276 | make_delta_scalarop_lhs!(Mul, mul; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
277 | make_delta_scalarop_lhs!(Div, div; f32 f64 i8 i16 i32 i64 isize u8 u16 u32 u64 usize); | |
278 | ||
279 | macro_rules! make_delta_unary { | |
280 | ($trait:ident, $fn:ident, $type:ty) => { | |
281 | impl<'a, F : Num + Neg<Output=F>, Domain : Clone> Neg for $type { | |
282 | type Output = DeltaMeasure<Domain, F>; | |
283 | fn $fn(self) -> Self::Output { | |
284 | let mut tmp = self.clone(); | |
285 | tmp.α = tmp.α.$fn(); | |
286 | tmp | |
287 | } | |
288 | } | |
289 | } | |
290 | } | |
291 | ||
292 | make_delta_unary!(Neg, neg, DeltaMeasure<Domain, F>); | |
293 | make_delta_unary!(Neg, neg, &'a DeltaMeasure<Domain, F>); | |
294 |