Q: Select values with a matrix of indices in MATLAB? In MATLAB, I am looking for an efficient (and/or vectorized) way of filling a matrix by selecting from multiple matrices given a "selector matrix." For instance, given three source matrices
M1 = [0.1, 0.2; 0.3, 0.4]
M2 = [1, 2; 3, 4]
M3 = [10, 20; 30, 40]

and a matrix of indices
I = [1, 3; 1, 2]

I want to generate a new matrix M = [0.1, 20; 0.3, 4] by selecting the first entry from M1, second from M3, etc.
I can definitely do it in a nested loop, going through each entry and filling in the value, but I am sure there is a more efficient way.

What if M1, M2, M3 and M are all 3D matrices (RGB images)? Each entry of I tells us from which matrix we should take a 3-vector. Say, if I(1, 3) = 3, then we know entries indexed by (1, 3, :) of M should be M3(1, 3, :).

A: One way of doing this could be to generate a 4D matrix with you images. It has the cost of increasing the amount of memory, or at least, change you memory scheme.
Mcat = cat(4, M1, M2, M3);

Then you can use the function sub2ind to get a vectorized Matrix creation.
% get the index for the basic Image matrix
I = repmat(I,[1 1 3]); % repeat the index for for RGB images
Itmp = sub2ind(size(I),reshape(1:numel(I),size(I)));

% update so that indices reach the I(x) value element on the 4th dim of Mcat.
Itmp = Itmp + (I-1)*numel(I);

% get the matrix
M = Mcat(Itmp);

I haven't tested it properly, but it should work.

A: I think the best way to approach this is to stack dimensions (ie have a matrix with values that are each of your indvidiual matricies). Unfortunately MATLAB doesn't really support array level indexing so what ends up happening is you end up using linear indexing to convert your values through the subs2ind command. I believe you can use the code below. 
M1 = [0.1, 0.2; 0.3, 0.4]
M2 = [1, 2; 3, 4]
M3 = [10, 20; 30, 40]



metamatrix=cat(3,M1,M2,M3)
%Create a 3 dimenssional or however many dimension matrix by concatenating
%lower order matricies

I=[1,1,1;1,2,3;2,1,1;2,2,2]

M=reshape(metamatrix(sub2ind(size(metamatrix),I(:,1),I(:,2),I(:,3))),size(metamatrix(:,:,1)))

With a more complex (3 dimensional case), you would have to extend the code for higher dimensions.

A: A way of doing this, without changing the way you store your variable is to use masks. If you have a few matrices, it is doing the job avoiding a for loop. You won't be able to fully vectorize without going through the cat function, or using cells.
M = zeros(size(M1));

Itmp = repmat(I==1,[1 1 size(M1,3)]); M(Itmp) = M1(Itmp);
Itmp = repmat(I==2,[1 1 size(M1,3)]); M(Itmp) = M2(Itmp);
Itmp = repmat(I==3,[1 1 size(M1,3)]); M(Itmp) = M3(Itmp);

