3

У меня есть размер матрицы 3D (x, y, N) и размер матрицы 2D (N, N).Линейная комбинация срезов в 3D-матрице MATLAB

Я хотел бы манипулировать этими двумя способами, чтобы каждый столбец в 2D-матрице имел коэффициенты для линейной комбинации двумерных размерных (x, y) срезов в 3D-матрице. И я хотел бы сделать это для всех N столбцов в 2D-матрице.

Схематически

Schematic Picture Link

В настоящее время код выглядит следующим образом:

A = zeros(numel(x_axis), numel(y_axis), N); 
B = zeros(numel(x_axis), numel(y_axis), N); 
C = zeros(N, N) 
for i = 1 : N 
    for j = 1 : N 
     A(:,:,i) = A(:,:,i) + B(:,:,j) * C(j,i); 
    end 
end 

Но это довольно медленно. Есть ли способ ускорить код MATLAB путем векторизации?

+0

У вас есть matlab 2016b или более поздняя версия? – obchardon

+0

К сожалению, нет. У меня есть доступ к 2015a по 2016 год. –

+0

Хорошо, потому что matlab 2016b представляет новую функцию, называемую неявным расширением, которая может линеаризовать эту проблему. Поэтому лучше всего использовать вместо этого 'bsxfun'. – obchardon

ответ

2

Если я правильно понимаю вашу проблему наилучшим образом, то это должно работать:

[p,q,N] = size(B); 
A = reshape(reshape(B, [p*q, N]) * C, [p, q, N]); 

редактировать: Чистого версию, предложенную Suever:

A = reshape(reshape(B, [], size(B, 3)) * C, size(B)) 

Обобщение на случай RD:

A = reshape(reshape(B, [], size(B, ndims(B))) * C, size(B)) 
+1

Я бы, вероятно, просто сделал: 'A = изменить форму (изменить, (B, [], размер (B, 3)) * C, размер (B))' – Suever

+0

Хорошая точка. Я продолжаю забывать, что вы можете пропустить аргументы в изменении. Вы выглядите намного элегантнее. +1 для этого. – Florian

+0

Как я могу расширить это до того, где B - это 4D-матрица и где C все еще является двумерной матрицей? В этом случае я хотел бы найти линейные комбинации 3D-фрагментов B. –

2

Вы можете использовать bsxfun, который рассчитает это очень быстро для вас. Мы должны использовать permute, чтобы немного упорядочить C, чтобы убедиться, что он имеет соответствующие размеры для использования bsxfun, а затем мы выполняем суммирование по третьему размеру полученного результата и применяем squeeze для удаления третьего измерения одноэлементного.

A = squeeze(sum(bsxfun(@times, B, permute(C, [3 4 1 2])), 3)) 
Смежные вопросы