Matrix indexing of a 3D matrix, one by one each 3D layer?
1 次查看(过去 30 天)
显示 更早的评论
J = cat(3, magic(4), magic(4), magic(4)); % 3D matrix
maskIdx = J(:,:,1)>8;
%%I want to do something like below
J{:,:,1}(maskIdx) = ones(8,1);
J{:,:,2}(maskIdx) = 2*ones(8,1);
J{:,:,3}(maskIdx) = 3*ones(8,1);
Please focus on LHS only. How to apply same maskIdx on different layers. Note maskIdx created by the 1st layer which is 2D.
2 个评论
Rik
2018-7-12
The only thing I can think of is using find and subs2ind to generalize this, but that feels very ineffective. So if nobody has a better idea and you can't implement this on your own, comment here and I'll post an answer with example code.
采纳的回答
Rik
2018-7-12
Logicals are 8 times smaller than doubles, so memory concerns shouldn't be an issue. If you can work with a big J, you can easily afford to replicate the mask. The code below does its thing in 3.4 seconds for a 1000000x100x3 J.
1e5 done in 0.0 seconds
1e6 done in 0.0 seconds
1e7 done in 0.3 seconds
1e8 done in 3.4 seconds
Name Size Bytes Class Attributes
J 1000000x100x3 2400000000 double
maskIdx 1000000x100x3 300000000 logical
code:
for k_base=5:8
k=10^(k_base-2);
clear J maskIdx n targetDim
J=rand(k,100,3);
maskIdx=J(:,:,1)>0.8;
n=sum(maskIdx(:));
A=ones(n,1);
B=2*A;
C=3*A;
tic
maskIdx(1,1,size(J,3))=false;%extend to 3D
targetDim=1;
J(circshift(maskIdx,targetDim-1,3))=A;
targetDim=2;
J(circshift(maskIdx,targetDim-1,3))=B;
targetDim=3;
J(circshift(maskIdx,targetDim-1,3))=C;
fprintf('1e%d done in %.1f seconds\n',log10(numel(J)/3),toc)
end
0 个评论
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Introduction to Installation and Licensing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!