Sat, 21 Dec 2024 14:27:14 -0500
Try to use HasDual with adjoints. Problem with nalgebra Instances.
src/linops.rs | file | annotate | diff | comparison | revisions | |
src/nalgebra_support.rs | file | annotate | diff | comparison | revisions |
--- a/src/linops.rs Tue Dec 31 08:30:43 2024 -0500 +++ b/src/linops.rs Sat Dec 21 14:27:14 2024 -0500 @@ -9,7 +9,7 @@ pub use crate::mapping::{Mapping, Space, Composition}; use crate::direct_product::Pair; use crate::instance::Instance; -use crate::norms::{NormExponent, PairNorm, L1, L2, Linfinity, Norm}; +use crate::norms::{NormExponent, PairNorm, L1, L2, Linfinity, Norm, HasDual}; /// Trait for linear operators on `X`. pub trait Linear<X : Space> : Mapping<X> @@ -80,13 +80,16 @@ }*/ /// Trait for forming the adjoint operator of `Self`. -pub trait Adjointable<X, Yʹ> : Linear<X> +pub trait Adjointable<X, F : Float = f64> : Linear<X> where - X : Space, - Yʹ : Space, + X : HasDual<F>, + Self::Codomain : HasDual<F>, { - type AdjointCodomain : Space; - type Adjoint<'a> : Linear<Yʹ, Codomain=Self::AdjointCodomain> where Self : 'a; + type AdjointCodomain : Instance<X::DualSpace>; + type Adjoint<'a> : Linear< + <Self::Codomain as HasDual<F>>::DualSpace, + Codomain=Self::AdjointCodomain, + > where Self : 'a; /// Form the adjoint operator of `self`. fn adjoint(&self) -> Self::Adjoint<'_>; @@ -99,21 +102,20 @@ /// operator. The space `Ypre` is the predual of its codomain, and should be the /// domain of the adjointed operator. `Self::Preadjoint` should be /// [`Adjointable`]`<'a,Ypre,X>`. - -pub trait Preadjointable<X : Space, Ypre : Space> : Linear<X> { +/// +/// We do not set further restrictions on the spacds, to allow preadjointing when `X` +/// is on the dual space of `Ypre`, but a subset of it. +pub trait Preadjointable<X : Space, Ypre : Space> : Linear<X> +//where +// Ypre : HasDual<F, DualSpace=Self::Codomain>, +{ type PreadjointCodomain : Space; - type Preadjoint<'a> : Adjointable< - Ypre, X, AdjointCodomain=Self::Codomain, Codomain=Self::PreadjointCodomain - > where Self : 'a; + type Preadjoint<'a> : Linear<Ypre, Codomain=Self::PreadjointCodomain> where Self : 'a; /// Form the adjoint operator of `self`. fn preadjoint(&self) -> Self::Preadjoint<'_>; } -/// Adjointable operators $A: X → Y$ between reflexive spaces $X$ and $Y$. -pub trait SimplyAdjointable<X : Space> : Adjointable<X,<Self as Mapping<X>>::Codomain> {} -impl<'a,X : Space, T> SimplyAdjointable<X> for T -where T : Adjointable<X,<Self as Mapping<X>>::Codomain> {} /// The identity operator #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] @@ -159,15 +161,15 @@ fn opnorm_bound(&self, _xexp : E, _codexp : E) -> F { F::ONE } } -impl<X : Clone + Space> Adjointable<X,X> for IdOp<X> { - type AdjointCodomain=X; - type Adjoint<'a> = IdOp<X> where X : 'a; +impl<X : Clone + HasDual<F, DualSpace=X>, F : Float> Adjointable<X, F> for IdOp<X> { + type AdjointCodomain = X; + type Adjoint<'a> = IdOp<X::DualSpace> where X : 'a; fn adjoint(&self) -> Self::Adjoint<'_> { IdOp::new() } } -impl<X : Clone + Space> Preadjointable<X,X> for IdOp<X> { - type PreadjointCodomain=X; +impl<X : Clone + Space> Preadjointable<X, X> for IdOp<X> { + type PreadjointCodomain = X; type Preadjoint<'a> = IdOp<X> where X : 'a; fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } @@ -332,17 +334,23 @@ } -impl<A, B, Yʹ, S, T> Adjointable<Pair<A,B>, Yʹ> for RowOp<S, T> +impl<F, A, B, Yʹ, S, T> Adjointable<Pair<A, B>, F> for RowOp<S, T> where - A : Space, - B : Space, + F : Float, + A : HasDual<F>, + B : HasDual<F>, + S : Adjointable<A, F>, + T : Adjointable<B, F>, Yʹ : Space, - S : Adjointable<A, Yʹ>, - T : Adjointable<B, Yʹ>, - Self : Linear<Pair<A, B>>, + S :: Codomain : HasDual<F, DualSpace=Yʹ>, + T :: Codomain : HasDual<F, DualSpace=Yʹ>, + S::Codomain : Add<T::Codomain>, + <S::Codomain as Add<T::Codomain>>::Output : HasDual<F, DualSpace=Yʹ>, + Self::Codomain : HasDual<F, DualSpace=Yʹ>, + //Self : Linear<Pair<A, B>>, // for<'a> ColOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< // Yʹ, - // Codomain=Pair<S::AdjointCodomain, T::AdjointCodomain> + // //Codomain=Pair<S::AdjointCodomain, T::AdjointCodomain> // >, { type AdjointCodomain = Pair<S::AdjointCodomain, T::AdjointCodomain>; @@ -360,12 +368,10 @@ Yʹ : Space, S : Preadjointable<A, Yʹ>, T : Preadjointable<B, Yʹ>, - Self : Linear<Pair<A, B>>, - for<'a> ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< - Yʹ, Pair<A,B>, - Codomain=Pair<S::PreadjointCodomain, T::PreadjointCodomain>, - AdjointCodomain = Self::Codomain, - >, + S::Codomain : Add<T::Codomain>, + <S::Codomain as Add<T::Codomain>>::Output : Space, + //Self : Linear<Pair<A, B>, Codomain=Y>, + //for<'a> ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable<Yʹ, F>, { type PreadjointCodomain = Pair<S::PreadjointCodomain, T::PreadjointCodomain>; type Preadjoint<'a> = ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; @@ -376,21 +382,22 @@ } -impl<A, Xʹ, Yʹ, R, S, T> Adjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> +impl<F, A, Aʹ, S, T> Adjointable<A, F> for ColOp<S, T> where - A : Space, - Xʹ : Space, - Yʹ : Space, - R : Space + ClosedAdd, - S : Adjointable<A, Xʹ, AdjointCodomain = R>, - T : Adjointable<A, Yʹ, AdjointCodomain = R>, - Self : Linear<A>, + F : Float, + A : HasDual<F>, + S : Adjointable<A, F>, + T : Adjointable<A, F>, + T::Codomain : HasDual<F>, + S::Codomain : HasDual<F>, + Aʹ : Space + Instance<A::DualSpace>, + <S as Adjointable<A, F>>::AdjointCodomain : Add<<T as Adjointable<A, F>>::AdjointCodomain, Output=Aʹ>, // for<'a> RowOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< - // Pair<Xʹ,Yʹ>, - // Codomain=R, + // Pair<<T::Codomain as HasDual<F>>::DualSpace, <S::Codomain as HasDual<F>>::DualSpace>, + // Codomain=Aʹ // >, { - type AdjointCodomain = R; + type AdjointCodomain = Aʹ; type Adjoint<'a> = RowOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; fn adjoint(&self) -> Self::Adjoint<'_> { @@ -398,22 +405,18 @@ } } -impl<A, Xʹ, Yʹ, R, S, T> Preadjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> +impl<A, Aʹ, Xʹ, Yʹ, S, T> Preadjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> where A : Space, + Aʹ : Space, Xʹ : Space, Yʹ : Space, - R : Space + ClosedAdd, - S : Preadjointable<A, Xʹ, PreadjointCodomain = R>, - T : Preadjointable<A, Yʹ, PreadjointCodomain = R>, - Self : Linear<A>, - for<'a> RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< - Pair<Xʹ,Yʹ>, A, - Codomain = R, - AdjointCodomain = Self::Codomain, - >, + S : Preadjointable<A, Xʹ, PreadjointCodomain=Aʹ>, + T : Preadjointable<A, Yʹ, PreadjointCodomain=Aʹ>, + Aʹ : ClosedAdd, + //for<'a> RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable<Pair<Xʹ,Yʹ>, F>, { - type PreadjointCodomain = R; + type PreadjointCodomain = Aʹ; type Preadjoint<'a> = RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; fn preadjoint(&self) -> Self::Preadjoint<'_> { @@ -478,21 +481,17 @@ } } -impl<A, B, Xʹ, Yʹ, R, S, T> Adjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> +impl<F, A, B, S, T> Adjointable<Pair<A,B>, F> for DiagOp<S, T> where - A : Space, - B : Space, - Xʹ: Space, - Yʹ : Space, - R : Space, - S : Adjointable<A, Xʹ>, - T : Adjointable<B, Yʹ>, - Self : Linear<Pair<A, B>>, - for<'a> DiagOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< - Pair<Xʹ,Yʹ>, Codomain=R, - >, + F: Float, + A : HasDual<F>, + B : HasDual<F>, + S : Adjointable<A, F>, + T : Adjointable<B, F>, + T::Codomain : HasDual<F>, + S::Codomain : HasDual<F>, { - type AdjointCodomain = R; + type AdjointCodomain = Pair<S::AdjointCodomain, T::AdjointCodomain>; type Adjoint<'a> = DiagOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; fn adjoint(&self) -> Self::Adjoint<'_> { @@ -500,23 +499,16 @@ } } -impl<A, B, Xʹ, Yʹ, R, S, T> Preadjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> +impl<A, B, Xʹ, Yʹ, S, T> Preadjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> where A : Space, B : Space, - Xʹ: Space, + Xʹ : Space, Yʹ : Space, - R : Space, S : Preadjointable<A, Xʹ>, T : Preadjointable<B, Yʹ>, - Self : Linear<Pair<A, B>>, - for<'a> DiagOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< - Pair<Xʹ,Yʹ>, Pair<A, B>, - Codomain=R, - AdjointCodomain = Self::Codomain, - >, { - type PreadjointCodomain = R; + type PreadjointCodomain = Pair<S::PreadjointCodomain, T::PreadjointCodomain>; type Preadjoint<'a> = DiagOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; fn preadjoint(&self) -> Self::Preadjoint<'_> {
--- a/src/nalgebra_support.rs Tue Dec 31 08:30:43 2024 -0500 +++ b/src/nalgebra_support.rs Sat Dec 21 14:27:14 2024 -0500 @@ -125,15 +125,18 @@ } } -impl<'own,SV1,SV2,SM,N,M,K,E> Adjointable<Matrix<E,M,K,SV1>, Matrix<E,N,K,SV2>> +impl<'own,SV,SM,N,M,E> Adjointable<Vector<E,M,SV>, E> for Matrix<E,N,M,SM> -where SM: Storage<E,N,M>, SV1: Storage<E,M,K> + Clone, SV2: Storage<E,N,K> + Clone, - N : Dim, M : Dim, K : Dim, E : Scalar + Zero + One + SimdComplexField, - DefaultAllocator : Allocator<N,K>, - DefaultAllocator : Allocator<M,K>, - DefaultAllocator : Allocator<N,M>, - DefaultAllocator : Allocator<M,N> { - type AdjointCodomain = OMatrix<E,M,K>; +where + SM: Storage<E,N,M>, SV: Storage<E,M> + Clone, + N : Dim, M : Dim, E : Scalar + Zero + One + RealField + Float, + DefaultAllocator : Allocator<M>, + DefaultAllocator : Allocator<N>, + DefaultAllocator : Allocator<N,M>, + DefaultAllocator : Allocator<M,N>, + OMatrix<E,M,N> : Linear<OVector<E, N>, Codomain = OVector<E, M>>, +{ + type AdjointCodomain = OVector<E, M>; type Adjoint<'a> = OMatrix<E,M,N> where SM : 'a; #[inline] @@ -242,10 +245,12 @@ impl<E,M,S> HasDual<E> for Vector<E,M,S> -where M : Dim, - S : Storage<E,M> + Clone, - E : Float + Scalar + Zero + One + RealField, - DefaultAllocator : Allocator<M> { +where + M : Dim, + S : Storage<E,M> + Clone, + E : Float + Scalar + Zero + One + RealField, + DefaultAllocator : Allocator<M> +{ // TODO: Doesn't work with different storage formats. type DualSpace = Self; }