Skip to content

Commit

Permalink
More sub2ind documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin-Mattheus-Moerman committed Mar 8, 2024
1 parent 62f1f1f commit 6187816
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 21 deletions.
38 changes: 17 additions & 21 deletions src/functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -578,30 +578,28 @@ end
Converts the linear indices in `ind`, for a matrix/array with size `siz`, to the
equivalent subscript indices.
"""
function ind2sub(siz,ind)

numDim = length(siz)
k = cumprod([siz[i] for i eachindex(siz)],dims=1)
m = prod(siz)

if any(ind.>m) || any(ind.<1)
error("Encountered index value of out of valid range 1:$m")
end

if length(ind)>1
A = [ind2sub_(ind_i,numDim,k) for ind_i ind]
else
A = ind2sub_(ind,numDim,k)
function ind2sub(siz::Union{Tuple{Vararg{Int64, N}}, Vector{Int64}},ind::Union{Tuple{Vararg{Int64, M}}, Vector{Int64}}) where N where M
if !isempty(ind) # Not empty so subscript indices will be derived
numDim = length(siz) # Number of dimensions from length of size
k = cumprod(siz) # Cumulative product of size
m = prod(siz) # Number of elements
if any(ind.>m) || any(ind.<1)
error("Encountered index value of out of valid range 1:$m")
end
if length(ind)>1 # Multiple indices so loop over them
A = [ind2sub_(ind_i,numDim,k) for ind_i ind]
else # Just one so
A = ind2sub_(ind,numDim,k)
end
else # Empty so return an empty vector
A = Vector{Int64}[]
end

return A
end

# ind2sub helper function to parse just a single linear index and produce a single subscript index set
function ind2sub_(ind,numDim,k)

function ind2sub_(ind::Integer,numDim::Int64,k::Union{Int64,Vector{Int64},Tuple{Vararg{Int64, N}}}) where N
a = Vector{Int64}(undef,numDim) # Initialise a

for q numDim:-1:1 # For all dimensions
if isone(q) # First 1st dimension
a[1] = rem(ind-1,k[1]) + 1
Expand All @@ -610,12 +608,10 @@ function ind2sub_(ind,numDim,k)
a[q] = (ind - p)./k[q-1] + 1 # Current
ind = p # Set indices as "previous"
end
end

end
return a
end


"""
sub2ind(siz,A)
Expand Down
31 changes: 31 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,37 @@ using Test, Comodo, Comodo.GeometryBasics
IJK_C = ind2sub(size(C),ind)
@test all([C[ind[i]] == C[IJK_C[i][1],IJK_C[i][2],IJK_C[i][3]] for i eachindex(ind)])
end

@testset "Vector specifying size" begin
C = rand(3,5,2)
IJK_C = ind2sub(collect(size(C)),ind)
@test all([C[ind[i]] == C[IJK_C[i][1],IJK_C[i][2],IJK_C[i][3]] for i eachindex(ind)])
end

@testset "Tuple specifying indices" begin
C = rand(3,5,2)
ind_tuple = Tuple(ind[i] for i eachindex(ind))
IJK_C = ind2sub(collect(size(C)),ind_tuple)
@test all([C[ind_tuple[i]] == C[IJK_C[i][1],IJK_C[i][2],IJK_C[i][3]] for i eachindex(ind_tuple)])
end
end

@testset "ind2sub_" verbose = true begin
ind = 6
@testset "1D i.e. Vector" begin
A = rand(30)
@test Comodo.ind2sub_(6,length(size(A)),cumprod(size(A))) == [6]
end

@testset "2D i.e. 2D Matrix" begin
B = rand(5,6)
@test Comodo.ind2sub_(6,length(size(B)),cumprod(size(B))) == [1,2]
end

@testset "3D i.e. 3D matrix" begin
C = rand(3,5,2)
@test Comodo.ind2sub_(6,length(size(C)),cumprod(size(C))) == [3,2,1]
end
end

@testset "elements2indices" verbose = true begin
Expand Down

0 comments on commit 6187816

Please sign in to comment.