--- a/src/linops.rs Wed Sep 03 09:52:30 2025 -0500 +++ b/src/linops.rs Wed Sep 03 10:08:28 2025 -0500 @@ -28,35 +28,39 @@ /// Vector spaces #[replace_float_literals(Self::Field::cast_from(literal))] pub trait VectorSpace: - Space<OwnedSpace = Self::Owned> - + Mul<Self::Field, Output = Self::Owned> - + Div<Self::Field, Output = Self::Owned> - + Add<Self, Output = Self::Owned> - + Add<Self::Owned, Output = Self::Owned> - + Sub<Self, Output = Self::Owned> - + Sub<Self::Owned, Output = Self::Owned> + Space<Principal = Self::PrincipalV> + + Mul<Self::Field, Output = Self::PrincipalV> + + Div<Self::Field, Output = Self::PrincipalV> + + Add<Self, Output = Self::PrincipalV> + + Add<Self::PrincipalV, Output = Self::PrincipalV> + + Sub<Self, Output = Self::PrincipalV> + + Sub<Self::PrincipalV, Output = Self::PrincipalV> + Neg - + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> - + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> + + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::PrincipalV> + + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::PrincipalV> { + /// Underlying scalar field type Field: Num; - type Owned: ClosedSpace + + /// Principal form of the space; always equal to [`Space::Principal`], but with + /// more traits guaranteed. + type PrincipalV: ClosedSpace + AXPY< Self, Field = Self::Field, - Owned = Self::Owned, - OwnedVariant = Self::Owned, - OwnedSpace = Self::Owned, + PrincipalV = Self::PrincipalV, + OwnedVariant = Self::PrincipalV, + Principal = Self::PrincipalV, >; /// Return a similar zero as `self`. - fn similar_origin(&self) -> Self::Owned; + fn similar_origin(&self) -> Self::PrincipalV; // { // self.make_origin_generator().make_origin() // } /// Return a similar zero as `x`. - fn similar_origin_inst<I: Instance<Self>>(x: I) -> Self::Owned { + fn similar_origin_inst<I: Instance<Self>>(x: I) -> Self::PrincipalV { x.eval(|xr| xr.similar_origin()) } } @@ -68,9 +72,9 @@ + MulAssign<Self::Field> + DivAssign<Self::Field> + AddAssign<Self> - + AddAssign<Self::Owned> + + AddAssign<Self::PrincipalV> + SubAssign<Self> - + SubAssign<Self::Owned> + + SubAssign<Self::PrincipalV> + for<'b> AddAssign<&'b Self> + for<'b> SubAssign<&'b Self> where @@ -93,8 +97,8 @@ fn set_zero(&mut self); } -pub trait ClosedVectorSpace: Instance<Self> + VectorSpace<Owned = Self> {} -impl<X: Instance<X> + VectorSpace<Owned = Self>> ClosedVectorSpace for X {} +pub trait ClosedVectorSpace: Instance<Self> + VectorSpace<PrincipalV = Self> {} +impl<X: Instance<X> + VectorSpace<PrincipalV = Self>> ClosedVectorSpace for X {} /// Efficient in-place application for [`Linear`] operators. #[replace_float_literals(F::cast_from(literal))] @@ -197,7 +201,7 @@ } impl<X: Space> Mapping<X> for IdOp<X> { - type Codomain = X::OwnedSpace; + type Codomain = X::Principal; fn apply<I: Instance<X>>(&self, x: I) -> Self::Codomain { x.into_owned() @@ -233,10 +237,10 @@ } } -impl<X: Clone + Space> Adjointable<X, X::OwnedSpace> for IdOp<X> { - type AdjointCodomain = X::OwnedSpace; +impl<X: Clone + Space> Adjointable<X, X::Principal> for IdOp<X> { + type AdjointCodomain = X::Principal; type Adjoint<'a> - = IdOp<X::OwnedSpace> + = IdOp<X::Principal> where X: 'a; @@ -245,10 +249,10 @@ } } -impl<X: Clone + Space> Preadjointable<X, X::OwnedSpace> for IdOp<X> { - type PreadjointCodomain = X::OwnedSpace; +impl<X: Clone + Space> Preadjointable<X, X::Principal> for IdOp<X> { + type PreadjointCodomain = X::Principal; type Preadjoint<'a> - = IdOp<X::OwnedSpace> + = IdOp<X::Principal> where X: 'a; @@ -262,9 +266,9 @@ pub struct SimpleZeroOp; impl<X: VectorSpace> Mapping<X> for SimpleZeroOp { - type Codomain = X::Owned; + type Codomain = X::PrincipalV; - fn apply<I: Instance<X>>(&self, x: I) -> X::Owned { + fn apply<I: Instance<X>>(&self, x: I) -> X::PrincipalV { X::similar_origin_inst(x) } } @@ -323,7 +327,7 @@ where Self: 'b; - fn origin(&self) -> Y::Owned; + fn origin(&self) -> Y::PrincipalV; fn as_ref(&self) -> Self::Ref<'_>; } @@ -334,7 +338,7 @@ Self: 'b; #[inline] - fn origin(&self) -> Y::Owned { + fn origin(&self) -> Y::PrincipalV { return self.similar_origin(); } @@ -351,7 +355,7 @@ Self: 'c; #[inline] - fn origin(&self) -> Y::Owned { + fn origin(&self) -> Y::PrincipalV { return self.similar_origin(); } @@ -392,8 +396,8 @@ X: HasDual<F, DualSpace = Xprime>, Y: HasDual<F, DualSpace = Yprime>, F: Float, - Xprime: VectorSpace<Field = F, Owned = Xprime>, - Xprime::Owned: AXPY<Field = F>, + Xprime: VectorSpace<Field = F, PrincipalV = Xprime>, + Xprime::PrincipalV: AXPY<Field = F>, Yprime: Space + Instance<Yprime>, { pub fn new_dualisable(y_og: OY, xprime_og: OXprime) -> Self { @@ -412,9 +416,9 @@ F: Float, OY: OriginGenerator<Y>, { - type Codomain = Y::Owned; + type Codomain = Y::PrincipalV; - fn apply<I: Instance<X>>(&self, _x: I) -> Y::Owned { + fn apply<I: Instance<X>>(&self, _x: I) -> Y::PrincipalV { self.codomain_origin_generator.origin() } } @@ -432,7 +436,7 @@ impl<X, Y, OY, O, F> GEMV<F, X, Y> for ZeroOp<X, Y, OY, O, F> where X: Space, - Y: AXPY<Field = F, Owned = Y>, + Y: AXPY<Field = F, PrincipalV = Y>, F: Float, OY: OriginGenerator<Y>, { @@ -450,7 +454,7 @@ where X: Space + Instance<X> + Norm<E1, F>, Y: VectorSpace<Field = F>, - Y::Owned: Clone, + Y::PrincipalV: Clone, F: Float, E1: NormExponent, E2: NormExponent, @@ -920,10 +924,10 @@ where F: Float, Domain: Space, - Domain::OwnedSpace: Mul<F>, - <Domain::OwnedSpace as Mul<F>>::Output: ClosedSpace, + Domain::Principal: Mul<F>, + <Domain::Principal as Mul<F>>::Output: ClosedSpace, { - type Codomain = <Domain::OwnedSpace as Mul<F>>::Output; + type Codomain = <Domain::Principal as Mul<F>>::Output; /// Compute the value of `self` at `x`. fn apply<I: Instance<Domain>>(&self, x: I) -> Self::Codomain { @@ -935,7 +939,7 @@ where F: Float, Domain: Space, - Domain::OwnedSpace: Mul<F>, - <Domain::OwnedSpace as Mul<F>>::Output: ClosedSpace, + Domain::Principal: Mul<F>, + <Domain::Principal as Mul<F>>::Output: ClosedSpace, { }