4 |
4 |
5 use numeric_literals::replace_float_literals; |
5 use numeric_literals::replace_float_literals; |
6 use std::marker::PhantomData; |
6 use std::marker::PhantomData; |
7 use serde::Serialize; |
7 use serde::Serialize; |
8 use crate::types::*; |
8 use crate::types::*; |
9 pub use crate::mapping::{Mapping, Space}; |
9 pub use crate::mapping::{Mapping, Space, Composition}; |
10 use crate::direct_product::Pair; |
10 use crate::direct_product::Pair; |
11 use crate::instance::Instance; |
11 use crate::instance::Instance; |
12 use crate::norms::{NormExponent, PairNorm, L1, L2, Linfinity}; |
12 use crate::norms::{NormExponent, PairNorm, L1, L2, Linfinity, Norm}; |
13 |
13 |
14 /// Trait for linear operators on `X`. |
14 /// Trait for linear operators on `X`. |
15 pub trait Linear<X : Space> : Mapping<X> |
15 pub trait Linear<X : Space> : Mapping<X> |
16 { } |
16 { } |
17 |
17 |
56 |
56 |
57 /// Bounded linear operators |
57 /// Bounded linear operators |
58 pub trait BoundedLinear<X, XExp, CodExp, F = f64> : Linear<X> |
58 pub trait BoundedLinear<X, XExp, CodExp, F = f64> : Linear<X> |
59 where |
59 where |
60 F : Num, |
60 F : Num, |
61 X : Space, |
61 X : Space + Norm<F, XExp>, |
62 XExp : NormExponent, |
62 XExp : NormExponent, |
63 CodExp : NormExponent |
63 CodExp : NormExponent |
64 { |
64 { |
65 /// A bound on the operator norm $\|A\|$ for the linear operator $A$=`self`. |
65 /// A bound on the operator norm $\|A\|$ for the linear operator $A$=`self`. |
66 /// This is not expected to be the norm, just any bound on it that can be |
66 /// This is not expected to be the norm, just any bound on it that can be |
169 impl<X : Clone + Space> Preadjointable<X,X> for IdOp<X> { |
169 impl<X : Clone + Space> Preadjointable<X,X> for IdOp<X> { |
170 type PreadjointCodomain=X; |
170 type PreadjointCodomain=X; |
171 type Preadjoint<'a> = IdOp<X> where X : 'a; |
171 type Preadjoint<'a> = IdOp<X> where X : 'a; |
172 |
172 |
173 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
173 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
|
174 } |
|
175 |
|
176 |
|
177 impl<S, T, E, X> Linear<X> for Composition<S, T, E> |
|
178 where |
|
179 X : Space, |
|
180 T : Linear<X>, |
|
181 S : Linear<T::Codomain> |
|
182 { } |
|
183 |
|
184 impl<F, S, T, E, X, Y> GEMV<F, X, Y> for Composition<S, T, E> |
|
185 where |
|
186 F : Num, |
|
187 X : Space, |
|
188 T : Linear<X>, |
|
189 S : GEMV<F, T::Codomain, Y>, |
|
190 { |
|
191 fn gemv<I : Instance<X>>(&self, y : &mut Y, α : F, x : I, β : F) { |
|
192 self.outer.gemv(y, α, self.inner.apply(x), β) |
|
193 } |
|
194 |
|
195 /// Computes `y = Ax`, where `A` is `Self` |
|
196 fn apply_mut<I : Instance<X>>(&self, y : &mut Y, x : I){ |
|
197 self.outer.apply_mut(y, self.inner.apply(x)) |
|
198 } |
|
199 |
|
200 /// Computes `y += Ax`, where `A` is `Self` |
|
201 fn apply_add<I : Instance<X>>(&self, y : &mut Y, x : I){ |
|
202 self.outer.apply_add(y, self.inner.apply(x)) |
|
203 } |
|
204 } |
|
205 |
|
206 impl<F, S, T, X, Z, Xexp, Yexp, Zexp> BoundedLinear<X, Xexp, Yexp, F> for Composition<S, T, Zexp> |
|
207 where |
|
208 F : Num, |
|
209 X : Space + Norm<F, Xexp>, |
|
210 Z : Space + Norm<F, Zexp>, |
|
211 Xexp : NormExponent, |
|
212 Yexp : NormExponent, |
|
213 Zexp : NormExponent, |
|
214 T : BoundedLinear<X, Xexp, Zexp, F, Codomain=Z>, |
|
215 S : BoundedLinear<Z, Zexp, Yexp, F>, |
|
216 { |
|
217 fn opnorm_bound(&self, xexp : Xexp, yexp : Yexp) -> F { |
|
218 let zexp = self.intermediate_norm_exponent; |
|
219 self.outer.opnorm_bound(zexp, yexp) * self.inner.opnorm_bound(xexp, zexp) |
|
220 } |
174 } |
221 } |
175 |
222 |
176 /// “Row operator” $(S, T)$; $(S, T)(x, y)=Sx + Ty$. |
223 /// “Row operator” $(S, T)$; $(S, T)(x, y)=Sx + Ty$. |
177 pub struct RowOp<S, T>(pub S, pub T); |
224 pub struct RowOp<S, T>(pub S, pub T); |
178 |
225 |
486 impl<F, A, B, S, T, ExpA, ExpB, ExpR> |
533 impl<F, A, B, S, T, ExpA, ExpB, ExpR> |
487 BoundedLinear<Pair<A, B>, PairNorm<ExpA, ExpB, $expj>, ExpR, F> |
534 BoundedLinear<Pair<A, B>, PairNorm<ExpA, ExpB, $expj>, ExpR, F> |
488 for RowOp<S, T> |
535 for RowOp<S, T> |
489 where |
536 where |
490 F : Float, |
537 F : Float, |
491 A : Space, |
538 A : Space + Norm<F, ExpA>, |
492 B : Space, |
539 B : Space + Norm<F, ExpB>, |
493 S : BoundedLinear<A, ExpA, ExpR, F>, |
540 S : BoundedLinear<A, ExpA, ExpR, F>, |
494 T : BoundedLinear<B, ExpB, ExpR, F>, |
541 T : BoundedLinear<B, ExpB, ExpR, F>, |
495 S::Codomain : Add<T::Codomain>, |
542 S::Codomain : Add<T::Codomain>, |
496 <S::Codomain as Add<T::Codomain>>::Output : Space, |
543 <S::Codomain as Add<T::Codomain>>::Output : Space, |
497 ExpA : NormExponent, |
544 ExpA : NormExponent, |
514 impl<F, A, S, T, ExpA, ExpS, ExpT> |
561 impl<F, A, S, T, ExpA, ExpS, ExpT> |
515 BoundedLinear<A, ExpA, PairNorm<ExpS, ExpT, $expj>, F> |
562 BoundedLinear<A, ExpA, PairNorm<ExpS, ExpT, $expj>, F> |
516 for ColOp<S, T> |
563 for ColOp<S, T> |
517 where |
564 where |
518 F : Float, |
565 F : Float, |
519 A : Space, |
566 A : Space + Norm<F, ExpA>, |
520 S : BoundedLinear<A, ExpA, ExpS, F>, |
567 S : BoundedLinear<A, ExpA, ExpS, F>, |
521 T : BoundedLinear<A, ExpA, ExpT, F>, |
568 T : BoundedLinear<A, ExpA, ExpT, F>, |
522 ExpA : NormExponent, |
569 ExpA : NormExponent, |
523 ExpS : NormExponent, |
570 ExpS : NormExponent, |
524 ExpT : NormExponent, |
571 ExpT : NormExponent, |