| 97 /// For an operator $A$ this is an operator $A\_\*$ |
100 /// For an operator $A$ this is an operator $A\_\*$ |
| 98 /// such that its adjoint $(A\_\*)^\*=A$. The space `X` is the domain of the `Self` |
101 /// such that its adjoint $(A\_\*)^\*=A$. The space `X` is the domain of the `Self` |
| 99 /// operator. The space `Ypre` is the predual of its codomain, and should be the |
102 /// operator. The space `Ypre` is the predual of its codomain, and should be the |
| 100 /// domain of the adjointed operator. `Self::Preadjoint` should be |
103 /// domain of the adjointed operator. `Self::Preadjoint` should be |
| 101 /// [`Adjointable`]`<'a,Ypre,X>`. |
104 /// [`Adjointable`]`<'a,Ypre,X>`. |
| 102 |
105 /// |
| 103 pub trait Preadjointable<X : Space, Ypre : Space> : Linear<X> { |
106 /// We do not set further restrictions on the spacds, to allow preadjointing when `X` |
| |
107 /// is on the dual space of `Ypre`, but a subset of it. |
| |
108 pub trait Preadjointable<X : Space, Ypre : Space> : Linear<X> |
| |
109 //where |
| |
110 // Ypre : HasDual<F, DualSpace=Self::Codomain>, |
| |
111 { |
| 104 type PreadjointCodomain : Space; |
112 type PreadjointCodomain : Space; |
| 105 type Preadjoint<'a> : Adjointable< |
113 type Preadjoint<'a> : Linear<Ypre, Codomain=Self::PreadjointCodomain> where Self : 'a; |
| 106 Ypre, X, AdjointCodomain=Self::Codomain, Codomain=Self::PreadjointCodomain |
|
| 107 > where Self : 'a; |
|
| 108 |
114 |
| 109 /// Form the adjoint operator of `self`. |
115 /// Form the adjoint operator of `self`. |
| 110 fn preadjoint(&self) -> Self::Preadjoint<'_>; |
116 fn preadjoint(&self) -> Self::Preadjoint<'_>; |
| 111 } |
117 } |
| 112 |
118 |
| 113 /// Adjointable operators $A: X → Y$ between reflexive spaces $X$ and $Y$. |
|
| 114 pub trait SimplyAdjointable<X : Space> : Adjointable<X,<Self as Mapping<X>>::Codomain> {} |
|
| 115 impl<'a,X : Space, T> SimplyAdjointable<X> for T |
|
| 116 where T : Adjointable<X,<Self as Mapping<X>>::Codomain> {} |
|
| 117 |
119 |
| 118 /// The identity operator |
120 /// The identity operator |
| 119 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
121 #[derive(Clone,Copy,Debug,Serialize,Eq,PartialEq)] |
| 120 pub struct IdOp<X> (PhantomData<X>); |
122 pub struct IdOp<X> (PhantomData<X>); |
| 121 |
123 |
| 157 E : NormExponent |
159 E : NormExponent |
| 158 { |
160 { |
| 159 fn opnorm_bound(&self, _xexp : E, _codexp : E) -> F { F::ONE } |
161 fn opnorm_bound(&self, _xexp : E, _codexp : E) -> F { F::ONE } |
| 160 } |
162 } |
| 161 |
163 |
| 162 impl<X : Clone + Space> Adjointable<X,X> for IdOp<X> { |
164 impl<X : Clone + HasDual<F, DualSpace=X>, F : Float> Adjointable<X, F> for IdOp<X> { |
| 163 type AdjointCodomain=X; |
165 type AdjointCodomain = X; |
| 164 type Adjoint<'a> = IdOp<X> where X : 'a; |
166 type Adjoint<'a> = IdOp<X::DualSpace> where X : 'a; |
| 165 |
167 |
| 166 fn adjoint(&self) -> Self::Adjoint<'_> { IdOp::new() } |
168 fn adjoint(&self) -> Self::Adjoint<'_> { IdOp::new() } |
| 167 } |
169 } |
| 168 |
170 |
| 169 impl<X : Clone + Space> Preadjointable<X,X> for IdOp<X> { |
171 impl<X : Clone + Space> Preadjointable<X, X> for IdOp<X> { |
| 170 type PreadjointCodomain=X; |
172 type PreadjointCodomain = X; |
| 171 type Preadjoint<'a> = IdOp<X> where X : 'a; |
173 type Preadjoint<'a> = IdOp<X> where X : 'a; |
| 172 |
174 |
| 173 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
175 fn preadjoint(&self) -> Self::Preadjoint<'_> { IdOp::new() } |
| 174 } |
176 } |
| 175 |
177 |
| 330 self.1.apply_add(&mut y.1, x); |
332 self.1.apply_add(&mut y.1, x); |
| 331 } |
333 } |
| 332 } |
334 } |
| 333 |
335 |
| 334 |
336 |
| 335 impl<A, B, Yʹ, S, T> Adjointable<Pair<A,B>, Yʹ> for RowOp<S, T> |
337 impl<F, A, B, Yʹ, S, T> Adjointable<Pair<A, B>, F> for RowOp<S, T> |
| 336 where |
338 where |
| 337 A : Space, |
339 F : Float, |
| 338 B : Space, |
340 A : HasDual<F>, |
| |
341 B : HasDual<F>, |
| |
342 S : Adjointable<A, F>, |
| |
343 T : Adjointable<B, F>, |
| 339 Yʹ : Space, |
344 Yʹ : Space, |
| 340 S : Adjointable<A, Yʹ>, |
345 S :: Codomain : HasDual<F, DualSpace=Yʹ>, |
| 341 T : Adjointable<B, Yʹ>, |
346 T :: Codomain : HasDual<F, DualSpace=Yʹ>, |
| 342 Self : Linear<Pair<A, B>>, |
347 S::Codomain : Add<T::Codomain>, |
| |
348 <S::Codomain as Add<T::Codomain>>::Output : HasDual<F, DualSpace=Yʹ>, |
| |
349 Self::Codomain : HasDual<F, DualSpace=Yʹ>, |
| |
350 //Self : Linear<Pair<A, B>>, |
| 343 // for<'a> ColOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< |
351 // for<'a> ColOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< |
| 344 // Yʹ, |
352 // Yʹ, |
| 345 // Codomain=Pair<S::AdjointCodomain, T::AdjointCodomain> |
353 // //Codomain=Pair<S::AdjointCodomain, T::AdjointCodomain> |
| 346 // >, |
354 // >, |
| 347 { |
355 { |
| 348 type AdjointCodomain = Pair<S::AdjointCodomain, T::AdjointCodomain>; |
356 type AdjointCodomain = Pair<S::AdjointCodomain, T::AdjointCodomain>; |
| 349 type Adjoint<'a> = ColOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
357 type Adjoint<'a> = ColOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
| 350 |
358 |
| 358 A : Space, |
366 A : Space, |
| 359 B : Space, |
367 B : Space, |
| 360 Yʹ : Space, |
368 Yʹ : Space, |
| 361 S : Preadjointable<A, Yʹ>, |
369 S : Preadjointable<A, Yʹ>, |
| 362 T : Preadjointable<B, Yʹ>, |
370 T : Preadjointable<B, Yʹ>, |
| 363 Self : Linear<Pair<A, B>>, |
371 S::Codomain : Add<T::Codomain>, |
| 364 for<'a> ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< |
372 <S::Codomain as Add<T::Codomain>>::Output : Space, |
| 365 Yʹ, Pair<A,B>, |
373 //Self : Linear<Pair<A, B>, Codomain=Y>, |
| 366 Codomain=Pair<S::PreadjointCodomain, T::PreadjointCodomain>, |
374 //for<'a> ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable<Yʹ, F>, |
| 367 AdjointCodomain = Self::Codomain, |
|
| 368 >, |
|
| 369 { |
375 { |
| 370 type PreadjointCodomain = Pair<S::PreadjointCodomain, T::PreadjointCodomain>; |
376 type PreadjointCodomain = Pair<S::PreadjointCodomain, T::PreadjointCodomain>; |
| 371 type Preadjoint<'a> = ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
377 type Preadjoint<'a> = ColOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
| 372 |
378 |
| 373 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
379 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
| 374 ColOp(self.0.preadjoint(), self.1.preadjoint()) |
380 ColOp(self.0.preadjoint(), self.1.preadjoint()) |
| 375 } |
381 } |
| 376 } |
382 } |
| 377 |
383 |
| 378 |
384 |
| 379 impl<A, Xʹ, Yʹ, R, S, T> Adjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> |
385 impl<F, A, Aʹ, S, T> Adjointable<A, F> for ColOp<S, T> |
| 380 where |
386 where |
| 381 A : Space, |
387 F : Float, |
| |
388 A : HasDual<F>, |
| |
389 S : Adjointable<A, F>, |
| |
390 T : Adjointable<A, F>, |
| |
391 T::Codomain : HasDual<F>, |
| |
392 S::Codomain : HasDual<F>, |
| |
393 Aʹ : Space + Instance<A::DualSpace>, |
| |
394 <S as Adjointable<A, F>>::AdjointCodomain : Add<<T as Adjointable<A, F>>::AdjointCodomain, Output=Aʹ>, |
| |
395 // for<'a> RowOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< |
| |
396 // Pair<<T::Codomain as HasDual<F>>::DualSpace, <S::Codomain as HasDual<F>>::DualSpace>, |
| |
397 // Codomain=Aʹ |
| |
398 // >, |
| |
399 { |
| |
400 type AdjointCodomain = Aʹ; |
| |
401 type Adjoint<'a> = RowOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
| |
402 |
| |
403 fn adjoint(&self) -> Self::Adjoint<'_> { |
| |
404 RowOp(self.0.adjoint(), self.1.adjoint()) |
| |
405 } |
| |
406 } |
| |
407 |
| |
408 impl<A, Aʹ, Xʹ, Yʹ, S, T> Preadjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> |
| |
409 where |
| |
410 A : Space, |
| |
411 Aʹ : Space, |
| 382 Xʹ : Space, |
412 Xʹ : Space, |
| 383 Yʹ : Space, |
413 Yʹ : Space, |
| 384 R : Space + ClosedAdd, |
414 S : Preadjointable<A, Xʹ, PreadjointCodomain=Aʹ>, |
| 385 S : Adjointable<A, Xʹ, AdjointCodomain = R>, |
415 T : Preadjointable<A, Yʹ, PreadjointCodomain=Aʹ>, |
| 386 T : Adjointable<A, Yʹ, AdjointCodomain = R>, |
416 Aʹ : ClosedAdd, |
| 387 Self : Linear<A>, |
417 //for<'a> RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable<Pair<Xʹ,Yʹ>, F>, |
| 388 // for<'a> RowOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< |
418 { |
| 389 // Pair<Xʹ,Yʹ>, |
419 type PreadjointCodomain = Aʹ; |
| 390 // Codomain=R, |
|
| 391 // >, |
|
| 392 { |
|
| 393 type AdjointCodomain = R; |
|
| 394 type Adjoint<'a> = RowOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
|
| 395 |
|
| 396 fn adjoint(&self) -> Self::Adjoint<'_> { |
|
| 397 RowOp(self.0.adjoint(), self.1.adjoint()) |
|
| 398 } |
|
| 399 } |
|
| 400 |
|
| 401 impl<A, Xʹ, Yʹ, R, S, T> Preadjointable<A,Pair<Xʹ,Yʹ>> for ColOp<S, T> |
|
| 402 where |
|
| 403 A : Space, |
|
| 404 Xʹ : Space, |
|
| 405 Yʹ : Space, |
|
| 406 R : Space + ClosedAdd, |
|
| 407 S : Preadjointable<A, Xʹ, PreadjointCodomain = R>, |
|
| 408 T : Preadjointable<A, Yʹ, PreadjointCodomain = R>, |
|
| 409 Self : Linear<A>, |
|
| 410 for<'a> RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< |
|
| 411 Pair<Xʹ,Yʹ>, A, |
|
| 412 Codomain = R, |
|
| 413 AdjointCodomain = Self::Codomain, |
|
| 414 >, |
|
| 415 { |
|
| 416 type PreadjointCodomain = R; |
|
| 417 type Preadjoint<'a> = RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
420 type Preadjoint<'a> = RowOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
| 418 |
421 |
| 419 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
422 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
| 420 RowOp(self.0.preadjoint(), self.1.preadjoint()) |
423 RowOp(self.0.preadjoint(), self.1.preadjoint()) |
| 421 } |
424 } |
| 476 self.0.apply_add(&mut y.0, u); |
479 self.0.apply_add(&mut y.0, u); |
| 477 self.1.apply_add(&mut y.1, v); |
480 self.1.apply_add(&mut y.1, v); |
| 478 } |
481 } |
| 479 } |
482 } |
| 480 |
483 |
| 481 impl<A, B, Xʹ, Yʹ, R, S, T> Adjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> |
484 impl<F, A, B, S, T> Adjointable<Pair<A,B>, F> for DiagOp<S, T> |
| 482 where |
485 where |
| 483 A : Space, |
486 F: Float, |
| 484 B : Space, |
487 A : HasDual<F>, |
| 485 Xʹ: Space, |
488 B : HasDual<F>, |
| 486 Yʹ : Space, |
489 S : Adjointable<A, F>, |
| 487 R : Space, |
490 T : Adjointable<B, F>, |
| 488 S : Adjointable<A, Xʹ>, |
491 T::Codomain : HasDual<F>, |
| 489 T : Adjointable<B, Yʹ>, |
492 S::Codomain : HasDual<F>, |
| 490 Self : Linear<Pair<A, B>>, |
493 { |
| 491 for<'a> DiagOp<S::Adjoint<'a>, T::Adjoint<'a>> : Linear< |
494 type AdjointCodomain = Pair<S::AdjointCodomain, T::AdjointCodomain>; |
| 492 Pair<Xʹ,Yʹ>, Codomain=R, |
|
| 493 >, |
|
| 494 { |
|
| 495 type AdjointCodomain = R; |
|
| 496 type Adjoint<'a> = DiagOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
495 type Adjoint<'a> = DiagOp<S::Adjoint<'a>, T::Adjoint<'a>> where Self : 'a; |
| 497 |
496 |
| 498 fn adjoint(&self) -> Self::Adjoint<'_> { |
497 fn adjoint(&self) -> Self::Adjoint<'_> { |
| 499 DiagOp(self.0.adjoint(), self.1.adjoint()) |
498 DiagOp(self.0.adjoint(), self.1.adjoint()) |
| 500 } |
499 } |
| 501 } |
500 } |
| 502 |
501 |
| 503 impl<A, B, Xʹ, Yʹ, R, S, T> Preadjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> |
502 impl<A, B, Xʹ, Yʹ, S, T> Preadjointable<Pair<A,B>, Pair<Xʹ,Yʹ>> for DiagOp<S, T> |
| 504 where |
503 where |
| 505 A : Space, |
504 A : Space, |
| 506 B : Space, |
505 B : Space, |
| 507 Xʹ: Space, |
506 Xʹ : Space, |
| 508 Yʹ : Space, |
507 Yʹ : Space, |
| 509 R : Space, |
|
| 510 S : Preadjointable<A, Xʹ>, |
508 S : Preadjointable<A, Xʹ>, |
| 511 T : Preadjointable<B, Yʹ>, |
509 T : Preadjointable<B, Yʹ>, |
| 512 Self : Linear<Pair<A, B>>, |
510 { |
| 513 for<'a> DiagOp<S::Preadjoint<'a>, T::Preadjoint<'a>> : Adjointable< |
511 type PreadjointCodomain = Pair<S::PreadjointCodomain, T::PreadjointCodomain>; |
| 514 Pair<Xʹ,Yʹ>, Pair<A, B>, |
|
| 515 Codomain=R, |
|
| 516 AdjointCodomain = Self::Codomain, |
|
| 517 >, |
|
| 518 { |
|
| 519 type PreadjointCodomain = R; |
|
| 520 type Preadjoint<'a> = DiagOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
512 type Preadjoint<'a> = DiagOp<S::Preadjoint<'a>, T::Preadjoint<'a>> where Self : 'a; |
| 521 |
513 |
| 522 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
514 fn preadjoint(&self) -> Self::Preadjoint<'_> { |
| 523 DiagOp(self.0.preadjoint(), self.1.preadjoint()) |
515 DiagOp(self.0.preadjoint(), self.1.preadjoint()) |
| 524 } |
516 } |