Mon, 12 May 2025 22:48:16 -0500
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))) } }