| |
1 /*! |
| |
2 Preadjoint construction helper |
| |
3 */ |
| |
4 |
| |
5 use std::marker::PhantomData; |
| |
6 use alg_tools::types::*; |
| |
7 pub use alg_tools::linops::*; |
| |
8 use alg_tools::norms::{Norm, HasDualExponent}; |
| |
9 |
| |
10 /// Helper structure for constructing preadjoints of `S` where `S : Linear<X>`. |
| |
11 /// [`Linear`] needs to be implemented for each instance, but [`Adjointable`] |
| |
12 /// and [`BoundedLinear`] have blanket implementations. |
| |
13 #[derive(Clone,Debug)] |
| |
14 pub struct PreadjointHelper<'a, S : 'a, X> { |
| |
15 pub forward_op : &'a S, |
| |
16 _domain : PhantomData<X> |
| |
17 } |
| |
18 |
| |
19 impl<'a, S : 'a, X> PreadjointHelper<'a, S, X> { |
| |
20 pub fn new(forward_op : &'a S) -> Self { |
| |
21 PreadjointHelper { forward_op, _domain: PhantomData } |
| |
22 } |
| |
23 } |
| |
24 |
| |
25 impl<'a, X, Ypre, S> Adjointable<Ypre, X> |
| |
26 for PreadjointHelper<'a, S, X> |
| |
27 where |
| |
28 X : Space, |
| |
29 Ypre : Space, |
| |
30 Self : Linear<Ypre>, |
| |
31 S : Clone + Linear<X> |
| |
32 { |
| |
33 type AdjointCodomain = S::Codomain; |
| |
34 type Adjoint<'b> = S where Self : 'b; |
| |
35 |
| |
36 fn adjoint(&self) -> Self::Adjoint<'_> { |
| |
37 self.forward_op.clone() |
| |
38 } |
| |
39 } |
| |
40 |
| |
41 impl<'a, F, X, Ypre, ExpXpre, ExpYpre, S> BoundedLinear<Ypre, ExpYpre, ExpXpre, F> |
| |
42 for PreadjointHelper<'a, S, X> |
| |
43 where |
| |
44 ExpXpre : HasDualExponent, |
| |
45 ExpYpre : HasDualExponent, |
| |
46 F : Float, |
| |
47 X : Space + Norm<F, ExpXpre::DualExp>, |
| |
48 Ypre : Space + Norm<F, ExpYpre>, |
| |
49 Self : Linear<Ypre>, |
| |
50 S : 'a + Clone + BoundedLinear<X, ExpXpre::DualExp, ExpYpre::DualExp, F> |
| |
51 { |
| |
52 fn opnorm_bound(&self, expy : ExpYpre, expx : ExpXpre) -> F { |
| |
53 self.forward_op.opnorm_bound(expx.dual_exponent(), expy.dual_exponent()) |
| |
54 } |
| |
55 } |