diff -r 1a38447a89fa -r 9226980e45a7 src/direct_product.rs
--- a/src/direct_product.rs Sat Dec 14 09:31:27 2024 -0500
+++ b/src/direct_product.rs Tue Dec 31 08:30:02 2024 -0500
@@ -9,65 +9,81 @@
use std::clone::Clone;
use serde::{Serialize, Deserialize};
use crate::types::{Num, Float};
-use crate::{maybe_lifetime, maybe_ref, impl_vectorspace_ops};
+use crate::{maybe_lifetime, maybe_ref};
use crate::euclidean::{Dot, Euclidean};
+use crate::instance::{Instance, InstanceMut, Decomposition, DecompositionMut, MyCow};
+use crate::mapping::Space;
+use crate::linops::AXPY;
+use crate::loc::Loc;
+use crate::norms::{Norm, PairNorm, NormExponent};
-#[derive(Debug,Clone,PartialEq,Eq,Serialize,Deserialize)]
+#[derive(Debug,Clone,Copy,PartialEq,Eq,Serialize,Deserialize)]
pub struct Pair (pub A, pub B);
impl Pair {
- pub fn new(a : A, b : B) -> Pair { Pair{ 0 : a, 1 : b } }
+ pub fn new(a : A, b : B) -> Pair { Pair(a, b) }
}
impl From<(A,B)> for Pair {
#[inline]
- fn from((a, b) : (A, B)) -> Pair { Pair{ 0 : a, 1 : b } }
+ fn from((a, b) : (A, B)) -> Pair { Pair(a, b) }
+}
+
+impl From> for (A,B) {
+ #[inline]
+ fn from(Pair(a, b) : Pair) -> (A,B) { (a, b) }
}
macro_rules! impl_binop {
- ($trait : ident, $fn : ident, $refl:ident, $refr:ident) => {
- impl_binop!(@doit: $trait, $fn;
- maybe_lifetime!($refl, &'l Pair),
- (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B));
+ (($a : ty, $b : ty), $trait : ident, $fn : ident, $refl:ident, $refr:ident) => {
+ impl_binop!(@doit: $a, $b, $trait, $fn;
+ maybe_lifetime!($refl, &'l Pair<$a,$b>),
+ (maybe_lifetime!($refl, &'l $a),
+ maybe_lifetime!($refl, &'l $b));
maybe_lifetime!($refr, &'r Pair),
- (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi));
+ (maybe_lifetime!($refr, &'r Ai),
+ maybe_lifetime!($refr, &'r Bi));
$refl, $refr);
};
- (@doit: $trait:ident, $fn:ident;
+ (@doit: $a:ty, $b:ty,
+ $trait:ident, $fn:ident;
$self:ty, ($aself:ty, $bself:ty);
$in:ty, ($ain:ty, $bin:ty);
$refl:ident, $refr:ident) => {
- impl<'l, 'r, A, B, Ai, Bi> $trait<$in>
+ impl<'l, 'r, Ai, Bi> $trait<$in>
for $self
where $aself: $trait<$ain>,
$bself: $trait<$bin> {
type Output = Pair<<$aself as $trait<$ain>>::Output,
- <$bself as $trait<$bin>>::Output>;
+ <$bself as $trait<$bin>>::Output>;
#[inline]
fn $fn(self, y : $in) -> Self::Output {
- Pair { 0 : maybe_ref!($refl, self.0).$fn(maybe_ref!($refr, y.0)),
- 1 : maybe_ref!($refl, self.1).$fn(maybe_ref!($refr, y.1)) }
+ Pair(maybe_ref!($refl, self.0).$fn(maybe_ref!($refr, y.0)),
+ maybe_ref!($refl, self.1).$fn(maybe_ref!($refr, y.1)))
}
}
};
}
macro_rules! impl_assignop {
- ($trait : ident, $fn : ident, $refr:ident) => {
- impl_assignop!(@doit: $trait, $fn;
+ (($a : ty, $b : ty), $trait : ident, $fn : ident, $refr:ident) => {
+ impl_assignop!(@doit: $a, $b,
+ $trait, $fn;
maybe_lifetime!($refr, &'r Pair),
- (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi));
+ (maybe_lifetime!($refr, &'r Ai),
+ maybe_lifetime!($refr, &'r Bi));
$refr);
};
- (@doit: $trait:ident, $fn:ident;
+ (@doit: $a : ty, $b : ty,
+ $trait:ident, $fn:ident;
$in:ty, ($ain:ty, $bin:ty);
$refr:ident) => {
- impl<'r, A, B, Ai, Bi> $trait<$in>
- for Pair
- where A: $trait<$ain>,
- B: $trait<$bin> {
+ impl<'r, Ai, Bi> $trait<$in>
+ for Pair<$a,$b>
+ where $a: $trait<$ain>,
+ $b: $trait<$bin> {
#[inline]
fn $fn(&mut self, y : $in) -> () {
self.0.$fn(maybe_ref!($refr, y.0));
@@ -78,26 +94,29 @@
}
macro_rules! impl_scalarop {
- ($trait : ident, $fn : ident, $refl:ident) => {
- impl_scalarop!(@doit: $trait, $fn;
- maybe_lifetime!($refl, &'l Pair),
- (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B));
+ (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident, $refl:ident) => {
+ impl_scalarop!(@doit: $field,
+ $trait, $fn;
+ maybe_lifetime!($refl, &'l Pair<$a,$b>),
+ (maybe_lifetime!($refl, &'l $a),
+ maybe_lifetime!($refl, &'l $b));
$refl);
};
- (@doit: $trait:ident, $fn:ident;
+ (@doit: $field : ty,
+ $trait:ident, $fn:ident;
$self:ty, ($aself:ty, $bself:ty);
$refl:ident) => {
// Scalar as Rhs
- impl<'l, F : Num, A, B> $trait
+ impl<'l> $trait<$field>
for $self
- where $aself: $trait,
- $bself: $trait {
- type Output = Pair<<$aself as $trait>::Output,
- <$bself as $trait>::Output>;
+ where $aself: $trait<$field>,
+ $bself: $trait<$field> {
+ type Output = Pair<<$aself as $trait<$field>>::Output,
+ <$bself as $trait<$field>>::Output>;
#[inline]
- fn $fn(self, a : F) -> Self::Output {
- Pair{ 0 : maybe_ref!($refl, self.0).$fn(a),
- 1 : maybe_ref!($refl, self.1).$fn(a)}
+ fn $fn(self, a : $field) -> Self::Output {
+ Pair(maybe_ref!($refl, self.0).$fn(a),
+ maybe_ref!($refl, self.1).$fn(a))
}
}
}
@@ -106,37 +125,38 @@
// Not used due to compiler overflow
#[allow(unused_macros)]
macro_rules! impl_scalarlhs_op {
- ($trait:ident, $fn:ident, $refr:ident, $field:ty) => {
- impl_scalarlhs_op!(@doit: $trait, $fn,
- maybe_lifetime!($refr, &'r Pair),
- (maybe_lifetime!($refr, &'r Ai), maybe_lifetime!($refr, &'r Bi));
+ (($a : ty, $b : ty), $field : ty, $trait:ident, $fn:ident, $refr:ident) => {
+ impl_scalarlhs_op!(@doit: $trait, $fn,
+ maybe_lifetime!($refr, &'r Pair<$a,$b>),
+ (maybe_lifetime!($refr, &'r $a),
+ maybe_lifetime!($refr, &'r $b));
$refr, $field);
};
- (@doit: $trait:ident, $fn:ident,
+ (@doit: $trait:ident, $fn:ident,
$in:ty, ($ain:ty, $bin:ty);
$refr:ident, $field:ty) => {
- impl<'r, Ai, Bi> $trait<$in>
+ impl<'r> $trait<$in>
for $field
where $field : $trait<$ain>
+ $trait<$bin> {
type Output = Pair<<$field as $trait<$ain>>::Output,
- <$field as $trait<$bin>>::Output>;
+ <$field as $trait<$bin>>::Output>;
#[inline]
fn $fn(self, x : $in) -> Self::Output {
- Pair{ 0 : self.$fn(maybe_ref!($refr, x.0)),
- 1 : self.$fn(maybe_ref!($refr, x.1))}
+ Pair(self.$fn(maybe_ref!($refr, x.0)),
+ self.$fn(maybe_ref!($refr, x.1)))
}
}
};
}
macro_rules! impl_scalar_assignop {
- ($trait : ident, $fn : ident) => {
- impl<'r, F : Num, A, B> $trait
- for Pair
- where A: $trait, B: $trait {
+ (($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> {
#[inline]
- fn $fn(&mut self, a : F) -> () {
+ fn $fn(&mut self, a : $field) -> () {
self.0.$fn(a);
self.1.$fn(a);
}
@@ -145,34 +165,77 @@
}
macro_rules! impl_unaryop {
- ($trait:ident, $fn:ident, $refl:ident) => {
+ (($a : ty, $b : ty), $trait:ident, $fn:ident, $refl:ident) => {
impl_unaryop!(@doit: $trait, $fn;
- maybe_lifetime!($refl, &'l Pair),
- (maybe_lifetime!($refl, &'l A), maybe_lifetime!($refl, &'l B));
+ maybe_lifetime!($refl, &'l Pair<$a,$b>),
+ (maybe_lifetime!($refl, &'l $a),
+ maybe_lifetime!($refl, &'l $b));
$refl);
};
(@doit: $trait:ident, $fn:ident;
$self:ty, ($aself:ty, $bself:ty);
$refl : ident) => {
- impl<'l, A, B> $trait
+ impl<'l> $trait
for $self
where $aself: $trait,
$bself: $trait {
type Output = Pair<<$aself as $trait>::Output,
- <$bself as $trait>::Output>;
+ <$bself as $trait>::Output>;
#[inline]
fn $fn(self) -> Self::Output {
- Pair{ 0 : maybe_ref!($refl, self.0).$fn(),
- 1 : maybe_ref!($refl, self.1).$fn()}
+ Pair(maybe_ref!($refl, self.0).$fn(),
+ maybe_ref!($refl, self.1).$fn())
}
}
}
}
+#[macro_export]
+macro_rules! impl_pair_vectorspace_ops {
+ (($a:ty, $b:ty), $field:ty) => {
+ impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add);
+ impl_pair_vectorspace_ops!(@binary, ($a, $b), Sub, sub);
+ impl_pair_vectorspace_ops!(@assign, ($a, $b), AddAssign, add_assign);
+ impl_pair_vectorspace_ops!(@assign, ($a, $b), SubAssign, sub_assign);
+ impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Mul, mul);
+ impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div);
+ // Compiler overflow
+ // $(
+ // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul);
+ // )*
+ impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign);
+ impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign);
+ impl_pair_vectorspace_ops!(@unary, ($a, $b), Neg, neg);
+ };
+ (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
+ impl_binop!(($a, $b), $trait, $fn, ref, ref);
+ impl_binop!(($a, $b), $trait, $fn, ref, noref);
+ impl_binop!(($a, $b), $trait, $fn, noref, ref);
+ impl_binop!(($a, $b), $trait, $fn, noref, noref);
+ };
+ (@assign, ($a : ty, $b : ty), $trait : ident, $fn :ident) => {
+ impl_assignop!(($a, $b), $trait, $fn, ref);
+ impl_assignop!(($a, $b), $trait, $fn, noref);
+ };
+ (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => {
+ impl_scalarop!(($a, $b), $field, $trait, $fn, ref);
+ impl_scalarop!(($a, $b), $field, $trait, $fn, noref);
+ };
+ (@scalar_lhs, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
+ impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, ref);
+ impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, noref);
+ };
+ (@scalar_assign, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => {
+ impl_scalar_assignop!(($a, $b), $field, $trait, $fn);
+ };
+ (@unary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
+ impl_unaryop!(($a, $b), $trait, $fn, ref);
+ impl_unaryop!(($a, $b), $trait, $fn, noref);
+ };
+}
-impl_vectorspace_ops!(impl_binop, impl_assignop, impl_scalarop, impl_scalarlhs_op,
- impl_scalar_assignop, impl_unaryop);
-
+impl_pair_vectorspace_ops!((f32, f32), f32);
+impl_pair_vectorspace_ops!((f64, f64), f64);
impl Dot, F> for Pair
where
@@ -186,15 +249,28 @@
}
}
-impl Euclidean for Pair
+type PairOutput = Pair<>::Output, >::Output>;
+
+impl Euclidean for Pair
where
A : Euclidean,
B : Euclidean,
- F : Float
+ F : Float,
+ PairOutput : Euclidean,
+ Self : Sized + Dot
+ + Mul> + MulAssign
+ + Div> + DivAssign
+ + Add>
+ + Sub>
+ + for<'b> Add<&'b Self, Output=PairOutput>
+ + for<'b> Sub<&'b Self, Output=PairOutput>
+ + AddAssign + for<'b> AddAssign<&'b Self>
+ + SubAssign + for<'b> SubAssign<&'b Self>
+ + Neg