From 3ab087ea7f0ebcb7d0e3c71bb6a6a22feda0884a Mon Sep 17 00:00:00 2001 From: mandragore Date: Wed, 2 May 2018 01:56:23 +0300 Subject: [PATCH] Implement Sum trait for Scalar --- src/scalar.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/scalar.rs b/src/scalar.rs index eb14546..300abf7 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -19,7 +19,7 @@ use core::ops::{Sub, SubAssign}; use core::ops::{Mul, MulAssign}; use core::ops::{Index}; use core::cmp::{Eq, PartialEq}; -use core::iter::Product; +use core::iter::{Product, Sum}; use core::borrow::Borrow; #[cfg(feature = "std")] @@ -307,6 +307,18 @@ where } } +impl Sum for Scalar +where + T: Borrow +{ + fn sum(iter: I) -> Self + where + I: Iterator + { + iter.fold(Scalar::zero(), |acc, item| acc + item.borrow()) + } +} + impl Scalar { /// Return a `Scalar` chosen uniformly at random using a user-provided RNG. /// @@ -957,6 +969,37 @@ mod test { } + #[test] + fn impl_sum() { + + // Test that sum works for non-empty iterators + let two = Scalar::from_u64(2); + let one_vector = vec![Scalar::one(), Scalar::one()]; + let should_be_two: Scalar = one_vector.iter().sum(); + assert_eq!(should_be_two, two); + + // Test that sum works for the empty iterator + let zero = Scalar::zero(); + let empty_vector = vec![]; + let should_be_zero: Scalar = empty_vector.iter().sum(); + assert_eq!(should_be_zero, zero); + + // Test that sum works for owned types + let xs = [Scalar::from_u64(1); 10]; + let ys = [Scalar::from_u64(2); 10]; + // now zs is an iterator with Item = Scalar + let zs = xs.iter().zip(ys.iter()).map(|(x,y)| x + y); + + let x_sum: Scalar = xs.iter().sum(); + let y_sum: Scalar = ys.iter().sum(); + let z_sum: Scalar = zs.sum(); + + assert_eq!(x_sum, Scalar::from_u64(10)); + assert_eq!(y_sum, Scalar::from_u64(20)); + assert_eq!(z_sum, Scalar::from_u64(30)); + assert_eq!(x_sum + y_sum, z_sum); + } + #[test] fn square() { let expected = &X * &X;