src/operator_arithmetic.rs

Wed, 03 Sep 2025 20:52:21 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 03 Sep 2025 20:52:21 -0500
branch
dev
changeset 172
73608862ef54
parent 171
fa8df5a14486
permissions
-rw-r--r--

nalgebra instance hacks

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
150
Tuomo Valkonen <tuomov@iki.fi>
parents: 133
diff changeset
5 use crate::instance::{ClosedSpace, Instance, Space};
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
6 use crate::mapping::{DifferentiableImpl, DifferentiableMapping, Mapping};
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
7 use crate::types::*;
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
8 use serde::Serialize;
68
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
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
11 pub trait Constant: Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> {
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
12 /// The type of the value
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
13 type Type: Float;
68
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
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
18 impl<F: Float> Constant for F {
68
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]
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
21 fn value(&self) -> F {
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
22 *self
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
23 }
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
24 }
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
25
75
e9f4550cfa18 Fix out-of-date references in doc comments
Tuomo Valkonen <tuomov@iki.fi>
parents: 69
diff changeset
26 /// Weighting of a [`Mapping`] by scalar multiplication.
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
27 #[derive(Copy, Clone, Debug, Serialize)]
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
28 pub struct Weighted<T, C: Constant> {
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
29 /// The weight
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
30 pub weight: C,
75
e9f4550cfa18 Fix out-of-date references in doc comments
Tuomo Valkonen <tuomov@iki.fi>
parents: 69
diff changeset
31 /// The base [`Mapping`] being weighted.
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
32 pub base_fn: T,
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
33 }
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
34
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
35 impl<T, C> Weighted<T, C>
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
36 where
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
37 C: Constant,
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
38 {
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
39 /// Construct from an iterator.
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
40 pub fn new(weight: C, base_fn: T) -> Self {
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
41 Weighted { weight, base_fn }
69
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 }
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
44
151
402d717bb5c0 lots of space changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 150
diff changeset
45 impl<'a, T, D, F, C> Mapping<D> for Weighted<T, C>
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
46 where
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
47 F: Float,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
48 D: Space,
151
402d717bb5c0 lots of space changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 150
diff changeset
49 T: Mapping<D>,
402d717bb5c0 lots of space changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 150
diff changeset
50 T::Codomain: ClosedMul<F>,
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
51 C: Constant<Type = F>,
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
52 {
151
402d717bb5c0 lots of space changes
Tuomo Valkonen <tuomov@iki.fi>
parents: 150
diff changeset
53 type Codomain = T::Codomain;
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
54
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
55 #[inline]
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
56 fn apply<I: Instance<D>>(&self, x: I) -> Self::Codomain {
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
57 self.base_fn.apply(x) * self.weight.value()
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
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
61 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
62 where
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
63 F: Float,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
64 D: Space,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
65 T: DifferentiableMapping<D, DerivativeDomain = V>,
150
Tuomo Valkonen <tuomov@iki.fi>
parents: 133
diff changeset
66 V: ClosedSpace + std::ops::Mul<F, Output = V>,
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
67 C: Constant<Type = F>,
68
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 type Derivative = V;
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
70
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
71 #[inline]
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
72 fn differential_impl<I: Instance<D>>(&self, x: I) -> Self::Derivative {
68
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
73 self.base_fn.differential(x) * self.weight.value()
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
74 }
c5f70e767511 Split out and generalise Weighted
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff changeset
75 }
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
76
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
77 /// A sum of [`Mapping`]s.
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
78 #[derive(Serialize, Debug, Clone)]
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
79 pub struct MappingSum<M>(Vec<M>);
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
80
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
81 impl<M> MappingSum<M> {
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
82 /// Construct from an iterator.
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
83 pub fn new<I: IntoIterator<Item = M>>(iter: I) -> Self {
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
84 MappingSum(iter.into_iter().collect())
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
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
87 /// 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
88 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
89 self.0.iter()
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
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
93 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
94 where
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
95 Domain: Space + Clone,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
96 M: Mapping<Domain>,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
97 M::Codomain: std::iter::Sum + Clone,
69
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 type Codomain = M::Codomain;
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
100
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
101 fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain {
171
fa8df5a14486 decompose
Tuomo Valkonen <tuomov@iki.fi>
parents: 151
diff changeset
102 x.eval_ref(|xr| self.0.iter().map(|c| c.apply(xr)).sum())
69
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
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
106 impl<Domain, M> DifferentiableImpl<Domain> for MappingSum<M>
69
e5fab0125a8e Move Sum to operator_arithmetic as MappingSum
Tuomo Valkonen <tuomov@iki.fi>
parents: 68
diff changeset
107 where
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
108 Domain: Space,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
109 M: DifferentiableMapping<Domain>,
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
110 M::DerivativeDomain: std::iter::Sum,
69
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
128
f75bf34adda0 Switch from Cow to MyCow for DifferentiableImpl to avoid Clone trait bound
Tuomo Valkonen <tuomov@iki.fi>
parents: 75
diff changeset
114 fn differential_impl<I: Instance<Domain>>(&self, x: I) -> Self::Derivative {
171
fa8df5a14486 decompose
Tuomo Valkonen <tuomov@iki.fi>
parents: 151
diff changeset
115 x.eval_ref(|xr| self.0.iter().map(|c| c.differential(xr)).sum())
69
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