src/linops.rs

branch
dev
changeset 78
cebedc4a8331
parent 61
05089fbc0310
child 79
d63e40672dd6
--- 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<'_> {

mercurial