Logical indexing two dimensions. How do I avoid a nested for loop?
1 次查看(过去 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 中查找有关 Whos 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!