src/operator_arithmetic.rs

branch
dev
changeset 69
e5fab0125a8e
parent 68
c5f70e767511
child 75
e9f4550cfa18
--- a/src/operator_arithmetic.rs	Tue Dec 31 08:48:50 2024 -0500
+++ b/src/operator_arithmetic.rs	Thu Dec 26 12:35:53 2024 -0500
@@ -31,6 +31,16 @@
     pub base_fn : T,
 }
 
+impl<T, C> Weighted<T, C>
+where
+    C : Constant,
+{
+    /// Construct from an iterator.
+    pub fn new(weight : C, base_fn : T) -> Self {
+        Weighted{ weight, base_fn }
+    }
+}
+
 impl<'a, T, V, D, F, C> Mapping<D> for Weighted<T, C>
 where
     F : Float,
@@ -62,3 +72,47 @@
         self.base_fn.differential(x) * self.weight.value()
     }
 }
+
+/// A sum of [`Mapping`]s.
+#[derive(Serialize, Debug, Clone)]
+pub struct MappingSum<M>(Vec<M>);
+
+impl< M> MappingSum<M> {
+    /// Construct from an iterator.
+    pub fn new<I : IntoIterator<Item = M>>(iter : I) -> Self {
+        MappingSum(iter.into_iter().collect())
+    }
+
+    /// Iterate over the component functions of the sum
+    pub fn iter(&self) -> std::slice::Iter<'_, M> {
+        self.0.iter()
+    }
+}
+
+impl<Domain, M> Mapping<Domain> for MappingSum<M>
+where
+    Domain : Space + Clone,
+    M : Mapping<Domain>,
+    M::Codomain : std::iter::Sum + Clone
+{
+    type Codomain = M::Codomain;
+
+    fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain {
+        let xr = x.ref_instance();
+        self.0.iter().map(|c| c.apply(xr)).sum()
+    }
+}
+
+impl<Domain, M> DifferentiableImpl<Domain> for MappingSum< M>
+where
+    Domain : Space + Clone,
+    M : DifferentiableMapping<Domain>,
+    M :: DerivativeDomain : std::iter::Sum
+{
+    type Derivative = M::DerivativeDomain;
+
+    fn differential_impl<I : Instance<Domain>>(&self, x : I) -> Self::Derivative {
+        let xr = x.ref_instance();
+        self.0.iter().map(|c| c.differential(xr)).sum()
+    }
+}

mercurial