Logical indexing two dimensions. How do I avoid a nested for loop?
2 ビュー (過去 30 日間)
古いコメントを表示
I have a matrix X with doubles of size = 450 8156 and another matrix C with logical values with size = 64 8156 where 400 of the 8156 elements of each of the 64 rows are true. And I also have yet another matrix T of logical values with size = 9 450 where 400 of the 450 elements of each row are true.
I want to extract all the true values of X so that the resulting matrix becomes of size = 400 400 9 64
I can do this easily with a double for loop like this:
for n = 1 : 64
for z = 1 : 9
A(:,:,z,n) = X(T(z,:)',C(n,:));
end
end
but it is very slow. Is there a faster, more reasonable, vectorized way of doing thing? By using repmat, reshape, bsxfun, arrayfun etc.? Anyone good with logical indexing that can help me out?
Thanks.
5 件のコメント
採用された回答
Jan
2016 年 4 月 17 日
編集済み: Jan
2016 年 4 月 17 日
You can try a logical indexing:
T = T.' ;
A = zeros(400,400,9,64);
Cn = false(1, size(X, 2));
for n = 1 : 64
Cn(:) = false;
Cn(C(n, :)) = true;
for z = 1 : 9
A(:,:,z,n) = X(T(:,z), Cn);
end
end
I have no idea if this is faster. Please provide some meaningful test data, such that the readers can perform some experiments before posting.
Do you have the parallel programming toolbox?
2 件のコメント
その他の回答 (2 件)
Azzi Abdelmalek
2016 年 4 月 15 日
You can improve your for loop by pre-allocating
A=zeros(400,400,9,64)
0 件のコメント
Jos (10584)
2016 年 4 月 15 日
Pre-allocate but also put the transpose out of the loop!
T = T.' ;
A = zeros(400,400,9,64)
for n = 1 : 64
for z = 1 : 9
A(:,:,z,n) = X(T(:,z), C(n,:));
end
end
Damn, this is fast :-)
2 件のコメント
Jos (10584)
2016 年 4 月 17 日
tens of thousands of times x 0.1s per time (which is fast) = thousands of seconds = a few hours. Maybe Matlab is not the right tool for the job?
参考
カテゴリ
Help Center および File Exchange で Loops and Conditional Statements についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!