3 |
3 |
4 TODO: This could be easily much more generic if `derive_more` could derive arithmetic |
4 TODO: This could be easily much more generic if `derive_more` could derive arithmetic |
5 operations on references. |
5 operations on references. |
6 */ |
6 */ |
7 |
7 |
8 use core::ops::{Mul,MulAssign,Div,DivAssign,Add,AddAssign,Sub,SubAssign,Neg}; |
|
9 use std::clone::Clone; |
|
10 use serde::{Serialize, Deserialize}; |
|
11 use crate::types::{Num, Float}; |
|
12 use crate::{maybe_lifetime, maybe_ref}; |
|
13 use crate::euclidean::Euclidean; |
8 use crate::euclidean::Euclidean; |
14 use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow}; |
9 use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow}; |
15 use crate::mapping::Space; |
|
16 use crate::linops::AXPY; |
10 use crate::linops::AXPY; |
17 use crate::loc::Loc; |
11 use crate::loc::Loc; |
18 use crate::norms::{Norm, PairNorm, NormExponent, Normed, HasDual, L2}; |
12 use crate::mapping::Space; |
19 |
13 use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2}; |
20 #[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)] |
14 use crate::types::{Float, Num}; |
21 pub struct Pair<A, B> (pub A, pub B); |
15 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; |
22 |
16 use serde::{Deserialize, Serialize}; |
23 impl<A, B> Pair<A,B> { |
17 use std::clone::Clone; |
24 pub fn new(a : A, b : B) -> Pair<A,B> { Pair(a, b) } |
18 |
25 } |
19 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] |
26 |
20 pub struct Pair<A, B>(pub A, pub B); |
27 impl<A, B> From<(A,B)> for Pair<A,B> { |
21 |
28 #[inline] |
22 impl<A, B> Pair<A, B> { |
29 fn from((a, b) : (A, B)) -> Pair<A,B> { Pair(a, b) } |
23 pub fn new(a: A, b: B) -> Pair<A, B> { |
30 } |
24 Pair(a, b) |
31 |
25 } |
32 impl<A, B> From<Pair<A,B>> for (A,B) { |
26 } |
33 #[inline] |
27 |
34 fn from(Pair(a, b) : Pair<A, B>) -> (A,B) { (a, b) } |
28 impl<A, B> From<(A, B)> for Pair<A, B> { |
|
29 #[inline] |
|
30 fn from((a, b): (A, B)) -> Pair<A, B> { |
|
31 Pair(a, b) |
|
32 } |
|
33 } |
|
34 |
|
35 impl<A, B> From<Pair<A, B>> for (A, B) { |
|
36 #[inline] |
|
37 fn from(Pair(a, b): Pair<A, B>) -> (A, B) { |
|
38 (a, b) |
|
39 } |
35 } |
40 } |
36 |
41 |
37 macro_rules! impl_binop { |
42 macro_rules! impl_binop { |
38 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refl:ident, $refr:ident) => { |
43 (($a : ty, $b : ty), $trait : ident, $fn : ident, $refl:ident, $refr:ident) => { |
39 impl_binop!(@doit: $a, $b, $trait, $fn; |
44 impl_binop!(@doit: $a, $b, $trait, $fn; |
239 |
246 |
240 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; |
247 type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>; |
241 |
248 |
242 impl<A, B, F> Euclidean<F> for Pair<A, B> |
249 impl<A, B, F> Euclidean<F> for Pair<A, B> |
243 where |
250 where |
244 A : Euclidean<F>, |
251 A: Euclidean<F>, |
245 B : Euclidean<F>, |
252 B: Euclidean<F>, |
246 F : Float, |
253 F: Float, |
247 PairOutput<F, A, B> : Euclidean<F>, |
254 PairOutput<F, A, B>: Euclidean<F>, |
248 Self : Sized |
255 Self: Sized |
249 + Mul<F, Output=PairOutput<F, A, B>> + MulAssign<F> |
256 + Mul<F, Output = PairOutput<F, A, B>> |
250 + Div<F, Output=PairOutput<F, A, B>> + DivAssign<F> |
257 + MulAssign<F> |
251 + Add<Self, Output=PairOutput<F, A, B>> |
258 + Div<F, Output = PairOutput<F, A, B>> |
252 + Sub<Self, Output=PairOutput<F, A, B>> |
259 + DivAssign<F> |
253 + for<'b> Add<&'b Self, Output=PairOutput<F, A, B>> |
260 + Add<Self, Output = PairOutput<F, A, B>> |
254 + for<'b> Sub<&'b Self, Output=PairOutput<F, A, B>> |
261 + Sub<Self, Output = PairOutput<F, A, B>> |
255 + AddAssign<Self> + for<'b> AddAssign<&'b Self> |
262 + for<'b> Add<&'b Self, Output = PairOutput<F, A, B>> |
256 + SubAssign<Self> + for<'b> SubAssign<&'b Self> |
263 + for<'b> Sub<&'b Self, Output = PairOutput<F, A, B>> |
257 + Neg<Output=PairOutput<F, A, B>> |
264 + AddAssign<Self> |
|
265 + for<'b> AddAssign<&'b Self> |
|
266 + SubAssign<Self> |
|
267 + for<'b> SubAssign<&'b Self> |
|
268 + Neg<Output = PairOutput<F, A, B>>, |
258 { |
269 { |
259 type Output = PairOutput<F, A, B>; |
270 type Output = PairOutput<F, A, B>; |
260 |
271 |
261 fn dot<I : Instance<Self>>(&self, other : I) -> F { |
272 fn dot<I: Instance<Self>>(&self, other: I) -> F { |
262 let Pair(u, v) = other.decompose(); |
273 let Pair(u, v) = other.decompose(); |
263 self.0.dot(u) + self.1.dot(v) |
274 self.0.dot(u) + self.1.dot(v) |
264 } |
275 } |
265 |
276 |
266 fn norm2_squared(&self) -> F { |
277 fn norm2_squared(&self) -> F { |
267 self.0.norm2_squared() + self.1.norm2_squared() |
278 self.0.norm2_squared() + self.1.norm2_squared() |
268 } |
279 } |
269 |
280 |
270 fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F { |
281 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { |
271 let Pair(u, v) = other.decompose(); |
282 let Pair(u, v) = other.decompose(); |
272 self.0.dist2_squared(u) + self.1.dist2_squared(v) |
283 self.0.dist2_squared(u) + self.1.dist2_squared(v) |
273 } |
284 } |
274 } |
285 } |
275 |
286 |
276 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> |
287 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B> |
277 where |
288 where |
278 U : Space, |
289 U: Space, |
279 V : Space, |
290 V: Space, |
280 A : AXPY<F, U>, |
291 A: AXPY<F, U>, |
281 B : AXPY<F, V>, |
292 B: AXPY<F, V>, |
282 F : Num, |
293 F: Num, |
283 Self : MulAssign<F>, |
294 Self: MulAssign<F>, |
284 Pair<A, B> : MulAssign<F>, |
295 Pair<A, B>: MulAssign<F>, |
285 Pair<A::Owned, B::Owned> : AXPY<F, Pair<U, V>>, |
296 Pair<A::Owned, B::Owned>: AXPY<F, Pair<U, V>>, |
286 { |
297 { |
287 |
|
288 type Owned = Pair<A::Owned, B::Owned>; |
298 type Owned = Pair<A::Owned, B::Owned>; |
289 |
299 |
290 fn axpy<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I, β : F) { |
300 fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { |
291 let Pair(u, v) = x.decompose(); |
301 let Pair(u, v) = x.decompose(); |
292 self.0.axpy(α, u, β); |
302 self.0.axpy(α, u, β); |
293 self.1.axpy(α, v, β); |
303 self.1.axpy(α, v, β); |
294 } |
304 } |
295 |
305 |
296 fn copy_from<I : Instance<Pair<U,V>>>(&mut self, x : I) { |
306 fn copy_from<I: Instance<Pair<U, V>>>(&mut self, x: I) { |
297 let Pair(u, v) = x.decompose(); |
307 let Pair(u, v) = x.decompose(); |
298 self.0.copy_from(u); |
308 self.0.copy_from(u); |
299 self.1.copy_from(v); |
309 self.1.copy_from(v); |
300 } |
310 } |
301 |
311 |
302 fn scale_from<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I) { |
312 fn scale_from<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I) { |
303 let Pair(u, v) = x.decompose(); |
313 let Pair(u, v) = x.decompose(); |
304 self.0.scale_from(α, u); |
314 self.0.scale_from(α, u); |
305 self.1.scale_from(α, v); |
315 self.1.scale_from(α, v); |
306 } |
316 } |
307 |
317 |
319 |
329 |
320 /// [`Decomposition`] for working with [`Pair`]s. |
330 /// [`Decomposition`] for working with [`Pair`]s. |
321 #[derive(Copy, Clone, Debug)] |
331 #[derive(Copy, Clone, Debug)] |
322 pub struct PairDecomposition<D, Q>(D, Q); |
332 pub struct PairDecomposition<D, Q>(D, Q); |
323 |
333 |
324 impl<A : Space, B : Space> Space for Pair<A, B> { |
334 impl<A: Space, B: Space> Space for Pair<A, B> { |
325 type Decomp = PairDecomposition<A::Decomp, B::Decomp>; |
335 type Decomp = PairDecomposition<A::Decomp, B::Decomp>; |
326 } |
336 } |
327 |
337 |
328 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D,Q> |
338 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q> |
329 where |
339 where |
330 A : Space, |
340 A: Space, |
331 B : Space, |
341 B: Space, |
332 D : Decomposition<A>, |
342 D: Decomposition<A>, |
333 Q : Decomposition<B>, |
343 Q: Decomposition<B>, |
334 { |
344 { |
335 type Decomposition<'b> = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> where Pair<A, B> : 'b; |
345 type Decomposition<'b> |
336 type Reference<'b> = Pair<D::Reference<'b>, Q::Reference<'b>> where Pair<A, B> : 'b; |
346 = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> |
337 |
347 where |
338 #[inline] |
348 Pair<A, B>: 'b; |
339 fn lift<'b>(Pair(u, v) : Self::Reference<'b>) -> Self::Decomposition<'b> { |
349 type Reference<'b> |
|
350 = Pair<D::Reference<'b>, Q::Reference<'b>> |
|
351 where |
|
352 Pair<A, B>: 'b; |
|
353 |
|
354 #[inline] |
|
355 fn lift<'b>(Pair(u, v): Self::Reference<'b>) -> Self::Decomposition<'b> { |
340 Pair(D::lift(u), Q::lift(v)) |
356 Pair(D::lift(u), Q::lift(v)) |
341 } |
357 } |
342 } |
358 } |
343 |
359 |
344 impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> |
360 impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> |
345 where |
361 where |
346 A : Space, |
362 A: Space, |
347 B : Space, |
363 B: Space, |
348 D : Decomposition<A>, |
364 D: Decomposition<A>, |
349 Q : Decomposition<B>, |
365 Q: Decomposition<B>, |
350 U : Instance<A, D>, |
366 U: Instance<A, D>, |
351 V : Instance<B, Q>, |
367 V: Instance<B, Q>, |
352 { |
368 { |
353 #[inline] |
369 #[inline] |
354 fn decompose<'b>(self) |
370 fn decompose<'b>( |
355 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> |
371 self, |
356 where Self : 'b, Pair<A, B> : 'b |
372 ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> |
|
373 where |
|
374 Self: 'b, |
|
375 Pair<A, B>: 'b, |
357 { |
376 { |
358 Pair(self.0.decompose(), self.1.decompose()) |
377 Pair(self.0.decompose(), self.1.decompose()) |
359 } |
378 } |
360 |
379 |
361 #[inline] |
380 #[inline] |
362 fn ref_instance(&self) |
381 fn ref_instance( |
363 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> |
382 &self, |
|
383 ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> { |
|
384 Pair(self.0.ref_instance(), self.1.ref_instance()) |
|
385 } |
|
386 |
|
387 #[inline] |
|
388 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> |
|
389 where |
|
390 Self: 'b, |
364 { |
391 { |
365 Pair(self.0.ref_instance(), self.1.ref_instance()) |
|
366 } |
|
367 |
|
368 #[inline] |
|
369 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b{ |
|
370 MyCow::Owned(Pair(self.0.own(), self.1.own())) |
392 MyCow::Owned(Pair(self.0.own(), self.1.own())) |
371 } |
393 } |
372 |
394 |
373 #[inline] |
395 #[inline] |
374 fn own(self) -> Pair<A, B> { |
396 fn own(self) -> Pair<A, B> { |
375 Pair(self.0.own(), self.1.own()) |
397 Pair(self.0.own(), self.1.own()) |
376 } |
398 } |
377 } |
399 } |
378 |
400 |
379 |
|
380 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V> |
401 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V> |
381 where |
402 where |
382 A : Space, |
403 A: Space, |
383 B : Space, |
404 B: Space, |
384 D : Decomposition<A>, |
405 D: Decomposition<A>, |
385 Q : Decomposition<B>, |
406 Q: Decomposition<B>, |
386 U : Instance<A, D>, |
407 U: Instance<A, D>, |
387 V : Instance<B, Q>, |
408 V: Instance<B, Q>, |
388 &'a U : Instance<A, D>, |
409 &'a U: Instance<A, D>, |
389 &'a V : Instance<B, Q>, |
410 &'a V: Instance<B, Q>, |
390 { |
411 { |
391 #[inline] |
412 #[inline] |
392 fn decompose<'b>(self) |
413 fn decompose<'b>( |
393 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> |
414 self, |
394 where Self : 'b, Pair<A, B> : 'b |
415 ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b> |
|
416 where |
|
417 Self: 'b, |
|
418 Pair<A, B>: 'b, |
395 { |
419 { |
396 Pair(D::lift(self.0.ref_instance()), Q::lift(self.1.ref_instance())) |
420 Pair( |
397 } |
421 D::lift(self.0.ref_instance()), |
398 |
422 Q::lift(self.1.ref_instance()), |
399 #[inline] |
423 ) |
400 fn ref_instance(&self) |
424 } |
401 -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> |
425 |
|
426 #[inline] |
|
427 fn ref_instance( |
|
428 &self, |
|
429 ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> { |
|
430 Pair(self.0.ref_instance(), self.1.ref_instance()) |
|
431 } |
|
432 |
|
433 #[inline] |
|
434 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> |
|
435 where |
|
436 Self: 'b, |
402 { |
437 { |
403 Pair(self.0.ref_instance(), self.1.ref_instance()) |
|
404 } |
|
405 |
|
406 #[inline] |
|
407 fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b { |
|
408 MyCow::Owned(self.own()) |
438 MyCow::Owned(self.own()) |
409 } |
439 } |
410 |
440 |
411 #[inline] |
441 #[inline] |
412 fn own(self) -> Pair<A, B> { |
442 fn own(self) -> Pair<A, B> { |
413 let Pair(ref u, ref v) = self; |
443 let Pair(ref u, ref v) = self; |
414 Pair(u.own(), v.own()) |
444 Pair(u.own(), v.own()) |
415 } |
445 } |
416 |
446 } |
417 } |
447 |
418 |
448 impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D, Q> |
419 impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D,Q> |
449 where |
420 where |
450 A: Space, |
421 A : Space, |
451 B: Space, |
422 B : Space, |
452 D: DecompositionMut<A>, |
423 D : DecompositionMut<A>, |
453 Q: DecompositionMut<B>, |
424 Q : DecompositionMut<B>, |
454 { |
425 { |
455 type ReferenceMut<'b> |
426 type ReferenceMut<'b> = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> where Pair<A, B> : 'b; |
456 = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> |
|
457 where |
|
458 Pair<A, B>: 'b; |
427 } |
459 } |
428 |
460 |
429 impl<A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> |
461 impl<A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V> |
430 where |
462 where |
431 A : Space, |
463 A: Space, |
432 B : Space, |
464 B: Space, |
433 D : DecompositionMut<A>, |
465 D: DecompositionMut<A>, |
434 Q : DecompositionMut<B>, |
466 Q: DecompositionMut<B>, |
435 U : InstanceMut<A, D>, |
467 U: InstanceMut<A, D>, |
436 V : InstanceMut<B, Q>, |
468 V: InstanceMut<B, Q>, |
437 { |
469 { |
438 #[inline] |
470 #[inline] |
439 fn ref_instance_mut(&mut self) |
471 fn ref_instance_mut( |
440 -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> |
472 &mut self, |
441 { |
473 ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> { |
442 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) |
474 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) |
443 } |
475 } |
444 } |
476 } |
445 |
477 |
446 impl<'a, A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for &'a mut Pair<U, V> |
478 impl<'a, A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for &'a mut Pair<U, V> |
447 where |
479 where |
448 A : Space, |
480 A: Space, |
449 B : Space, |
481 B: Space, |
450 D : DecompositionMut<A>, |
482 D: DecompositionMut<A>, |
451 Q : DecompositionMut<B>, |
483 Q: DecompositionMut<B>, |
452 U : InstanceMut<A, D>, |
484 U: InstanceMut<A, D>, |
453 V : InstanceMut<B, Q>, |
485 V: InstanceMut<B, Q>, |
454 { |
486 { |
455 #[inline] |
487 #[inline] |
456 fn ref_instance_mut(&mut self) |
488 fn ref_instance_mut( |
457 -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> |
489 &mut self, |
458 { |
490 ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> { |
459 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) |
491 Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut()) |
460 } |
492 } |
461 } |
493 } |
462 |
494 |
463 |
495 impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>> for Pair<A, B> |
464 impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>> |
496 where |
465 for Pair<A,B> |
497 F: Num, |
466 where |
498 ExpA: NormExponent, |
467 F : Num, |
499 ExpB: NormExponent, |
468 ExpA : NormExponent, |
500 ExpJ: NormExponent, |
469 ExpB : NormExponent, |
501 A: Norm<F, ExpA>, |
470 ExpJ : NormExponent, |
502 B: Norm<F, ExpB>, |
471 A : Norm<F, ExpA>, |
503 Loc<F, 2>: Norm<F, ExpJ>, |
472 B : Norm<F, ExpB>, |
504 { |
473 Loc<F, 2> : Norm<F, ExpJ>, |
505 fn norm(&self, PairNorm(expa, expb, expj): PairNorm<ExpA, ExpB, ExpJ>) -> F { |
474 { |
|
475 fn norm(&self, PairNorm(expa, expb, expj) : PairNorm<ExpA, ExpB, ExpJ>) -> F { |
|
476 Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj) |
506 Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj) |
477 } |
507 } |
478 } |
508 } |
479 |
509 |
480 |
510 impl<F: Float, A, B> Normed<F> for Pair<A, B> |
481 impl<F : Float, A, B> Normed<F> for Pair<A,B> |
511 where |
482 where |
512 A: Normed<F>, |
483 A : Normed<F>, |
513 B: Normed<F>, |
484 B : Normed<F>, |
|
485 { |
514 { |
486 type NormExp = PairNorm<A::NormExp, B::NormExp, L2>; |
515 type NormExp = PairNorm<A::NormExp, B::NormExp, L2>; |
487 |
516 |
488 #[inline] |
517 #[inline] |
489 fn norm_exponent(&self) -> Self::NormExp { |
518 fn norm_exponent(&self) -> Self::NormExp { |