Speed up indexing without using a loop
21 ビュー (過去 30 日間)
古いコメントを表示
Hi all,
I would like to know if there is a way to speed up indexing procedure in the following code:
N; % given nx1 matrix with some values
D = inf(n,1);
D(1,1) = 0;
M = zeros(n,1)
while sum(M)~=length(N)
D_adj = D;
M_index = find(M);
D_adj(M_index) = inf; % or any very large number
[~,index_m] = min(D_adj);
M(index_m) = 1;
FOR LOOP % another code for a FOR loop to update values in matrix D;
end
Essentially, for every iteration within WHILE loop, I update a corresponding element of matrix M (by allocation value of 1). My main problem and what slows down my code is the procedure for computing M_index, updating the corresponding elements in matrix D_adj (by allocation value of inf so that they are not taken into account when computing the min value of all elements in matrix D_adj that have zero value in matrix M), and finding the index (of the min element in D_adj) in matrix D. Do you have any suggestion on how I can improve these operations?
Thanks in advance!
4 件のコメント
採用された回答
Jan
2018 年 3 月 16 日
編集済み: Jan
2018 年 3 月 16 日
Maybe logical indexing is faster:
N; % given nx1 matrix with some values
D = inf(n,1);
D(1,1) = 0;
M = false(n,1);
while ~all(M)
D_adj = D;
D_adj(M) = inf; % or any very large number
[~, index_m] = min(D_adj);
M(index_m) = true;
FOR LOOP % another code for a FOR loop to update values in matrix D;
end
Remember the golden rule of optimizing code: Use the profiler at first to find the bottleneck of the function. If you accelerate a part of the by a factor 2, but this part needs 2% of the processing time, the total speedup is 1% only.
I doubt, that this indexing is the bottleneck of your code. But logical indexing should be at least faster.
I guess, that the part hidden behind "FOR LOOP" can be improved such, that the new minimal value can be found by a cheaper method.
3 件のコメント
Jan
2018 年 3 月 16 日
編集済み: Jan
2018 年 3 月 16 日
Posting the original code is useful. You create variables dynamically by a load without catching the inputs. This impedes the JIT acceleration and the debugging. I guess, that all data you load from the file in "N_v", "aa_indx1" and "A_indx"? Then:
Data = load('data.mat');
N_v = Data.N_v;
aa_indx1 = Data.aa_indx1;
A_indx = Data.A_indx;
... expand this on demand
Replace:
MM = [1:1:length(N_v)]';
by the nicer:
MM = (1:length(N_v)).';
This will not improve the runtime, but there is no need for the concatenation operator [] here.
ismembc is not supported in modern Matlab versions anymore. I assume that this part can be simplified:
aa= A_indx(aa_indx1{indx_v,1},:);
a = aa(~ismembc(aa(:,2),MM(M)),:);
Something like this:
a = aa(M(aa(:, 2)));
but this is a bold guess only. I cannot run your code currently.
This loop can be vectorized:
for i = 1:length(a(:,1))
d_v_indx_j = a(i,2);
if d_v(d_v_indx_j) > d_v(indx_v) + a(i,3)
d_v(d_v_indx_j) = d_v(indx_v) + a(i,3);
p_v(d_v_indx_j) = N_v(indx_v);
end
end
by:
c = a(:, 2); % do this before the loops
...
d = d_v(index_v) + a(:, 3);
m = d_v(c) > d;
d_v(m) = d(m);
p_v(m) = N_v(indx_v);
As said already: This is untested, but the idea should be clear.
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Matrix Indexing についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!