More Efficient ismember Calculation

2 Ansichten (letzte 30 Tage)
Ayden Clay
Ayden Clay am 16 Apr. 2020
Kommentiert: Ayden Clay am 20 Apr. 2020
Hello, I'm working on an interpolation for a specific project that I'm working on and have managed to produce a very fast interpolation function for N-D array for042. There is one final bottleneck that is taking up 84% of the total run-time of the program. Inserted are the profiler and exemplar code, any and all optimizations are greatly appreciated, but the particular line is obvious from the profiler.
alpha = -5:5:30;
mach = 1:6:25;
beta = -5:2.5:5;
num = zeros(length(alpha),length(mach),length(beta));
for cnt = 1:numel(alpha)
for cnt1 = 1:numel(mach)
for cnt2 = 1:length(beta)
num(cnt,cnt1,cnt2) = 3*alpha(cnt)+mach(cnt1)/2+beta(cnt2);
end
end
end
for cnt2 = 1:length(beta)
data.for006{cnt2}.cd = num(:,:,cnt2);
end
Is an example of the data set that we're working with.
And the line in question from the profiler is part of this block:
a = zeros(1,2^size(CURRENT,1)-1);
curridx = zeros(1,size(CURRENT,1));
for cnt = 1:(2^size(CURRENT,1))
change = find((rem(cnt-1,2.^(0:size(CURRENT,1)-1))==0)==1);
curridx(change) = 1*curridx(change)==0;
idx = lidx.*(curridx==0) + uidx.*(curridx==1);
chkvals = zeros(1,length(idx));
for cnt1 = 1:length(idx)
B = RANGES{cnt1};
chkvals(cnt1) = B(idx(cnt1));
end
chkvals = [chkvals(2),chkvals(4:end)];
% INEFFICIENT LINE %
a(cnt) = DATA.for042{find(ismember(DATA.permutation,chkvals,'rows'))}.cn(sub2ind_a(siz,idx));
end
  11 Kommentare
Walter Roberson
Walter Roberson am 17 Apr. 2020
But the length of idx does not depend upon the contents of CURRENT, only on the size of CURRENT, right? So you can pre-compute it.
In the great majority of cases, if you can move a computation out of a loop, doing so will result in more efficient code. This is not always the case, but most of the time.
Ayden Clay
Ayden Clay am 20 Apr. 2020
ahh, I understand! I've now, I believe, moved as much as I can outside of loops.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Steven Lord
Steven Lord am 16 Apr. 2020
What's the most time consuming part of that line that you've identified as the bottleneck? Is it the ismember call, the indexing into DATA.for042, the indexing into the result of that indexing to retrieve part of the cn field, or the assignment into a section of a? To tell, break that into four parts (for performance profiling purposes.)
ind = ismember(DATA.permutation,chkvals,'rows');
data1 = DATA.for042{ind};
data2 = data1.cn(sub2ind_a(siz,idx));
a(cnt) = data2;
My guess is that the ismember call still might be the most time consuming part of that process, but it's not going to be all 83.4% of the total runtime of your code.
  6 Kommentare
Walter Roberson
Walter Roberson am 17 Apr. 2020
But you should still make the other improvements I noted about not computing the same value multiple times.
Ayden Clay
Ayden Clay am 20 Apr. 2020
I completely agree, I've implemented a large number of those changes too (there may be more), I've tried to remove some of the for loops in favour of vector operations. There is still some work to be done, but this is much closer to what I needed. Thank you.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange

Produkte


Version

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by