# Sub2ind on julia

I have this matlab code I want to convert it to julia, but there is no sub2ind in julia. Does anyone have any ideia how i can translate it?

‘’’
for c = 1:num_channels

    l1_c = sub2ind(size(SAT), row_indices, l_idx, repmat(c, h, w));
u0_c = sub2ind(size(SAT), row_indices, u_idx, repmat(c, h, w));

l0_c = sub2ind(size(SAT), row_indices, l_idx - 1, repmat(c, h, w));
u1_c = sub2ind(size(SAT), row_indices, u_idx + 1, repmat(c, h, w));

l1 = sub2ind(size(SAT), row_indices, l_idx);
u0 = sub2ind(size(SAT), row_indices, u_idx);

l0 = sub2ind(size(SAT), row_indices, l_idx - 1);
u1 = sub2ind(size(SAT), row_indices, u_idx + 1);

% Full (center) areas.
C = SAT(u0_c) - SAT(l1_c);

% Left fractional areas.
alpha = (l_pos - xform_domain_position(l0)) ./ (xform_domain_position(l1) - xform_domain_position(l0));
yi    = I(l0_c) + alpha .* ( I(l1_c) - I(l0_c) );
L     = 0.5 .* (yi + I(l1_c)) .* (1-alpha) .* (xform_domain_position(l1) - xform_domain_position(l0));

% Right fractional areas.
alpha = (u_pos - xform_domain_position(u0)) ./ (xform_domain_position(u1) - xform_domain_position(u0));
yi    = I(u0_c) + alpha .* ( I(u1_c) - I(u0_c) );
R     = 0.5 .* (yi + I(u0_c)) .* (alpha) .* (xform_domain_position(u1) - xform_domain_position(u0));

F(:,:,c) = (L + C + R) / (2 * box_radius);

end


‘’’

1 Like

Could you give an example of one line of my code using this solution? I really could not implemented it, really new to Julia.

We could give you a better answer if you gave us an executable example. I have no idea what most of the variables above look like.

julia> SAT_SIZE = (2,3,5)
(2, 3, 5)

julia> SAT = reshape(1:prod(SAT_SIZE), SAT_SIZE);

julia> linidx = LinearIndices(size(SAT));

julia> linidx[2,3,5]
30

julia> linidx[1,2,4]
21

julia> linidx[1:2, 2:3, 4:5]
2×2×2 Array{Int64, 3}:
[:, :, 1] =
21  23
22  24

[:, :, 2] =
27  29
28  30


I came from Scilab where also ind2sub/sub2ind was used. For my uses, I converted that as follows:

dims = (10,10,10) # example
lindex = LinearIndices((dims[1],dims[2],dims[3]))
grid = CartesianIndices((1:dims[1],1:dims[2],1:dims[3]))[lindex]
gridx = getindex.(grid,1)
gridy = getindex.(grid,2)
gridz = getindex.(grid,3)


Here lindex can be any linear index you already have into a matrix. To get linear indices from x,y,z locations,

julia> grid[50]
CartesianIndex(10, 5, 1)

julia> lindex[grid[50]]
50

julia> lindex[grid[1:10,5,1]]
10-element Vector{Int64}:
41
42
43
⋮
49
50


If you are in a pinch, you can just use the following.

julia> function sub2ind(sz, args...)
linidx = LinearIndices(sz)
getindex.([linidx], args...)
end
sub2ind (generic function with 1 method)

julia> row = [1 2 3 1];

julia> col = [2 2 2 3];

julia> sub2ind((3,3), row, col)
1×4 Matrix{Int64}:
4  5  6  7

julia> I1 = [1 2 1 2];

julia> I2 = [2 2 1 1];

julia> I3 = [1 1 2 2];

julia> sub2ind((2,2,2), I1, I2, I3)
1×4 Matrix{Int64}:
3  4  5  6

julia> sub2ind((3,4,2), 2,1,2)
1-element Vector{Int64}:
14

1 Like

Looking at your example, it appears that you don’t need a linear index explicitly, but rather the ability to index an array at arbitrary combinations of coordinates. In Julia, CartesianIndex is a great tool for this.

For example, I would use l0 = @. CartesianIndex(row_indices, l_idx - 1) (note the @., which makes this equivalent to l0 = CartesianIndex.(row_indices, l_idx .- 1)). Then using these indices is as simple as xform_domain_position[l0].

3 Likes