src/direct_product.rs

branch
dev
changeset 151
402d717bb5c0
parent 150
c4e394a9c84c
child 152
dab30b331f49
child 155
45d03cf92c23
equal deleted inserted replaced
150:c4e394a9c84c 151:402d717bb5c0
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 crate::euclidean::Euclidean; 8 use crate::euclidean::Euclidean;
9 use crate::instance::{ 9 use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable};
10 ClosedSpace, Decomposition, DecompositionMut, Instance, InstanceMut, MyCow, Ownable,
11 };
12 use crate::linops::{VectorSpace, AXPY}; 10 use crate::linops::{VectorSpace, AXPY};
13 use crate::loc::Loc; 11 use crate::loc::Loc;
14 use crate::mapping::Space; 12 use crate::mapping::Space;
15 use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2}; 13 use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2};
16 use crate::types::{Float, Num}; 14 use crate::types::{Float, Num};
287 /// compiler overflows. 285 /// compiler overflows.
288 impl<A, B, F: Float> Euclidean<F> for Pair<A, B> 286 impl<A, B, F: Float> Euclidean<F> for Pair<A, B>
289 where 287 where
290 A: Euclidean<F>, 288 A: Euclidean<F>,
291 B: Euclidean<F>, 289 B: Euclidean<F>,
292 //Pair<A, B>: Euclidean<F>, 290 // //Pair<A, B>: Euclidean<F>,
293 Self: Sized 291 // Self: Sized
294 + Mul<F, Output = <Self as VectorSpace>::Owned> 292 // + Mul<F, Output = Self::OwnedEuclidean>
295 + MulAssign<F> 293 // + MulAssign<F>
296 + Div<F, Output = <Self as VectorSpace>::Owned> 294 // + Div<F, Output = Self::OwnedEuclidean>
297 + DivAssign<F> 295 // + DivAssign<F>
298 + Add<Self, Output = <Self as VectorSpace>::Owned> 296 // + Add<Self, Output = Self::OwnedEuclidean>
299 + Sub<Self, Output = <Self as VectorSpace>::Owned> 297 // + Sub<Self, Output = Self::OwnedEuclidean>
300 + for<'b> Add<&'b Self, Output = <Self as VectorSpace>::Owned> 298 // + for<'b> Add<&'b Self, Output = Self::OwnedEuclidean>
301 + for<'b> Sub<&'b Self, Output = <Self as VectorSpace>::Owned> 299 // + for<'b> Sub<&'b Self, Output = Self::OwnedEuclidean>
302 + AddAssign<Self> 300 // + AddAssign<Self>
303 + for<'b> AddAssign<&'b Self> 301 // + for<'b> AddAssign<&'b Self>
304 + SubAssign<Self> 302 // + SubAssign<Self>
305 + for<'b> SubAssign<&'b Self> 303 // + for<'b> SubAssign<&'b Self>
306 + Neg<Output = <Self as VectorSpace>::Owned>, 304 // + Neg<Output = Self::OwnedEuclidean>,
307 { 305 {
306 type OwnedEuclidean = Pair<A::OwnedEuclidean, B::OwnedEuclidean>;
307
308 fn dot<I: Instance<Self>>(&self, other: I) -> F { 308 fn dot<I: Instance<Self>>(&self, other: I) -> F {
309 other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v)) 309 other.eval_decompose(|Pair(u, v)| self.0.dot(u) + self.1.dot(v))
310 } 310 }
311 311
312 fn norm2_squared(&self) -> F { 312 fn norm2_squared(&self) -> F {
316 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F { 316 fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
317 other.eval_decompose(|Pair(u, v)| self.0.dist2_squared(u) + self.1.dist2_squared(v)) 317 other.eval_decompose(|Pair(u, v)| self.0.dist2_squared(u) + self.1.dist2_squared(v))
318 } 318 }
319 } 319 }
320 320
321 impl<F, A, B, O, P> VectorSpace for Pair<A, B> 321 impl<F, A, B> VectorSpace for Pair<A, B>
322 where 322 where
323 A: VectorSpace<Field = F, Owned = O, OwnedVariant = O>, 323 A: VectorSpace<Field = F>,
324 B: VectorSpace<Field = F, Owned = P, OwnedVariant = P>, 324 B: VectorSpace<Field = F>,
325 O: ClosedSpace + AXPY<A, Field = F, Owned = O, OwnedVariant = O>,
326 P: ClosedSpace + AXPY<B, Field = F, Owned = P, OwnedVariant = P>,
327 F: Num, 325 F: Num,
328 { 326 {
329 type Field = F; 327 type Field = F;
330 type Owned = Pair<O, P>; 328 type Owned = Pair<A::Owned, B::Owned>;
331 329
332 /// Return a similar zero as `self`. 330 /// Return a similar zero as `self`.
333 fn similar_origin(&self) -> Self::Owned { 331 fn similar_origin(&self) -> Self::Owned {
334 Pair(self.0.similar_origin(), self.1.similar_origin()) 332 Pair(self.0.similar_origin(), self.1.similar_origin())
335 } 333 }
345 U: Space, 343 U: Space,
346 V: Space, 344 V: Space,
347 A: AXPY<U, Field = F>, 345 A: AXPY<U, Field = F>,
348 B: AXPY<V, Field = F>, 346 B: AXPY<V, Field = F>,
349 F: Num, 347 F: Num,
350 Self: MulAssign<F> + DivAssign<F>, 348 // Self: MulAssign<F> + DivAssign<F>,
351 Pair<A, B>: MulAssign<F> + DivAssign<F>, 349 // Pair<A, B>: MulAssign<F> + DivAssign<F>,
352 { 350 {
353 fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) { 351 fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) {
354 x.eval_decompose(|Pair(u, v)| { 352 x.eval_decompose(|Pair(u, v)| {
355 self.0.axpy(α, u, β); 353 self.0.axpy(α, u, β);
356 self.1.axpy(α, v, β); 354 self.1.axpy(α, v, β);
381 /// [`Decomposition`] for working with [`Pair`]s. 379 /// [`Decomposition`] for working with [`Pair`]s.
382 #[derive(Copy, Clone, Debug)] 380 #[derive(Copy, Clone, Debug)]
383 pub struct PairDecomposition<D, Q>(D, Q); 381 pub struct PairDecomposition<D, Q>(D, Q);
384 382
385 impl<A: Space, B: Space> Space for Pair<A, B> { 383 impl<A: Space, B: Space> Space for Pair<A, B> {
384 type OwnedSpace = Pair<A::OwnedSpace, B::OwnedSpace>;
386 type Decomp = PairDecomposition<A::Decomp, B::Decomp>; 385 type Decomp = PairDecomposition<A::Decomp, B::Decomp>;
387 } 386 }
388 387
389 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q> 388 impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q>
390 where 389 where

mercurial