src/mapping.rs

branch
dev
changeset 61
05089fbc0310
parent 59
9226980e45a7
child 68
c5f70e767511
--- a/src/mapping.rs	Tue Dec 31 09:02:55 2024 -0500
+++ b/src/mapping.rs	Tue Dec 31 08:30:43 2024 -0500
@@ -4,10 +4,11 @@
 
 use std::marker::PhantomData;
 use std::borrow::Cow;
-use crate::types::Float;
+use crate::types::{Num, Float};
 use serde::Serialize;
 use crate::loc::Loc;
 pub use crate::instance::{Instance, Decomposition, BasicDecomposition, Space};
+use crate::norms::{Norm, NormExponent};
 
 /// A mapping from `Domain` to `Codomain`.
 ///
@@ -17,6 +18,33 @@
 
     /// Compute the value of `self` at `x`.
     fn apply<I : Instance<Domain>>(&self, x : I) -> Self::Codomain;
+
+    #[inline]
+    /// Form the composition `self ∘ other`
+    fn compose<X : Space, T : Mapping<X, Codomain=Domain>>(self, other : T)
+        -> Composition<Self, T>
+    where
+        Self : Sized
+    {
+        Composition{ outer : self, inner : other, intermediate_norm_exponent : () }
+    }
+
+
+    #[inline]
+    /// Form the composition `self ∘ other`, assigning a norm to the inermediate space
+    fn compose_with_norm<F, X, T, E>(
+        self, other : T, norm : E
+    )  -> Composition<Self, T, E>
+    where
+        Self : Sized,
+        X : Space,
+        T : Mapping<X, Codomain=Domain>,
+        E : NormExponent,
+        Domain : Norm<F, E>,
+        F : Num
+    {
+        Composition{ outer : self, inner : other, intermediate_norm_exponent : norm }
+    }
 }
 
 /// Automatically implemented shorthand for referring to [`Mapping`]s from [`Loc<F, N>`] to `F`.
@@ -236,3 +264,25 @@
 impl<X : Space, F : Copy, G : Sized + Mapping<X, Codomain=Loc<F, N>> + Clone, const N : usize>
 SliceCodomain<X, F, N>
 for G {}
+
+
+/// The composition S ∘ T. `E` is for storing a `NormExponent` for the intermediate space.
+pub struct Composition<S, T, E = ()> {
+    pub outer : S,
+    pub inner : T,
+    pub intermediate_norm_exponent : E
+}
+
+impl<S, T, X, E> Mapping<X> for Composition<S, T, E>
+where
+    X : Space,
+    T : Mapping<X>,
+    S : Mapping<T::Codomain>
+{
+    type Codomain = S::Codomain;
+
+    #[inline]
+    fn apply<I : Instance<X>>(&self, x : I) -> Self::Codomain {
+        self.outer.apply(self.inner.apply(x))
+    }
+}

mercurial