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