From e5e53fb77d656246e45ade457ef0b0cc650ba644 Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Fri, 12 Jan 2018 01:54:54 +0900 Subject: [PATCH 1/4] Implement Sum/Product --- src/lib.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 18fa4e0..81cddc7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,9 +26,10 @@ use std::fmt; #[cfg(test)] use std::hash; use std::ops::{Add, Div, Mul, Neg, Sub, Rem}; +use std::iter::{Sum, Product}; use std::str::FromStr; -use traits::{Zero, One, Num, Inv, Float}; +use traits::{Zero, One, Num, NumAssign, Inv, Float}; // FIXME #1284: handle complex NaN & infinity etc. This // probably doesn't map to C's _Complex correctly. @@ -1069,6 +1070,46 @@ impl Num for Complex { } } +impl Sum for Complex { + fn sum(iter: I) -> Self where I: Iterator { + let mut s = Self::zero(); + for c in iter { + s += c; + } + s + } +} + +impl<'a, T: 'a + Clone + NumAssign> Sum<&'a Complex> for Complex { + fn sum(iter: I) -> Self where I: Iterator> { + let mut s = Self::zero(); + for c in iter { + s += c; + } + s + } +} + +impl Product for Complex { + fn product(iter: I) -> Self where I: Iterator { + let mut s = Self::one(); + for c in iter { + s *= c; + } + s + } +} + +impl<'a, T: 'a + Clone + NumAssign> Product<&'a Complex> for Complex { + fn product(iter: I) -> Self where I: Iterator> { + let mut s = Self::one(); + for c in iter { + s *= c; + } + s + } +} + #[cfg(feature = "serde")] impl serde::Serialize for Complex where T: serde::Serialize From f549f3001c6916a7f530d4e0746d039a9d483e04 Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Fri, 12 Jan 2018 02:02:54 +0900 Subject: [PATCH 2/4] Add test of Sum/Product --- src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 81cddc7..218910d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1958,4 +1958,18 @@ mod test { test("1i - 2i"); test("+ 1 - 3.0i"); } + + #[test] + fn test_sum() { + let v = vec![_0_1i, _4_2i, _1_0i, _1_1i]; + let _: Complex64 = v.iter().sum(); + let _: Complex64 = v.into_iter().sum(); + } + + #[test] + fn test_prod() { + let v = vec![_0_1i, _4_2i, _1_0i, _1_1i]; + let _: Complex64 = v.iter().product(); + let _: Complex64 = v.into_iter().product(); + } } From 84b6ae8e1efeda54895be62e93fd226194a1206a Mon Sep 17 00:00:00 2001 From: Toshiki Teramura Date: Fri, 12 Jan 2018 02:22:37 +0900 Subject: [PATCH 3/4] Change test case to check result --- src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 218910d..8e939ad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1961,15 +1961,15 @@ mod test { #[test] fn test_sum() { - let v = vec![_0_1i, _4_2i, _1_0i, _1_1i]; - let _: Complex64 = v.iter().sum(); - let _: Complex64 = v.into_iter().sum(); + let v = vec![_0_1i, _1_0i]; + assert_eq!(v.iter().sum::(), _1_1i); + assert_eq!(v.into_iter().sum::(), _1_1i); } #[test] fn test_prod() { - let v = vec![_0_1i, _4_2i, _1_0i, _1_1i]; - let _: Complex64 = v.iter().product(); - let _: Complex64 = v.into_iter().product(); + let v = vec![_0_1i, _1_0i]; + assert_eq!(v.iter().product::(), _0_1i); + assert_eq!(v.into_iter().product::(), _0_1i); } } From eaf701028ec745215c3b84fc971e1871e37f0ea0 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 6 Mar 2018 13:54:24 -0800 Subject: [PATCH 4/4] Use folds for Sum and Product Folding can be faster for some iterators, and this way we also don't need to require `NumAssign`. --- src/lib.rs | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8e939ad..d68032f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,7 @@ use std::ops::{Add, Div, Mul, Neg, Sub, Rem}; use std::iter::{Sum, Product}; use std::str::FromStr; -use traits::{Zero, One, Num, NumAssign, Inv, Float}; +use traits::{Zero, One, Num, Inv, Float}; // FIXME #1284: handle complex NaN & infinity etc. This // probably doesn't map to C's _Complex correctly. @@ -1070,43 +1070,27 @@ impl Num for Complex { } } -impl Sum for Complex { +impl Sum for Complex { fn sum(iter: I) -> Self where I: Iterator { - let mut s = Self::zero(); - for c in iter { - s += c; - } - s + iter.fold(Self::zero(), |acc, c| acc + c) } } -impl<'a, T: 'a + Clone + NumAssign> Sum<&'a Complex> for Complex { +impl<'a, T: 'a + Num + Clone> Sum<&'a Complex> for Complex { fn sum(iter: I) -> Self where I: Iterator> { - let mut s = Self::zero(); - for c in iter { - s += c; - } - s + iter.fold(Self::zero(), |acc, c| acc + c) } } -impl Product for Complex { +impl Product for Complex { fn product(iter: I) -> Self where I: Iterator { - let mut s = Self::one(); - for c in iter { - s *= c; - } - s + iter.fold(Self::one(), |acc, c| acc * c) } } -impl<'a, T: 'a + Clone + NumAssign> Product<&'a Complex> for Complex { +impl<'a, T: 'a + Num + Clone> Product<&'a Complex> for Complex { fn product(iter: I) -> Self where I: Iterator> { - let mut s = Self::one(); - for c in iter { - s *= c; - } - s + iter.fold(Self::one(), |acc, c| acc * c) } }