Skip to content

Instantly share code, notes, and snippets.

@AndyGreenwell
Created May 11, 2016 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndyGreenwell/4c2f1481f5c974eb14f8c8266affe85b to your computer and use it in GitHub Desktop.
Save AndyGreenwell/4c2f1481f5c974eb14f8c8266affe85b to your computer and use it in GitHub Desktop.
Update to groupslices
@generated function groupslices{T,N}(A::AbstractArray{T,N}, dim::Int)
quote
if !(1 <= dim <= $N)
ArgumentError("Input argument dim must be 1 <= dim <= $N, but is currently $dim")
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
# Collect index of first row for each hash
uniquerow = Array(Int, size(A, dim))
firstrow = Dict{Prehashed,Int}()
for k = 1:size(A, dim)
uniquerow[k] = get!(firstrow, Prehashed(hashes[k]), k)
end
uniquerows = collect(values(firstrow))
# Check for collisions
collided = falses(size(A, dim))
@inbounds begin
@nloops $N i A d->(if d == dim
k = i_d
j_d = uniquerow[k]
else
j_d = i_d
end) begin
if (@nref $N A j) != (@nref $N A i)
collided[k] = true
end
end
end
if any(collided)
nowcollided = BitArray(size(A, dim))
while any(collided)
# Collect index of first row for each collided hash
empty!(firstrow)
for j = 1:size(A, dim)
collided[j] || continue
uniquerow[j] = get!(firstrow, Prehashed(hashes[j]), j)
end
for v in values(firstrow)
push!(uniquerows, v)
end
# Check for collisions
fill!(nowcollided, false)
@nloops $N i A d->begin
if d == dim
k = i_d
j_d = uniquerow[k]
(!collided[k] || j_d == k) && continue
else
j_d = i_d
end
end begin
if (@nref $N A j) != (@nref $N A i)
nowcollided[k] = true
end
end
(collided, nowcollided) = (nowcollided, collided)
end
end
ie = unique(uniquerow)
ic_dict = Dict{Int,Int}()
for k = 1:length(ie)
ic_dict[ie[k]] = k
end
ic = similar(uniquerow)
for k = 1:length(ic)
ic[k] = ic_dict[uniquerow[k]]
end
return ic
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment