How to make zip work with more than 6 elements?
I want to use zip (or azip!) with 7 producers but its only implemented for max 6 producers. Is there a convenient way to also implement it for more producers?
Minimal Example Code:
let v1: Array1<i32> = Array1::zeros(3);
let v2: Array1<i32> = Array1::zeros(3);
let v3: Array1<i32> = Array1::zeros(3);
let v4: Array1<i32> = Array1::zeros(3);
let v5: Array1<i32> = Array1::zeros(3);
let v6: Array1<i32> = Array1::zeros(3);
let v7: Array1<i32> = Array1::zeros(3);
Zip::from(&v1)
.and(&v2)
.and(&v3)
.and(&v4)
.and(&v5)
.and(&v6)
.and(&v7)
.for_each(|v1, v2, v3, v4, v5, v6, v7| {
println!("{}, {}, {}, {}, {}, {}, {}", v1, v2, v3, v4, v5, v6, v7);
});
Error:
error[E0599]: no method named
andfound for structndarray::Zip<(ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>), Dim<[usize; 1]>>in the current scope --> src\main.rs:47:14 | 47 | .and(&v7) | ^^^ method not found inndarray::Zip<(ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>, ArrayBase<ViewRepr<&i32>, Dim<[usize; 1]>>), Dim<[usize; 1]>>| = note: the method was found for -ndarray::Zip<(P1,), D>-ndarray::Zip<(P1, P2), D>-ndarray::Zip<(P1, P2, P3), D>-ndarray::Zip<(P1, P2, P3, P4), D>-ndarray::Zip<(P1, P2, P3, P4, P5), D>
It's not currently possible with ndarray0.15. It might be possible some day with the new features Rust keeps adding, I don't know.
What I do when I need to Zip on "too much" elements is
- Try to refactor. I don't know your precise problem but it's sometimes possible to
- reduce the number of arrays. Maybe by merging some of them
Array1<(f32, f32)>. This is sometimes possible if you're are creating them just before the Zip. - separate your work into 2 blocks and loop 2 times instead of 1.
- reduce the number of arrays. Maybe by merging some of them
- Use
indexedand use the index to get the missing elements. - Prepare an iterator beforehand and call
.next()at the start of the Zip.
Of course, those are all hacks, but we must live with the limit. If they make it possible to work with 7 arrays, someone will ask for 8 :)
Coming from Python and Julia in my area of simulation, the expressions come from SymPy and can often involve many variables. I find the limitation on the number of produces in Zip a bit unnatural.
I started this discussion https://github.com/rust-ndarray/ndarray/discussions/1240 for figuring out the correct way to vectorize (SIMD) element-wise operation. A separate but possible related question is, how to get optimized performance for element-wise operations that involve more than six arrays?