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