Add Mapping codomain slicing and RealVectorField dev

Wed, 04 Oct 2023 08:59:29 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 04 Oct 2023 08:59:29 -0500
branch
dev
changeset 35
3b82a9d16307
parent 34
3dbc04100b09
child 36
6a4b44b2cdf2

Add Mapping codomain slicing and RealVectorField

src/loc.rs file | annotate | diff | comparison | revisions
src/mapping.rs file | annotate | diff | comparison | revisions
--- a/src/loc.rs	Wed Oct 04 08:02:14 2023 -0500
+++ b/src/loc.rs	Wed Oct 04 08:59:29 2023 -0500
@@ -135,6 +135,14 @@
     }
 }
 
+impl<F> Loc<F, 1> {
+    #[inline]
+    pub fn flatten1d(self) -> F {
+        let Loc([v]) = self;
+        v
+    }
+}
+
 impl<F, const N : usize> From<Loc<F, N>> for [F; N] {
     #[inline]
     fn from(other : Loc<F, N>) -> [F; N] {
--- a/src/mapping.rs	Wed Oct 04 08:02:14 2023 -0500
+++ b/src/mapping.rs	Wed Oct 04 08:59:29 2023 -0500
@@ -49,6 +49,13 @@
 impl<F : Float, T, const N : usize> RealMapping<F, N> for T
 where T : Mapping<Loc<F, N>, Codomain = F> {}
 
+/// A helper trait alias for referring to [`Mapping`]s from [`Loc<F, N>`] to [`Loc<F, M>`].
+pub trait RealVectorField<F : Float, const N : usize, const M : usize>
+: Mapping<Loc<F, N>, Codomain = Loc<F, M>> {}
+
+impl<F : Float, T, const N : usize, const M : usize> RealVectorField<F, N, M> for T
+where T : Mapping<Loc<F, N>, Codomain = Loc<F, M>> {}
+
 
 /// Trait for calculation the differential of `Self` as a mathematical function on `X`.
 pub trait Differentiable<X> : Sized {
@@ -144,8 +151,76 @@
     }
 }
 
+
+/// Container for flattening [`Loc`]`<F, 1>` codomain of a [`Mapping`] to `F`.
+pub struct FlattenedCodomain<X, F, G : Mapping<X, Codomain=Loc<F, 1>>> {
+    g : G,
+    _phantoms : PhantomData<(X, F)>
+}
+
+impl<X, F, G : Mapping<X, Codomain=Loc<F, 1>>> Apply<X> for FlattenedCodomain<X, F, G> {
+    type Output = F;
+
     #[inline]
     fn apply(&self, x : X) -> Self::Output {
-        self.g.differential(x)
+        self.g.apply(x).flatten1d()
+    }
+}
+
+/// An auto-trait for constructing a [`FlattenCodomain`] structure for
+/// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`.
+pub trait FlattenCodomain<X, F> : Mapping<X, Codomain=Loc<F, 1>> + Sized {
+    /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
+    fn flatten_codomain(self) -> FlattenedCodomain<X, F, Self> {
+        FlattenedCodomain{ g : self, _phantoms : PhantomData }
     }
 }
+
+impl<X, F, G : Sized + Mapping<X, Codomain=Loc<F, 1>>> FlattenCodomain<X, F> for G {}
+
+
+/// Container for dimensional slicing [`Loc`]`<F, N>` codomain of a [`Mapping`] to `F`.
+pub struct SlicedCodomain<X, F, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> {
+    g : G,
+    slice : usize,
+    _phantoms : PhantomData<(X, F)>
+}
+
+impl<X, F : Copy, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> Apply<X>
+for SlicedCodomain<X, F, G, N> {
+    type Output = F;
+
+    #[inline]
+    fn apply(&self, x : X) -> Self::Output {
+        let tmp : [F; N] = self.g.apply(x).into();
+        // Safety: `slice_codomain` below checks the range.
+        unsafe { *tmp.get_unchecked(self.slice) }
+    }
+}
+
+impl<'a, X, F : Copy, G : Mapping<X, Codomain=Loc<F, N>>, const N : usize> Apply<&'a X>
+for SlicedCodomain<X, F, G, N> {
+    type Output = F;
+
+    #[inline]
+    fn apply(&self, x : &'a X) -> Self::Output {
+        let tmp : [F; N] = self.g.apply(x).into();
+        // Safety: `slice_codomain` below checks the range.
+        unsafe { *tmp.get_unchecked(self.slice) }
+    }
+}
+
+/// An auto-trait for constructing a [`FlattenCodomain`] structure for
+/// flattening the codomain of a [`Mapping`] from [`Loc`]`<F, 1>` to `F`.
+pub trait SliceCodomain<X, F : Copy, const N : usize> : Mapping<X, Codomain=Loc<F, N>> + Sized {
+    /// Flatten the codomain from [`Loc`]`<F, 1>` to `F`.
+    fn slice_codomain(self, slice : usize) -> SlicedCodomain<X, F, Self, N> {
+        assert!(slice < N);
+        SlicedCodomain{ g : self, slice, _phantoms : PhantomData }
+    }
+}
+
+impl<X, F : Copy, G : Sized + Mapping<X, Codomain=Loc<F, N>>, const N : usize>
+SliceCodomain<X, F, N>
+for G {}
+

mercurial