Introduzione
Un sistema di n equazioni lineari in n incognite x1,
x2, ......, xn può scriversi in notazione
algebrica:
a11x1 + a12x2 + a13x3 + ....... + a1nxn = b1
a21x1 + a22x2 + a23x3 + ....... + a2nxn = b2
...................................................................... (1.1)
.......................................................................
an1x1 + an2x2 + an3x3 + ...... + annxn = bn
ove i termini ai j sono i coefficienti del sistema, mentre b1, b2, ..... , bn sono i termini noti o in forma matriciale compatta:
A X = B (1.2)
dove:
A =
= matrice dei
coefficienti del sistema (1.3)
Il rango della matrice A (massimo numero di righe o di colonne di A linearmente indipendenti tra loro) si dice anche rango del sistema. Se esso è pari al numero di equazioni (ovvero, nel nostro caso, al numero delle incognite) , il sistema lineare si dice normale.
X =
= vettore
colonna delle incognite (1.4)
B =
= vettore
colonna dei termini noti (1.5)
Indichiamo inoltre con A’ la seguente matrice:
A’ =
= matrice
dei coefficienti e termini noti o matrice completa (1.6)
Una equazione del sistema può essere scritta anche nella forma:
(i = 1, 2, .... , n)
(1.7)
Relativamente alla soluzione di un sistema di questo tipo, si presentano
quattro possibilità:
Definizioni relative alle matrici
(1.8)U =
(1.9)
Viceversa per una matrice triangolare inferiore L.
Per la risoluzione del sistema, è opportuno ricordare alcune proprietà e definizioni relativi ai sistemi stessi, alle matrici e al calcolo matriciale.
Vale la proprietà commutativa rispetto al prodotto con la matrice inversa, ossia:
A-1 A = A A-1 = I
I metodi per risolvere sistemi di equazioni lineari possono suddividersi in due categorie:
I metodi iterativi invece, non prevedono un numero preefissato di iterazioni,
e portano ad una soluzione "approssimata", nel senso che essa sará
comunque affetta da un errore, che teoricamente puó essere
reso piccolo a piacere aumentando il numero delle iterazioni.
Dal punto di vista pratico si fissa il vettore soluzione X(0)
(prima iterazione) arbitrariamente, si sostituiscono i suoi valori
nel sistema e se lo soddisfa vuol dire che esso rappresenta la soluzione
e quindi si interrompe il calcolo, altrimenti, in base all'errore
commesso si determina un nuovo valore X(1) e si itera il procedimento
fino a quando la successione dei valori generati converge verso la soluzione.
Alcuni esempi di metodi iterativi sono il metodo di Jacobi ed il metodo
di Gauss - Seidel.
Anche se non esiste un criterio che possa indicare a priori quale metodo
risolutivo adottare, risulta che i metodi diretti che certamente offrono
maggiori garanzie, al crescere delle dimensioni del sistema vengono sostituiti
dai i metodi iterativi.
Il metodo di eliminazione di Gauss-Jordan (una variante del metodo di Gauss) è basato sulla trasformazione della matrice
A' nella forma:
~
~
cui corrisponde la seguente soluzione del sistema: x1 =
b1 ....... xn = bn
Tale metodo si basa su n iterazioni identificate dall'indice
k durante le quali vengono trasformati i coefficienti del sistema..
Durante la prima iterazione k=1 si vuole ridurre a 1 il coefficiente
di x1 nella prima equazione, e a 0 in tutte le altre, pertanto:
Come detto tale trasformazione è stata derivata eseguendo:
sulla riga k la trasformazione dei coefficienti akj
in a'kj = akj /akk
( j = i, i + 1, .... DIM)
e sulle righe i la trasformazione dei coefficienti: aij
in a'ij = aij-a'kj *aik
( j = i, i + 1, .... DIM)
Si procede quindi con l’iterazione successiva.
Durante la seconda iterazione k=2 si vuole ridurre a 1 il coefficiente
di x2 nella seconda equazione, e a 0 in tutte le altre, pertanto:
all'ultima iterazione (quella di indice n) la matrice si sarà
trasformata nella seguente:
ove nella colonna di indice n+1 troviamo le soluzioni del sistema.
Al procedimento descritto può essere associato il seguente
algoritmo:
in cui per aumentare l'efficienza sono state eseguite solo le operazioni
che contribuiscono al calcolo della soluzione e non quelle che contribuiscono
alla riduzione a 0 e 1 dei termini della matrice.
Programma per la risoluzione di sistemi di equazioni lineari con il metodo di Gauss-Jordan
Si noti che un programma completo dovrebbe prevedere dei controlli sia sul determinante A (diverso da =) sia sugli elementi akk della matrice che dovrebbero essere diversi da 0 (ciò può comunque essere ottenuto scambiando di posto alle equazioni).
EQUAZIONI NON LINEARI
Numerosi problemi di matematica applicata corrispondono ad equazioni non lineari del tipo ¦(x) = 0 di cui non si conosce la soluzione in forma chiusa (e quindi l’espressione analitica delle radici) o di cui è complesso il calcolo, pertanto sono indispensabili dei metodi numerici che conducano alla individuazione delle radici.
Quando l’equazione non lineare ¦(x) ad una incognita soddisfa il teorema di esistenza degli zeri, ossia è reale e continua in un intervallo chiuso e limitato [a,b] ed assumere valori di segno opposto agli estremi dell’intervallo, possono essere usati alcuni metodi iterativi per individuare la soluzione.
Infatti se una funzione ¦(x) è reale e continua in un intervallo chiuso e limitato [a,b] e assume valori di segno opposto agli estremi dell’intervallo (ovvero ¦(a) .¦(b) < 0), allora, per il teorema di esistenza degli zeri esiste sicuramente un punto x, detto zero della funzione, interno all’intervallo [a,b] in cui ¦(x) assume il valore 0, che rappresenta la radice dell’equazione ¦(x) = 0.
La ricerca di tutti gli zeri della funzione deve essere preceduta quindi dalla tabulazione della funzione f(x) con passo adeguato in modo da individuare tutti gli intervalli chiusi [a,b] che contengono al loro interno le radici e nell’applicare a ogni singolo intervallo il metodo risolutivo scelto.
La valutazione numerica di ciascuna radice avviene tramite la costruzione di una opportuna successione di valori {xi}, tale che risulti:
lim {xn} = x
ove x Î
[a,b] e
f (x ) = 0
n® ¥
La successione {xi} dei valori ottenuti dipende dal procedimento iterativo applicato.
Data una successione di valori {xi} si definiscono:
errore (assoluto) di troncamento en: en = x - xn
fattore di convergenza c: c = lim e n+1/
e n
n® ¥
Nei successivi paragrafi saranno analizzati i metodi di bisezione e delle corde (iterativi a due punti) ed il metodo di Newton-Raphson (iterativo a un punto).
#include <iostream.h>
main()
{
double prec=1.0;
while ((1.+ prec)!=1.0) prec/=2.;
prec*=2;
cout<<prec;
}
timeelapsed% a.out
2.22045e-16timeelapsed%
#include <iostream.h>
main()
{
float prec=1.0;
float a=1.0;
float x=2.0;
while ((a+ prec)!=a) prec/=x;
prec*=2;
cout<<prec;
}
timeelapsed% g++ b.c
timeelapsed% a.out
1.19209e-07timeelapsed%
Il metodo di bisezione è il metodo iterativo più semplice e sicuramente convergente per calcolare le radici di un’equazione non lineare ¦(x) reale e continua in un intervallo chiuso e limitato [a,b] che assuma valori di segno opposto agli estremi dell’intervallo.
Il metodo di bisezione consiste nel considerare il punto medio xm
=(a + b)/2 dell’intevallo [a,b] e verificare se xm è
una radice.
Per verificare questa condizione, non si controlla se ¦
(xm ) = 0, ma (poiché si lavora con i numeri reali) se
|¦ (xm) | < p, ove p rappresenta
la precisione scelta.
Se xm non è una radice si valuta il segno del prodotto
¦(a) .¦(xm)
e si procede allo stesso modo nel sottointervallo [a, xm] se
il segno è negativo, o nel sottointervallo [xm,b] se
è positivo.
Naturalmente iterando il procedimento si genera una successione di termini {xi}, ciascuno dei quali rappresenta l’intersezione con l’asse X della retta individuata dai punti di coordinate (a, segno f(a)) e (b, segno f(b)) che solo sotto le ipotesi fatte converge sicuramente alla radice richiesta.
Il metodo di bisezione, come risulta osservando la Fig.1.1 ad ogni iterazione dimezza l’intervallo contenente la radice che viene calcolata con la precisione desiderata.
Il punto di forza di questo metodo è nella sua semplicità e sicura convergenza, il suo punto debole è invece nella scarsa efficienza rispetto agli altri metodi infatti poiché ad ogni passo viene dimezzato l’intervallo contenente la radice, pertanto richiede un numero elevato di iterazioni.
PROGRAM EQUAZNLIN
Il metodo delle corde è un metodo iterativo più efficiente per calcolare le radici di un’equazione non lineare ¦(x) reale e continua in un intervallo chiuso e limitato [a,b] che assuma valori di segno opposto agli estremi dell’intervallo, condizione che, come detto in precedenza, assicura la presenza di almeno una radice.
Il metodo delle corde (o della falsa posizione), la cui interpretazione grafica è riportata in Fig.1.2, consiste nel calcolare se l’intersezione xi della retta (corda) passante per i punti A,B di coordinate (a,ƒ(a)) e (b, ƒ(b)) rispettivamente con l’asse delle ascisse è una radice.
Poiché l’equazione di una retta passante per i punti A,B ha equazione:
x - a =
y- ƒ(a)
b - a
ƒ(b) -ƒ(a)
ponendo y=0 si ottiene:
x= a - (b - a) * f(a)
ƒ(b) -ƒ(a)
o ancora meglio:
x= a*f(b) - b* f(a)
ƒ(b) -ƒ(a)
Per verificare questa condizione, non si controlla se ¦
(xi ) = 0, ma (poiché si lavora con i numeri reali)
se |¦ (xi ) | < p, ove
p rappresenta la precisione scelta.
Se xi non è una radice si valuta il segno del
prodotto ¦(a) .¦(xi
) e si procede allo stesso modo nel sottointervallo [a, xi ]
se il segno è negativo, o nel sottointervallo [xi ,b]
se è positivo.
Pertanto iterando il procedimento si genera una successione di termini {xi}, il cui termine (i+1)-esimo è:
xi+1 = xi-1 *f(
xi ) - xi * f(
xi-1 )
i= 2,3,4…..
ƒ(xi) - ƒ(xi-1)
Poiché il procedimento su cui è basato il metodo delle corde approssima la funzione con la retta individuata dai punti di coordinate (a, f(a)) e (b, f(b)) si può dimostrare che l’errore commesso durante ogni iterazione è minore e pertanto è necessario un minor numero di iterazioni, come può essere provato facendo eseguire il programma.
METODO DELLE CORDE
Al procedimento descritto (sostituendo ad a x1 e a b
x2) può essere associato il seguente algoritmo:
Si noti che nell'algoritmo abbiamo inserito anche il controllo su |f2-f1|<p
in quanto nel caso che fossimo vicini ad un punto singolare (massimo, minimo,
flesso) si tenterebbe di dividere per 0 e ciò causerebbe un errore.
In un programma completo andrebbe previsto che in tale ipotesi si ricominci
l'esecuzione con due diversi valori iniziali x1, x2.
METODO DI NEWTON-RAPHSON
Il metodo di Newton-Raphson è tra i metodi iterativi descritti il più efficiente.
Esso consiste nel calcolare se l’intersezione x1 della retta tangente al grafico della funzione passante per un punto A di coordinate (x0,ƒ(x0)) con l’asse delle ascisse è una radice.
Per verificare questa condizione, non si controlla se ¦ (x1 ) = 0, ma (poiché si lavora con i numeri reali) se |¦ (x1) | < p, ove p rappresenta la precisione scelta.
Ricordando che:
y – ƒ(x0)= ƒ' (x0) (x– x0)
pertanto ponendo y=0 si ottiene:
– ƒ(x0)= ƒ' (x0)
x – ƒ' (x0) x0
quindi l'ascissa x1in cui la tangente incontra l'asse delle X:
x1= x0 – ƒ(x0) / ƒ' (x0)
Se se |¦
(x1) | < p, ovvero se x1
è una radice si interrompe l'elaborazione, altrimenti si procede
con un altro punto x2 intersezione della retta tangente al grafico
della funzione passante per un punto di coordinate (x1,ƒ(x1)),
applicando iterativamente il metodo si genera una successione di termini
{xi}, il cui termine (i+1)-esimo è:
xi+1 = xi – ƒ(xi)/ ƒ' (xi) i = 0,1,2….
Poiché il procedimento su cui è basato il metodo di Newton
approssima la funzione con la retta tangente al grafico della funzione
si può dimostrare che l’errore commesso durante ogni iterazione
è minore rispetto a quello commesso nei metodi precedenti, infatti
si dice che il metodo di Newton è del secondo ordine o che ha convergenza
quadratica, cioè l’errore al passo n-esimo è proporzionale
al quadrato dell’errore al passo precedente e pertanto richiede un minor
numero di iterazioni, come può essere provato facendo eseguire il
programma.
Si noti però che, a differenza degli altri metodi, la convergenza
della successione { xi } non è garantita per ogni x0
e per ogni funzione ƒ.
Per poter codificare l’algoritmo di Newton occorre introdurre anche il calcolo delle derivate delle funzioni oltre che di ƒ(x).
Per quanto attiene il calcolo della derivata di una funzione ricordandone la definizione:
ƒ' (xi) = lim
f(x+D x) - f(x)
D x® 0
D x
basta fissare un valore molto piccolo per D x e calcolare numericamente il valore che la funzione assume in corrispondenza della x.
METODO DI NEWTON_RAPHSON
Data la funzione f(x) di cui si riporta il grafico, i punti P,
Q e A individuano il triangolo rettangolo PQA.
Possiamo scrivere che :
Da cui deriva la corrispondenza tra il coefficiente angolare m ()
con il valore della derivata prima della funzione calcolata nel punto
di coordinate x f(x).
La valutazione di integrali definiti quando non è nota la primitiva
della funzione integranda o quando il procedimento analitico risulta complesso
richiede l’applicazione di metodi numerici.
Le tecniche numeriche si basano sull’applicazione di una formula che
usa i valori che la funzione integranda assume all’interno dell’intervallo
di integrazione.
Ogni formula di integrazione numerica ha un suo grado di precisione
infatti:
b
n
ò f(x) =
å ci f(x)
+ Rn (f)
a
i=1
il primo termine è detto parte approssimante e Rn (f) errore di troncamento.
La valutazione numerica dell’integrale avviene tramite la costruzione di una opportuna successione di valori {xi}, tale che risulti:
n
b
lim å
ci f(x) = ò
f(x) e Rn (f) = 0
n® ¥
i=1
a
La successione {xi} dei valori ottenuti dipende dal procedimento iterativo applicato.
Nei successivi paragrafi saranno analizzati alcuni tra i metodi di integrazione numerica più semplici da realizzare: il metodo dei rettangoli, dei trapezi e di Cavalieri-Simpson.
Il metodo dei rettangoli è il metodo iterativo più semplice per calcolare l’integrale definito di una funzione ¦(x) reale e continua in un intervallo chiuso e limitato [a,b].
Esso consiste nel suddividere l’intervallo di integrazione [a,b] in un certo numero di sottointervalli n e nell’approssimare la funzione all’interno di ciascun intervallo con il valore costante che questa assume nel suo punto medio, pertanto il calcolo dell’integrale numerico viene quindi a corrispondere con la somma dei rettangoli aventi come base l’ampiezza costante dei sottointervalli h = (b-a)/n e come altezza il valore che la funzione assume nel punto medio di ciascun rettangolo.
La formula risultante, nel caso in cui si scelga n=1 risulta:
b
ò f(x) »
h *f (a+h/2) ove h= (b-a)
a
Nel caso in cui n=2, h= (b-a)/n
b
ò f(x) »
h* f (a+h/2) + h f(a+h/2+h)
a
mentre per n generico e h= (b-a)/2n si ha:
b
n-1
ò f(x) »
å h f(a+(1/2+i) h)
a
i=0
Il procedimento di calcolo dell’integrale, può essere semplicemente
realizzato prevedendo n iterazioni che conviene numerare con i
da 0 a n-1 e incrementare ad ogni passo, come è riportato
nel programma, la somma integrale con il valore: F(A+(i+.5)*h)
.
infatti la x dovrebbe assumere i valori:
A+h/2, A+h/2+h,A+ h/2+h+h,....ovvero ad ogni iterazione x= A+(i+0.5)h
Per una migliore approssimazione del risultato e per non incorrere
in problemi di convergenza il calcolo dell’integrale viene ripetuto dimezzando
a ogni passo l’ampiezza dei sottointevalli, fino a quando la differenza
tra due valori successivamente calcolati è minore della precisione
che si vuole raggiungere nel calcolo.
Per verificare questa condizione (poiché si lavora con i numeri reali) si controlla se |I-I1 | < p, ove p rappresenta la precisione scelta.
Nel metodo dei rettangoli, la cui interpretazione grafica è riportata in Fig.2.1 poiché si approssima la funzione, in ogni sottointervallo, con la retta parallela all’asse x di equazione y = f(xi) viene commesso un errore di approssimazione che richiede un elevato numero di iterazioni prima di giungere al risultato.
Esso consiste nel suddividere l’intervallo di integrazione [a,b] in
un certo numero di sottointervalli n e nell’approssimare
la funzione all’interno di ciascun intervallo con la spezzata che congiunge
i punti per cui passa il grafico della funzione agli estremi di ogni intervallo,
pertanto il calcolo dell’integrale corrisponde alla somma dei trapezi aventi
come altezza l’ampiezza dei sottointervalli SPEP = (b-a)/n
e come base maggiore e minore il valore che la funzione assume agli estremi
dei singoli sottointervalli.
La formula risultante, nel caso in cui si scelga n=1 risulta:
b
ò f(x) »
h/2 ( f (a+h) + f(a)) ove
h= (b-a)
a
Nel caso in cui n=2, h= (b-a)/n
b
ò f(x) »
h/2 ( f (a+h) + f(a)) + h/2 ( f (a+2h) + f(a+h))
a
mentre per n generico e h= (b-a)/2n si ha:
b
n-1
ò f(x) »
å h/2 [f(a+(i+1)
h) + f(a+i h)]
oppure
a
i=0
b
n-1
ò f(x) »
h/2 [f(a+f(b)] + å
h [f(a+i h)] (detta formula di Bezout)
a
i=0
Il calcolo dell’integrale, di cui in Fig.2.2.ne è riportata
l’ interpretazione grafica, può essere semplicemente realizzato
prevedendo n iterazioni che conviene numerare con un indice i
da 0 a n-1 e incrementare ad ogni passo la somma integrale
con il valore:
h*.5*
((F(a+i*h)+F(a+(i+1)*h)))
Infatti durante il procedimento di calcolo si deve generare una successione di termini ( ciascuno rappresentante l’area di un trapezio), ove si moltiplica l’altezza costante dei trapezi, pari ad h, per la somma delle due basi diviso 2, pertanto, come è riportato nel programma:
I=I+(h*.5*(F(a+i*h)+F(a+(i+1)*h)))
Per rendere minimo l’errore e per non incorrere in problemi di convergenza il procedimento viene ripetuto dimezzando a ogni passo l’ampiezza dei sottointevalli, fino a quando la differenza tra due valori successivamente calcolati diventa trascurabile ovvero (poiché si lavora con i numeri reali) fino a quando |I2-I1 | < p, ove p rappresenta la tolleranza scelta.
S può dimostrare che l’errore commesso usando la formula trapezoidale, che risulta :
R(t) < 1/12 (xi - xi+1)3• f¢ ¢ (x )
è molto minore rispetto a quello commesso usando la formula rettangolare, pertanto il risultato ottenuto a parità di sottointervalli risulta più approssimato.

SUBROUTINE TRAPEZI
METODO DI CAVALIERI-SIMPSON
Il metodo di Cavalieri-Simpson consiste nel suddividere l’intevallo
[a,b] in un certo numero di sottointervalli n e nell’approssimare
la funzione, all’interno di ogni sottointervallo, con una parabola individuata
dai punti di coordinate:
(xi, f(xi)), (xi+1, f(xi+1))
e dal punto intermedio (xi + (b-a)n) f(xi
+ (b-a)n)).
La formula risultante, nel caso in cui si scelga n=1 risulta:
b
ò f(x) »
(h/3)[f(a)+4f (a+h)+f( b)]
ove h= (b-a)/2
a
Nel caso in cui n=2, h= (b-a)/2n
b
ò f(x) »
(h/3)[f(a)+4f (a+h)+f( a+2h)] + (h/3)[f(a+2h)+4f (a+3h)+f( b)]
a
mentre per n generico e h= (b-a)/2n si ha:
b
ò
f(x) » (h/3)[f(a)+4f (x1)+2f(x2)+....+
4f(x2n-1)+f(x2n)]
a
Il procedimento di calcolo dell’integrale, può essere semplicemente realizzato inizializzando la somma integrale con la sommatoria dei primi due termini e dell’ultimo termine:
I=(F(a)+F(b)+4*F(a+h*(2*n-1)))*h/3.0
tramite l’iterazione di n passi che conviene numerare tramite un indice i da 0 a n-1, ove la somma integrale verrà incrementata con la coppia di termini successivi di coefficiente 4 e 2:
I=I+h/3.0*(4*F(a+i*h)+2*F(a+(i+1)*h))
Si noti che il calcolo dell’integrale secondo questo metodo, come risulta
osservando la Fig.2.3 prevede la ulteriore divisione a metà di ogni
intervallo, pertanto dopo aver fissato il valore iniziale di n questo
sarà subito raddoppiato per poter iniziare correttamente il calcolo.
Come nei casi precedenti per rendere minimo l’errore e per non incorrere
in problemi di convergenza il procedimento viene ripetuto raddoppiando
a ogni iterazione il numero dei sottointevalli, fino a quando la differenza
tra due valori successivamente calcolati è minore della precisione
che si vuole raggiungere nel calcolo, ovvero si controlla se |I2-I1
| < p, ove p rappresenta la tolleranza scelta.
Il metodo di Cavalieri-Simpson è uno tra i metodi più utilizzati per la notevole precisione che è in grado di raggiungere con pochi intervalli di calcolo, infatti è possibile dimostrare che l’errore di calcolo commesso risulta :
R(t) < 1/90 (xi - xi+1)5• f¢ ¢ (x )
ovvero molto minore rispetto alle formule presentate in precedenza.
