src/direct_product.rs

changeset 94
1f19c6bbf07b
parent 64
4f6ca107ccb1
--- a/src/direct_product.rs	Tue Apr 08 13:30:12 2025 -0500
+++ b/src/direct_product.rs	Sun Apr 27 20:29:43 2025 -0500
@@ -5,33 +5,38 @@
 operations on references.
 */
 
-use core::ops::{Mul,MulAssign,Div,DivAssign,Add,AddAssign,Sub,SubAssign,Neg};
-use std::clone::Clone;
-use serde::{Serialize, Deserialize};
-use crate::types::{Num, Float};
-use crate::{maybe_lifetime, maybe_ref};
 use crate::euclidean::Euclidean;
-use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow};
-use crate::mapping::Space;
+use crate::instance::{Decomposition, DecompositionMut, Instance, InstanceMut, MyCow};
 use crate::linops::AXPY;
 use crate::loc::Loc;
-use crate::norms::{Norm, PairNorm, NormExponent, Normed, HasDual, L2};
+use crate::mapping::Space;
+use crate::norms::{HasDual, Norm, NormExponent, Normed, PairNorm, L2};
+use crate::types::{Float, Num};
+use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
+use serde::{Deserialize, Serialize};
+use std::clone::Clone;
 
-#[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)]
-pub struct Pair<A, B> (pub A, pub B);
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
+pub struct Pair<A, B>(pub A, pub B);
 
-impl<A, B> Pair<A,B> {
-    pub fn new(a : A, b : B) -> Pair<A,B> { Pair(a, b) }
+impl<A, B> Pair<A, B> {
+    pub fn new(a: A, b: B) -> Pair<A, B> {
+        Pair(a, b)
+    }
 }
 
-impl<A, B> From<(A,B)> for Pair<A,B> {
+impl<A, B> From<(A, B)> for Pair<A, B> {
     #[inline]
-    fn from((a, b) : (A, B)) -> Pair<A,B> { Pair(a, b) }
+    fn from((a, b): (A, B)) -> Pair<A, B> {
+        Pair(a, b)
+    }
 }
 
-impl<A, B> From<Pair<A,B>> for (A,B) {
+impl<A, B> From<Pair<A, B>> for (A, B) {
     #[inline]
-    fn from(Pair(a, b) : Pair<A, B>) -> (A,B) { (a, b) }
+    fn from(Pair(a, b): Pair<A, B>) -> (A, B) {
+        (a, b)
+    }
 }
 
 macro_rules! impl_binop {
@@ -152,16 +157,18 @@
 
 macro_rules! impl_scalar_assignop {
     (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
-        impl<'r> $trait<$field>
-        for Pair<$a, $b>
-        where $a: $trait<$field>, $b: $trait<$field> {
+        impl<'r> $trait<$field> for Pair<$a, $b>
+        where
+            $a: $trait<$field>,
+            $b: $trait<$field>,
+        {
             #[inline]
-            fn $fn(&mut self, a : $field) -> () {
+            fn $fn(&mut self, a: $field) -> () {
                 self.0.$fn(a);
                 self.1.$fn(a);
             }
         }
-    }
+    };
 }
 
 macro_rules! impl_unaryop {
@@ -241,24 +248,28 @@
 
 impl<A, B, F> Euclidean<F> for Pair<A, B>
 where
-    A : Euclidean<F>,
-    B : Euclidean<F>,
-    F : Float,
-    PairOutput<F, A, B> : Euclidean<F>,
-    Self : Sized
-          + Mul<F, Output=PairOutput<F, A, B>> + MulAssign<F>
-          + Div<F, Output=PairOutput<F, A, B>> + DivAssign<F>
-          + Add<Self, Output=PairOutput<F, A, B>>
-          + Sub<Self, Output=PairOutput<F, A, B>>
-          + for<'b> Add<&'b Self, Output=PairOutput<F, A, B>>
-          + for<'b> Sub<&'b Self, Output=PairOutput<F, A, B>>
-          + AddAssign<Self> + for<'b> AddAssign<&'b Self>
-          + SubAssign<Self> + for<'b> SubAssign<&'b Self>
-          + Neg<Output=PairOutput<F, A, B>>
+    A: Euclidean<F>,
+    B: Euclidean<F>,
+    F: Float,
+    PairOutput<F, A, B>: Euclidean<F>,
+    Self: Sized
+        + Mul<F, Output = PairOutput<F, A, B>>
+        + MulAssign<F>
+        + Div<F, Output = PairOutput<F, A, B>>
+        + DivAssign<F>
+        + Add<Self, Output = PairOutput<F, A, B>>
+        + Sub<Self, Output = PairOutput<F, A, B>>
+        + for<'b> Add<&'b Self, Output = PairOutput<F, A, B>>
+        + for<'b> Sub<&'b Self, Output = PairOutput<F, A, B>>
+        + AddAssign<Self>
+        + for<'b> AddAssign<&'b Self>
+        + SubAssign<Self>
+        + for<'b> SubAssign<&'b Self>
+        + Neg<Output = PairOutput<F, A, B>>,
 {
     type Output = PairOutput<F, A, B>;
 
-    fn dot<I : Instance<Self>>(&self, other : I) -> F {
+    fn dot<I: Instance<Self>>(&self, other: I) -> F {
         let Pair(u, v) = other.decompose();
         self.0.dot(u) + self.1.dot(v)
     }
@@ -267,7 +278,7 @@
         self.0.norm2_squared() + self.1.norm2_squared()
     }
 
-    fn dist2_squared<I : Instance<Self>>(&self, other : I) -> F {
+    fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
         let Pair(u, v) = other.decompose();
         self.0.dist2_squared(u) + self.1.dist2_squared(v)
     }
@@ -275,31 +286,30 @@
 
 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B>
 where
-    U : Space,
-    V : Space,
-    A : AXPY<F, U>,
-    B : AXPY<F, V>,
-    F : Num,
-    Self : MulAssign<F>,
-    Pair<A, B> :  MulAssign<F>,
-    Pair<A::Owned, B::Owned> : AXPY<F, Pair<U, V>>,
+    U: Space,
+    V: Space,
+    A: AXPY<F, U>,
+    B: AXPY<F, V>,
+    F: Num,
+    Self: MulAssign<F>,
+    Pair<A, B>: MulAssign<F>,
+    Pair<A::Owned, B::Owned>: AXPY<F, Pair<U, V>>,
 {
-
     type Owned = Pair<A::Owned, B::Owned>;
 
-    fn axpy<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I, β : F) {
+    fn axpy<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I, β: F) {
         let Pair(u, v) = x.decompose();
         self.0.axpy(α, u, β);
         self.1.axpy(α, v, β);
     }
 
-    fn copy_from<I : Instance<Pair<U,V>>>(&mut self, x : I) {
+    fn copy_from<I: Instance<Pair<U, V>>>(&mut self, x: I) {
         let Pair(u, v) = x.decompose();
         self.0.copy_from(u);
         self.1.copy_from(v);
     }
 
-    fn scale_from<I : Instance<Pair<U,V>>>(&mut self, α : F, x : I) {
+    fn scale_from<I: Instance<Pair<U, V>>>(&mut self, α: F, x: I) {
         let Pair(u, v) = x.decompose();
         self.0.scale_from(α, u);
         self.1.scale_from(α, v);
@@ -321,52 +331,64 @@
 #[derive(Copy, Clone, Debug)]
 pub struct PairDecomposition<D, Q>(D, Q);
 
-impl<A : Space, B : Space> Space for Pair<A, B> {
+impl<A: Space, B: Space> Space for Pair<A, B> {
     type Decomp = PairDecomposition<A::Decomp, B::Decomp>;
 }
 
-impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D,Q>
+impl<A, B, D, Q> Decomposition<Pair<A, B>> for PairDecomposition<D, Q>
 where
-    A : Space,
-    B : Space,
-    D : Decomposition<A>,
-    Q : Decomposition<B>,
+    A: Space,
+    B: Space,
+    D: Decomposition<A>,
+    Q: Decomposition<B>,
 {
-    type Decomposition<'b> = Pair<D::Decomposition<'b>, Q::Decomposition<'b>> where Pair<A, B> : 'b;
-    type Reference<'b> = Pair<D::Reference<'b>, Q::Reference<'b>> where Pair<A, B> : 'b;
+    type Decomposition<'b>
+        = Pair<D::Decomposition<'b>, Q::Decomposition<'b>>
+    where
+        Pair<A, B>: 'b;
+    type Reference<'b>
+        = Pair<D::Reference<'b>, Q::Reference<'b>>
+    where
+        Pair<A, B>: 'b;
 
     #[inline]
-    fn lift<'b>(Pair(u, v) : Self::Reference<'b>) -> Self::Decomposition<'b> {
+    fn lift<'b>(Pair(u, v): Self::Reference<'b>) -> Self::Decomposition<'b> {
         Pair(D::lift(u), Q::lift(v))
     }
 }
 
 impl<A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
 where
-    A : Space,
-    B : Space,
-    D : Decomposition<A>,
-    Q : Decomposition<B>,
-    U : Instance<A, D>,
-    V : Instance<B, Q>,
+    A: Space,
+    B: Space,
+    D: Decomposition<A>,
+    Q: Decomposition<B>,
+    U: Instance<A, D>,
+    V: Instance<B, Q>,
 {
     #[inline]
-    fn decompose<'b>(self)
-        -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
-    where Self : 'b, Pair<A, B> : 'b
+    fn decompose<'b>(
+        self,
+    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
+    where
+        Self: 'b,
+        Pair<A, B>: 'b,
     {
         Pair(self.0.decompose(), self.1.decompose())
     }
 
     #[inline]
-    fn ref_instance(&self)
-        -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_>
-    {
+    fn ref_instance(
+        &self,
+    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> {
         Pair(self.0.ref_instance(), self.1.ref_instance())
     }
 
     #[inline]
-    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b{
+    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>>
+    where
+        Self: 'b,
+    {
         MyCow::Owned(Pair(self.0.own(), self.1.own()))
     }
 
@@ -376,35 +398,43 @@
     }
 }
 
-
 impl<'a, A, B, U, V, D, Q> Instance<Pair<A, B>, PairDecomposition<D, Q>> for &'a Pair<U, V>
 where
-    A : Space,
-    B : Space,
-    D : Decomposition<A>,
-    Q : Decomposition<B>,
-    U : Instance<A, D>,
-    V : Instance<B, Q>,
-    &'a U : Instance<A, D>,
-    &'a V : Instance<B, Q>,
+    A: Space,
+    B: Space,
+    D: Decomposition<A>,
+    Q: Decomposition<B>,
+    U: Instance<A, D>,
+    V: Instance<B, Q>,
+    &'a U: Instance<A, D>,
+    &'a V: Instance<B, Q>,
 {
     #[inline]
-    fn decompose<'b>(self)
-        -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
-    where Self : 'b, Pair<A, B> : 'b
+    fn decompose<'b>(
+        self,
+    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Decomposition<'b>
+    where
+        Self: 'b,
+        Pair<A, B>: 'b,
     {
-        Pair(D::lift(self.0.ref_instance()), Q::lift(self.1.ref_instance()))
+        Pair(
+            D::lift(self.0.ref_instance()),
+            Q::lift(self.1.ref_instance()),
+        )
     }
 
     #[inline]
-    fn ref_instance(&self)
-        -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_>
-    {
+    fn ref_instance(
+        &self,
+    ) -> <PairDecomposition<D, Q> as Decomposition<Pair<A, B>>>::Reference<'_> {
         Pair(self.0.ref_instance(), self.1.ref_instance())
     }
 
     #[inline]
-    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>> where Self : 'b {
+    fn cow<'b>(self) -> MyCow<'b, Pair<A, B>>
+    where
+        Self: 'b,
+    {
         MyCow::Owned(self.own())
     }
 
@@ -413,75 +443,74 @@
         let Pair(ref u, ref v) = self;
         Pair(u.own(), v.own())
     }
-
 }
 
-impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D,Q>
+impl<A, B, D, Q> DecompositionMut<Pair<A, B>> for PairDecomposition<D, Q>
 where
-    A : Space,
-    B : Space,
-    D : DecompositionMut<A>,
-    Q : DecompositionMut<B>,
+    A: Space,
+    B: Space,
+    D: DecompositionMut<A>,
+    Q: DecompositionMut<B>,
 {
-    type ReferenceMut<'b> = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>> where Pair<A, B> : 'b;
+    type ReferenceMut<'b>
+        = Pair<D::ReferenceMut<'b>, Q::ReferenceMut<'b>>
+    where
+        Pair<A, B>: 'b;
 }
 
 impl<A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for Pair<U, V>
 where
-    A : Space,
-    B : Space,
-    D : DecompositionMut<A>,
-    Q : DecompositionMut<B>,
-    U : InstanceMut<A, D>,
-    V : InstanceMut<B, Q>,
+    A: Space,
+    B: Space,
+    D: DecompositionMut<A>,
+    Q: DecompositionMut<B>,
+    U: InstanceMut<A, D>,
+    V: InstanceMut<B, Q>,
 {
     #[inline]
-    fn ref_instance_mut(&mut self)
-        -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_>
-    {
+    fn ref_instance_mut(
+        &mut self,
+    ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> {
         Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut())
     }
 }
 
 impl<'a, A, B, U, V, D, Q> InstanceMut<Pair<A, B>, PairDecomposition<D, Q>> for &'a mut Pair<U, V>
 where
-    A : Space,
-    B : Space,
-    D : DecompositionMut<A>,
-    Q : DecompositionMut<B>,
-    U : InstanceMut<A, D>,
-    V : InstanceMut<B, Q>,
+    A: Space,
+    B: Space,
+    D: DecompositionMut<A>,
+    Q: DecompositionMut<B>,
+    U: InstanceMut<A, D>,
+    V: InstanceMut<B, Q>,
 {
     #[inline]
-    fn ref_instance_mut(&mut self)
-        -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_>
-    {
+    fn ref_instance_mut(
+        &mut self,
+    ) -> <PairDecomposition<D, Q> as DecompositionMut<Pair<A, B>>>::ReferenceMut<'_> {
         Pair(self.0.ref_instance_mut(), self.1.ref_instance_mut())
     }
 }
 
-
-impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>>
-for Pair<A,B>
+impl<F, A, B, ExpA, ExpB, ExpJ> Norm<F, PairNorm<ExpA, ExpB, ExpJ>> for Pair<A, B>
 where
-    F : Num,
-    ExpA : NormExponent,
-    ExpB : NormExponent,
-    ExpJ : NormExponent,
-    A : Norm<F, ExpA>,
-    B : Norm<F, ExpB>,
-    Loc<F, 2> : Norm<F, ExpJ>,
+    F: Num,
+    ExpA: NormExponent,
+    ExpB: NormExponent,
+    ExpJ: NormExponent,
+    A: Norm<F, ExpA>,
+    B: Norm<F, ExpB>,
+    Loc<F, 2>: Norm<F, ExpJ>,
 {
-    fn norm(&self, PairNorm(expa, expb, expj) : PairNorm<ExpA, ExpB, ExpJ>) -> F {
+    fn norm(&self, PairNorm(expa, expb, expj): PairNorm<ExpA, ExpB, ExpJ>) -> F {
         Loc([self.0.norm(expa), self.1.norm(expb)]).norm(expj)
     }
 }
 
-
-impl<F : Float, A, B> Normed<F> for Pair<A,B>
+impl<F: Float, A, B> Normed<F> for Pair<A, B>
 where
-    A : Normed<F>,
-    B : Normed<F>,
+    A: Normed<F>,
+    B: Normed<F>,
 {
     type NormExp = PairNorm<A::NormExp, B::NormExp, L2>;
 
@@ -496,11 +525,10 @@
     }
 }
 
-impl<F : Float, A, B> HasDual<F> for Pair<A,B>
+impl<F: Float, A, B> HasDual<F> for Pair<A, B>
 where
-    A : HasDual<F>,
-    B : HasDual<F>,
-
+    A: HasDual<F>,
+    B: HasDual<F>,
 {
     type DualSpace = Pair<A::DualSpace, B::DualSpace>;
 }

mercurial