2016-11-24 2 views
0

В MATLAB я ищу эффективный (и/или векторизованный) способ заполнения матрицы, выбирая из нескольких матриц с учетом «селекторной матрицы». Например, даны три матрицы источникаВыберите значения с матрицей индексов в MATLAB?

M1 = [0.1, 0.2; 0.3, 0.4] 
M2 = [1, 2; 3, 4] 
M3 = [10, 20; 30, 40] 

и матрица индексов

I = [1, 3; 1, 2] 

Я хочу, чтобы создать новую матрицу M = [0.1, 20; 0.3, 4], выбрав первую запись из M1, второй из M3 и т.д.

Я могу определенно сделать это во вложенном цикле, пройдя каждую запись и заполнив ее, но я уверен, что есть более эффективный способ.


Что делать, если M1, M2, M3 и M являются все 3D матрицы (RGB изображения)? Каждая запись I рассказывает нам, из какой матрицы мы должны взять 3-вектор. Скажем, если I(1, 3) = 3, то мы знаем, что записи, индексированные (1, 3, :) из M, должны быть M3(1, 3, :).

ответ

0

Способ сделать это, не изменяя способ хранения вашей переменной, - использовать маски. Если у вас несколько матриц, это делает работу, избегая цикла for. Вы не сможете полностью векторизовать, не проходя через функцию cat, или используя ячейки.

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); 
0

Одним из способов сделать это может быть создание 4D-матрицы с вашими изображениями. У него есть затраты на увеличение объема памяти или, по крайней мере, изменение схемы памяти.

Mcat = cat(4, M1, M2, M3); 

Затем вы можете использовать функцию sub2ind, чтобы создать Векторизованный Matrix.

% 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); 

Я не проверял его должным образом, но он должен работать.

0

Я думаю, что лучший способ приблизиться к этому - это размерность стека (т. Е. Иметь матрицу со значениями, которые являются вашими отдельными матрицами). К сожалению, MATLAB на самом деле не поддерживает индексирование уровня массива, поэтому в итоге вы используете линейную индексацию для преобразования своих значений через команду subs2ind. Я считаю, что вы можете использовать приведенный ниже код.

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))) 

С более сложным (3-мерным корпусом) вам необходимо расширить код для более высоких измерений.

Смежные вопросы