From 3c7de6e1fe1de6786abb3bd6b354c22c3d8d9e62 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Wed, 2 Mar 2016 22:31:21 +0100 Subject: [PATCH 01/15] start exploring array stacking --- src/lib.rs | 2 ++ src/stacking.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/stacking.rs diff --git a/src/lib.rs b/src/lib.rs index 53c82e7a2..70e0eccca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,7 @@ pub use iterators::{ pub use arraytraits::AsArray; pub use linalg::{LinalgScalar, NdFloat}; +pub use stacking::ArrayStackingExt; mod arraytraits; #[cfg(feature = "serde")] @@ -129,6 +130,7 @@ mod linspace; mod numeric_util; mod si; mod error; +mod stacking; /// Implementation's prelude. Common types used everywhere. mod imp_prelude { diff --git a/src/stacking.rs b/src/stacking.rs new file mode 100644 index 000000000..b77510bee --- /dev/null +++ b/src/stacking.rs @@ -0,0 +1,30 @@ + +use imp_prelude::*; + +/// A slice extension trait for concatenating arrays. +pub trait ArrayStackingExt { + type Output; + + /// Stack the given arrays along the specified axis. + /// + /// *Panics* if axis is out of bounds + /// *Panics* if the slice is empty. + fn stack(&self, axis: Axis) -> Self::Output; +} + +impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] + where A: Clone, + D: Dimension +{ + type Output = OwnedArray; + + fn stack(&self, Axis(axis): Axis) -> ::Output { + assert!(self.len() > 0); + let mut res_dim = self[0].dim().clone(); + let stacked_dim = self.iter() + .fold(0, |acc, a| acc + a.dim().slice()[axis]); + res_dim.slice_mut()[axis] = stacked_dim; + let mut res = OwnedArray::zeros(stacked_dim); + unimplemented!() + } +} From 18606d60d9a567c4832d212c9affe79ce9811183 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Thu, 3 Mar 2016 22:48:56 +0100 Subject: [PATCH 02/15] first prototype implementation for stacking --- src/stacking.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index b77510bee..ba89d9479 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -1,5 +1,6 @@ use imp_prelude::*; +use libnum; /// A slice extension trait for concatenating arrays. pub trait ArrayStackingExt { @@ -13,18 +14,30 @@ pub trait ArrayStackingExt { } impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] - where A: Clone, - D: Dimension + where A: Clone + libnum::Zero, + D: Dimension + RemoveAxis { type Output = OwnedArray; - fn stack(&self, Axis(axis): Axis) -> ::Output { + fn stack(&self, axis: Axis) -> ::Output { assert!(self.len() > 0); let mut res_dim = self[0].dim().clone(); let stacked_dim = self.iter() - .fold(0, |acc, a| acc + a.dim().slice()[axis]); - res_dim.slice_mut()[axis] = stacked_dim; - let mut res = OwnedArray::zeros(stacked_dim); - unimplemented!() + .fold(0, |acc, a| acc + a.dim().index(axis)); + *res_dim.index_mut(axis) = stacked_dim; + let mut res = OwnedArray::zeros(res_dim); + + let mut array_iter = self.iter(); + let mut in_iter = array_iter.next().unwrap().axis_iter(axis); + let mut cum = *self[0].dim().index(axis); + for (ind, mut out) in res.axis_iter_mut(axis).enumerate() { + if ind == cum { + let cur_array = array_iter.next().unwrap(); + cum += *cur_array.dim().index(axis); + in_iter = cur_array.axis_iter(axis); + } + out.assign(&in_iter.next().unwrap()); + } + res } } From ab0527c8c994f7c02d62a3b49c02c0e4b397c252 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Thu, 3 Mar 2016 22:57:21 +0100 Subject: [PATCH 03/15] add basic test for stacking --- src/lib.rs | 2 +- tests/stacking.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/stacking.rs diff --git a/src/lib.rs b/src/lib.rs index 70e0eccca..dcdb02204 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -130,7 +130,7 @@ mod linspace; mod numeric_util; mod si; mod error; -mod stacking; +pub mod stacking; /// Implementation's prelude. Common types used everywhere. mod imp_prelude { diff --git a/tests/stacking.rs b/tests/stacking.rs new file mode 100644 index 000000000..fe08d9436 --- /dev/null +++ b/tests/stacking.rs @@ -0,0 +1,21 @@ + +extern crate ndarray; + + +use ndarray::{ + arr2, + Axis, +}; + +use ndarray::stacking::ArrayStackingExt; + +#[test] +fn vstack() { + let a = arr2(&[[2., 2.], + [3., 3.]]); + let b = [a.view(), a.view()].stack(Axis(0)); + assert_eq!(b, arr2(&[[2., 2.], + [3., 3.], + [2., 2.], + [3., 3.]])); +} From fbeb26259ad7ebc31451ff1f529a5f053686c928 Mon Sep 17 00:00:00 2001 From: bluss Date: Fri, 4 Mar 2016 13:04:44 +0100 Subject: [PATCH 04/15] simplify stacking impl using split_at --- src/stacking.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index ba89d9479..feb54134b 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -27,16 +27,14 @@ impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] *res_dim.index_mut(axis) = stacked_dim; let mut res = OwnedArray::zeros(res_dim); - let mut array_iter = self.iter(); - let mut in_iter = array_iter.next().unwrap().axis_iter(axis); - let mut cum = *self[0].dim().index(axis); - for (ind, mut out) in res.axis_iter_mut(axis).enumerate() { - if ind == cum { - let cur_array = array_iter.next().unwrap(); - cum += *cur_array.dim().index(axis); - in_iter = cur_array.axis_iter(axis); + { + let mut assign_view = res.view_mut(); + for array in self { + let len = *array.dim().index(axis); + let (mut front, rest) = assign_view.split_at(axis, len); + front.assign(array); + assign_view = rest; } - out.assign(&in_iter.next().unwrap()); } res } From 645d0f2319456ba20cf02fa17ba251bbca26fb07 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 13:10:55 +0100 Subject: [PATCH 05/15] stacking: require Copy bound, no zero-initialization --- src/stacking.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index feb54134b..1959a2e6c 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -1,6 +1,5 @@ use imp_prelude::*; -use libnum; /// A slice extension trait for concatenating arrays. pub trait ArrayStackingExt { @@ -14,7 +13,7 @@ pub trait ArrayStackingExt { } impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] - where A: Clone + libnum::Zero, + where A: Copy, D: Dimension + RemoveAxis { type Output = OwnedArray; @@ -25,7 +24,15 @@ impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] let stacked_dim = self.iter() .fold(0, |acc, a| acc + a.dim().index(axis)); *res_dim.index_mut(axis) = stacked_dim; - let mut res = OwnedArray::zeros(res_dim); + + // we can safely use uninitialized values here because they are Copy + // and we will only ever write to them + let size = res_dim.size(); + let mut v = Vec::with_capacity(size); + unsafe { + v.set_len(size); + } + let mut res = OwnedArray::from_vec_dim(res_dim, v).unwrap(); { let mut assign_view = res.view_mut(); From 1a709b761e1557e77d678247940c99ca6fe603f5 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 13:16:51 +0100 Subject: [PATCH 06/15] stacking is now a free function `ndarray::stack` --- src/lib.rs | 2 +- src/stacking.rs | 60 ++++++++++++++++++----------------------------- tests/stacking.rs | 4 +--- 3 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index dcdb02204..c882865cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,7 +100,7 @@ pub use iterators::{ pub use arraytraits::AsArray; pub use linalg::{LinalgScalar, NdFloat}; -pub use stacking::ArrayStackingExt; +pub use stacking::stack; mod arraytraits; #[cfg(feature = "serde")] diff --git a/src/stacking.rs b/src/stacking.rs index 1959a2e6c..81a5d2b21 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -1,48 +1,34 @@ use imp_prelude::*; -/// A slice extension trait for concatenating arrays. -pub trait ArrayStackingExt { - type Output; - - /// Stack the given arrays along the specified axis. - /// - /// *Panics* if axis is out of bounds - /// *Panics* if the slice is empty. - fn stack(&self, axis: Axis) -> Self::Output; -} - -impl<'a, A, D> ArrayStackingExt for [ArrayView<'a, A, D>] +pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) + -> OwnedArray where A: Copy, D: Dimension + RemoveAxis { - type Output = OwnedArray; + assert!(arrays.len() > 0); + let mut res_dim = arrays[0].dim().clone(); + let stacked_dim = arrays.iter() + .fold(0, |acc, a| acc + a.dim().index(axis)); + *res_dim.index_mut(axis) = stacked_dim; - fn stack(&self, axis: Axis) -> ::Output { - assert!(self.len() > 0); - let mut res_dim = self[0].dim().clone(); - let stacked_dim = self.iter() - .fold(0, |acc, a| acc + a.dim().index(axis)); - *res_dim.index_mut(axis) = stacked_dim; - - // we can safely use uninitialized values here because they are Copy - // and we will only ever write to them - let size = res_dim.size(); - let mut v = Vec::with_capacity(size); - unsafe { - v.set_len(size); - } - let mut res = OwnedArray::from_vec_dim(res_dim, v).unwrap(); + // we can safely use uninitialized values here because they are Copy + // and we will only ever write to them + let size = res_dim.size(); + let mut v = Vec::with_capacity(size); + unsafe { + v.set_len(size); + } + let mut res = OwnedArray::from_vec_dim(res_dim, v).unwrap(); - { - let mut assign_view = res.view_mut(); - for array in self { - let len = *array.dim().index(axis); - let (mut front, rest) = assign_view.split_at(axis, len); - front.assign(array); - assign_view = rest; - } + { + let mut assign_view = res.view_mut(); + for array in arrays { + let len = *array.dim().index(axis); + let (mut front, rest) = assign_view.split_at(axis, len); + front.assign(array); + assign_view = rest; } - res } + res } diff --git a/tests/stacking.rs b/tests/stacking.rs index fe08d9436..bf4339f72 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -7,13 +7,11 @@ use ndarray::{ Axis, }; -use ndarray::stacking::ArrayStackingExt; - #[test] fn vstack() { let a = arr2(&[[2., 2.], [3., 3.]]); - let b = [a.view(), a.view()].stack(Axis(0)); + let b = ndarray::stack(&[a.view(), a.view()], Axis(0)); assert_eq!(b, arr2(&[[2., 2.], [3., 3.], [2., 2.], From a2283e9b05f7d9fc64ef159d9dec617d9a757694 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 13:28:25 +0100 Subject: [PATCH 07/15] `stack` now returns `Result` --- src/stacking.rs | 17 ++++++++++++++--- tests/stacking.rs | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index 81a5d2b21..5da9d3d18 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -1,13 +1,24 @@ use imp_prelude::*; +use error::{ShapeError, ErrorKind, from_kind}; +/// Stack arrays along the given axis. +/// +/// *Panics* if axis is out of bounds. pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) - -> OwnedArray + -> Result, ShapeError> where A: Copy, D: Dimension + RemoveAxis { - assert!(arrays.len() > 0); + if arrays.len() == 0 { + return Err(from_kind(ErrorKind::Unsupported)); + } let mut res_dim = arrays[0].dim().clone(); + let common_dim = res_dim.remove_axis(axis); + if arrays.iter().any(|a| a.dim().remove_axis(axis) != common_dim) { + return Err(from_kind(ErrorKind::IncompatibleShape)); + } + let stacked_dim = arrays.iter() .fold(0, |acc, a| acc + a.dim().index(axis)); *res_dim.index_mut(axis) = stacked_dim; @@ -30,5 +41,5 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) assign_view = rest; } } - res + Ok(res) } diff --git a/tests/stacking.rs b/tests/stacking.rs index bf4339f72..b647a4908 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -11,7 +11,7 @@ use ndarray::{ fn vstack() { let a = arr2(&[[2., 2.], [3., 3.]]); - let b = ndarray::stack(&[a.view(), a.view()], Axis(0)); + let b = ndarray::stack(&[a.view(), a.view()], Axis(0)).unwrap(); assert_eq!(b, arr2(&[[2., 2.], [3., 3.], [2., 2.], From 86cb8016968420e17db0b93adaeec2a2c6bdcef8 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 18:27:47 +0100 Subject: [PATCH 08/15] use try instead of unwrap --- src/stacking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stacking.rs b/src/stacking.rs index 5da9d3d18..9f1fda21e 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -30,7 +30,7 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) unsafe { v.set_len(size); } - let mut res = OwnedArray::from_vec_dim(res_dim, v).unwrap(); + let mut res = try!(OwnedArray::from_vec_dim(res_dim, v)); { let mut assign_view = res.view_mut(); From ce4fc93d27d33d0fc62ee8d8ea3e5cc3433f85eb Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 18:47:13 +0100 Subject: [PATCH 09/15] implement a stacking macro --- src/stacking.rs | 7 +++++++ tests/stacking.rs | 3 +++ 2 files changed, 10 insertions(+) diff --git a/src/stacking.rs b/src/stacking.rs index 9f1fda21e..6f6825423 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -43,3 +43,10 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) } Ok(res) } + +#[macro_export] +macro_rules! stack { + ([ $( $a:expr ),* ]; $axis:expr) => { + ndarray::stack(&[ $($a.view() ),* ], $axis).unwrap() + } +} diff --git a/tests/stacking.rs b/tests/stacking.rs index b647a4908..38e9e4293 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -1,4 +1,5 @@ +#[macro_use(stack)] extern crate ndarray; @@ -16,4 +17,6 @@ fn vstack() { [3., 3.], [2., 2.], [3., 3.]])); + + let b = stack!([a.view(), a]; Axis(1)); } From b34a0c8d96b5a68767a6bcc40b3d5c1d59a18fd4 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 21:14:54 +0100 Subject: [PATCH 10/15] lighter syntax for stacking macro --- src/stacking.rs | 2 +- tests/stacking.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index 6f6825423..44a455945 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -46,7 +46,7 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) #[macro_export] macro_rules! stack { - ([ $( $a:expr ),* ]; $axis:expr) => { + ($axis:expr, $( $a:expr ),+ ) => { ndarray::stack(&[ $($a.view() ),* ], $axis).unwrap() } } diff --git a/tests/stacking.rs b/tests/stacking.rs index 38e9e4293..e86d8c9d6 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -18,5 +18,5 @@ fn vstack() { [2., 2.], [3., 3.]])); - let b = stack!([a.view(), a]; Axis(1)); + let b = stack!(Axis(1), a.view(), a); } From 3a3e27809f66634f5326256f21d428010a5a84b6 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 21:20:32 +0100 Subject: [PATCH 11/15] stacking returns OutOfBounds error instead of panicking --- src/stacking.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index 44a455945..d55faadfd 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -3,17 +3,18 @@ use imp_prelude::*; use error::{ShapeError, ErrorKind, from_kind}; /// Stack arrays along the given axis. -/// -/// *Panics* if axis is out of bounds. pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) -> Result, ShapeError> where A: Copy, D: Dimension + RemoveAxis { + let mut res_dim = arrays[0].dim().clone(); + if axis.axis() >= res_dim.slice().len() { + return Err(from_kind(ErrorKind::OutOfBounds)); + } if arrays.len() == 0 { return Err(from_kind(ErrorKind::Unsupported)); } - let mut res_dim = arrays[0].dim().clone(); let common_dim = res_dim.remove_axis(axis); if arrays.iter().any(|a| a.dim().remove_axis(axis) != common_dim) { return Err(from_kind(ErrorKind::IncompatibleShape)); From ddcc85c443fb856b7a4d29b8623b56b0e2de3572 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 21:37:20 +0100 Subject: [PATCH 12/15] clean some contrvied implemntation points --- src/stacking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index d55faadfd..db586a1b3 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -8,8 +8,8 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) where A: Copy, D: Dimension + RemoveAxis { - let mut res_dim = arrays[0].dim().clone(); - if axis.axis() >= res_dim.slice().len() { + let mut res_dim = arrays[0].dim(); + if axis.axis() >= res_dim.ndim() { return Err(from_kind(ErrorKind::OutOfBounds)); } if arrays.len() == 0 { From 99c014579113988bb736de1ed33fefd088b0e4cb Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 21:41:01 +0100 Subject: [PATCH 13/15] change order of arguments in stacking --- src/stacking.rs | 4 ++-- tests/stacking.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index db586a1b3..62643d92e 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -3,7 +3,7 @@ use imp_prelude::*; use error::{ShapeError, ErrorKind, from_kind}; /// Stack arrays along the given axis. -pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) +pub fn stack<'a, A, D>(axis: Axis, arrays: &[ArrayView<'a, A, D>]) -> Result, ShapeError> where A: Copy, D: Dimension + RemoveAxis @@ -48,6 +48,6 @@ pub fn stack<'a, A, D>(arrays: &[ArrayView<'a, A, D>], axis: Axis) #[macro_export] macro_rules! stack { ($axis:expr, $( $a:expr ),+ ) => { - ndarray::stack(&[ $($a.view() ),* ], $axis).unwrap() + ndarray::stack($axis, &[ $($a.view() ),* ]).unwrap() } } diff --git a/tests/stacking.rs b/tests/stacking.rs index e86d8c9d6..76a8955f3 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -12,7 +12,7 @@ use ndarray::{ fn vstack() { let a = arr2(&[[2., 2.], [3., 3.]]); - let b = ndarray::stack(&[a.view(), a.view()], Axis(0)).unwrap(); + let b = ndarray::stack(Axis(0), &[a.view(), a.view()]).unwrap(); assert_eq!(b, arr2(&[[2., 2.], [3., 3.], [2., 2.], From 47621413222a314e8837f197b6faec65d32c7d0f Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Fri, 4 Mar 2016 21:54:46 +0100 Subject: [PATCH 14/15] enhance stacking tests, catching missed panic in the way --- src/stacking.rs | 6 +++--- tests/stacking.rs | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index 62643d92e..8fde266f3 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -8,13 +8,13 @@ pub fn stack<'a, A, D>(axis: Axis, arrays: &[ArrayView<'a, A, D>]) where A: Copy, D: Dimension + RemoveAxis { + if arrays.len() == 0 { + return Err(from_kind(ErrorKind::Unsupported)); + } let mut res_dim = arrays[0].dim(); if axis.axis() >= res_dim.ndim() { return Err(from_kind(ErrorKind::OutOfBounds)); } - if arrays.len() == 0 { - return Err(from_kind(ErrorKind::Unsupported)); - } let common_dim = res_dim.remove_axis(axis); if arrays.iter().any(|a| a.dim().remove_axis(axis) != common_dim) { return Err(from_kind(ErrorKind::IncompatibleShape)); diff --git a/tests/stacking.rs b/tests/stacking.rs index 76a8955f3..031fda31c 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -6,10 +6,13 @@ extern crate ndarray; use ndarray::{ arr2, Axis, + Ix, + OwnedArray, + ErrorKind, }; #[test] -fn vstack() { +fn stacking() { let a = arr2(&[[2., 2.], [3., 3.]]); let b = ndarray::stack(Axis(0), &[a.view(), a.view()]).unwrap(); @@ -18,5 +21,20 @@ fn vstack() { [2., 2.], [3., 3.]])); - let b = stack!(Axis(1), a.view(), a); + let c = stack!(Axis(0), a.view(), b); + assert_eq!(c, arr2(&[[2., 2.], + [3., 3.], + [2., 2.], + [3., 3.], + [2., 2.], + [3., 3.]])); + + let res = ndarray::stack(Axis(1), &[a.view(), c.view()]); + assert_eq!(res.unwrap_err().kind(), ErrorKind::IncompatibleShape); + + let res = ndarray::stack(Axis(2), &[a.view(), c.view()]); + assert_eq!(res.unwrap_err().kind(), ErrorKind::OutOfBounds); + + let res: Result, _> = ndarray::stack(Axis(0), &[]); + assert_eq!(res.unwrap_err().kind(), ErrorKind::Unsupported); } From 806b2bdd05bc071ee318ee6e98a3faad66247c66 Mon Sep 17 00:00:00 2001 From: Vincent Barrielle Date: Sat, 5 Mar 2016 10:12:10 +0100 Subject: [PATCH 15/15] stacking macro must take owning arrays by reference --- src/stacking.rs | 2 +- tests/stacking.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stacking.rs b/src/stacking.rs index 8fde266f3..22010b135 100644 --- a/src/stacking.rs +++ b/src/stacking.rs @@ -48,6 +48,6 @@ pub fn stack<'a, A, D>(axis: Axis, arrays: &[ArrayView<'a, A, D>]) #[macro_export] macro_rules! stack { ($axis:expr, $( $a:expr ),+ ) => { - ndarray::stack($axis, &[ $($a.view() ),* ]).unwrap() + ndarray::stack($axis, &[ $(ndarray::ArrayView::from($a) ),* ]).unwrap() } } diff --git a/tests/stacking.rs b/tests/stacking.rs index 031fda31c..7f9f9bfe0 100644 --- a/tests/stacking.rs +++ b/tests/stacking.rs @@ -21,7 +21,7 @@ fn stacking() { [2., 2.], [3., 3.]])); - let c = stack!(Axis(0), a.view(), b); + let c = stack!(Axis(0), a.view(), &b); assert_eq!(c, arr2(&[[2., 2.], [3., 3.], [2., 2.],