Accessing an element of an array using an array as its index.

Hello,
I am writing up an interpolation function and need to define the vertices of the hypercube surrounding the current values.
My current code to do this is:
% (3) Calculate the A values that are the vertices of the N-D hypercube.
a = zeros(1,2^size(CURRENT,1)-1);
curridx = zeros(1,size(CURRENT,1));
idx = zeros(1,size(CURRENT,1));
for cnt = 1:(2^size(CURRENT,1))
change = find((mod(cnt-1,2.^(0:size(CURRENT,1)-1))==0)==1);
curridx(change) = 1*curridx(change)==0;
for cnt1 = 1:size(CURRENT,1)
idx(cnt1) = lidx(cnt1)*(curridx(cnt1)==0)+uidx(cnt1)*(curridx(cnt1)==1);
end
Subs = num2cell(idx);
a(cnt) = DATA(Subs{:});
end
With the profiler showing that the lines
Subs = num2cell(idx);
a(cnt) = DATA(Subs{:});
Are 32.1% and 23.8% of the total run-time respectively. Does anybody know a more efficient method?
Thank you!

4 commentaires

Why do you need to convert numeric to cell?
Subs = num2cell(idx);
a(cnt) = DATA(Subs{:});
Why don't just
a(cnt) = DATA(idx); % only one values inside 'idx'?
And no for loop is needed. Use element-wise operator .*
% for cnt1 = 1:size(CURRENT,1)
% idx(cnt1) = lidx(cnt1)*(curridx(cnt1)==0)+uidx(cnt1)*(curridx(cnt1)==1);
% end
idx = lidx.*(curridx==0) + uidx.*(curridx==1);
Thank you for your suggestions Darova.
Currently, idx is an 1xN array since it points to, say, 7 variables which are concatenated into a singular dataset.
So idx is worked out from the list alpha,beta,mach,delta1,delta2,delta3 and delta4 is there an efficient way to change this into it's singular index? If so, then your method could be more efficient than what I am currently using.
did you try my suggestions?
I did, sadly idx is a 7x1 number, and isn't readily inputtable into data.

Connectez-vous pour commenter.

 Réponse acceptée

Interesting...I guess your question title should be edited to "use array as subscripts into multidimensional array". I dug into the sub2ind() to extract how to use subscripts to get a linear index and came up with this test
siz = [4,3,5,7]
subs = [1,2,4,6]
subsc = num2cell(subs)
ndx = sub2ind(siz,1,2,4,6)
ndx = sub2ind(siz,subsc{:})
ndx = subs(1);
k = cumprod(siz);
for i = 2:length(subs)
ndx = ndx + (subs(i)-1)*k(i-1);
end
ndx
So you should be able to do
function ndx = sub2ind_a(siz,subs)
% no-check version of sub2ind, with input array of subs
ndx = subs(:,1);
k = cumprod(siz);
for i = 2:size(subs,2)
ndx = ndx + (subs(:,i)-1)*k(i-1);
end
end
And in your code:
siz = size(DATA); % somewhere at the top
% and in your loop
a(cnt) = DATA(sub2ind_a(siz,idx));
For readability I would change your variable name "idx" to "subs_a" or something.

4 commentaires

but not sure if this solves the speed problem, though i would think so
I'll give this a go now and approve it as an answer if it works, thank you!
This absolutely works and is around 5% faster, which is wonderful.
Thank you greatly!
The difference between indexing on the linearized subscripts versus using num2cell and subscripting is about 10x faster on my laptop...maybe you are spending too much time determining the subscripts themselves (e.g., see darova's comments about the looping)

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by