instantiated-fubar draft dev

Mon, 12 May 2025 22:48:16 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 12 May 2025 22:48:16 -0500
branch
dev
changeset 137
d5dfcb6abcf5
parent 136
22fd33834ab7

instantiated-fubar

src/direct_product.rs file | annotate | diff | comparison | revisions
src/instance.rs file | annotate | diff | comparison | revisions
src/operator_arithmetic.rs file | annotate | diff | comparison | revisions
src/sets.rs file | annotate | diff | comparison | revisions
--- a/src/direct_product.rs	Mon May 12 21:56:42 2025 -0500
+++ b/src/direct_product.rs	Mon May 12 22:48:16 2025 -0500
@@ -6,7 +6,9 @@
 */
 
 use crate::euclidean::Euclidean;
-use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow};
+use crate::instance::{
+    Decomposition, DecompositionMut, Instance, InstanceMut, Instantiated, MyCow,
+};
 use crate::linops::AXPY;
 use crate::loc::Loc;
 use crate::mapping::Space;
@@ -367,6 +369,25 @@
         Pair<A, B>: 'b;
 }
 
+impl<A, B, U, V, D, Q> Instantiated<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
+where
+    A: Space,
+    B: Space,
+    U: Instantiated<A, D>,
+    V: Instantiated<B, Q>,
+    D: Decomposition<A>,
+    Q: Decomposition<B>,
+{
+    type RefInstance<'b>
+        = Pair<U::RefInstance<'b>, V::RefInstance<'b>>
+    where
+        Self: 'b;
+
+    fn ref_inst(&self) -> Self::RefInstance<'_> {
+        Pair(self.0.ref_inst(), self.1.ref_inst())
+    }
+}
+
 impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
 where
     A: Space,
@@ -376,6 +397,12 @@
     U: Instance<A, D>,
     V: Instance<B, Q>,
 {
+    type Instantiated = Pair<U::Instantiated, V::Instantiated>;
+
+    fn instantiate(self) -> Self::Instantiated {
+        Pair(self.0.instantiate(), self.1.instantiate())
+    }
+
     fn eval_decompose<'b, R>(
         self,
         f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
@@ -425,6 +452,14 @@
     &'a U: Instance<A, D>,
     &'a V: Instance<B, Q>,
 {
+    type Instantiated =
+        Pair<<&'a U as Instance<A, D>>::Instantiated, <&'a V as Instance<B, Q>>::Instantiated>;
+
+    fn instantiate(self) -> Self::Instantiated {
+        let &Pair(ref u, ref v) = self;
+        Pair(u.instantiate(), v.instantiate())
+    }
+
     fn eval_decompose<'b, R>(
         self,
         f: impl FnOnce(Pair<D::Decomposition<'b>, Q::Decomposition<'b>>) -> R,
--- a/src/instance.rs	Mon May 12 21:56:42 2025 -0500
+++ b/src/instance.rs	Mon May 12 22:48:16 2025 -0500
@@ -80,6 +80,32 @@
         X: 'b;
 }
 
+pub trait Instantiated<X: Space, D = <X as Space>::Decomp>: Instance<X, D>
+where
+    D: Decomposition<X>,
+{
+    type RefInstance<'b>: Instance<X, D> + Copy
+    where
+        Self: 'b;
+
+    fn ref_inst(&self) -> Self::RefInstance<'_>;
+}
+
+impl<X: Space> Instantiated<X, BasicDecomposition> for X
+where
+    X: Instance<X, BasicDecomposition> + Clone,
+    for<'b> &'b X: Instance<X, BasicDecomposition>,
+{
+    type RefInstance<'b>
+        = &'b X
+    where
+        Self: 'b;
+
+    fn ref_inst(&self) -> Self::RefInstance<'_> {
+        self
+    }
+}
+
 /// Helper trait for functions to work with either owned values or references to either the
 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this
 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`].
@@ -89,6 +115,8 @@
 where
     D: Decomposition<X>,
 {
+    type Instantiated: Space + Instantiated<X, D>;
+
     /// Decomposes self according to `decomposer`, and evaluate `f` on the result.
     /// Consumes self.
     fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R
@@ -106,8 +134,23 @@
     /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary.
     fn own(self) -> X;
 
+    /// Instantiate to something that can be 'referenced'.
+    ///
+    /// This is distinct from [`own`], as it is not guaranteed that `&'b X` is an
+    /// [`Instance`] of `X`.
+    fn instantiate(self) -> Self::Instantiated;
+
     // ************** automatically implemented methods below from here **************
 
+    /// Evaluate `f` on the result of [`instantiate`]ing self, and then referencing.
+    fn eval_inst_ref<R>(
+        self,
+        f: impl for<'b> FnOnce(<Self::Instantiated as Instantiated<X, D>>::RefInstance<'b>) -> R,
+    ) -> R {
+        let inst = self.instantiate();
+        f(inst.ref_inst())
+    }
+
     /// Returns an owned instance or reference to `X`, converting non-true instances when necessary.
     ///
     /// Default implementation uses [`Self::own`]. Consumes the input.
@@ -146,6 +189,12 @@
 }
 
 impl<X: Space + Clone> Instance<X, BasicDecomposition> for X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -179,6 +228,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -212,6 +267,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a mut X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -246,6 +307,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for MyCow<'a, X> {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
--- a/src/operator_arithmetic.rs	Mon May 12 21:56:42 2025 -0500
+++ b/src/operator_arithmetic.rs	Mon May 12 22:48:16 2025 -0500
@@ -2,7 +2,7 @@
 Arithmetic of [`Mapping`]s.
  */
 
-use crate::instance::{Instance, Space};
+use crate::instance::{Instance, Instantiated, Space};
 use crate::mapping::{DifferentiableImpl, DifferentiableMapping, Mapping};
 use crate::types::*;
 use serde::Serialize;
@@ -99,7 +99,9 @@
     type Codomain = M::Codomain;
 
     fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain {
-        x.eval_ref_decompose(|xr| self.0.iter().map(|c| c.apply(xr)).sum())
+        let xi = x.instantiate();
+        let xr = xi.ref_inst();
+        self.0.iter().map(|c| c.apply(xr)).sum()
     }
 }
 
@@ -112,6 +114,9 @@
     type Derivative = M::DerivativeDomain;
 
     fn differential_impl<I: Instance<Domain>>(&self, x: I) -> Self::Derivative {
-        x.eval_ref_decompose(|xr| self.0.iter().map(|c| c.differential(xr)).sum())
+        let xi = x.instantiate();
+        let xr = xi.ref_inst();
+
+        self.0.iter().map(|c| c.differential(xr)).sum()
     }
 }
--- a/src/sets.rs	Mon May 12 21:56:42 2025 -0500
+++ b/src/sets.rs	Mon May 12 22:48:16 2025 -0500
@@ -148,6 +148,6 @@
     F: Float,
 {
     fn contains<I: Instance<A>>(&self, item: I) -> bool {
-        item.eval_ref_decompose(|r| self.0.iter().all(|halfspace| halfspace.contains(r)))
+        item.eval_inst_ref(|r| self.0.iter().all(|halfspace| halfspace.contains(r)))
     }
 }

mercurial