From b83975b04ffabd1b1d6e53e9bd05646678c92641 Mon Sep 17 00:00:00 2001 From: timholy Date: Sun, 6 Apr 2014 07:40:47 -0500 Subject: [PATCH] Add Cartesian product iteration. Fixes #1917 --- base/exports.jl | 1 + base/multidimensional.jl | 17 +++++++++++++++++ test/combinatorics.jl | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/base/exports.jl b/base/exports.jl index ab32dc26f1c5e..85cea3237e09c 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -918,6 +918,7 @@ export # iteration done, enumerate, + eachindex, next, start, zip, diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 07e7df2470d77..fa65c6956e0b1 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -1,3 +1,20 @@ +# Cartesian product iteration + +immutable SizeIterator{N} + I::NTuple{N,Int} +end +getindex(I::SizeIterator, n) = I.I[n] + +@ngenerate N NTuple{N,Int} start{N}(lim::SizeIterator{N}) = @ntuple N d->1 +done{N}(lim::SizeIterator{N}, I::NTuple{N,Int}) = I[N] > lim[N] +@ngenerate N (NTuple{N,Int},NTuple{N,Int}) function next{N}(lim::SizeIterator{N}, I::NTuple{N,Int}) + @nif N i->I[i](newI = @ntuple N d->((d < i) ? 1 : ((d == i) ? I[d]+1 : I[d]))) + I, newI +end + +eachindex(A::Array) = SizeIterator(size(A)) +eachindex(dims::Dims) = SizeIterator(dims) + ### From array.jl @ngenerate N Nothing function checksize(A::AbstractArray, I::NTuple{N, Any}...) diff --git a/test/combinatorics.jl b/test/combinatorics.jl index 49b9fac475d6f..44d596f7a57d5 100644 --- a/test/combinatorics.jl +++ b/test/combinatorics.jl @@ -34,3 +34,9 @@ end @test binomial(int64(67), int64(29)) == binomial(BigInt(67), BigInt(29)) == 7886597962249166160 @test binomial(int128(131), int128(62)) == binomial(BigInt(131), BigInt(62)) == 157311720980559117816198361912717812000 +# Cartesian product iteration +A = reshape(1:6, 2, 3) +indexes = ((1,1),(2,1),(1,2),(2,2),(1,3),(2,3)) +for (I,ind) in zip(eachindex(A), indexes) + @test I == ind +end