Mon, 06 Jan 2025 20:29:25 -0500
More Serialize / Deserialize / Debug derives
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
1 | /*! |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
2 | Arithmetic of [`Mapping`]s. |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
3 | */ |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
4 | |
86
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
5 | use serde::{Serialize, Deserialize}; |
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
6 | use crate::types::*; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
7 | use crate::instance::{Space, Instance}; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
8 | use crate::mapping::{Mapping, DifferentiableImpl, DifferentiableMapping}; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
9 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
10 | /// A trait for encoding constant [`Float`] values |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
11 | pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
12 | /// The type of the value |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
13 | type Type : Float; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
14 | /// Returns the value of the constant |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
15 | fn value(&self) -> Self::Type; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
16 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
17 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
18 | impl<F : Float> Constant for F { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
19 | type Type = F; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
20 | #[inline] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
21 | fn value(&self) -> F { *self } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
22 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
23 | |
75
e9f4550cfa18
Fix out-of-date references in doc comments
Tuomo Valkonen <tuomov@iki.fi>
parents:
69
diff
changeset
|
24 | /// Weighting of a [`Mapping`] by scalar multiplication. |
86
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
25 | #[derive(Copy,Clone,Debug,Serialize,Deserialize)] |
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
26 | pub struct Weighted<T, C : Constant> { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
27 | /// The weight |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
28 | pub weight : C, |
75
e9f4550cfa18
Fix out-of-date references in doc comments
Tuomo Valkonen <tuomov@iki.fi>
parents:
69
diff
changeset
|
29 | /// The base [`Mapping`] being weighted. |
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
30 | pub base_fn : T, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
31 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
32 | |
69
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
33 | impl<T, C> Weighted<T, C> |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
34 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
35 | C : Constant, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
36 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
37 | /// Construct from an iterator. |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
38 | pub fn new(weight : C, base_fn : T) -> Self { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
39 | Weighted{ weight, base_fn } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
40 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
41 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
42 | |
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
43 | impl<'a, T, V, D, F, C> Mapping<D> for Weighted<T, C> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
44 | where |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
45 | F : Float, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
46 | D : Space, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
47 | T : Mapping<D, Codomain=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
48 | V : Space + ClosedMul<F>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
49 | C : Constant<Type=F> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
50 | { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
51 | type Codomain = V; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
52 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
53 | #[inline] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
54 | fn apply<I : Instance<D>>(&self, x : I) -> Self::Codomain { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
55 | self.base_fn.apply(x) * self.weight.value() |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
56 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
57 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
58 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
59 | impl<'a, T, V, D, F, C> DifferentiableImpl<D> for Weighted<T, C> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
60 | where |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
61 | F : Float, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
62 | D : Space, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | T : DifferentiableMapping<D, DerivativeDomain=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | V : Space + std::ops::Mul<F, Output=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
65 | C : Constant<Type=F> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
66 | { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
67 | type Derivative = V; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
68 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
69 | #[inline] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
70 | fn differential_impl<I : Instance<D>>(&self, x : I) -> Self::Derivative { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
71 | self.base_fn.differential(x) * self.weight.value() |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
72 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
73 | } |
69
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
74 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
75 | /// A sum of [`Mapping`]s. |
86
d5b0e496b72f
More Serialize / Deserialize / Debug derives
Tuomo Valkonen <tuomov@iki.fi>
parents:
75
diff
changeset
|
76 | #[derive(Debug, Clone, Serialize, Deserialize)] |
69
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
77 | pub struct MappingSum<M>(Vec<M>); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
78 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
79 | impl< M> MappingSum<M> { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
80 | /// Construct from an iterator. |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
81 | pub fn new<I : IntoIterator<Item = M>>(iter : I) -> Self { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
82 | MappingSum(iter.into_iter().collect()) |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
83 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
84 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
85 | /// Iterate over the component functions of the sum |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
86 | pub fn iter(&self) -> std::slice::Iter<'_, M> { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
87 | self.0.iter() |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
88 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
89 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
90 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
91 | impl<Domain, M> Mapping<Domain> for MappingSum<M> |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
92 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
93 | Domain : Space + Clone, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
94 | M : Mapping<Domain>, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
95 | M::Codomain : std::iter::Sum + Clone |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
96 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
97 | type Codomain = M::Codomain; |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
98 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
99 | fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
100 | let xr = x.ref_instance(); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
101 | self.0.iter().map(|c| c.apply(xr)).sum() |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
102 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
103 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
104 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
105 | impl<Domain, M> DifferentiableImpl<Domain> for MappingSum< M> |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
106 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
107 | Domain : Space + Clone, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
108 | M : DifferentiableMapping<Domain>, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
109 | M :: DerivativeDomain : std::iter::Sum |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
110 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
111 | type Derivative = M::DerivativeDomain; |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
112 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
113 | fn differential_impl<I : Instance<Domain>>(&self, x : I) -> Self::Derivative { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
114 | let xr = x.ref_instance(); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
115 | self.0.iter().map(|c| c.differential(xr)).sum() |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
116 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
117 | } |