src/direct_product.rs

changeset 94
1f19c6bbf07b
parent 64
4f6ca107ccb1
equal deleted inserted replaced
93:123f7f38e161 94:1f19c6bbf07b
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;
150 }; 155 };
151 } 156 }
152 157
153 macro_rules! impl_scalar_assignop { 158 macro_rules! impl_scalar_assignop {
154 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { 159 (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
155 impl<'r> $trait<$field> 160 impl<'r> $trait<$field> for Pair<$a, $b>
156 for Pair<$a, $b> 161 where
157 where $a: $trait<$field>, $b: $trait<$field> { 162 $a: $trait<$field>,
163 $b: $trait<$field>,
164 {
158 #[inline] 165 #[inline]
159 fn $fn(&mut self, a : $field) -> () { 166 fn $fn(&mut self, a: $field) -> () {
160 self.0.$fn(a); 167 self.0.$fn(a);
161 self.1.$fn(a); 168 self.1.$fn(a);
162 } 169 }
163 } 170 }
164 } 171 };
165 } 172 }
166 173
167 macro_rules! impl_unaryop { 174 macro_rules! impl_unaryop {
168 (($a : ty, $b : ty), $trait:ident, $fn:ident, $refl:ident) => { 175 (($a : ty, $b : ty), $trait:ident, $fn:ident, $refl:ident) => {
169 impl_unaryop!(@doit: $trait, $fn; 176 impl_unaryop!(@doit: $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 {
494 fn is_zero(&self) -> bool { 523 fn is_zero(&self) -> bool {
495 self.0.is_zero() && self.1.is_zero() 524 self.0.is_zero() && self.1.is_zero()
496 } 525 }
497 } 526 }
498 527
499 impl<F : Float, A, B> HasDual<F> for Pair<A,B> 528 impl<F: Float, A, B> HasDual<F> for Pair<A, B>
500 where 529 where
501 A : HasDual<F>, 530 A: HasDual<F>,
502 B : HasDual<F>, 531 B: HasDual<F>,
503
504 { 532 {
505 type DualSpace = Pair<A::DualSpace, B::DualSpace>; 533 type DualSpace = Pair<A::DualSpace, B::DualSpace>;
506 } 534 }

mercurial