diff --git a/src/lib.rs b/src/lib.rs index 661b67b..a1158b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1507,21 +1507,103 @@ impl Num for Complex { } } +#[derive(Clone, Copy)] +struct ComplexSIMD([Complex; 4]); + +impl ComplexSIMD { + fn sum(&self) -> Complex { + self.0[0].clone() + self.0[1].clone() + self.0[2].clone() + self.0[3].clone() + } +} + +impl Add for ComplexSIMD { + type Output = ComplexSIMD; + + fn add(self, rhs: Self) -> Self::Output { + Self([ + self.0[0].clone() + rhs.0[0].clone(), + self.0[1].clone() + rhs.0[1].clone(), + self.0[2].clone() + rhs.0[2].clone(), + self.0[3].clone() + rhs.0[3].clone(), + ]) + } +} + impl Sum for Complex { - fn sum(iter: I) -> Self + fn sum(mut iter: I) -> Self where I: Iterator, { - iter.fold(Self::zero(), |acc, c| acc + c) + let mut complex_sum = ComplexSIMD::([ + Complex::zero(), + Complex::zero(), + Complex::zero(), + Complex::zero(), + ]); + loop { + if let Some(val0) = iter.next() { + if let Some(val1) = iter.next() { + if let Some(val2) = iter.next() { + if let Some(val3) = iter.next() { + complex_sum = complex_sum + + ComplexSIMD::([ + val0.clone(), + val1.clone(), + val2.clone(), + val3.clone(), + ]); + } else { + return complex_sum.sum() + val0 + val1 + val2; + } + } else { + return complex_sum.sum() + val0 + val1; + } + } else { + return complex_sum.sum() + val0; + } + } else { + return complex_sum.sum(); + } + } } } impl<'a, T: 'a + Num + Clone> Sum<&'a Complex> for Complex { - fn sum(iter: I) -> Self + fn sum(mut iter: I) -> Self where I: Iterator>, { - iter.fold(Self::zero(), |acc, c| acc + c) + let mut complex_sum = ComplexSIMD::([ + Complex::zero(), + Complex::zero(), + Complex::zero(), + Complex::zero(), + ]); + loop { + if let Some(val0) = iter.next() { + if let Some(val1) = iter.next() { + if let Some(val2) = iter.next() { + if let Some(val3) = iter.next() { + complex_sum = complex_sum + + ComplexSIMD::([ + val0.clone(), + val1.clone(), + val2.clone(), + val3.clone(), + ]); + } else { + return complex_sum.sum() + val0 + val1 + val2; + } + } else { + return complex_sum.sum() + val0 + val1; + } + } else { + return complex_sum.sum() + val0; + } + } else { + return complex_sum.sum(); + } + } } }