Try to use HasDual with adjoints. Problem with nalgebra Instances. draft dev

Sat, 21 Dec 2024 14:27:14 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Sat, 21 Dec 2024 14:27:14 -0500
branch
dev
changeset 78
cebedc4a8331
parent 61
05089fbc0310
child 79
d63e40672dd6

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;
 }

mercurial