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