Mon, 30 Dec 2024 11:00:12 -0500
Fix RowOp apply_mut.
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 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
5 | use serde::Serialize; |
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 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
24 | /// Weighting of a [`Support`] and [`Apply`] by scalar multiplication; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
25 | /// output of [`Support::weigh`]. |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
26 | #[derive(Copy,Clone,Debug,Serialize)] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
27 | pub struct Weighted<T, C : Constant> { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
28 | /// The weight |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
29 | pub weight : C, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
30 | /// The base [`Support`] or [`Apply`] being weighted. |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
31 | pub base_fn : T, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
32 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
33 | |
69
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
34 | impl<T, C> Weighted<T, C> |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
35 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
36 | C : Constant, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
37 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
38 | /// Construct from an iterator. |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
39 | 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
|
40 | Weighted{ weight, base_fn } |
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 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
43 | |
68
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
44 | 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
|
45 | where |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
46 | F : Float, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
47 | D : Space, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
48 | T : Mapping<D, Codomain=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
49 | V : Space + ClosedMul<F>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
50 | C : Constant<Type=F> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
51 | { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
52 | type Codomain = V; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
53 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
54 | #[inline] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
55 | fn apply<I : Instance<D>>(&self, x : I) -> Self::Codomain { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
56 | self.base_fn.apply(x) * self.weight.value() |
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 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
60 | 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
|
61 | where |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
62 | F : Float, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | D : Space, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | T : DifferentiableMapping<D, DerivativeDomain=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
65 | V : Space + std::ops::Mul<F, Output=V>, |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
66 | C : Constant<Type=F> |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
67 | { |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
68 | type Derivative = V; |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
69 | |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
70 | #[inline] |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
71 | 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
|
72 | self.base_fn.differential(x) * self.weight.value() |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
73 | } |
c5f70e767511
Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
74 | } |
69
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
75 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
76 | /// A sum of [`Mapping`]s. |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
77 | #[derive(Serialize, Debug, Clone)] |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
78 | pub struct MappingSum<M>(Vec<M>); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
79 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
80 | impl< M> MappingSum<M> { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
81 | /// Construct from an iterator. |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
82 | 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
|
83 | MappingSum(iter.into_iter().collect()) |
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 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
86 | /// 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
|
87 | 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
|
88 | self.0.iter() |
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 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
92 | 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
|
93 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
94 | Domain : Space + Clone, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
95 | M : Mapping<Domain>, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
96 | M::Codomain : std::iter::Sum + Clone |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
97 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
98 | type Codomain = M::Codomain; |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
99 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
100 | 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
|
101 | let xr = x.ref_instance(); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
102 | 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
|
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 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
106 | 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
|
107 | where |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
108 | Domain : Space + Clone, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
109 | M : DifferentiableMapping<Domain>, |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
110 | M :: DerivativeDomain : std::iter::Sum |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
111 | { |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
112 | type Derivative = M::DerivativeDomain; |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
113 | |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
114 | 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
|
115 | let xr = x.ref_instance(); |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
116 | 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
|
117 | } |
e5fab0125a8e
Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents:
68
diff
changeset
|
118 | } |