src/preadjoint_helper.rs

changeset 52
f0e8704d3f0e
parent 35
b087e3eab191
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/preadjoint_helper.rs	Mon Feb 17 13:54:53 2025 -0500
@@ -0,0 +1,55 @@
+/*!
+Preadjoint construction helper
+*/
+
+use std::marker::PhantomData;
+use alg_tools::types::*;
+pub use alg_tools::linops::*;
+use alg_tools::norms::{Norm, HasDualExponent};
+
+/// Helper structure for constructing preadjoints of `S` where `S : Linear<X>`.
+/// [`Linear`] needs to be implemented for each instance, but [`Adjointable`]
+/// and [`BoundedLinear`] have blanket implementations.
+#[derive(Clone,Debug)]
+pub struct PreadjointHelper<'a, S : 'a, X> {
+    pub forward_op : &'a S,
+    _domain : PhantomData<X>
+}
+
+impl<'a, S : 'a, X> PreadjointHelper<'a, S, X> {
+    pub fn new(forward_op : &'a S) -> Self {
+        PreadjointHelper { forward_op, _domain: PhantomData }
+    }
+}
+
+impl<'a, X, Ypre, S> Adjointable<Ypre, X>
+for PreadjointHelper<'a, S, X>
+where
+    X : Space,
+    Ypre : Space,
+    Self : Linear<Ypre>,
+    S : Clone + Linear<X>
+{
+    type AdjointCodomain = S::Codomain;
+    type Adjoint<'b> = S where Self : 'b;
+
+    fn adjoint(&self) -> Self::Adjoint<'_> {
+        self.forward_op.clone()
+    }
+}
+
+impl<'a, F, X, Ypre, ExpXpre, ExpYpre, S> BoundedLinear<Ypre, ExpYpre, ExpXpre, F>
+for PreadjointHelper<'a, S, X>
+where
+    ExpXpre : HasDualExponent,
+    ExpYpre : HasDualExponent,
+    F : Float,
+    X : Space + Norm<F, ExpXpre::DualExp>,
+    Ypre : Space + Norm<F, ExpYpre>,
+    Self : Linear<Ypre>,
+    S : 'a + Clone + BoundedLinear<X, ExpXpre::DualExp, ExpYpre::DualExp, F>
+{
+    fn opnorm_bound(&self, expy : ExpYpre, expx : ExpXpre) -> F {
+        self.forward_op.opnorm_bound(expx.dual_exponent(), expy.dual_exponent())
+    }
+}

mercurial