try draft dev

Wed, 03 Sep 2025 08:40:17 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Wed, 03 Sep 2025 08:40:17 -0500
branch
dev
changeset 161
5df5258332d1
parent 160
e7920e205785

try

src/instance.rs file | annotate | diff | comparison | revisions
src/linops.rs file | annotate | diff | comparison | revisions
src/mapping.rs file | annotate | diff | comparison | revisions
--- a/src/instance.rs	Tue Sep 02 15:18:30 2025 -0500
+++ b/src/instance.rs	Wed Sep 03 08:40:17 2025 -0500
@@ -215,14 +215,14 @@
         Self: 'b;
 
     /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary.
-    fn own(self) -> D::OwnedInstance;
+    fn own(self) -> X;
 
     // ************** automatically implemented methods below from here **************
 
     /// Returns an owned instance or reference to `X`, converting non-true instances when necessary.
     ///
     /// Default implementation uses [`Self::own`]. Consumes the input.
-    fn cow<'b>(self) -> MyCow<'b, D::OwnedInstance>
+    fn cow<'b>(self) -> MyCow<'b, X>
     where
         Self: 'b,
     {
@@ -233,7 +233,7 @@
     /// Evaluates `f` on a reference to self.
     ///
     /// Default implementation uses [`Self::cow`]. Consumes the input.
-    fn eval<'b, R>(self, f: impl FnOnce(&D::OwnedInstance) -> R) -> R
+    fn eval<'b, R>(self, f: impl FnOnce(&X) -> R) -> R
     where
         X: 'b,
         Self: 'b,
@@ -245,11 +245,7 @@
     /// Evaluates `f` or `g` depending on whether a reference or owned value is available.
     ///
     /// Default implementation uses [`Self::cow`]. Consumes the input.
-    fn either<'b, R>(
-        self,
-        f: impl FnOnce(D::OwnedInstance) -> R,
-        g: impl FnOnce(&D::OwnedInstance) -> R,
-    ) -> R
+    fn either<'b, R>(self, f: impl FnOnce(X) -> R, g: impl FnOnce(&X) -> R) -> R
     where
         Self: 'b,
     {
--- a/src/linops.rs	Tue Sep 02 15:18:30 2025 -0500
+++ b/src/linops.rs	Wed Sep 03 08:40:17 2025 -0500
@@ -56,7 +56,7 @@
     // }
 
     /// Return a similar zero as `x`.
-    fn similar_origin_inst<I: Instance<Self>>(x: I) -> Self::Owned {
+    fn similar_origin_inst<I: Instance<Self::Owned>>(x: I) -> Self::Owned {
         x.eval(|xr| xr.similar_origin())
     }
 }
@@ -77,15 +77,15 @@
     X: Space,
 {
     /// Computes  `y = βy + αx`, where `y` is `Self`.
-    fn axpy<I: Instance<X>>(&mut self, α: Self::Field, x: I, β: Self::Field);
+    fn axpy<I: Instance<X::OwnedSpace>>(&mut self, α: Self::Field, x: I, β: Self::Field);
 
     /// Copies `x` to `self`.
-    fn copy_from<I: Instance<X>>(&mut self, x: I) {
+    fn copy_from<I: Instance<X::OwnedSpace>>(&mut self, x: I) {
         self.axpy(1.0, x, 0.0)
     }
 
     /// Computes  `y = αx`, where `y` is `Self`.
-    fn scale_from<I: Instance<X>>(&mut self, α: Self::Field, x: I) {
+    fn scale_from<I: Instance<X::OwnedSpace>>(&mut self, α: Self::Field, x: I) {
         self.axpy(α, x, 0.0)
     }
 
@@ -100,17 +100,17 @@
 #[replace_float_literals(F::cast_from(literal))]
 pub trait GEMV<F: Num, X: Space, Y = <Self as Mapping<X>>::Codomain>: Linear<X> {
     /// Computes  `y = αAx + βy`, where `A` is `Self`.
-    fn gemv<I: Instance<X>>(&self, y: &mut Y, α: F, x: I, β: F);
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, α: F, x: I, β: F);
 
     #[inline]
     /// Computes `y = Ax`, where `A` is `Self`
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Y, x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, x: I) {
         self.gemv(y, 1.0, x, 0.0)
     }
 
     #[inline]
     /// Computes `y += Ax`, where `A` is `Self`
-    fn apply_add<I: Instance<X>>(&self, y: &mut Y, x: I) {
+    fn apply_add<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, x: I) {
         self.gemv(y, 1.0, x, 1.0)
     }
 }
@@ -199,7 +199,7 @@
 impl<X: Space> Mapping<X> for IdOp<X> {
     type Codomain = X::OwnedSpace;
 
-    fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         x.into_owned()
     }
 }
@@ -213,11 +213,11 @@
     X: Space,
 {
     // Computes  `y = αAx + βy`, where `A` is `Self`.
-    fn gemv<I: Instance<X>>(&self, y: &mut Y, α: F, x: I, β: F) {
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, α: F, x: I, β: F) {
         y.axpy(α, x, β)
     }
 
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Y, x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, x: I) {
         y.copy_from(x);
     }
 }
@@ -264,7 +264,7 @@
 impl<X: VectorSpace> Mapping<X> for SimpleZeroOp {
     type Codomain = X::Owned;
 
-    fn apply<I: Instance<X>>(&self, x: I) -> X::Owned {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> X::Owned {
         X::similar_origin_inst(x)
     }
 }
@@ -279,11 +279,11 @@
     X: VectorSpace<Field = F> + Instance<X>,
 {
     // Computes  `y = αAx + βy`, where `A` is `Self`.
-    fn gemv<I: Instance<X>>(&self, y: &mut Y, _α: F, _x: I, β: F) {
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, _α: F, _x: I, β: F) {
         *y *= β;
     }
 
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Y, _x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, _x: I) {
         y.set_zero();
     }
 }
@@ -414,7 +414,7 @@
 {
     type Codomain = Y::Owned;
 
-    fn apply<I: Instance<X>>(&self, _x: I) -> Y::Owned {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, _x: I) -> Y::Owned {
         self.codomain_origin_generator.origin()
     }
 }
@@ -437,11 +437,11 @@
     OY: OriginGenerator<Y>,
 {
     // Computes  `y = αAx + βy`, where `A` is `Self`.
-    fn gemv<I: Instance<X>>(&self, y: &mut Y, _α: F, _x: I, β: F) {
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, _α: F, _x: I, β: F) {
         *y *= β;
     }
 
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Y, _x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, _x: I) {
         y.set_zero();
     }
 }
@@ -504,17 +504,17 @@
     T: Linear<X>,
     S: GEMV<F, T::Codomain, Y>,
 {
-    fn gemv<I: Instance<X>>(&self, y: &mut Y, α: F, x: I, β: F) {
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, α: F, x: I, β: F) {
         self.outer.gemv(y, α, self.inner.apply(x), β)
     }
 
     /// Computes `y = Ax`, where `A` is `Self`
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Y, x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, x: I) {
         self.outer.apply_mut(y, self.inner.apply(x))
     }
 
     /// Computes `y += Ax`, where `A` is `Self`
-    fn apply_add<I: Instance<X>>(&self, y: &mut Y, x: I) {
+    fn apply_add<I: Instance<X::OwnedSpace>>(&self, y: &mut Y, x: I) {
         self.outer.apply_add(y, self.inner.apply(x))
     }
 }
@@ -551,7 +551,7 @@
 {
     type Codomain = <S::Codomain as Add<T::Codomain>>::Output;
 
-    fn apply<I: Instance<Pair<A, B>>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<Pair<A::OwnedSpace, B::OwnedSpace>>>(&self, x: I) -> Self::Codomain {
         x.eval_decompose(|Pair(a, b)| self.0.apply(a) + self.1.apply(b))
     }
 }
@@ -576,14 +576,14 @@
     F: Num,
     Self: Linear<Pair<U, V>, Codomain = Y>,
 {
-    fn gemv<I: Instance<Pair<U, V>>>(&self, y: &mut Y, α: F, x: I, β: F) {
+    fn gemv<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(&self, y: &mut Y, α: F, x: I, β: F) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.gemv(y, α, u, β);
             self.1.gemv(y, α, v, F::ONE);
         })
     }
 
-    fn apply_mut<I: Instance<Pair<U, V>>>(&self, y: &mut Y, x: I) {
+    fn apply_mut<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(&self, y: &mut Y, x: I) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.apply_mut(y, u);
             self.1.apply_add(y, v);
@@ -591,7 +591,7 @@
     }
 
     /// Computes `y += Ax`, where `A` is `Self`
-    fn apply_add<I: Instance<Pair<U, V>>>(&self, y: &mut Y, x: I) {
+    fn apply_add<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(&self, y: &mut Y, x: I) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.apply_add(y, u);
             self.1.apply_add(y, v);
@@ -611,7 +611,7 @@
 {
     type Codomain = Pair<S::Codomain, T::Codomain>;
 
-    fn apply<I: Instance<A>>(&self, a: I) -> Self::Codomain {
+    fn apply<I: Instance<A::OwnedSpace>>(&self, a: I) -> Self::Codomain {
         Pair(a.eval_ref_decompose(|r| self.0.apply(r)), self.1.apply(a))
     }
 }
@@ -632,18 +632,18 @@
     F: Num,
     Self: Linear<X, Codomain = Pair<A, B>>,
 {
-    fn gemv<I: Instance<X>>(&self, y: &mut Pair<A, B>, α: F, x: I, β: F) {
+    fn gemv<I: Instance<X::OwnedSpace>>(&self, y: &mut Pair<A, B>, α: F, x: I, β: F) {
         x.eval_ref_decompose(|r| self.0.gemv(&mut y.0, α, r, β));
         self.1.gemv(&mut y.1, α, x, β);
     }
 
-    fn apply_mut<I: Instance<X>>(&self, y: &mut Pair<A, B>, x: I) {
+    fn apply_mut<I: Instance<X::OwnedSpace>>(&self, y: &mut Pair<A, B>, x: I) {
         x.eval_ref_decompose(|r| self.0.apply_mut(&mut y.0, r));
         self.1.apply_mut(&mut y.1, x);
     }
 
     /// Computes `y += Ax`, where `A` is `Self`
-    fn apply_add<I: Instance<X>>(&self, y: &mut Pair<A, B>, x: I) {
+    fn apply_add<I: Instance<X::OwnedSpace>>(&self, y: &mut Pair<A, B>, x: I) {
         x.eval_ref_decompose(|r| self.0.apply_add(&mut y.0, r));
         self.1.apply_add(&mut y.1, x);
     }
@@ -755,7 +755,7 @@
 {
     type Codomain = Pair<S::Codomain, T::Codomain>;
 
-    fn apply<I: Instance<Pair<A, B>>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<Pair<A::OwnedSpace, B::OwnedSpace>>>(&self, x: I) -> Self::Codomain {
         x.eval_decompose(|Pair(a, b)| Pair(self.0.apply(a), self.1.apply(b)))
     }
 }
@@ -780,14 +780,20 @@
     F: Num,
     Self: Linear<Pair<U, V>, Codomain = Pair<A, B>>,
 {
-    fn gemv<I: Instance<Pair<U, V>>>(&self, y: &mut Pair<A, B>, α: F, x: I, β: F) {
+    fn gemv<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(
+        &self,
+        y: &mut Pair<A, B>,
+        α: F,
+        x: I,
+        β: F,
+    ) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.gemv(&mut y.0, α, u, β);
             self.1.gemv(&mut y.1, α, v, β);
         })
     }
 
-    fn apply_mut<I: Instance<Pair<U, V>>>(&self, y: &mut Pair<A, B>, x: I) {
+    fn apply_mut<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(&self, y: &mut Pair<A, B>, x: I) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.apply_mut(&mut y.0, u);
             self.1.apply_mut(&mut y.1, v);
@@ -795,7 +801,7 @@
     }
 
     /// Computes `y += Ax`, where `A` is `Self`
-    fn apply_add<I: Instance<Pair<U, V>>>(&self, y: &mut Pair<A, B>, x: I) {
+    fn apply_add<I: Instance<Pair<U::OwnedSpace, V::OwnedSpace>>>(&self, y: &mut Pair<A, B>, x: I) {
         x.eval_decompose(|Pair(u, v)| {
             self.0.apply_add(&mut y.0, u);
             self.1.apply_add(&mut y.1, v);
@@ -925,7 +931,7 @@
     type Codomain = <Domain as Mul<F>>::Output;
 
     /// Compute the value of `self` at `x`.
-    fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         x.own() * self.0
     }
 }
--- a/src/mapping.rs	Tue Sep 02 15:18:30 2025 -0500
+++ b/src/mapping.rs	Wed Sep 03 08:40:17 2025 -0500
@@ -17,7 +17,7 @@
     type Codomain: ClosedSpace;
 
     /// Compute the value of `self` at `x`.
-    fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain;
+    fn apply<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::Codomain;
 
     #[inline]
     /// Form the composition `self ∘ other`
@@ -81,7 +81,7 @@
         Self: 'b;
 
     /// Calculate differential at `x`
-    fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain;
+    fn differential<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::DerivativeDomain;
 
     /// Form the differential mapping of `self`.
     fn diff(self) -> Self::Differential<'static>;
@@ -107,7 +107,7 @@
     type Derivative: ClosedSpace;
 
     /// Compute the differential of `self` at `x`, consuming the input.
-    fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative;
+    fn differential_impl<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Derivative;
 }
 
 impl<T, Domain> DifferentiableMapping<Domain> for T
@@ -122,7 +122,7 @@
         Self: 'b;
 
     #[inline]
-    fn differential<I: Instance<Domain>>(&self, x: I) -> Self::DerivativeDomain {
+    fn differential<I: Instance<Domain::OwnedSpace>>(&self, x: I) -> Self::DerivativeDomain {
         self.differential_impl(x)
     }
 
@@ -155,7 +155,7 @@
     type Codomain = G::DerivativeDomain;
 
     #[inline]
-    fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         (*self.g).differential(x)
     }
 }
@@ -175,7 +175,7 @@
     type Codomain = F;
 
     #[inline]
-    fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         self.g.apply(x).flatten1d()
     }
 }
@@ -207,7 +207,7 @@
     type Codomain = F;
 
     #[inline]
-    fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         let tmp: [F; N] = (*self.g).apply(x).into();
         // Safety: `slice_codomain` below checks the range.
         unsafe { *tmp.get_unchecked(self.slice) }
@@ -253,7 +253,7 @@
     type Codomain = S::Codomain;
 
     #[inline]
-    fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain {
+    fn apply<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Codomain {
         self.outer.apply(self.inner.apply(x))
     }
 }
@@ -273,7 +273,7 @@
     type Derivative = Y;
 
     /// Compute the differential of `self` at `x`, consuming the input.
-    fn differential_impl<I: Instance<X>>(&self, x: I) -> Self::Derivative {
+    fn differential_impl<I: Instance<X::OwnedSpace>>(&self, x: I) -> Self::Derivative {
         // Composition {
         //     outer: self
         //         .outer

mercurial