function [x,errs,iter,flag]=metodo_jacobi(A,x,b,maxit,tol)

% oggetto:
% la routine risolve il sistema lineare Ax=b mediante 
% il metodo di Jacobi
%
% input:
% A: matrice quadrata non singolare
% x: approssimazione iniziale della soluzione 
%     (vettore colonna)
% b: termine noto (vettore colonna)
% maxit: numer massimo di iterazioni
% tol: tolleranza del metodo di Jacobi
%
% output:  
% x: approssimazione della soluzione, fornita dal 
%      metodo di Jacobi.
% errs: norme dell'errore 
%                  norm(x_new-x_old)/norm(x_new) 
%     al variare delle iterazioni, ovvero lo step 
%     relativo.
% iter: numero di iterazioni del metodo
% flag: 0: si e' raggiunta l'approssimazione 
%             desiderata della soluzione
%       1: non si e' raggiunta l'approssimazione 
%             desiderata della soluzione

% inizializzazioni
flag=0;

% --- le matrici P, N per il metodo di Jacobi ---
P=diag(diag(A));

% se il determinante di P e' uguale a "1", allora 
% il metodo di Jacobi non si puo' applicare in
%  quanto qualche componente A(k,k)=0; 
% in effetti P e' una matrice diagonale, 
% il determinante di P e' il prodotto degli elementi
% sulla diagonale per cui e' nullo sse qualche 
% A(k,k)=0; 

if det(P) == 0
    errs=[]; iter=0; flag=1;  return;
end

N=diag(diag(A))-A;

% --- iterazioni del metodo di Jacobi ---
for iter=1:maxit                       
    x_old=x;
    x=P\(N*x_old+b);   % nuova iterazione
    % calcolo step relativo
    errs(iter)=norm(x-x_old)/norm(x);  
    % se error e' suff. piccolo si esce dalla routine
    if (errs(iter)<=tol), return, end  
end

% se abbiamo raggiunto questo punto abbiamo fatto
%  troppe iterazioni senza successo e quindi 
% poniamo "flag=1".
flag=1;                            