[Matlab] Metodo iterativo di Jacobi
Salve ragazzi, ho creato il seguente algoritmo per implementare il metodo iterativo di Jacobi per la risoluzione di sistemi lineari
Ho però un problema alquanto strano: se faccio agire l'algoritmo su matrici e vettori random funziona (ho verificato con A\b), se invece lo uso per sistemi presi da libri di testo funziona solo se come vettore iniziale do il vettore soluzione. Riuscireste a farmi capire quale parte del codice è sbagliata gentilmente?
PS: L'algoritmo è ancora in stato di bozza: mancano ancora i vari casi da escludere (matrici non singolari, con elementi diagonali nulli, ecc.) ma per i test ho preso solo i casi possibili, quindi dovrebbe funzionare.
PPS: Anche se il controllo dell'errore lo faccio su norm(x-x0) non cambia niente...stessi errori
function [ sol ] = Jacobiter( A,b,x0,tol,imax )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
[row,column]=size(A);
n=length(b);
iter=0;
r=b-A*x';
err=norm(r);
while err>tol & iter<imax
for i=1:n
s=sum(A(i,1:i-1).*x0(1:i-1));
s=s+sum(A(i,i+1:end).*x0(i+1:end));
x(i)=(b(i)-s)/A(i,i);
iter=iter+1;
end
r=b-A*x';
err=norm(r);
x0=x;
end
sol=x';
endHo però un problema alquanto strano: se faccio agire l'algoritmo su matrici e vettori random funziona (ho verificato con A\b), se invece lo uso per sistemi presi da libri di testo funziona solo se come vettore iniziale do il vettore soluzione. Riuscireste a farmi capire quale parte del codice è sbagliata gentilmente?
PS: L'algoritmo è ancora in stato di bozza: mancano ancora i vari casi da escludere (matrici non singolari, con elementi diagonali nulli, ecc.) ma per i test ho preso solo i casi possibili, quindi dovrebbe funzionare.
PPS: Anche se il controllo dell'errore lo faccio su norm(x-x0) non cambia niente...stessi errori
Risposte
Non ho esaminato a fondo il codice, ma l'altro giorno scrivere una cosa del genere in MatLab mi aveva dato dei problemi.
Prova con
Non ti assciuro che sia questo l'errore!
while err>tol & iter<imax
Prova con
while(and(err>tol, iter<imax))
Non ti assciuro che sia questo l'errore!
Grazie mille per la risposta ma non credo sia quello l'errore. Se uso l'algoritmo su A=rand(n)+q*eye(n), b=rand(n,1) va tutto bene, altrimenti no 
Idem per l'algoritmo di Gauss Seidel appena creato e presumo per il metodo di rilassamento che sto per andare a scrivere.
Ecco Gauss Seidel:
Idem per l'algoritmo di Gauss Seidel appena creato e presumo per il metodo di rilassamento che sto per andare a scrivere.
Ecco Gauss Seidel:
function [ sol,iter ] = GausSeidel( A,b,x0,tol,imax )
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
[row,column]=size(A);
n=length(b);
if column~=n
error('Errore: la matrice A e il vettore b non hanno dimensioni compatibili');
end
D=diag(A);
if any(D)==0
error('La matrice ha elemento/i diagonale/i nullo/i')
end
iter=0;
err=inf;
x0=x0';
x=x0;
while (err>tol & iter<imax)
for i=1:n
s1=A(i,1:i-1)*x(1:i-1);
s2=A(i,i+1:n)*x0(i+1:n);
x(i) = (b(i)-s1-s2)/A(i,i);
iter=iter+1;
end
err=norm(x-x0);
x0=x;
end
sol=x;
end
[xdom="Raptorista"]Sposto nella sezione più appropriata!
[/xdom]
Ho un problema analogo ... nel senso che il programma in matlab è strano mi restituisc e ogni giorno un numero di iterazioni diverso e a volte nn mi da la soluzione esatta pure se la matrice è strett a diag dominante...molto strano... posto il codice magari qlk è csì gentile da aiutarmi?...
function [ x, itnum, res, ratio, err, rap, flag ] = jacobi( A, b, w, x0, tol, maxit, xsol )
% Metodo iterativo di Jacobi rilassato per sistemi lineari
%
%Input:
% A: Matrice del sistema
% b: Termine noto (vettore colonna)
% w: Parametro di rilassamento ( se è uguale a 1 stiamo lavorando con
% Jacobi non rilassato)
% x0: Vettone iniziale
% tol: Tolleranza sul test d'arresto
% maxit: Numero massimo di iterazioni
% xsol: Soluzione del sistema
%Output:
% x: Vettore soluzione del metodo
% itnum: Numero di iterazioni effettuate
% res: Residuo al passo k
% ratio: Rapporto tra i residui ai passi consecutivi
% err: Errore al passo k
% rap: Rapporto ta gli errori ai passi consecutivi
% flag: Se flag = 0 converge nel numero massimo di iterazioni
% fissato altrimenti flag=1
if ( det(A) == 0 )
disp('** La matrice è singolare');
else
[n,n] = size (A);
I = eye(n);
L = -tril(A);
U = -triu(A);
D = diag(diag(A));
L = L+D;
U = U+D;
x = x0;
flag = 0;
itnum = 1;
T = (1-w)*I+w*D^(-1)*(L+U);
C = w*D^(-1)*b;
res(1) = norm(A*x-b);
err(1) = norm(xsol-x0);
while ( itnum <= maxit && res(itnum) >= tol )
itnum = itnum+1;
x = T*x+C;
res(itnum )= norm (A*x-b);
ratio(itnum-1)= res(itnum)/res(itnum - 1);
err(itnum)= norm(xsol-x);
rap(itnum-1)= (err(itnum))/(err(itnum-1));
end
if (res(itnum)>= tol)
flag=1;
else
disp('** Jacobi non converge nel numero di iterazioni fissato');
end
end
% Grafico rappresentate il rapporto tra gli errori ai passi
% consecutivi-numero di iterazioni in scala logaritmica sull'asse y
figure(1)
y=[2:itnum];
semilogy(y,rap,'r-o');
% Nomino gli assi
xlabel('num iterazioni');
ylabel('rapporto errori');
end
function [ x, itnum, res, ratio, err, rap, flag ] = jacobi( A, b, w, x0, tol, maxit, xsol )
% Metodo iterativo di Jacobi rilassato per sistemi lineari
%
%Input:
% A: Matrice del sistema
% b: Termine noto (vettore colonna)
% w: Parametro di rilassamento ( se è uguale a 1 stiamo lavorando con
% Jacobi non rilassato)
% x0: Vettone iniziale
% tol: Tolleranza sul test d'arresto
% maxit: Numero massimo di iterazioni
% xsol: Soluzione del sistema
%Output:
% x: Vettore soluzione del metodo
% itnum: Numero di iterazioni effettuate
% res: Residuo al passo k
% ratio: Rapporto tra i residui ai passi consecutivi
% err: Errore al passo k
% rap: Rapporto ta gli errori ai passi consecutivi
% flag: Se flag = 0 converge nel numero massimo di iterazioni
% fissato altrimenti flag=1
if ( det(A) == 0 )
disp('** La matrice è singolare');
else
[n,n] = size (A);
I = eye(n);
L = -tril(A);
U = -triu(A);
D = diag(diag(A));
L = L+D;
U = U+D;
x = x0;
flag = 0;
itnum = 1;
T = (1-w)*I+w*D^(-1)*(L+U);
C = w*D^(-1)*b;
res(1) = norm(A*x-b);
err(1) = norm(xsol-x0);
while ( itnum <= maxit && res(itnum) >= tol )
itnum = itnum+1;
x = T*x+C;
res(itnum )= norm (A*x-b);
ratio(itnum-1)= res(itnum)/res(itnum - 1);
err(itnum)= norm(xsol-x);
rap(itnum-1)= (err(itnum))/(err(itnum-1));
end
if (res(itnum)>= tol)
flag=1;
else
disp('** Jacobi non converge nel numero di iterazioni fissato');
end
end
% Grafico rappresentate il rapporto tra gli errori ai passi
% consecutivi-numero di iterazioni in scala logaritmica sull'asse y
figure(1)
y=[2:itnum];
semilogy(y,rap,'r-o');
% Nomino gli assi
xlabel('num iterazioni');
ylabel('rapporto errori');
end
Stai infrangendo in un colpo solo una marea di punti del regolamento, ed inoltre ti ammonisco con il mio cartellino preferito