MATLAB Answers

How can I make following part of code without for loop?

1 ビュー (過去 30 日間)
Shamsi Musayev
Shamsi Musayev 2020 年 5 月 13 日
コメント済み: Rik 2020 年 5 月 13 日
How can I make following part of code without for loop?:
for i=1:n_values
pre_matrix(i,J{i})=0
end
J{i} is a cell array that each cell includes some numbers that I want to change those elements in i-th row of pre_matrix. Each cell has different numbers and size of cells are different.
pre_matrix is very huge matrix, therefore it takes so long time to create matrix everytime. Is it possible to do same work without for loop?

  0 件のコメント

サインインしてコメントする。

採用された回答

Kelly Kearney
Kelly Kearney 2020 年 5 月 13 日
I'm having a hard time finding a solution that's faster than the original loop...
% Build test data
n_values = 10000;
nc = 100;
pre_matrix = rand(n_values,nc);
sz = size(pre_matrix);
J = cell(1,n_values);
for ii = 1:n_values
n0 = randi(nc,1);
J{ii} = randi(nc,1,n0);
end
% The original loop
tic
for i=1:n_values
pre_matrix(i,J{i})=0;
end
toc
% Indexing directly, but with loop to get row indices (Rik's suggestion)
tic
I = cell(size(J));
for ii = 1:n_values
I{ii} = ii.*ones(size(J{ii}));
end
idx = sub2ind(sz, cat(2, I{:}), cat(2, J{:}));
pre_matrix(idx) = 0;
toc
% Indexing directly, no explicit loops
tic
I = cellfun(@(a,b) ones(size(a)).*b, J, num2cell(1:n_values), 'uni', 0);
idx = sub2ind(sz, cat(2, I{:}), cat(2, J{:}));
pre_matrix(idx) = 0;
toc
Results:
Elapsed time is 0.017597 seconds. <- loop
Elapsed time is 0.047797 seconds. <- indexing with loop
Elapsed time is 0.119106 seconds. <- indexing with cellfun
My guess here is perhaps the culprit is that missing semicolon in the loop? If you're printing out the huge matrix every iteration, that's definitely going to take some time! But the loop itself is pretty fast.

  2 件のコメント

Shamsi Musayev
Shamsi Musayev 2020 年 5 月 13 日
Thanks for your time, Kelly. You are totally right, I closed command window, hence, I did not observed that it is printing matrix in each step and I have not checked the culprit :)
Rik
Rik 2020 年 5 月 13 日
Good catch. I guess this is why you want mlint to give you warnings about missing semicolons.

サインインしてコメントする。

その他の回答 (1 件)

Rik
Rik 2020 年 5 月 13 日
Your issue is probably not with the loop itself, but with the modifications to the large matrix. You should probably generate a list of indices and do the modification in one go.
sz=size(pre_matrix);
ind_list=cell(1,n_values);
for i=1:n_values
ind_list{i}=sub2ind(sz,i*ones(size(J{i})),J{i});
end
ind_list=cell2mat(ind_list);%untested code, check this line
pre_matrix(ind_list)=0;

  1 件のコメント

Shamsi Musayev
Shamsi Musayev 2020 年 5 月 13 日
Yeah, it was the problem. For each step of the for loop matrix was modified and new matrix was created, hence, it took so long time. Your code worked very well. Thanks :)

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by