METODI ITERATIVI DI JACOBI E GAUSS-SEIDEL

Похожие документы
Page Rank. Guerra Stefano. 1. DESCRIZIONE DEL PROBLEMA "Page Rank" 2. DESCRIZIONE DELL ALGORITMO. Pagina 2

Calcolo Numerico - Prova Matlab 19 luglio 2013

Esercitazione 6: Metodi iterativi per sistemi lineari.

1. Si scriva una function Matlab che implementa il seguente metodo di punto fisso

Progetto Matlab N 2. Calcolo Numerico 6 CFU. Corso di Laurea in Ingegneria delle Comunicazioni 31/05/2014

Registro di Matematica Applicata /18 - Dott.ssa L. Fermo 2

Programmare con MATLAB c Parte 5 Cicli: for e while

Laboratorio di Calcolo Numerico Laboratorio 12: Metodi iterativi per la soluzione di sistemi lineari

Sistemi lineari. Lucia Gastaldi. DICATAM - Sez. di Matematica,

Corso di laurea in Informatica Calcolo Numerico Prof.ssa L. D Amore 12 Dicembre 2008 Esercizi di riepilogo tipo prova d esame

UD4 - MATLAB. M-file. Efficienza degli algoritmi. Formati d uscita

Esercizio 1. Esercizio 2

Metodi Numerici con elementi di Programmazione A.A

Esercizi di MatLab. Sommario Esercizi di introduzione a MatLab per il corso di Calcolo Numerico e Laboratorio, A.A

CORSO DI LABORATORIO DI INFORMATICA

Codifica-Decodifica DTMF

Esercitazione 4: Vettori e Matrici

Il programma OCTAVE per l insegnamento dell algebra lineare nella Scuola Secondaria p. 1

Equazioni e sistemi non lineari

Programma del corso di: Laboratorio di Programmazione e Calcolo Corso di laurea in Matematica a.a Proff. B. Paternoster, D.

Diario delle lezioni di Analisi Numerica laurea Magistrale in Statistica e Informatica A.A

Corso di laurea in Matematica Laboratorio di Programmazione e Calcolo Prof. A. Murli. Esercizi di riepilogo - LABORATORIO

RISOLUZIONE DI SISTEMI LINEARI

8 Metodi iterativi per la risoluzione di sistemi lineari

Equazioni e sistemi non lineari

Risoluzione di sistemi lineari sparsi e di grandi dimensioni

Gradiente Coniugato Precondizionato in MatLab

Esercitazioni con GNU Octave

MATLAB c. Lucia Gastaldi Dipartimento di Matematica Lezione 4 (15 ottobre 2003)

Equazioni e sistemi non lineari

Documentazione esterna al software matematico sviluppato con MatLab

Транскрипт:

1. DESCRIZIONE DEL PROBLEMA Function file che implementa: L algoritmo di Jacobi o di Gauss Seidel per la risoluzione di un sistema lineare Ax=b con A sparsa (generata dall utente con il comando sparse). Parametri di input: A matrice sparsa di coefficienti b vettore dei termini noti metodo: stringa di caratteri: jac, metodo di Jacobi, gs metodo di Gauss Seidel. x0 facoltativo, vettore dei valori iniziali, se omesso x0=vettore nullo TOL facoltativo, tolleranza gestita dall utente, se omessa TOL=epsilon macchina MAXITER facoltativo, numero massimo di iterazioni, se omesso MAXITER=1000 Parametri di output: x soluzione calcolata del sistema NITER facoltativo. Numero di iterazioni effettuate Si testi il software su matrici sparse di notevoli dimensioni, generate usando funzioni Matlab specifiche per la generazione di matrici sparse, che siano non singolari e ben condizionate. Illustrare, attraverso grafico, la struttura delle matrici di test. 2. DESCRIZIONE DELL ALGORITMO Per risolvere il problema sono stati creati i seguenti file: crea_matrici.m : file di script che crea la matrice e avvia l algoritmo. Test.m: function che avvia l algoritmo scelto jacobi_metodo.m: function che implementa il medodo di Jacobi gauss_sei_medoto.m: function che implementa il metodo di Gauss-Seidel Pagina 2

2.1 function " crea_matrici.m" A=[]; dim = input ('Inserisci le dimensioni della matrice\n' ); controlla_parametro( dim) in = input ('Scegli che tipo di matrice vuoi creare:\n[1] Matrice Random\n[2] Del tipo toeppen\n[3] Del tipo di poisson\n[4] Generata col comando sparse\n\n','s'); if strcmp( in,'1')== 1 dens = input ('Inserisci il coefficiente di densità [0,005]'); if ( isempty( dens)) dens = 0.005; if ( dens >= 1) dens = 0.005; A = sprand( dim, dim, dens)+ speye( dim, dim ); % Sprand genera una matrice sparsa random di (dim,dim,densità); %Speye invece genera una matrice composta da 1 sulla diagonale %principale elseif strcmp( in,'2')== 1 A = gallery ('toeppen', dim)+ speye( dim, dim); elseif strcmp( in,'3')== 1 A = gallery ('poisson', dim); elseif strcmp( in,'4')== 1 A = sparse( dim, dim, 1)+ speye( dim, dim); test( A ); %lancia la funzione test(a) Questo file di script riceve in input da tastiera: la dimensione della matrice; il tipo; (toeppen, poisson ecc ) il coefficiente di densità. Una volta inseriti i parametri di input viene chiamata la funzione test. 2.2 function " Test.m" function Test( A ) controlla_matrice( A ); % check sulla matrice figure ('Name','Distribuzione della matrice A','NumberTitle', 'off'); spy( A ); % visualizzazione matrice in ingresso N = size( A ); % dimensione matrice x= ones( N( 1), 1 ); % vettore colonna della dimensione matrice A b = A* x ; % sistema % calcolo dell'indice di condizionamento della matrice sprintf ('Indice di condizionamento matrice: %s', condest( A)); tol = eps (); % tolleranza di default pari all'epsilon macchina tol_in = input ('Inserire tolleranza [epsilon macchina]: '); if (~ isempty( tol_in)) tol = tol_in; Pagina 3

%% Selezione Metodo Risolutivo selettore = '1'; while strcmp( selettore, '0') == 0 selettore = input ('Quale metodo vuoi usare?\n [jac] metodo di Jacobi\n [gs] metodo di Gauss Seidel\n [0] per terminare\n','s'); t = cputime; clc; if strcmp( selettore, 'jac') == 1 fprintf ('Jacobi\n------\n'); [ xc iter] = jacobi_metodo( A, b, tol, 1000); fprintf (' - Numero di iterazioni: %d\n', iter); fprintf (' - Tempo impiegato: %6.4f\n', cputime- t); fprintf (' - Errore: %6.4f\n', norm( xc- x)/ norm( xc)); fprintf ('\n------\n\n'); elseif strcmp( selettore, 'gs') == 1 fprintf ('Gauss Seidel\n------\n' ); [ xc iter] = gauss_sei_metodo ( A, b, tol, 1000); fprintf (' - Numero di iterazioni: %d\n', iter); fprintf (' - Tempo impiegato: %6.4f\n', cputime- t); fprintf (' - Errore: %6.4f\n', norm( xc- x)/ norm( xc)); fprintf ('\n------\n\n'); elseif strcmp( selettore, '0') == 1 disp ('Arrivederci') Questa funzione per prima cosa visualizza la struttura della matrice sparsa mediante la funzione spy. Successivamente chiede di inserire la tolleranza (se questa è vuota la tolleranza è uguale all epsilon macchina). Successivamente viene chiesto all utente quale metodo di risoluzione utilizzare. Una volta scelto il metodo viene chiamata la funzione appropriata e vengono stampati a video le informazioni riguardo al tempo di esecuzione, il numero di iterazioni e l eventuale errore. 2.3 function " jacobi_metodo.m" function [ x, num_iter]= jacobi_metodo( A, b, TOL, max_iter) %controllo sul numero di parametri if ( nargin== 0 nargin== 1) error ('I parametri A e b sono obbligatori!' ); switch nargin case 2 TOL= 10^- 7; max_iter= 1000; case 3 max_iter= 1000; %controllo sul primo paramentro di input controlla_matrice( A); %controllo sul secondo parametro Pagina 4

controlla_vettore( b); %controllo sul terzo parametro controlla_parametro( TOL); %controllo sul quarto parametro controlla_parametro( max_iter); %controllo di compatibilità tra A e b if ( size( A, 1)~= size( b, 1)) error ('Le dimensioni di A e b sono incompatibili' ); %correggo la tolleranza: se l'utente inserisce una tolleranza non %accettabile (inferiore a eps), essa viene corretta con eps. TOL= max( TOL, eps); n= size( A, 1); x= zeros ( n, 1 ); %vettore iniziale x0= x; %D è la matrice diagonale ottenuta a partire dalla diagonale della matrice %di input A: si crea una matrice con elementi tutti nulli tranne quelli %della diagonale che sono gli stessi di quelli della diagonale di A D = diag( diag( A)); %J=-inv(D)*(L+U) dove L è la matrice triangolare inferiore ed U è la %matrice triangolare inferiore. L+U si ottiene a partire dalla matrice A %annullando la diagonale. %Matlab suggerisce di usare l'operatore \ che è più veloce di inv per %cacolare l'inversa di una matrice. J = D\( D - A); %c=inv(d)*b c = D\ b; num_iter= 0; while ( ( norm( x- x0)> TOL* norm( x) num_iter== 0) && num_iter< max_iter ) x0 = x; x = J* x0+ c; num_iter = num_iter + 1; %se si è usciti fuori dal ciclo while perchè il numero di iterazioni %effettuate ha superato il limite massimo, ciò viene segnalato all'utente if( num_iter>= max_iter) error ('Attenzione raggiunto il massimo numero di iterazioni possibili i risultati potrebbero essere inaccurati' ); %controllo sui parametri di output if ( nargout < 2) error ('Attenzione errore sui parametri di output' ); Questa funzione è l implementazione del metodo di Jacobi. Viene per prima cosa definita una tolleraza da utilizzare. Nel caso questa non venga inserita dall utente, viene settata pari all epsilon macchina. Poi viene effettuata la suddivisione della matrice di partenza nelle sottomatrici previste dal metodo. Una volta fatto questo viene effettuato il vero e Pagina 5

proprio metodo iterativo, che può terminare o dopo aver raggiunto il massimo numero di iterazioni o dopo aver raggiunto un numero sufficiente di cifre significative. 2.4 function " gauss_sei_metodo.m" function [ x, num_iter]= gauss_sei( A, b, TOL, maxiter) %controllo sul numero di parametri if ( nargin== 0 nargin== 1) error ('I parametri A e b sono obbligatori!' ); switch nargin case 2 TOL= 10^- 7; maxiter= 1000; case 3 maxiter= 1000; %controllo sul primo paramentro di input controlla_matrice( A); %controllo sul secondo parametro controlla_vettore( b); %controllo sul terzo parametro controlla_parametro( TOL); %controllo sul quarto parametro controlla_parametro( maxiter); %controllo di compatibilità tra A e b if ( size( A, 1)~= size( b, 1)) error ('Le dimensioni di A e b sono incompatibili' ); [ N M]= size( A); %correggo la tolleranza TOL= max( TOL, eps); %U matrice triangolare superiore U = triu( A, 1); %L matrice triangolare inferiore L = tril( A,- 1); %crea una matrice sparsa MxN con elementi diversi da 0 quelli della %diagonale di A D = spdiags( diag( A), 0, M, N); %calcola dell'inversa di D+L. idl = inv( D+ L); %calcola la matrice di iterazione B del metodo di Gauss-Seidel. Pagina 6

B = - idl* U; iter = 0; %calcolo della costante (D+L)^-1*b della formula itarariva di Gauss-Seidel. c = idl* b; x0 = zeros( N, 1); %Inizializzazione del vettore xh uguale al vettore iniziale x0 xh = x0; %Esegue il calcolo del vettore x al passo 1 xk = B* xh + c; %Ciclo di iterazione del metodo di Jacobi con controllo sulla precisone raggiunta e sul numero massimo di iterazioni inserite dall'utente while norm( xk - xh) >= TOL* norm( xh) & iter <= maxiter %Esegue il calcolo del vettore x al passo k xh = xk; xk = B* xh + c; %Incremento del numero di iterazioni iter = iter + 1; x = xk; num_iter= iter; if num_iter>= maxiter error ('Raggiunto limite massimo di iterazioni. La soluzione potrebbe non avere l accuratezza richiesta.' ); Questa funzione implementa il metodo iterativo di Gauss-Seibel. Dopo aver effettuato un controllo sugli ingressi la matrice A viene splitatta nelle matrici previste dal metodo iterativo in questione, per poi entrare in un ciclo while che effettua il calcolo del vettore x al passo k. Il procedimento si arresta o quando viene raggiunto il massimo numero di iterazioni o quando si raggiunge un numero sufficiente di cifre significative. 3. ECCEZIONI PREVISTE I controlli che vengono fatti sugli elementi di input sono riportati nei seguenti files.m: controlla_matrice.m; controlla_parametro.m; controlla_vettore.m 3.1 function " controlla_matrice.m" function controlla_matrice( A) Pagina 7

if ischar( A) error ('La matrice deve contenere solo numeri' ); elseif isvector( A) error ('Deve essere una matrice' ); elseif size( A, 1) ~= size( A, 2) error ('La matrice deve essere quadrata' ); elseif ~ isempty( find( isnan( A), 1)) error ('La matrice non deve contenere valori NaN' ); elseif ~ isempty( find( isinf( A), 1)) error ('La matrice non deve contenere valori Inf' ); elseif isempty( find( diag( A), 1)) error ('La diagonale principale ha valori nulli' ); elseif det( A) == 0 error ('La matrice è singolare' ); elseif issparse( A) == 0 error ('La matrice deve essere sparsa' ); 3.2 controlla_parametro.m function controlla_parametro ( num) if isnan( num) error ('Il parametro non deve essere NaN' ); elseif isinf( num) error ('Il parametro non deve essere Inf' ); elseif ~ isequal( num, abs( num)) error ('Il parametro deve essere positivo' ); elseif ischar( num) error ('Il parametro non deve contenere caratteri' ); 3.3 function " controlla_vettore.m " function controlla_vettore( b) if isempty( b) error ('Il vettore non deve essere vuoto' ); elseif ~ isvector( b) error ('Il parametro deve essere un vettore' ); elseif ischar( b) error ('Il vettore deve contenere solo numeri' ); elseif ~ isempty( find( isnan( b), 1)) error ('Il vettore non deve contenere valori NaN' ); elseif ~ isempty( find( isinf( b), 1)) error ('Il vettore non deve contenere valori Inf' ); 4. ESEMPI D USO In questa sezione verranno riportati alcuni esempi di utilizzo del programma con diverse matrici di diverse dimensioni, applicando i due metodi iterativi implementati. Il primo esempio pre in input una matrice random di dimensioni 1000x1000 con coefficiente di densità di 0.010. Pagina 8

Applicando il metodo di Jacobi abbiamo l output della figura seguente: Mentre applicando Gauss-Seidel abbiamo il seguente risultato: Come possiamo vedere il metodo di Jacobi è stato più veloce sia in termini di iterazioni eseguite, ma soprattutto in termini di tempo impiegato. Il prossimo esempio pre in esame una matrice di tipo Toeppen di dimensioni 1000x1000 Pagina 9

Applicando il metodo si Jacobi abbiamo il seguente output: Mentre con Gauss-Seidel abbiamo: In quetso caso Jacobi è sempre più veloce ma G-S non impiega nessun numero di iterazioni per ottenere il risultato. Nel prossimo esempio consideriamo una matrice di Poisson 65x65 Pagina 10

Applicando Jacobi abbiamo: In questo caso viene raggiunto il massimo numero di iterazione (che è pari a 1000). Pagina 11