Split out and generalise Weighted dev

Tue, 31 Dec 2024 08:48:50 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Tue, 31 Dec 2024 08:48:50 -0500
branch
dev
changeset 68
c5f70e767511
parent 67
d7c0f431cbd6
child 69
e5fab0125a8e
child 80
f802ddbabcfc

Split out and generalise Weighted

src/bisection_tree/support.rs file | annotate | diff | comparison | revisions
src/lib.rs file | annotate | diff | comparison | revisions
src/mapping.rs file | annotate | diff | comparison | revisions
src/operator_arithmetic.rs file | annotate | diff | comparison | revisions
--- a/src/bisection_tree/support.rs	Mon Dec 30 09:49:08 2024 -0500
+++ b/src/bisection_tree/support.rs	Tue Dec 31 08:48:50 2024 -0500
@@ -13,21 +13,7 @@
 use crate::loc::Loc;
 use super::aggregator::Bounds;
 use crate::norms::{Norm, L1, L2, Linfinity};
-
-/// A trait for encoding constant [`Float`] values
-pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> {
-    /// The type of the value
-    type Type : Float;
-    /// Returns the value of the constant
-    fn value(&self) -> Self::Type;
-}
-
-impl<F : Float> Constant for F {
-    type Type = F;
-    #[inline]
-    fn value(&self) -> F { *self }
-}
-
+pub use crate::operator_arithmetic::{Weighted, Constant};
 
 /// A trait for working with the supports of [`Apply`]s.
 ///
@@ -64,12 +50,6 @@
     fn shift(self, x : Loc<F, N>) -> Shift<Self, F, N> {
         Shift { shift : x, base_fn : self }
     }
-
-    /// Multiply `self` by the scalar `a`.
-    #[inline]
-    fn weigh<C : Constant<Type=F>>(self, a : C) -> Weighted<Self, C> {
-        Weighted { weight : a, base_fn : self }
-    }
 }
 
 /// Trait for globally analysing a property `A` of a [`Apply`].
@@ -204,40 +184,6 @@
 
 impl_shift_norm!(L1 L2 Linfinity);
 
-/// Weighting of a [`Support`] and [`Apply`] by scalar multiplication;
-/// output of [`Support::weigh`].
-#[derive(Copy,Clone,Debug,Serialize)]
-pub struct Weighted<T, C : Constant> {
-    /// The weight
-    pub weight : C,
-    /// The base [`Support`] or [`Apply`] being weighted.
-    pub base_fn : T,
-}
-
-impl<'a, T, V, F : Float, C, const N : usize> Mapping<Loc<F, N>> for Weighted<T, C>
-where T : Mapping<Loc<F, N>, Codomain=V>,
-      V : Space + std::ops::Mul<F,Output=V>,
-      C : Constant<Type=F> {
-    type Codomain = V;
-
-    #[inline]
-    fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
-        self.base_fn.apply(x) * self.weight.value()
-    }
-}
-
-impl<'a, T, V, F : Float, C, const N : usize> DifferentiableImpl<Loc<F, N>> for Weighted<T, C>
-where T : DifferentiableMapping<Loc<F, N>, DerivativeDomain=V>,
-      V : Space + std::ops::Mul<F, Output=V>,
-      C : Constant<Type=F> {
-    type Derivative = V;
-
-    #[inline]
-    fn differential_impl<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Derivative {
-        self.base_fn.differential(x) * self.weight.value()
-    }
-}
-
 impl<'a, T, F : Float, C, const N : usize> Support<F,N> for Weighted<T, C>
 where T : Support<F, N>,
       C : Constant<Type=F> {
--- a/src/lib.rs	Mon Dec 30 09:49:08 2024 -0500
+++ b/src/lib.rs	Tue Dec 31 08:48:50 2024 -0500
@@ -42,5 +42,7 @@
 pub(crate) mod metaprogramming;
 pub mod direct_product;
 pub mod convex;
+pub mod discrete_gradient;
+pub mod operator_arithmetic;
 
 pub use types::*;
--- a/src/mapping.rs	Mon Dec 30 09:49:08 2024 -0500
+++ b/src/mapping.rs	Tue Dec 31 08:48:50 2024 -0500
@@ -4,8 +4,7 @@
 
 use std::marker::PhantomData;
 use std::borrow::Cow;
-use crate::types::{Num, Float};
-use serde::Serialize;
+use crate::types::{Num, Float, ClosedMul};
 use crate::loc::Loc;
 pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space};
 use crate::norms::{Norm, NormExponent};
@@ -45,6 +44,17 @@
     {
         Composition{ outer : self, inner : other, intermediate_norm_exponent : norm }
     }
+
+    /// Multiply `self` by the scalar `a`.
+    #[inline]
+    fn weigh<C>(self, a : C) -> Weighted<Self, C>
+    where
+        Self : Sized,
+        C : Constant,
+        Self::Codomain : ClosedMul<C::Type>,
+    {
+        Weighted { weight : a, base_fn : self }
+    }
 }
 
 /// Automatically implemented shorthand for referring to [`Mapping`]s from [`Loc<F, N>`] to `F`.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/operator_arithmetic.rs	Tue Dec 31 08:48:50 2024 -0500
@@ -0,0 +1,64 @@
+/*!
+Arithmetic of [`Mapping`]s.
+ */
+
+use serde::Serialize;
+use crate::types::*;
+use crate::instance::{Space, Instance};
+use crate::mapping::{Mapping, DifferentiableImpl, DifferentiableMapping};
+
+/// A trait for encoding constant [`Float`] values
+pub trait Constant : Copy + Sync + Send + 'static + std::fmt::Debug + Into<Self::Type> {
+    /// The type of the value
+    type Type : Float;
+    /// Returns the value of the constant
+    fn value(&self) -> Self::Type;
+}
+
+impl<F : Float> Constant for F {
+    type Type = F;
+    #[inline]
+    fn value(&self) -> F { *self }
+}
+
+/// Weighting of a [`Support`] and [`Apply`] by scalar multiplication;
+/// output of [`Support::weigh`].
+#[derive(Copy,Clone,Debug,Serialize)]
+pub struct Weighted<T, C : Constant> {
+    /// The weight
+    pub weight : C,
+    /// The base [`Support`] or [`Apply`] being weighted.
+    pub base_fn : T,
+}
+
+impl<'a, T, V, D, F, C> Mapping<D> for Weighted<T, C>
+where
+    F : Float,
+    D : Space,
+    T : Mapping<D, Codomain=V>,
+    V : Space + ClosedMul<F>,
+    C : Constant<Type=F>
+{
+    type Codomain = V;
+
+    #[inline]
+    fn apply<I : Instance<D>>(&self, x : I) -> Self::Codomain {
+        self.base_fn.apply(x) * self.weight.value()
+    }
+}
+
+impl<'a, T, V, D, F, C> DifferentiableImpl<D> for Weighted<T, C>
+where
+    F : Float,
+    D : Space,
+    T : DifferentiableMapping<D, DerivativeDomain=V>,
+    V : Space + std::ops::Mul<F, Output=V>,
+    C : Constant<Type=F>
+{
+    type Derivative = V;
+
+    #[inline]
+    fn differential_impl<I : Instance<D>>(&self, x : I) -> Self::Derivative {
+        self.base_fn.differential(x) * self.weight.value()
+    }
+}

mercurial