Как рассчитать это в Matlab без цикла For

Так как matlab работает медленно при выполнении цикла for, я обычно избегаю цикла for для всех моих кодов и превращаю их в матричный расчет, который был бы быстрым. Но вот проблема, которую я не могу найти умным способом:

У меня тревожная матрица

A=[a1,a2,a3,...,an], 

здесь a1,a2,a3....an - столбцы матрицы.

Еще одна матрица nxn

B=[b1,b2,b3,...,bn], 

аналогично b1,b2,b3... также являются столбцами B.

А также тревожная матрица М.

Я хочу вычислить матрицу NXN

C=[c1,c2,c3,...,cn], 

thus (M+diag(ai))*ci = bi.

а именно

ci = (M+diag(ai))\bi.

Я знаю один способ без цикла for:

C(:)=( blkdiag(M)+diag(A(:)) )\B(:).

Но это будет делать слишком много вычислений, чем необходимо.

Какие-нибудь умные решения? Вы можете предположить, что в вычислении нет проблемы сингулярности.

1 ответ

Утверждение "циклы медленны в Matlab" больше не соответствует действительности, так как Matlab...euhm, R2008a? (кто-то, пожалуйста, сообщите мне об этом:)

В любом случае, попробуйте это:

clc
clear all

M = rand(50);
a = rand(50);
b = rand(50);

% simple loop approach
tic
c = zeros(size(b));
for ii = 1:size(b,2)
    c(:,ii) = ( M+diag(a(:,ii)) ) \ b(:,ii);
end
toc

% not-so-simple vectorized approach
tic
MM = repmat({M}, 50,1);
c2 = (blkdiag(MM{:})+diag(a(:)))\b(:);
toc

norm(c(:)-c2(:))

Результаты:

Elapsed time is 0.011226 seconds.  % loop
Elapsed time is 1.049130 seconds.  % no-loop
ans =
     5.091221148787843e-10         % results are indeed "equal"

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

Некоторые проблемы просто не подходят для векторизации. Я думаю, что это один.

Другие вопросы по тегам