Reputation: 75
Strangely enough I could not find a general answer for this simple question. The one linked answer here is not general.
sub2ind
can be avoided, I believe, with the following equivalence [here]
sub2ind(size(A), row1, row2, row3, row4)
is equivalent to
row1+ (row2-1)*size(A,1) + (row3-1)*size(A,1) *size(A,2) + (row4-1)*size(A,1) *size(A,2) *size(A,3)
.
Meanwhile ind2sub
for 2 dimensions (i.e., no row3, row4
....) can be avoided as:
i = rem(index-1,size(A,1))+1;
j = (index-i)/size(A,1)+ 1 ;
is equivalent to:
[i,j] = ind2sub(size(A),index);
How do we generalize ind2sub
for 3D matrices and so on? I am not interested in debates about whether we should avoid it or not.
Upvotes: 3
Views: 1078
Reputation: 60645
Your ind2sub
code can be generalized simply by adding another rem
over the second dimension:
i = rem(index-1, size(A,1)) + 1;
index = (index-i) / size(A,1) + 1;
j = rem(index-1, size(A,2)) + 1;
k = (index-j) / size(A,2) + 1;
This is actually a lot easier to do using zero-based indexing, since it gets rid of all the +1
and -1
bits. This would be the generalized code for any number of dimensions:
index = index-1; % convert to 0-based indexing
sz = size(A);
i = zeros(size(sz));
for d = 1:numel(sz)
i(d) = rem(index, sz(d));
index = (index - i(d)) / sz(d);
end
i = i + 1; % convert back to 1-based indexing
Upvotes: 2
Reputation: 13
Blockquote
i = rem(index-1, size(A,1)) + 1;
index = (index-i) / size(A,1) + 1;
j = rem(index-1, size(A,2)) + 1;
k = (index-i) / size(A,2) + 1;
This part over here doesn't seem to work properly with the k. I see different values for the ind2sub's obtained k and the one obtained in the given code. (diff is smaller than 1 though)
EDIT: seems that last line needs to be
Blockquote
k = (index-j) / size(A,2) + 1;
Finally, checking with "tic/toc", this implementation is not faster that ind2sub in Matlab R2020b...
Upvotes: 0