Skip to content

Commit

Permalink
Adding updated API signatures based on discussion in JuliaLang#14142
Browse files Browse the repository at this point in the history
This commit adds updated argument signatures for the functionality discussed in JuliaLang#14142 wherein each of these functions only returns one single output argument containing index vectors of various purposes related to the unique slices currently returned from the unique function taking two input arguments.  Still needs tests and doc integration.
  • Loading branch information
AndyGreenwell committed Mar 6, 2016
1 parent 088c7ea commit 51f0321
Showing 1 changed file with 128 additions and 0 deletions.
128 changes: 128 additions & 0 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -832,3 +832,131 @@ If `dim` is specified, returns unique regions of the array `itr` along `dim`.
@nref $N A d->d == dim ? sort!(uniquerows) : (1:size(A, d))
end
end

"""
groupslices(A, dim)
Returns a vector of integers where each integer element of the returned vector
is a group number corresponding to the unique slices along dimension `dim` as
returned from `unique(A, dim)`, where `A` can be a multidimensional array.
Example usage:
If `C = unique(A, dim)`, `ic = groupslices(A, dim)`, and
rank(A) == rank(C) == 3, then:
if dim == 1
all(A .== C[ic,:,:])
elseif dim == 2
all(A .== C[:,ic,:])
elseif dim == 3
all(A .== C[:,:,ic])
end
"""

@generated function groupslices{T,N}(A::AbstractArray{T,N}, dim::Int)
quote
if !(1 <= dim <= $N)
error("Input argument dim must be 1 <= dim <= $N, but is currently $dim")

This comment has been minimized.

Copy link
@tkelman

tkelman Mar 12, 2016

this should use a more specific exception type, probably ArgumentError

end
hashes = zeros(UInt, size(A, dim))

# Compute hash for each row
k = 0
@nloops $N i A d->(if d == dim; k = i_d; end) begin
@inbounds hashes[k] = hash(hashes[k], hash((@nref $N A i)))
end

ic = Array(Int, size(A, dim))
firstrow = Dict{Prehashed,Int}()
icdict = Dict{Int,Int}()
h = 0
for k = 1:size(A, dim)
tmp = get!(firstrow, Prehashed(hashes[k]), k)
if !haskey(icdict,tmp)
h += 1
icdict[tmp] = h
ic[k] = h
else
ic[k] = icdict[tmp]
end
end

return ic
end
end

"""
groupinds(ic)
Returns a vector of vectors of integers wherein the vector of group slice
index integers as returned from `groupslices(A, dim)` is converted into a
grouped vector of vectors. Each vector entry in the returned vector of
vectors contains all of the positional indices of slices in the original
input array `A` that correspond to the unique slices along dimension `dim`
that are present in the array `C` as returned from `unique(A, dim)`.
"""

function groupinds(ic::Vector{Int})
n = length(unique(ic))
ib = Array(Vector{Int},n)
for k = 1:n
ib[k] = Int[]
end
for h = 1:length(ic)
push!(ib[ic[h]], h)
end
return ib
end

"""
firstinds(ic::Vector{Int})
firstinds(ib::Vector{Vector{Int}})
Returns a vector of integers containing the first index position of each unique
value in the input integer vector `ic`, or the first index position of each
entry in the input vector of integer vectors `ib`.
When operating on the output returned from `unique(A, dim)`, the returned
vector of integers correspond to the positions of the first of each unique slice
present in the original input multidimensional array `A` along dimension `dim`.
The implementation of `firstinds` accepting a vector of integers operates on the
output returned from `groupslices(A, dim)`.
The implementation of `firstinds` accepting a vector of vector of integers
operates on the output returned from `groupinds(ic::Vector{Int})`
"""

function firstinds(ic::Vector{Int})
id = unique(ic)
n = length(id)
ia = Array(Int,n)
for i = 1:n
ia[i] = findfirst(ic, id[i])
end
return ia
end

function firstinds(ib::Vector{Vector{Int}})
ia = map(first, ib)
end

"""
lastinds(ic::Vector{Int})
Returns a vector of integers containing the last index position of each unique
value in the input integer vector `ic`.
When operating on the output returned from `groupinds(unique(A, dim))`, the
returned vector of integers correspond to the positions of the last of each
unique slice present in the original input multidimensional array `A` along
dimension `dim`.
The implementation of `firstinds` accepting a vector of vector of integers
operates on the output returned from `groupinds(ic::Vector{Int})`
"""

function lastinds(ib::Vector{Vector{Int}})
ia = map(last, ib)
end

0 comments on commit 51f0321

Please sign in to comment.