- i и j по умолчанию определены как комплексные числа, поэтому лучше использовать ii и jj.
- Matlab дает предупреждающие сообщения + примеры того, как их исправить, чтобы вы могли использовать его для исправления своего кода.
На ваш код вы получите предупреждения:
plotGauss
увеличивает размер на каждой итерации:
plotGauss=[plotGauss;normVal];
Решение: заменить цикл while на цикл for, давая разумное количество итераций, предварительно инициализировать массив plotGauss и разорвать цикл for, когда normVal (ii) <= tol </p>
sigma
передается между итерациями, поэтому вы не делаете его параллельным:
parfor j=1:i-1
sigma = sigma+A(i,j)*x(j);
end
Решение: вычислить умножения в parfor для сохранения результатов во временном массиве, а затем
сумма после цикла.
tmp = zeros(1,n);
...
parfor jj=1:ii-1
tmp(jj)= A(ii,jj)*x(jj);
end
sigma = sum(tmp(1:ii-1));
в итоге:
не проверено (извините, у меня нет matlab дома)
MAX_ITER = 100;
A=[5 -2 3 0 6; -3 9 1 -2 7.4; 2 -1 -7 1 6.7; 4 3 -5 7 9; 2 3.5 6.1 -4 -8.1];
b=[-1 2 3 0.5 3.1]' ;
x=rand(5,1);
n=size(x,1);
normVal=inf;
tol=1e-3;
% GaussItr=0; => see below for loop
sigma = 0;
tmp = zeros(1,n);
plotGauss=nan*ones(1,MAX_ITER);
timeStart = tic;
for kk=1:MAX_ITER
x_old = x ;
for ii=1:n
parfor jj=1:ii-1
tmp(jj)= A(ii,jj)*x(jj);
end
tmp(ii) = 0; % to keep sigma as sum of all tmp elements
parfor jj=ii+1:n
tmp(jj)= A(ii,jj)*x_old(jk);
end
sigma = sum(tmp);
x(ii)=(1/A(ii,ii))*(b(ii)-sigma);
end
% GaussItr=GaussItr+1; => use kk index instead
normVal=norm(x_old-x);
plotGauss(kk) = normVal;
if normVal<=tol
break; % break the for loop if we already reached desire tolerance
end
end
timeEnd = toc(timeStart);
GaussItr = kk;
if normVal>tol
error('code finished after %d iterations without reaching desired tolerance',GaussItr);
end