Strange Behavior of Matlab
2 views (last 30 days)
Show older comments
Leonardo Gherlinzoni
on 22 Sep 2017
Answered: Leonardo Gherlinzoni
on 23 Sep 2017
The following exercise function solve linear system Ax=b with J.O.R. method:
function [x]=milspojor(A,b,x0,om,tol,itmax)
%Input-Check/Inizializzazione
[n,m]=size(A);
if n~=m
error('Error:Non-Squared Matrix!');
end
if min(abs(eig(A)))==0
error('Error:Singular Matrix!');
end
if isrow(b)==1
b=b';
end
if isrow(x0)==1
x0=x0';
end
it=0;r=b-A*x0;err0=norm(r,2);
err=err0;x=x0;
%Calcolo
while err > tol && it < itmax
it = it + 1;xit=zeros(n,1);
for i=1:n
xit(i)=om*...
(b(i)-(A(i,1:i-1)*x(1:i-1)+A(i,i+1:n)*x(i+1:n)))/A(i,i)+...
(1-om)*x(i);
end
x=xit;r=b-A*x;err=norm(r,2)/err0;
end
if it < itmax
fprintf('\nConvergence-Reached @at n=% d',it);
end
if it >= itmax
error('Error:Convergence-Not-Reached!');
end
end
Using as an Example: A=[-3 3 -6;-4 7 -8;5 7 -9] b=[-6 -5 3] (so exact solution is [1 1 1]) tol=eps, itmax=500;om=1 (Jacobi method) and x0=rand(3,1)=[0.8147 0.9058 0.1270]
the function works and the output is : Convergence-Reached @at n= 181 x =[1.0000 1.0000 1.0000]
BUT If I change the order of the scalar division (/A(i,i)) in the for loop in this way:
xit(i)=(om/A(i,i))*...
(b(i)-(A(i,1:i-1)*x(1:i-1)+A(i,i+1:n)*x(i+1:n)))+...
(1-om)*x(i);
(This is a fully licensed and apparently insignificant operation!!)
I get an unexpected result: the method don't converge and i get the Error Message described in the last if cicle.
I tought that this is caused by approximation error but I try to execute a single cicle of the for loop and in each way i get the same result.
So help me.... why this strange behavior?
0 Comments
Accepted Answer
OCDER
on 22 Sep 2017
Edited: OCDER
on 22 Sep 2017
Nothing's wrong with the equation, but it's an approximation error caused when you're dividing/multiplying numbers with many decimal numbers that cannot be represented by the computer. I ran both versions of the equation and had the code stop when the two equations started to return different xit (it's not final solution). EX:
xit_1 =
2.150133809189486
-0.102098536507900
0.422401406963743
xit_2 =
2.150133809189486
-0.102098536507900
0.422401406963744
Doing computation with floating point numbers can be tricky, and so you have to account for rounding error (it's an issue in other programming languages too - not just MATLAB). More info about this from MathWorks here: https://www.mathworks.com/help/matlab/matlab_prog/floating-point-numbers.html#f2-98690
To fix your code, increase the tolerance tol. Ex:
while err > tol + 3*eps && it < itmax
....
end
0 Comments
More Answers (1)
See Also
Categories
Find more on Operators and Elementary Operations in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!