From b36f56a6dbf6006712f5ba6978626106df6a11b0 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Thu, 11 Apr 2019 00:13:35 +0200 Subject: [PATCH 1/2] Implement Zip::all() Test if every element of the iterator matches a predicate. This is useful, for instance, to test if two matrices are elementwise "similar" (within a given threshold) without modifying the matrices. --- src/zip/mod.rs | 16 ++++++++++++++++ tests/azip.rs | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/zip/mod.rs b/src/zip/mod.rs index b26e2aebb..5492505c0 100644 --- a/src/zip/mod.rs +++ b/src/zip/mod.rs @@ -738,6 +738,22 @@ macro_rules! map_impl { }) } + /// Tests if every element of the iterator matches a predicate. + /// + /// Returns `true` if `predicate` evaluates to `true` for all elements. + pub fn all(mut self, mut predicate: F) -> bool + where F: FnMut($($p::Item),*) -> bool + { + self.apply_core(true, move |_, args| { + let ($($p,)*) = args; + if predicate($($p),*) { + FoldWhile::Continue(true) + } else { + FoldWhile::Done(false) + } + }).into_inner() + } + expand_if!(@bool [$notlast] /// Include the producer `p` in the Zip. diff --git a/tests/azip.rs b/tests/azip.rs index a5e53e0e0..3364f3c67 100644 --- a/tests/azip.rs +++ b/tests/azip.rs @@ -271,3 +271,19 @@ fn test_indices_split_1() { } } } + +#[test] +fn test_zip_all() { + let a = Array::::zeros(62); + let b = Array::::ones(62); + assert_eq!(true, Zip::from(&a).and(&b).all(|&x, &y| x + y == 1.0)); + assert_eq!(false, Zip::from(&a).and(&b).all(|&x, &y| x == y)); +} + +#[test] +fn test_zip_all_empty_array() { + let a = Array::::zeros(0); + let b = Array::::ones(0); + assert_eq!(true, Zip::from(&a).and(&b).all(|&_x, &_y| true)); + assert_eq!(true, Zip::from(&a).and(&b).all(|&_x, &_y| false)); +} From 48275c40655d37bfb9cac48b75b99e9648a55e67 Mon Sep 17 00:00:00 2001 From: Michael Neumann Date: Sat, 13 Apr 2019 16:17:36 +0200 Subject: [PATCH 2/2] Enhance documentation and test cases for Zip::all() --- src/zip/mod.rs | 10 ++++++++++ tests/azip.rs | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/zip/mod.rs b/src/zip/mod.rs index 5492505c0..fc8b99c7d 100644 --- a/src/zip/mod.rs +++ b/src/zip/mod.rs @@ -741,6 +741,16 @@ macro_rules! map_impl { /// Tests if every element of the iterator matches a predicate. /// /// Returns `true` if `predicate` evaluates to `true` for all elements. + /// Returns `true` if the input arrays are empty. + /// + /// Example: + /// + /// ``` + /// use ndarray::{array, Zip}; + /// let a = array![1, 2, 3]; + /// let b = array![1, 4, 9]; + /// assert!(Zip::from(&a).and(&b).all(|&a, &b| a * a == b)); + /// ``` pub fn all(mut self, mut predicate: F) -> bool where F: FnMut($($p::Item),*) -> bool { diff --git a/tests/azip.rs b/tests/azip.rs index 3364f3c67..39a5d2991 100644 --- a/tests/azip.rs +++ b/tests/azip.rs @@ -276,8 +276,11 @@ fn test_indices_split_1() { fn test_zip_all() { let a = Array::::zeros(62); let b = Array::::ones(62); + let mut c = Array::::ones(62); + c[5] = 0.0; assert_eq!(true, Zip::from(&a).and(&b).all(|&x, &y| x + y == 1.0)); assert_eq!(false, Zip::from(&a).and(&b).all(|&x, &y| x == y)); + assert_eq!(false, Zip::from(&a).and(&c).all(|&x, &y| x + y == 1.0)); } #[test]