Hi there, I've got a 3d matrix and I'm trying to select a
subset of elements to create a 2d matrix. At the moment I'm
doing this in a loop, and was wondering if anyone had a
trick they could teach me to avoid this loop becoming a
bottleneck.
Imagine a 3x3x3 rubix cube of elements:
>> rc = rand(3,3,3);
I can select, say, a plane through the 3rd dimension as follows:
>> myPlanar2d = squeeze(rc(2,:,:));
But what if I want to move along the 3rd dimension of my
rubix cube and select, say, the [1 3 2] rows instead of just
the second row as above? At the moment I'm doing this in a
loop as follows:
idxs = [1 3 2];
myIndexed2d = zeros(3,3);
for i = 1:length(idxs)
myIndexed2d(i,:) = rc(idxs(i),:,i);
end
Is there a shortcut I can take that avoids my loop?
However, if you're looking for speed, then in newer
versions of MATLAB (at least since since R2006a) the loop
is likely to be faster for the purely numeric data that
you're manipulating.
> Hi there, I've got a 3d matrix and I'm trying to select a
> subset of elements to create a 2d matrix. At the moment I'm
> doing this in a loop, and was wondering if anyone had a
> trick they could teach me to avoid this loop becoming a
> bottleneck.
>
> Imagine a 3x3x3 rubix cube of elements:
>>> rc = rand(3,3,3);
>
> I can select, say, a plane through the 3rd dimension as follows:
>
>>> myPlanar2d = squeeze(rc(2,:,:));
>
> But what if I want to move along the 3rd dimension of my
> rubix cube and select, say, the [1 3 2] rows instead of just
> the second row as above? At the moment I'm doing this in a
> loop as follows:
>
> idxs = [1 3 2];
> myIndexed2d = zeros(3,3);
> for i = 1:length(idxs)
> myIndexed2d(i,:) = rc(idxs(i),:,i);
> end
>
> Is there a shortcut I can take that avoids my loop?
You can use sub2ind. Build 3 3x3 matrices, where the first contains the
i indices desired for each of the elements, the second the j indices, etc.
I leave the timing to you. The loop will probably be faster, though
sub2ind might win if you need to do this repeatedly, and precompute one
or more of the index matrices.
meshgrid or ndgrid can also help generate the "easy" matrices. For
instance, the second two matrices above (j and k) can be generated like:
"Phil Goddard" <philgoddardNOSPAM@telus.net> wrote in
message <fsfdem$ait$1@fred.mathworks.com>...
> You could use ARRAYFUN in conjunction with an appropriate
> function handle, i.e.
>
> fh = @(idx,page) rc(idx,:,page)';
> myIndexed2d = cell2mat(arrayfun(fh,idxs,1:length
> (idxs),'UniformOutput',false))';
>
> However, if you're looking for speed, then in newer
> versions of MATLAB (at least since since R2006a) the loop
> is likely to be faster for the purely numeric data that
> you're manipulating.
>
> Phil.
Thanks Phil and Peter.
The real voxel data I'm working with is much larger than
3x3x3, so the sub2ind method ends up taking too much memory
to build the index arrays. The arrayfun method is new to me
so I'll try this and check its speed compared to the loop.
Public Submission Policy
NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for
all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content.
Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available
via MATLAB Central. Read the complete Disclaimer prior to use.