src/bisection_tree/support.rs

changeset 90
b3c35d16affe
parent 75
e9f4550cfa18
child 86
d5b0e496b72f
--- a/src/bisection_tree/support.rs	Tue Feb 20 12:33:16 2024 -0500
+++ b/src/bisection_tree/support.rs	Mon Feb 03 19:22:16 2025 -0500
@@ -1,35 +1,23 @@
 
 /*!
-Traits for representing the support of a [`Apply`], and analysing the mapping on a [`Cube`].
+Traits for representing the support of a [`Mapping`], and analysing the mapping on a [`Cube`].
 */
 use serde::Serialize;
 use std::ops::{MulAssign,DivAssign,Neg};
 use crate::types::{Float, Num};
 use crate::maputil::map2;
-use crate::mapping::Apply;
+use crate::mapping::{
+    Instance, Mapping, DifferentiableImpl, DifferentiableMapping, Space
+};
 use crate::sets::Cube;
 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;
-}
+pub use crate::operator_arithmetic::{Weighted, Constant};
 
-impl<F : Float> Constant for F {
-    type Type = F;
-    #[inline]
-    fn value(&self) -> F { *self }
-}
-
-
-/// A trait for working with the supports of [`Apply`]s.
+/// A trait for working with the supports of [`Mapping`]s.
 ///
-/// Apply is not a super-trait to allow more general use.
+/// `Mapping` is not a super-trait to allow more general use.
 pub trait Support<F : Num, const N : usize> : Sized + Sync + Send + 'static {
     /// Return a cube containing the support of the function represented by `self`.
     ///
@@ -62,15 +50,9 @@
     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`].
+/// Trait for globally analysing a property `A` of a [`Mapping`].
 ///
 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as
 /// [`Bounds`][super::aggregator::Bounds].
@@ -91,7 +73,7 @@
 //     }
 // }
 
-/// Trait for locally analysing a property `A` of a [`Apply`] (implementing [`Support`])
+/// Trait for locally analysing a property `A` of a [`Mapping`] (implementing [`Support`])
 /// within a [`Cube`].
 ///
 /// Typically `A` is an [`Aggregator`][super::aggregator::Aggregator] such as
@@ -105,10 +87,10 @@
     fn local_analysis(&self, cube : &Cube<F, N>) -> A;
 }
 
-/// Trait for determining the upper and lower bounds of an float-valued [`Apply`].
+/// Trait for determining the upper and lower bounds of an float-valued [`Mapping`].
 ///
 /// This is a blanket-implemented alias for [`GlobalAnalysis`]`<F, Bounds<F>>`
-/// [`Apply`] is not a supertrait to allow flexibility in the implementation of either
+/// [`Mapping`] is not a supertrait to allow flexibility in the implementation of either
 /// reference or non-reference arguments.
 pub trait Bounded<F : Float> : GlobalAnalysis<F, Bounds<F>> {
     /// Return lower and upper bounds for the values of of `self`.
@@ -120,28 +102,30 @@
 
 impl<F : Float, T : GlobalAnalysis<F, Bounds<F>>> Bounded<F> for T { }
 
-/// Shift of [`Support`] and [`Apply`]; output of [`Support::shift`].
+/// Shift of [`Support`] and [`Mapping`]; output of [`Support::shift`].
 #[derive(Copy,Clone,Debug,Serialize)] // Serialize! but not implemented by Loc.
 pub struct Shift<T, F, const N : usize> {
     shift : Loc<F, N>,
     base_fn : T,
 }
 
-impl<'a, T, V, F : Float, const N : usize> Apply<&'a Loc<F, N>> for Shift<T,F,N>
-where T : Apply<Loc<F, N>, Output=V> {
-    type Output = V;
+impl<'a, T, V : Space, F : Float, const N : usize> Mapping<Loc<F, N>> for Shift<T,F,N>
+where T : Mapping<Loc<F, N>, Codomain=V> {
+    type Codomain = V;
+
     #[inline]
-    fn apply(&self, x : &'a Loc<F, N>) -> Self::Output {
-        self.base_fn.apply(x - &self.shift)
+    fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
+        self.base_fn.apply(x.own() - &self.shift)
     }
 }
 
-impl<'a, T, V, F : Float, const N : usize> Apply<Loc<F, N>> for Shift<T,F,N>
-where T : Apply<Loc<F, N>, Output=V> {
-    type Output = V;
+impl<'a, T, V : Space, F : Float, const N : usize> DifferentiableImpl<Loc<F, N>> for Shift<T,F,N>
+where T : DifferentiableMapping<Loc<F, N>, DerivativeDomain=V> {
+    type Derivative = V;
+
     #[inline]
-    fn apply(&self, x : Loc<F, N>) -> Self::Output {
-        self.base_fn.apply(x - &self.shift)
+    fn differential_impl<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Derivative {
+        self.base_fn.differential(x.own() - &self.shift)
     }
 }
 
@@ -200,38 +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> Apply<&'a Loc<F, N>> for Weighted<T, C>
-where T : for<'b> Apply<&'b Loc<F, N>, Output=V>,
-      V : std::ops::Mul<F,Output=V>,
-      C : Constant<Type=F> {
-    type Output = V;
-    #[inline]
-    fn apply(&self, x : &'a Loc<F, N>) -> Self::Output {
-        self.base_fn.apply(x) * self.weight.value()
-    }
-}
-
-impl<'a, T, V, F : Float, C, const N : usize> Apply<Loc<F, N>> for Weighted<T, C>
-where T : Apply<Loc<F, N>, Output=V>,
-      V : std::ops::Mul<F,Output=V>,
-      C : Constant<Type=F> {
-    type Output = V;
-    #[inline]
-    fn apply(&self, x : Loc<F, N>) -> Self::Output {
-        self.base_fn.apply(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> {
@@ -331,30 +283,21 @@
 impl_weighted_norm!(L1 L2 Linfinity);
 
 
-/// Normalisation of [`Support`] and [`Apply`] to L¹ norm 1.
+/// Normalisation of [`Support`] and [`Mapping`] to L¹ norm 1.
 ///
 /// Currently only scalar-valued functions are supported.
 #[derive(Copy, Clone, Debug, Serialize, PartialEq)]
 pub struct Normalised<T>(
-    /// The base [`Support`] or [`Apply`].
+    /// The base [`Support`] or [`Mapping`].
     pub T
 );
 
-impl<'a, T, F : Float, const N : usize> Apply<&'a Loc<F, N>> for Normalised<T>
-where T : Norm<F, L1> + for<'b> Apply<&'b Loc<F, N>, Output=F> {
-    type Output = F;
+impl<'a, T, F : Float, const N : usize> Mapping<Loc<F, N>> for Normalised<T>
+where T : Norm<F, L1> + Mapping<Loc<F,N>, Codomain=F> {
+    type Codomain = F;
+
     #[inline]
-    fn apply(&self, x : &'a Loc<F, N>) -> Self::Output {
-        let w = self.0.norm(L1);
-        if w == F::ZERO { F::ZERO } else { self.0.apply(x) / w }
-    }
-}
-
-impl<'a, T, F : Float, const N : usize> Apply<Loc<F, N>> for Normalised<T>
-where T : Norm<F, L1> + Apply<Loc<F,N>, Output=F> {
-    type Output = F;
-    #[inline]
-    fn apply(&self, x : Loc<F, N>) -> Self::Output {
+    fn apply<I : Instance<Loc<F, N>>>(&self, x : I) -> Self::Codomain {
         let w = self.0.norm(L1);
         if w == F::ZERO { F::ZERO } else { self.0.apply(x) / w }
     }
@@ -449,7 +392,7 @@
 : MulAssign<F> + DivAssign<F> + Neg<Output=Self> + Clone + Sync + Send + 'static {
     /// The identification type
     type Id : 'static + Copy;
-    /// The type of the [`Support`] (often also a [`Apply`]).
+    /// The type of the [`Support`] (often also a [`Mapping`]).
     type SupportType : 'static + Support<F, N>;
     /// An iterator over all the [`Support`]s of the generator.
     type AllDataIter<'a> : Iterator<Item=(Self::Id, Self::SupportType)> where Self : 'a;

mercurial