More Efficient ismember Calculation

3 次查看(过去 30 天)
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 个评论
Walter Roberson
Walter Roberson 2020-4-17
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 2020-4-20
ahh, I understand! I've now, I believe, moved as much as I can outside of loops.

请先登录,再进行评论。

采纳的回答

Steven Lord
Steven Lord 2020-4-16
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 个评论
Walter Roberson
Walter Roberson 2020-4-17
But you should still make the other improvements I noted about not computing the same value multiple times.
Ayden Clay
Ayden Clay 2020-4-20
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.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Loops and Conditional Statements 的更多信息

产品


版本

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by