src/operator_arithmetic.rs

Tue, 31 Dec 2024 23:49:09 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 31 Dec 2024 23:49:09 -0500
branch
dev
changeset 85
f2fc6115b897
parent 75
e9f4550cfa18
child 86
d5b0e496b72f
permissions
-rw-r--r--

simplify

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
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.
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25 #[derive(Copy,Clone,Debug,Serialize)]
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.
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
76 #[derive(Serialize, Debug, Clone)]
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 }

mercurial