Вычислить матричное произведение для широкого диапазона скалярных значений - PullRequest
0 голосов
/ 13 сентября 2018

Предположим, a - это вектор 1 x n, b - это вектор n x 1, A - это матрица n x n, а xx - это вектор m x 1.Я хочу вычислить fxx, который можно вычислить следующим образом:

for i = 1:m
    fxx(i)=a*expm(xx(i)*A)*b;
end

это, конечно, работает, но кажется, что это очень медленный метод, есть ли лучший встроенный способ для решения этой проблемы?тип for петли?

1 Ответ

0 голосов
/ 13 сентября 2018

Проблема в том, что expm реализовано только для 2D матриц, поэтому вам нужно вызывать это для 2D срезов. Единственное небольшое возможное ускорение - это предварительный расчет xx*A для 3D-матрицы:

n=5;
m=10;
a = rand(1,n);
b = rand(n,1);
A = rand(n,n);
xx = rand(m,1);

tmp = bsxfun(@times,permute(xx,[3 2 1]),A); % Pre-calculate the matrix multiplication

fxx = zeros(m,1);
for ii = 1:m
    fxx(ii) = a*expm(tmp(:,:,m))*b;
end

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


В ваших комментариях вы утверждаете, что m обычно очень велик. Если это так, parfor может помочь вам, если у вас есть набор инструментов для параллельных вычислений. В этом случае предварительный расчет трехмерной матрицы может не сработать, поскольку она будет очень большой в ОЗУ, поэтому просто используйте:

fxx=zeros(m,1);
parfor ii = 1:m
    fxx(ii) = a*expm(xx(ii)*A)*b;
end

Для получения дополнительной информации о том, как parfor может помочь вам, и как это может быть еще быстрее при правильной нарезке переменных, см. Следующий вопрос: Экономия времени и памяти с помощью parfor?

...