Multidimensional Indices of Multiple pages

2 views (last 30 days)
Hi, I have a matrix of dimensions 5 by 7 by 50 e.g. g1 = rand(5,7,50) I have another matrix of indices for the row and column e.g. [1 3; 4 5; etc] Now I would like to index all the pages at those indices:
My attempt albeit slow:
for page = 2:50
lg = sub2ind(size(g1), ind(:,1), ind(:,2), page.*ones(length(ind),1),1))
g1(lg)
end
Could someone explain to me how to do the above without for loop. I think I can follow one of the link below to remove the sub2ind. Thx!
In addition to the following I did look at the doc
  1 Comment
Sean de Wolski
Sean de Wolski on 30 Apr 2012
+1 well written, well researched question. Welcome to MATLAB Answers!

Sign in to comment.

Accepted Answer

Andrei Bobrov
Andrei Bobrov on 30 Apr 2012
id12 = [1 3; 4 5];
out = g1(bsxfun(@plus,bsxfun(@minus,id12,[0 1])*[1;size(g1,1)],(0:size(g1,3)-1)*prod(size(g1(:,:,1)))));
  3 Comments
Geoff
Geoff on 1 May 2012
I really need to get my head around this bsxfun. Andrei, you seem to use it for at least 50% of your answers. It's obviously a powerful tool.
Sean de Wolski
Sean de Wolski on 1 May 2012
@Geoff, consider these, figure out how they're working:
A = bsxfun(@times,ones(2,3),reshape(1:5,1,1,5))
B = bsxfun(@plus,1:5,(1:4).')
Then answer this one:
http://www.mathworks.com/matlabcentral/cody/problems/4-make-a-checkerboard-matrix
with bsxfun

Sign in to comment.

More Answers (2)

Geoff
Geoff on 30 Apr 2012
You could use linear indexing if you convert each row/column into a page start index, then take the page range....
g1 = rand(5,7,50);
xy = [1 3; 4 5; 2 1];
% Get the first page index for each xy pair.
start = xy(:,1) + (xy(:,2)-1) * size(g1,1);
% Generate linear index across all pages.
makerange = @(x) x:size(g1,1)*size(g1,2):numel(g1);
indices = cell2mat( arrayfun( @makerange, start, 'UniformOutput', false ) );
% Pull out the pages. One page per row, corresponding to the rows in xy.
pages = g1(indices);
I'm a MatLab newbie, so there might be clever functions I don't know about that do some of this work for you. That effectively does what you are asking though. =)
  3 Comments
Geoff
Geoff on 1 May 2012
Bummer. I didn't think that _anything_ was slower than MatLab loops! =)
Sean de Wolski
Sean de Wolski on 1 May 2012
@Geoff, common misperception. Since the advent of the JIT compiler for-loops are often faster than vectorized methods.

Sign in to comment.


Sean de Wolski
Sean de Wolski on 30 Apr 2012
perhaps I'm not clear but if:
A = bsxfun(@times,ones(5,7),reshape(1:50,1,1,50)) %each slice is its index
and you want to extract all slices at rows 3,4 and cols, 4,5, just use the colon operator on the 3rd dimension
A([3 4],[4 5],:)
And you are correct, sub2ind will likely be slower than a well written for-loop.
  1 Comment
Wing
Wing on 30 Apr 2012
Not sure how this would work.
E.g.
g1 = rand(2,3,2)
g1(:,:,1) =
0.4008 0.8510 0.7962
0.9449 0.0088 0.6873
g1(:,:,2) =
0.9097 0.7171 0.0740
0.5371 0.9865 0.3725
indices = [1 3;2 1]
indices =
1 3
2 1
which means that we want to index row 1 column 3 and index row 2 and column 1.
So, getting "all"(initial post it starts from the second slice) the slices at those indices would give:
0.7962, 0.0740
0.9449, 0.5371

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!