2013-05-08 6 views
1

У меня есть две петли, встроенные в код, который повторяется много раз. Я хочу, чтобы ускорить процесс:Как векторизовать матрицу, индекс которой является матрицей в MATLAB?

for i = 1:10 
for j = 1:10 
    A(i,j) = B(i,j,D(i,j))*C(i,j); 
end 
end 

Здесь D состоит из целых чисел, которые являются индексы к B. Вне зависимости от D для-петли может быть заменена поэлементно умножения матриц. Проблема заключается в том, как оценить B элегантным способом. Я искал SO и MathWorks-страницы и попытался линейной индексации, но это приводит к ошибкам:

d = reshape(D, 100, []); 
b = reshape(B, 100, []); 
arrayfun(@(x) b(x,d(x)), 1:100); 

Что я делаю неправильно? Есть ли способ заменить два for-loops?

+0

Проблема не только оценки 'b' изящным образом, вы перезапись' Ā' все время, которое означает, что единственный результат, вы сможете get - последний слой, т. е. когда 'i = 10' и' j = '10' – Oleg

+0

@OlegKomarov Спасибо, что комментируете! Мой код на самом деле все в порядке и делает то, что он должен был делать: создание элементарной матрицы Matrix 'A' путем умножения элементов' B' и 'C'. Сложная часть - поиск индексов из 'D'. –

ответ

1

Вы можете превратить D в линейный индекс:

[rows,cols]=ndgrid(1:10,1:10); 
idx = sub2ind(size(B),rows(:),cols(:),D(:)); 

A = zeros(10,10); %# initialize A to the right size 
A(:) = B(idx).*C(:); 
+0

Отлично! Ваш фрагмент кода привел меня к решению, которое выполняется значительно быстрее, чем мои for-loops. Поскольку 'B' является трехмерным массивом, ваша вторая строка кода должна быть' idx = sub2ind (size (B), rows (:), cols (:), D (:)); 'Спасибо! –

+0

@ BQ92-PwDD3: Я исправил решение. Рад, что это помогло! – Jonas

0

Вы можете использовать поэлементное умножение B против слоев в A упорядоченных по показателям в D (обратите внимание, что вы перекручивание сначала по строкам, затем столбцы, а значит, вы идете прямо до конца строки, то к следующий ряд и т. д. ... поэтому я транспонирую и переформатируюсь в столбец D).

Простой способ заключается в использовании bsxfun():

out = bsxfun(@times, A(:,:,reshape(D',[],1)), B); 

, где каждый слой аут:

out(:,:,1) = A(:,:,D(1,1)).*B(:,:) 
out(:,:,2) = A(:,:,D(1,2)).*B(:,:) 
... 
out(:,:,ncols*(i-1) + j) = A(:,:,D(i,j)).*B(:,:) 

Если это не то, что вы хотите, мое плохое. Я удалю ответ.

+0

Спасибо за ваше предложение. Существует путаница переменных. Кроме того, я не мог понять, как это решение решит проблему ... –

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