Creative Commons Attribuzione- Non commerciale -Non opere derivate 3.0 Italia License
a.a. 2011/2012
Annamaria Mazzia: Appunti di Calcolo Numerico,
Dipartimento di Ingegneria Civile Edile e Ambientale
Università degli Studi di Padova
VERSIONE A . A . 2011/2012 .
Indice iii
1 Struttura dell’elaboratore 1
1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 La preistoria del computer: Babbage e Lovelace . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Gli albori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Architettura del Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Software e Sistema Operativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.5.1 Per capire meglio il sistema operativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 Il file system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.7 Un po’ di storia sui sistemi operativi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.8 Lavorare in ambiente Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.9 Editor di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2 Richiami di analisi 13
2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 Identità trigonometriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3 Regole su funzione esponenziale e logaritmica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.4 Derivate e integrali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.5 Teoremi utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4 Zeri di funzione 37
4.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.2 Metodo delle Bisezioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.3 Metodo del Punto Fisso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.4 Il Metodo di Newton-Raphson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.5 Convergenza di un metodo iterativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.6 Complessità computazionale di uno schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.7 Il metodo delle secanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.8 Confronto tra i metodi di Newton-Raphson e la Regula Falsi . . . . . . . . . . . . . . . . . . . . . 50
4.9 Metodo di Newton-Raphson per radici multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
iii
I NDICE
5 Interpolazione 61
5.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2 Interpolazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.3 Interpolazione polinomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.3.1 Funzioni base monomiali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.3.2 Polinomi di Lagrange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.3.3 Formula dell’errore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.3.4 Differenze divise e formula di Newton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.4 Considerazioni sull’interpolazione polinomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.4.1 Fenomeno di Runge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.4.2 Malcondizionamento nell’interpolazione con funzioni base monomiali . . . . . . . . . 72
5.5 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6 Approssimazione 77
6.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.2 Retta di regressione lineare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
6.3 Approssimazione polinomiale ai minimi quadrati . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
6.4 Approssimazioni di tipo esponenziale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.5 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
iv
Indice
v
I NDICE
Bibliografia 211
vi
CAPITOLO
1
S TRUTTURA DELL’ ELABORATORE
Albert Einstein
1.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 La preistoria del computer: Babbage e Lovelace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Gli albori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Architettura del Computer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.5 Software e Sistema Operativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.5.1 Per capire meglio il sistema operativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6 Il file system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.7 Un po’ di storia sui sistemi operativi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.8 Lavorare in ambiente Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.9 Editor di testo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1 Introduzione
Se dobbiamo comprare un computer, abbiamo solo l’imbarazzo della scelta tra i tanti disponibili sul
mercato. Ma in base a quali criteri scegliamo un computer?
Le caratteristiche fondamentali di un computer si possono riassumere in poche parole-chiave: pro-
cessore, sistema operativo, memoria. Cosa significano esattamente? E, prima ancora, cosa significa
Computer?
1
1. S TRUTTURA DELL’ ELABORATORE
In generale, un computer esegue operazioni logiche e aritmetiche e ha una memoria per conservare i dati.
Un programma contiene le informazioni relative alle operazioni da eseguire.
Hardware Si definisce hardware la struttura fisica del computer cioè i i suoi componenti elettronici e i dispositivi
fisici che lo compongono.
Software Si chiama, invece, software l’insieme delle istruzioni (i programmi) che consentono all’hardware di
svolgere i propri compiti (per esempio, il sistema operativo – Windows, Linux, etc – è un tipo di software;
programmi applicativi come Word, Excel, LaTex sono dei software).
Attraverso un computer, elaboriamo dati (numeri, suoni, video, fotografie) in modo da ottenere in-
formazioni (lettere, tabelle, risultati di procedimenti numerici. . . ). Alcune di queste informazioni possono
diventare dati da elaborare di nuovo al computer.
2
1.3. Gli albori
era seduto nella stanza della Società Analitica, a Cambridge, lavorando, mezzo addormentato, su una tavola
dei logaritmi, arrivò un altro membro della società che gli chiese cosa stesse sognando. E lui rispose : – Sto
pensando che tutte queste tavole – riferendosi alle tavole dei logaritmi – potrebbero essere calcolate da una
macchina!
Nel 1821, Babbage e il suo amico e astronomo John Herschel stanno controllando delle tabelle calcolate
a mano. Errore dopo errore, Babbage esclama : – Volesse Dio che questi calcoli venissero eseguiti da una
macchina a vapore!
Il suo desiderio di creare una macchina per eseguire calcoli si concretizzò in due progetti, quello della
Macchina alle Differenze e quello della Macchina Analitica2 . La Macchina alle Differenze doveva calcolare
in modo automatico funzioni polinomiali ma non venne mai completata per il suo costo eccessivamente
elevato. La Macchina Analitica, invece, doveva essere una macchina di calcolo programmabile, e si può con-
siderare come la prima idea del moderno computer. Anche questo progetto, tuttavia, rimase incompiuto.
Solo nel 2002 è stato possibile costruire una macchina che rispondesse al progetto di Babbage.
Nel 1833, Babbage incontrò Ada Lovelace3 , figlia del famoso poeta Lord Byron. Lovelace, appena dicias- Ada Lovelace
settenne, aveva parecchie conoscenze matematiche, inusuali per l’epoca, e si entusiasmò talmente tanto per
il progetto di Babbage, da intuire altre potenzialità della macchina stessa, come la capacità dei numeri di
poter rappresentare altre entità quali le lettere dell’alfabeto o le note musicali, e che dalla manipolazione dei
numeri la macchina avrebbe esteso la propria potenza oltre il mondo della matematica. Sempre la Lovela-
ce intuì che la soluzione dei problemi matematici si sarebbe effettuata attraverso delle procedure di calcolo
(quelli che noi chiamiamo programmi).
Alla luce degli sviluppi che si sono avuti nel ventesimo secolo, la visione di Babbage e della Lovelace
appare profetica.
3
1. S TRUTTURA DELL’ ELABORATORE
a persuadere l’Istituto di Ricerca Aerodinamica del Terzo Reich a continuare i suoi studi. Completa quindi la
costruzione dello Z2 e inizia a lavorare sullo Z3, che è il primo computer che Zuse costruisce per essere usato
e non per verificare le proprie idee. Lo Z3 ha non solo l’unità aritmetica ma anche la memoria realizzata con
relè elettromeccanici, ben 2600. Z3 fu la prima macchina di calcolo programmabile e venne usata dall’in-
dustria aerea per risolvere sistemi di equazioni e altri sistemi matematici ricavati da problemi di vibrazione
degli apparecchi aerei messi sotto stress.
Quando Zuse propose di passare all’uso di un computer basato su valvole elettroniche, la proposta fu
respinta perchè i tedeschi si consideravano così vicini alla vittoria della guerra che ulteriori sforzi nella ricerca
non apparivano necessari.
Il lavoro di Zuse, comunque, andò avanti con la costruzione dello Z4, di S1 e S2. E, soprattutto, fu
completamente indipendente dai lavori di John Eckert e John Mauchly negli Stati Uniti e di A. Turing in
Inghilterra.
In Inghilterrra, Turing6 si occupò di problematiche riguardanti un macchina di calcolo digitale astratta,
con una memoria senza limiti, mentre negli USA Eckert e Mauchly7 costruirono l’ENIAC (Electronic Inte-
grator and Computer). L’ENIAC fu costruito, con progetto di Eckert, in piena seconda guerra mondiale, a
partire dal 1943, presso il Ballistic Research Laboratory e fu completato nel febbraio del 1946. La macchina
era pensata per compiere operazioni di carattere generale, ma fu costruita con lo scopo preciso di compilare
tabelle per le traiettorie di bombe. L’ENIAC conteneva circa 18. 000 valvole termoioniche e misurava circa 2
metri e mezzo di altezza per 24 metri di lunghezza! La macchina era più di mille volte veloce di tutti i prede-
cessori elettromeccanici costruiti fino a quel momento e poteva eseguire 5000 addizioni al secondo. Le sue
operazioni erano controllate da un programma che veniva inserito dall’esterno mediante nastri perforati.
von Intanto, nel 1944 aveva iniziato a collaborare nella costruzione dell’ENIAC, John von Neumann8 . Egli si
Neumann accorse che l’architettura della macchina andava rivista e che la programmazione del computer mediante un
numero enorme di cavi e interruttori rendeva lenta e poco flessibile la programmazione stessa. Sostenne,
quindi, che il programma non dovesse essere rigidamente predisposto nell’hardware tramite interruttori e
cavi e neanche letto mediante nastri perforati, ma risiedesse in una memoria su cui poter scrivere e accedere
velocemente insieme ai dati da elaborare. Von Neumann per primo descrisse l’architettura dei calcolatori in
termini logico-funzionale, secondo uno schema astratto non legato ai dispositivi fisici utilizzati per le varie
operazioni. E il suo schema, sostanzialmente invariato, è l’architettura adottata dai calcolatori dei nostri
giorni!
Prima di von Neumann, il calcolatore veniva controllato mediante programmi non modificabili, registrati
su nastro perforato o cablati in una configurazione di cavetti e interruttori. Con von Neumann si presenta
un’architettura di riferimento precisa.
Il primo calcolatore costruito seguendo l’architettura di von Neumann entrò in funzione nel 1948
all’Università di Manchester e venne chiamato Manchester Mark I.
Inizia, in tal modo, una nuova fase per i calcolatori: i programmi che controllano le operazioni da svolgere
risiedono nella memoria del calcolatore insieme ai dati e possono essere modificati dinamicamente nel corso
dell’elaborazione.
Dal 1948 fino ai nostri giorni, lo sviluppo dei calcolatori elettronici ha avuto ritmi esponenziali: l’inven-
zione del circuito integrato (chip) alla fine degli anni cinquanta permise non solo di ridurre via via lo spazio
fisico occupato dai computer ma anche di ottenere computer sempre più potenti tanto che, in due suoi la-
vori, del 1965 e del 1975, Gordon Moore9 stabilì che il numero dei transistor inseribili su un chip raddoppia
6 Alan Turing (1912-1954), matematico inglese, si interessò di logica matematica e di teoria della probabilità. Introdusse il concetto
di una macchina astratta, detta macchina di Turing e pose questioni riguardanti l’intelligenza artificiale
7 John Presper Eckert (1919-1995) e John William Mauchly (1907-1980) lavorarono a quello che si può considerare il vero primo
calcolatore elettronico.
8 John von Neumann (1903-1957) ungherese, studiò prima a Berlino, poi a Zurigo e infine a Budapest, dove ricevette il dottorato in
matematica. Nel 1930 si trasferì alla Università di Princeton dove insegnò matematica. Il suo nome è legato a studi in diversi settori:
teoria dei giochi, matematica applicata, logica... Occupa un ruolo fondamentale nello sviluppo dei calcolatori elettronici. Ricevette
numerosi premi e riconoscimenti in tutto il mondo.
9 Gordon Moore è nato nel 1929 in California. Di lui basti ricordare che ha stabilito la legge di Moore, è co-fondatore della Intel
Corporation e nel 2008 ha ricevuto la medaglia d’onore dell’IEEE per il suo pioneristico contributo nei processi dei circuiti integra-
ti, e per la leadership nello sviluppo della memoria del MOS (semiconduttore metal-ossido), del microprocessore e dell’industria dei
semiconduttori.
4
1.4. Architettura del Computer
approssimativamente ogni 24 mesi (legge di Moore). Nel 1971 tre ingegneri della Intel tra cui l’italiano Fe-
derico Faggin10 inventarono il microprocessore, vale a dire un’intera CPU in un singolo circuito integrato:
su una piastrina di 4 × 3 millimetri riuscirono a inserire 2250 transistor, che formavano il cuore di un inte-
ro computer: questo microprocessore fu chiamato Intel 4004 ed era capace di eseguire 60. 000 operazioni al
secondo.
Se pensiamo che il processore Intel Pentium 4 introdotto nel 2000 ha 42. 000. 000 processori e l’Intel Ita-
nium 2 (con 9MB di cache) introdotto nel 2004 ha 592. 000. 000 transistors, ci accorgiamo di come la legge di
Moore, dal 1968 ad oggi, sia stata rispettata.
5
1. S TRUTTURA DELL’ ELABORATORE
attuali hanno valori di frequenza del clock che variano tra gli 8 MHz e i 3500 MHz (1 MHz = 1 milione di
istruzioni al secondo).
La memoria serve per conservare le istruzioni da eseguire e per scrivere/leggere i dati elaborati. Si
suddivide in memoria principale e memoria secondaria.
La memoria principale (o di lavoro) è la memoria in grado di conservare dinamicamente dati e
programmi che il processore sta utilizzando. A sua volta la memoria principale può essere di due tipi:
G memoria di sola lettura (read-only memory): ROM. Viene scritta una volta per tutte dal produttore del
sistema e contiene programmi e informazioni specifiche per il sistema; è utilizzata per memorizzare
parametri di configurazione del sistema, utili all’avvio del computer;
G memoria per scrittura-lettura (random access memory): RAM. Serve alla CPU per lavorare con i
programmi inseriti dall’utente.
Poichè la RAM conserva i dati solo fino a quando il computer rimane acceso (infatti è detta memoria
di tipo volatile, perchè se ne perde il contenuto quando la macchina viene spenta), per conservare dati e
programmi per tempi lunghi e a sistema spento, si utilizza la memoria di massa (o secondaria) – dischi
RAM come l’Hard Disk, CDROM, DVD, pendrive USB. . . .
La RAM può essere pensata come una sequenza di celle (locazioni), ognuna identificata da un indirizzo e
capace di contenere informazioni binarie.
L’unità minima indirizzabile della memoria è detta parola (word) e può variare da macchina a macchina.
In genere una parola vale un byte, cioè 8 bit.
Il computer scambia informazioni con il “mondo esterno” per mezzo delle periferiche di input/output
(monitor, mouse, stampante, web-cam,...).
Input è l’inserimento di dati nel computer per l’elaborazione. Output è il trasferimento di dati dal
computer a dispositivi che permettono all’utente di vedere/ascoltare i risultati dell’elaborazione.
6
1.5. Software e Sistema Operativo
I primi sistemi operativi iniziarono a vedersi intorno alla metà degli anni cinquanta quando si cominciò
a individuare una serie di programmi standard di comune utilizzo indipendenti dall’applicazione specifica
richiesta al computer. Cenni storici
L’evoluzione dei sistemi operativi ha influenzato anche lo sviluppo dell’hardware in quanto per suppor-
tare certe funzioni del sistema operativo sono necessari meccanismi hardware ad hoc (basti pensare alla
gestione della memoria o delle interruzioni).
I primi computer come lo Z3 di Zuse o l’ENIAC non avevano sistema operativo. Per inserire un program-
ma (scritto in linguaggio macchina) bisognava azionare un gruppo di interruttori o modificare collegamenti
tramite opportuni cavi e spinotti. Ci rendiamo conto, quindi, di quanto fosse difficile usare il computer per
risolvere problemi mediante l’esecuzione di un programma perchè oltre alla competenza specifica del pro-
blema da risolvere, si richiedeva una grande conoscenza tecnica della macchina su cui si doveva lavorare. Il
programma doveva contenere non solo le istruzioni per la risoluzione del problema (per esempio un sistema
di equazioni) ma anche le istruzioni per gestire le unità di input e output e delle altre periferiche collegate al
computer. Infine, poteva essere eseguito un solo programma alla volta.
Considerando gli elevatissimi costi per la realizzazione e la gestione dei primi computer, il calcolo auto-
matico era una risorsa preziosa a disposizione di pochi utenti. Tutto ciò portò ad un ripensamento del modo
7
1. S TRUTTURA DELL’ ELABORATORE
G
sistema operativo, che cambiava da macchina a macchina!
lo sviluppo di questo sistema operativo fu molto delicato e complesso e aprì lo studio delle
problematiche relative all’ingegneria del software.
Nonostante questi progressi, la multiprogrammazione non permetteva molta interattività tra utente e
computer: di fatto l’utente consegnava i dati e il programma da eseguire (un pacco di schede perforate) all’o-
peratore del computer e accedeva ai risultati dopo qualche ora se non addirittura dopo giorni e giorni, risul-
tati che riceveva in forma cartacea ad esecuzione avvenuta (non c’era ancora il monitor per la visualizzazione
su video dei risultati).
Per risolvere questo tipo di problemi, l’uso delle schede fu sostituito da appositi terminali sempre collegati
al computer e furono cambiate le modalità di gestione dell’unità centrale modificando i sistemi operativi
esistenti. Si arrivò all’interazione con il computer non più mediante schede perforate bensì tramite tastiera-
stampante o tramite tastiera-monitor.
Alla fine del 1950 si introdusse il concetto di time-sharing che permetteva l’esecuzione di più processi
in modo da poter soddisfare le esigenze di più utenti contemporaneamente. Con il time-sharing si assegna,
infatti, un piccolo intervallo di tempo a ciascun processo dando l’impressione che ciascun processo vada
avanti parallelamente agli altri.
Gli sviluppi del sistema operativo ottenuti da allora fino ad oggi si possono così riassumere: il sistema
operativo fornisce funzioni di base per la gestione delle risorse, quali:
G uso del processore (multitasking: l’uso della CPU è permesso ad un programma alla volta per brevi
G
intervalli di tempo, quindi l’utente può eseguire più programmi contemporaneamente)
G
uso della memoria centrale (memoria virtuale)
G
riconoscimento e gestione degli utenti (multiutenza)
G
gestione delle periferiche (drivers)
G
file system
Sul software interfaccia grafico.
Il software di base (o general purpose) può avere funzioni varie: editor di testo, elaborazione di testi, fogli
elettronici, posta elettronica, internet.
Il software applicativo è costituito da programmi che hanno obiettivi specifici come intrattenimento,
Memoria controllo di sistemi, progettazione (CAD), risoluzione di problemi matematici.
cache Per migliorare le prestazioni di un computer si inserisce una memoria intermedia tra CPU e RAM, detta
cache. Si trova all’interno del processore. È più veloce della RAM ma anche più costosa.
8
1.6. Il file system
9
1. S TRUTTURA DELL’ ELABORATORE
appositamente per il sistema Unix. In tal modo il sistema operativo diventava facilmente portabile su mac-
chine di tipo diverso senza dipendere eccessivamente dalle caratteristiche dell’hardware su cui veniva fatto
funzionare. Diversamente dalle abitudini del tempo, l’azienda AT & T distribuì Unix nelle università e rese
disponibili i codici sorgenti utilizzati per realizzarlo. Questo portò ad una sua ulteriore innovazione grazie a
tutti i ricercatori delle università che iniziarono a sperimentarlo.
Quando furono messi in commercio i primi microcomputer (a partire dal 1975), fu necessario sviluppa-
re sistemi operativi appositamente progettati per sfruttare le poche risorse disponibili essendo le risorse di
calcolo di tali macchine molto limitate. Inoltre, queste macchine erano pensate più per gli appassionati che
per il personale tecnico esperto e quindi era importante creare un sistema operativo che fosse d’uso relativa-
mente semplice. In questo campo si distinsero Bill Gates e Paul Allen, che iniziarono la loro attività scrivendo
il linguaggio di programmazione Basic per il micromputer Altair. Nel 1975 crearono una ditta... la Microsoft.
Un altro microcomputer, popolare nei primi anni ottanta, fu l’Apple sviluppato da Steve Wozniak e Steve
Jobs. Per questa macchina svilupparono un sistema più semplice ed efficiente di quello usato per l’Altair, che
si ispirava vagamente al sistema Unix.
I sistemi operativi per i microcomputer dovevano essere più semplici di quelli impiegati per i grandi com-
puter, in quanto la macchina veniva utilizzata da un solo utente e le periferiche collegate erano poche e sem-
plici. Il problema maggiore ero quello di gestire i file su floppy disk (gli antenati dei CD-ROM e dei DVD, in
uso fino ad una decina di anni fa) o su nastri magnetici e mettere a disposizione dell’utente un linguaggio
di programmazione semplice, come il Basic. Tuttavia, il confine tra linguaggio di programmazione e sistema
operativo non era ancora ben definito e, una volta avviato, il sistema era pronto per ricevere sia comandi del
sistema operativo, sia istruzioni in linguaggio Basic.
I microcomputer iniziarono ad avere un grosso successo tanto che all’inizio degli anni ottanta, l’IBM pen-
sò di entrare in questo settore (prima si era solo occupata di grandi computer e di software), introducendo
il personal computer, IBM PC, realizzando in tal modo una macchina che servisse non solo per gli appas-
sionati e per giocare (uno dei fattori che aveva determinato il successo dei microcomputer) ma anche come
strumento di studio, per i professionisti e per la gestione di piccole aziende.
L’IBM incaricò Bill Gates di realizzare un sistema operativo per il nuovo personal computer. Il successo
dell’IBM PC portò al successo anche di Bill Gates: i profitti della Microsoft iniziarono a crescere in modo
esponenziale. Il sistema realizzato dalla Microsoft prese il nome di MS-Dos e divenne il sistema operativo
più diffuso al mondo grazie alla standardizzazione dei personal computer lanciato dall’IBM.
Il sistema MS-Dos non era facile da usare perchè l’utente interagiva con il computer solo attraverso
comandi testuali la cui sintassi non era così semplice da ricordare (qualche anno più tardi fu lanciata sul
mercato una versione più amichevole).
Nel 1984, invece, dalla Apple fu prodotto il personal computer Macintosh che adottava un tipo di inter-
faccia grafico progettato per interagire in modo semplice e intuitivo con l’utente. Il Macintosh utilizzava un
interfaccia grafico chiamato GUI (Graphic User Interface) composto da icone, finestre, menù... Gli oggetti
dell’ambiente operativo erano rappresentati con simboli grafici di facile intuizione senza dover comprende-
re a fondo tutti i tecnicismi informatici. L’interfaccia GUI non era un’invezione della Apple perchè era stata
già sperimentata nel corso degli anni settanta dalla Xerox, che però non aveva intuito le potenzialità di questo
lavoro, lasciandone invece la fortuna e il successo alla Apple che, insieme ad esso, introdusse il mouse.
Ovviamente, queste novità furono molto apprezzate e la Microsoft, per colmare questa lacuna, lanciò un
altro sistema operativo basato su interfaccia grafica: nel 1985 nacque il primo Windows 1.0 che trovò pochi
consensi perchè troppo lento e instabile. Nel 1986, con la comparsa di nuovi microprocessori, il sistema
Windows cominciò a funzionare in modo adeguato tanto che le versioni di Windows 3.1 e di Windows 95
portarono al sopravvento del sistema operativo Windows rispetto al Macintosh.
Accanto a questi sistemi operativi, e forse anche per ridurre lo strapotere della Microsoft, si deve vede-
re la strada percorsa da un informatico di Helsinki (data di nascita 1969), Linus Benedict Torvalds, che ha
introdotto il sistema Linux.
Durante gli studi universitari, Torvalds si era interessato di sistemi operativi e aveva studiato una versio-
ne semplificata di Unix, chiamata Minix. Questo sistema poteva funzionare su personal computer e veniva
distributo con i programmi sorgenti disponibili. Torvalds migliorò il sistema Minix, in modo da poterlo uti-
lizzare come alternativa a Windows, nella logica di non realizzare profitti (cioè non diventare milionario) ma
di realizzare un sistema utilizzabile gratuitamente da tutti e migliorabile con il contributo di tutti (la filosofia
10
1.8. Lavorare in ambiente Linux
dell’open source). Nel 1991 fu completata la prima versione del sistema, che fu chiamata Linux e venne mes-
sa a disposizione di tutti. Torvalds si riservò il compito di coordinare i diversi miglioramenti via via introdotti
dagli altri sviluppatori.
Tra le tante distribuzioni attualmente in uso ricordiamo: Debian, Ubuntu, Fedora, Gentoo, Slackware. . .
Linux si è dimostrato e si dimostra tuttora un valido sistema operativo, affidabile, sicuro e di buone
prestazioni, in grado di gestire situazioni multiutente e multitasking.
Ed è il sistema operativo di riferimento del corso di Calcolo Numerico.
studente@george:~ $
Vediamo ora alcuni comandi essenziali (comandi da scrivere dopo il prompt, in una finestra di terminale
– dopodichè si clicca il tasto di Invio):
G ls mostra l’elenco dei files e delle directories contenuti nella directory attuale ( ls sta per list):
Esempio:
studente@george:~ $ ls
Un volta cliccato Invio, compare l’elenco delle directories presenti nello spazio di lavoro disponibile per
l’utente studente sulla macchina george, ad esempio (i numeri a sinistra delle directories o files sono
indicatori dello spazio che occupano in memoria):
5 appunti/ 4 mail/
2 calcolonumerico/ 4 movies/
3 fortran/ 1 varie/
3 foto/ 57 prova.pdf
G Per cambiare directory, si deve digitare cd nome-directory
(cd sta per change directory). Esempio: per entrare nella directory foto, scriviamo
studente@george:~ $ cd foto
Una volta cliccato il tasto di Invio, si è entrati nella directory foto:
studente@george:~/foto $
G Il comando cd .. fa tornare nella directory precedente.
G Per creare una nuova directory: mkdir nomedirectory (mkdir sta per make directory).
G Per copiare un file dentro una directory: cp nomefile nomedirectory (cp sta per copy).
G Per trasferire un file in una directory mv nomefile nomedirectory (mv sta per move).
G Per rinominare un file (o una directory): mv nomevecchio nomenuovo .
G Per cancellare un file si usa il comando rm nomefile.
G Per cancellare una directory, dobbiamo prima cancellare tutti i files della directory e poi usare il
comando rmdir nomedirectory.
11
1. S TRUTTURA DELL’ ELABORATORE
G Per sapere in quale directory ci troviamo, si usa il comando pwd. Esempio: siamo nella directory foto,
che è una sottodirectory della home di studente. Con il comando pwd si ha:
studente@george:~/foto $ pwd
studente@george:~/foto $ /home/studente/foto
Esempio 1.8.1 Abbiamo due directory chiamate uno e due e il file prova.f nella directory uno.
Vogliamo copiare il file dalla directory uno alla directory due.
Se ci troviamo nella home, cioè nell’ambiente di partenza, dobbiamo scrivere
cp uno/prova.f due
Se ora passiamo nella directory due e facciamo ls, vedremo il file prova.f
studente@george:~ $ cd due
studente@george:~/due $ ls
total 1
1 prova.f
Riassumendo
G ls : lista dei files e delle directory
G cd : per cambiare directory
G mkdir: per creare una nuova directory
G cp: per copiare files
G mv: per trasferire o rinominare files
G rm: per cancellare files
G rmdir: per cancellare directories
12
CAPITOLO
2
R ICHIAMI DI ANALISI
2.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2 Identità trigonometriche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3 Regole su funzione esponenziale e logaritmica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.4 Derivate e integrali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.5 Teoremi utili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1 Introduzione
Quando si descrivono teoremi, si danno definizioni o, semplicemente, si discute di matematica, è
abbastanza usuale prendere in prestito lettere dell’alfabeto greco.
È importante, quindi, saperle riconoscere e chiamarle in maniera corretta:
A α Alfa N ν Nu
B β Beta Ξ ξ Xi
Γ γ Gamma O o Omicron
∆ δ Delta Π π Pi
E ² Epsilon P ρ Rho
Z ζ Zeta Σ σ Sigma
H η Eta T τ Tau
Θ θ Theta Υ υ Upsilon
I ι Iota Φ φ Fi
K κ Kappa X χ Chi
Λ λ Lambda Ψ ψ Psi
M µ Mu Ω ω Omega
13
2. R ICHIAMI DI ANALISI
1x = 1
a x+y = a x a y a x y = (a x ) y
a loga (x) = x a0 = 1
a x−y = a x /a y a x b x = (ab)x
loga (x y) = loga (x) + loga (y) loga (x/y) = loga (x) − loga (y)
loga (x y ) = y loga (x) loga (a x ) = x
loga (x)
logb (x) = b x = a x loga (b)
loga (b)
14
2.5. Teoremi utili
Diamo ora una tabella delle derivate e degli integrali delle funzioni più note (per gli integrali lasciamo
fuori la costante di integrazione), e con la simbologia arcsin(x) ≡ arcoseno(x), arccos(x) ≡ arcocoseno(x),
cot(x) ≡ cotangente (x), arctan(x) ≡ arcotangente(x), arccot(x) ≡, arcocotangente(x).
f f0 f f0
1
ln(x) ex ex
x
sin (x) cos (x) cos (x) − sin (x)
1 1
tan (x) (= sec2 (x)) cot (x) − 2
cos2 (x) sin (x)
1 1 1 1
tan (x) − cot (x)
cos (x) cos (x) sin (x) sin (x)
1 1
arcsin (x) p arccos (x) −p
1 − x2 1 − x2
1 1
arctan (x) arccot(x) −
1 + x2 1 + x2
R R
f fdx f fdx
x r +1
xr (r 6= 1) x −1 ln |x|
r +1
ex ex ln |x| x ln |x| − x
sin (x) − cos (x) cos (x) sin (x)
1
tan (x) ln | | cot (x) ln | sin (x)|
cos (x)
1 1 1 1
ln | + tan (x)| ln | + cot (x)|
cos (x) cos (x) sin (x) sin (x)
1 1
tan (x) − cot (x)
cos2 (x) sin2 (x)
15
2. R ICHIAMI DI ANALISI
Quindi per funzioni continue, un valore compreso tra i due estremi dell’insieme di definizione, è un valore
assunto dalla funzione stessa (in uno o più punti).
Come conseguenza di questo teorema, se f (a) f (b) < 0 (la funzione assume segno opposto agli estre-
mi dell’intervallo [a, b]) allora esiste almeno un punto ξ tale che f (ξ) = 0, cioè esiste almeno una radice
dell’equazione f (x) = 0 nell’intervallo [a, b].
Teorema 2.5.4 (Esistenza del punto fisso) Data una funzione g definita in [a, b], continua e tale che a ≤
g (x) ≤ b per ogni x ∈ [a, b], allora g ammette almeno un punto fisso.
Dimostrazione. Dire che una funzione g ammette almeno un punto fisso, vuol dire che esiste almeno
un punto ξ nel suo insieme di definizione, tale che g (ξ) = ξ.
Dalle ipotesi del teorema, i valori della funzione g sono contenuti nell’intervallo [a, b] e, in particolare
a ≤ g (a) ≤ b e a ≤ g (b) ≤ b. Definiamo, perciò, la funzione continua Φ(x) mediante la relazione
Φ(x) = g (x) − x
Allora Φ(a) = g (a) − a > 0 e Φ(b) = g (b) − b < 0. Per il Teorema del Valore Intermedio esiste almeno un punto
ξ ∈]a, b[ tale che Φ(ξ) = 0, vale a dire g (ξ) − ξ = 0, cioè g (ξ) = ξ. Esiste almeno un punto fisso per la funzione
g. 4
16
2.5. Teoremi utili
Teorema 2.5.5 (Esistenza e unicità del punto fisso) Data una funzione g di classe C 1 in [a, b], con a ≤ g (x) ≤
b per ogni x ∈ [a, b], e con |g 0 (x)| ≤ m < 1 per ogni x ∈ [a, b] allora esiste ed è unico il punto fisso della g in tale
intervallo.
Dimostrazione. L’esistenza di almeno un punto fisso è assicurata dal teorema precedente (le ipotesi del
teorema precedente ci sono tutte). Supponiamo, allora, che esistano due punti fissi ξ e η, con ξ 6= η, per la
funzione g . Si ha
|ξ − η| = |g (ξ) − g (η)|
Applicando il teorema del Valor Medio, esiste un punto c compreso tra ξ e η per cui
|ξ − η| ≤ m|ξ − η| < |ξ − η|
Si arriva ad una contraddizione. L’assurdo deriva dall’aver supposto ξ 6= η. Quindi ξ = η e il punto fisso è
unico. 4
Teorema 2.5.6 (Teorema del Valor Medio del Calcolo Integrale) Se f ∈ C ([a, b]) e g è integrabile in [a, b] e
g (x) non cambia segno in [a, b], allora esiste un punto ξ ∈]a, b[ tale che
Z b Z b
f (x)g (x) d x = f (ξ) g (x) d x
a a
Per g ≡ 1, questo teorema ci dà il valore medio della funzione f sull’intervallo [a, b], dato da f (ξ) =
1 Rb
f (x) d x
b−a a
Teorema 2.5.7 (Teorema di Rolle generalizzato) Sia f ∈ C ([a, b]) n volte differenziabile in ]a, b[. Se f si an-
nulla in n +1 punti distinti x 0 , x 1 , . . . , x n in ]a, b[, allora esiste un punto ξ ∈]a, b[ in cui la derivata n-sima della
f si annulla: f (n) (ξ) = 0.
(x − x 0 )2 00
f (x) = f (x 0 ) + f 0 (x 0 )(x − x 0 ) + f (ξx )
2
dove ξx è un opportuno punto di [a, b] che si trova sul segmento individuato da x 0 e x.
f 00 (x 0 ) f (n) (x 0 )
f (x) = f (x 0 ) + f 0 (x 0 )(x − x 0 ) + (x − x 0 )2 + . . . + (x − x 0 )n + R n
2! n!
dove
f (n+1) (ξx )
R n (x) = (x − x 0 )n+1
(n + 1)!
con ξx un opportuno punto di [a, b] che si trova sul segmento individuato da x 0 e x.
1 Brook Taylor (1685 - 1731) fu un matematico inglese che sviluppò quello che oggi è chiamato calcolo delle differenze finite.
L’importanza del suo lavoro e, soprattutto, della formula conosciuta oggi con il suo nome, venne riconosciuta solo nel 1772 da Lagrange.
17
CAPITOLO
3
R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
NUMB3RS
3.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Aritmetica di macchina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.3 Conversione di base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.4 Rappresentazione IEEE dei numeri di macchina . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.5 Precisione numerica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.6 Propagazione degli errori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.7 Instabilità e malcondizionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.7.1 Instabilità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.7.2 Malcondizionamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.1 Introduzione
Molte volte, si pensa che i risultati numerici ottenuti da un calcolatore elettronico, specie se sono ottenuti
come output di un sofisticato software, non contengano errori e, se ne abbiano, siano da ritenersi trascurabili.
In realtà, quando si esegue un programma al calcolatore, bisogna prima di tutto aver verificato che sia stato
scritto correttamente (il programma deve, cioè, tradurre correttamente il problema matematico che si vuole
risolvere). Inoltre, bisogna tener conto che i risultati numerici sono sempre affetti da un certo tipo di errore,
che può essere, per esempio, di arrotondamento o di troncamento: π è un numero con infinite cifre decimali
ma il calcolatore lo può vedere solo come un numero con finite cifre decimali..., molte formule non possono
essere usate così come sono ma devono essere in qualche modo semplificate (basti pensare ad una somma di
infiniti termini). Non tenere conto di questi fattori può portare a risultati davvero disastrosi, come può essere
19
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
verificato andando a controllare la pagina web dedicata ai disastri dovuti a uno scorretto calcolo numerico:
http://www.ima.umn.edu/~arnold/disasters/disasters.html
La pagina web è del prof. Douglas N. Arnold, dell’Università del Minnesota, e viene introdotta con la
seguente frase (traducendo): Stai seguendo con attenzione il tuo corso di analisi numerica o di calcolo scienti-
fico? Se no, potrebbe essere un caro errore. Nel seguito, ci sono esempi dalla vita reale di ciò che può succedere
quando gli algoritmi numerici non sono applicati correttamente.
Vediamo alcuni di questi disastri numerici.
Esempio sul Il 25 febbraio 1991, durante la prima Guerra del Golfo, un missile Patriot fallì l’intercettazione di un
disastro del missile Scud iracheno. Questo errore costò la vita di 28 soldati, un centinaio di feriti e la distruzione di
missile
Patriot un capannone americano. La causa del disastro fu dovuto ad errori di arrotondamento nel sistema ope-
rativo del Patriot: ad ogni secondo che passava si introduceva un ritardo infinitesimo che comportava un
errore nella valutazione della traiettoria del missile Scud. Col passare delle ore il ritardo accumulato fu
tale da far intercettare una posizione del tutto diversa da quella in cui si trovava il missile da abbattere.
Difatti, il computer usato per controllare il missile Patriot era basato su
un’aritmetica a 24 bit. Per i calcoli, il tempo veniva registrato dall’orolo-
gio interno del sistema in decine di secondi e successivamente moltipli-
cato per 1/10 per ottenere i secondi, utilizzando 24 bit in virgola fissa. Il
numero 1/10 in base 2 ha infinite cifre decimali: la sua espansione bina-
ria è infatti 0.0001100110011001100110011001100 . . .. In 24 bit esso veni-
va registrato come 0.00011001100110011001100 introducendo un erro-
re di 0.0000000000000000000000011001100 . . ., che, in base 10, significa
circa 0.000000095.
Gli errori di arrotondamento nella conversione del tem-
po causarono un errore nel calcolo della traiettoria: il tem-
po di 100 ore calcolato in secondi diede il valore 359999.6567
Figura 3.1: Il disastro del missile invece di 360000, un errore di 0.3433 secondi che portò
Patriot il Patriot 687 metri fuori della traiettoria del missile Scud!
L’esplosione
dell’Ariane 5 Il 4 giugno 1996, dopo una spesa di 7 miliardi di dollari, e dopo appena 40
secondi dal suo lancio, esplose il razzo Ariane 5, nella Guiana Francese. Il razzo
e il suo carico erano valutati per oltre 500 milioni di dollari. Perciò il costo
totale della missione era stato di oltre 7 miliardi e mezzo di dollari. Fu scoperto
che l’errore era nel software e, in particolare, nella componente del Sistema di
Riferimento Inerziale, che era stato preso dal software dell’Ariane 4. Certe parti
del software dell’Ariane 5 erano state aggiornate rispetto al software dell’Ariane
4, ma non si era aggiornato quanto preso dal software dell’Ariane 4.
In particolare, il fallimento dell’Ariane 5 è dovuto ad un errore di con-
versione da un sistema a 64 bit a virgola mobile ad uno a 16 bit a virgola
fissa.
La velocità orizzontale del razzo rispetto alla piattaforma misurato in 64 bit
era un numero più grande del massimo consentito nell’aritmetica a 16 bit. Si
ebbe quindi un errore di overflow che causò l’arresto del software di controllo
del volo 37 secondi dopo il lancio del razzo. Dopo 3 secondi il razzo si distrusse.
Il disastro del
Mars Climate Il disastro, invece, del veicolo spaziale della missione Mars Climate Orbiter
Orbiter Figura 3.2: L’esplosione di
non si trova sulla pagina web del prof. Douglas, ma i dettagli della storia si pos-
Ariane 5
sono trovare, ad esempio, sul sito http://marsprogram.jpl.nasa.gov/
msp98/orbiter.
Il 23 settembre 1999 si perdono le tracce del veicolo spazia-
le Mars Climate Orbiter. Gli obiettivi di questa missione della NASA erano sia di monito-
raggio dei cambiamenti climatici sia di supporto per la missione Mars Polar Lander. I costi
della Climate Orbiter e della Polar Lander erano di un totale di oltre 320 milioni di dollari.
20
3.2. Aritmetica di macchina
µ ¶
1 0 3 3 3 3
= 0.3333333 . . . = + + + + . . . × 100
3 100 101 102 103 104
µ ¶
3 1 4 1 5
π = 3.14159265358979 . . . = + + + + . . . × 100
100 101 102 103 104
Osserviamo che abbiamo scritto 1/3 e π in base 10, usando, quindi, le cifre 0, 1, 2, . . . , 9 per poterli
rappresentare.
In genere, un numero reale x può essere rappresentato in base N come
x = x m N m + x m−1 N m−1 + . . . + x 1 N + x 0 + x −1 N −1 + x −2 N −2 + . . . x −n N −n
| {z }| {z }
parte intera parte frazionaria
Tuttavia, i calcolatori hanno una memoria finita per poter rappresentare i numeri. Ciò significa che solo
una sequenza finita di cifre possono essere usate. Inoltre, i calcolatori lavorano in base binaria, quindi ogni
numero può essere rappresentato mediante una sequenza di 0 e 1.
Avendo in mente questi due fattori, possiamo ora capire la rappresentazione dei numeri al calcolatore,
per cui ad ogni numero reale x è associato il numero di macchina denotato come f l (x), in rappresentazione
floating point – virgola mobile.
21
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
| {z }
parte intera
| {z }
parte frazionaria
Il passaggio di un numero dalla rappresentazione in base 10 a quella in base 2 si effettua, invece, in due
passi.
G Si prende la parte intera del numero e la si divide per 2: se il resto della divisione è zero, allora la cor-
rispondente cifra binaria sarà 0; se il resto è diverso da zero, la corrispondente cifra binaria sarà 1. Si ripete
la procedura sul risultato avuto dalla divisione, fino a quando si arriva a 1. In tal modo, calcoliamo le cifre
binarie a partire da x 0 (il primo resto ottenuto) e andando avanti con indice crescente.
G Si prende la parte frazionaria del numero e la si moltiplica per 2. Se il risultato dell’operazione ha la
parte intera diversa da zero, allora la corrispondente cifra binaria vale 1, altrimenti vale 0. Si ripete la proce-
dura sulla parte frazionaria del risultato appena ottenuto e si continua fino a quando si arriva allo zero (o se
si vede che c’è una periodicità nei risultati). Le cifre binarie vengono costruite da x −1 con indice decrescente.
Esempio 3.3.2 Vogliamo convertire il numero 725.625 dalla base 10 nella base 2.
Per la parte intera si ha:
Per la parte decimale si ha :
: 2 = quoziente resto
.625 × 2 = 1.250 x −1 = 1
725 362 1 x0
.250 × 2 = 0.50 x −2 = 0
362 181 0 x1
.5 × 2 = 1.0 x −3 = 1
181 90 1 x2
.0 × 2 = 0.0
90 45 0 x3
45 22 1 x4
22 11 0 x5
11 5 1 x6
5 2 1 x7
2 1 0 x8
1 0 1 x9
In base 2 il numero diventa 1011010101.101.
22
3.4. Rappresentazione IEEE dei numeri di macchina
Osserviamo che un numero può avere una rappresentazione finita in base 10 e infinita in base 2. Vediamo
in dettaglio un esempio:
11
Esempio 3.3.3 Scriviamo il numero , che è 1.1 in base 10, nella base 2.
10
Per la parte intera:
Per la parte decimale:
: 2 = quoziente resto
.1 × 2 = 0.2 x −1 = 0
1 0 1 x0
.2 × 2 = 0.4 x −2 = 0
.4 × 2 = 0.8 x −3 = 0
.8 × 2 = 1.6 x −3 = 1
.6 × 2 = 1.2 x −4 = 1
.2 × 2 = 0.4 x −5 = 0
.4 × 2 = 0.8 x −6 = 0
.8 × 2 = 1.6 x −7 = 1
.6 × 2 = 1.2 x −8 = 1
.2 × 2 = 0.4 x −9 = 0
Osserviamo che nella parte decimale si ripetono all’infinito le cifre 0011. Il numero in base 2 si scrive quindi
come: 1.0 0011
| {z } 0011
| {z } . . .
23
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
dove
G 1+ f 2 + f 2 +. . .+ f 2 è la mantissa, normalizzata, cui sono riservati
−1
−1
−2
−2
−n
−n
un numero n di bits,
G e è la potenza della base 2 cui sono riservati un numero Ne di bits ed è
limitato a variare in un determinato intervallo [L,U ].
Il primo 1 della mantissa (che corrisponde a f 0 ) non viene messo in memoria ma c’è. La rappresentazione
in virgola mobile può essere schematizzata nel modo seguente (s, e ed f rappresentano i bits riservati rispet-
tivamente per il segno della mantissa, e per le cifre dell’esponente e della mantissa – ogni celletta può avere
il valore 0 o 1):
Abbiamo 1 bit riservato al segno (si ha 0 per il segno + e 1 per il segno −), un numero Ne di bits per
l’esponente 2e , e un numero n di bits per la mantissa.
La scelta del numero di bits da riservare all’esponente e alla mantissa si basa su un compromesso tra la
dimensione dell’esponente (e quindi il più piccolo e il più grande numero rappresentabile) e la dimensione
della mantissa (e quindi la precisione del numero rappresantibile, più o meno cifre decimali).
Nel sistema IEEE, la rappresentazione in singola precisione è a 32 bits mentre quella in doppia precisione
è a 64 bits. La suddivisione dei bits tra esponente e mantissa viene ripartita nel modo seguente:
s Ne n # totale bits
Singola precisione 1 8 23 32
Doppia precisione 1 11 52 64
Gli esponenti possono essere sia positivi sia negativi ma si preferisce memorizzarli come interi positivi
(senza segno). Abbiamo dunque bisogno di una tecnica che permetta di rappresentare esponenti negativi
come interi positivi. La tecnica utilizzata nello standard IEEE è chiamata di biasing (distorsione): un numero
positivo (detto bias) viene aggiunto all’esponente (sia esso positivo o negativo) in modo che il risultato finale
sia sempre positivo. Ed è questo valore che viene memorizzato per rappresentare l’esponente. L’esponente
viene quindi rappresentato in forma biased (parziale, influenzata da un altro numero): se e è l’esponente
2
effettivo, noi memorizziamo il valore b + e dove b è il bias dato b = 0111
| {z. . . 1}, vale a dire b = 1 + 2 + 2 + . . . +
Ne bits
Ne−1
1 − 2
2Ne−2 +0·2Ne−1 = = 2Ne−1 −1 (si veda la nota per capire perchè si ha questo risultato nella somma).
1−2
Per trovare il limite superiore e inferiore entro cui può variare e, dobbiamo tener conto del fatto che, nella
rappresentazione IEEE, due patterns di bits sono riservati per rappresentare numeri speciali quali lo zero,
infinito e il Not-a-Number, precisamente 0000 . . . 0 e 1111 . . . 1.
Quindi, b + e non può essere uguale nè a 0000 . . . 0, nè a 1111 . . . 1. Ciò significa che il massimo esponente
che si può rappresentare è dato sottraendo a 1111 . . . 1 il valore 1 in base 2, cioè da 1111 . . . 1 − 0000 . . . 01 =
1111 . . . 10.
Si ha b + e ≤ 1111 . . . 10, o equivalentemente, 0111 . . . 1 + e ≤ 1111 . . . 10, da cui ricaviamo
.
Il limite superiore U è proprio uguale a b.
24
3.4. Rappresentazione IEEE dei numeri di macchina
1. |000{z. . . 0} ×2L = 2L
n bits
Se si vuole rappresentare un numero al di fuori di questo intervallo si ha overflow o underflow.
In singola e doppia precisione abbiamo, per il più grande e il più piccolo numero positivo rappresentabile,
i seguenti valori:
Esempio 3.4.1 Vogliamo scrivere il numero 5.7510 in formato IEEE in singola precisione.
Effettuiamo prima la conversione in base 2:
Per la parte intera: Per la parte decimale:
5 2 1 x0 .75 × 2 = 1.50 x −1 = 1
2 1 0 x1 .5 × 2 = 1.0 x −2 = 1
1 0 1 x2 .0 × 2 = 0.0
Quindi 5.7510 = 101.112 = 1.0111 × 22 .
Memorizziamo ora il numero in singola precisione:
Per l’esponente, essendo p = 2, si ha:
(b + p)10 = (127 + 2)10 = 12910 = 100000012
Per la mantissa, m = 23 e si deve trascurare l’1 della normalizzazione, quindi memorizzeremo le cifre 0111
e poi avremo tutti 0.
0 1 1 1 0 0 0 ... 0 0 0 0 0 0 0 0 0 0
Il segno è positivo, quindi s = 0
Perciò la memorizzazione, considerati i bits per il segno, l’esponente e la mantissa è:
0 1 0 0 0 0 0 0 1 0 1 1 1 0 ... 0 0 0 0 0
|{z} | {z } | {z }
s esponent e mant i ssa
(n+1)
1 È il risultato di una somma del tipo S = 1 + a + a 2 + . . . + a n e vale S = 1 − a 1
. In questo caso, a = = 2−1 . Osserviamo, inoltre,
1−a 2
che, dati n valori w 1 , w 2 , . . . , w n usiamo la seguente simbologia per indicare la loro somma:
n
X
wi = w1 + w2 + w3 + . . . wn
i =1
.
25
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
I valori ±∞ si hanno se si fa una divisione per zero o si fa un calcolo che comporta overflow.
Si ha invece il Not-a-Number (NaN) come risultato di operazioni non definite, come 0/0 o log 0.
A seconda della macchina si ha:
N 1−t N p nel troncamento
∗
|x − x | ≤ 1 1−t p
N N nell’arrotondamento
2
2 Evitiamo di effettuare tutti i passaggi che portano alle formule dell’errore assoluto e relativo, che sono il risultato di maggiorazioni
di serie geometriche.
26
3.6. Propagazione degli errori
|x − x ∗ |
Per l’errore relativo , invece, si ha:
|x|
1−t
|x − x ∗ | N nel troncamento
≤ 1 1−t
|x| N nell’arrotondamento
2
1
Il valore N 1−t è il numero conosciuto come precisione di macchina.
2
Esempio
Nel caso della rappresentazione IEEE di un numero, si ha t −1 = n, (ricordiamo che nella rappresentazione
IEEE si memorizza il numero normalizzato), da cui l’errore di arrotondamento relativo che si commette è
|x − x ∗ |
≤ 2−(n+1) .
|x|
In singola precisione (n = 23), avremo
|x − x ∗ |
≤ 2−24 ≈ 5.96 × 10−8
|x|
ciò significa che avremo 8 cifre decimali corrette.
In doppia precisione (n = 52) avremo
|x − x ∗ |
≤ 2−53 ≈ 1.11 × 10−16
|x|
ciò significa che avremo 16 cifre decimali corrette.
x(1 + e x ) x x
= (1 + e x )(1 − e y + e 2y + . . .) ≈ (1 + e x − e y )
y(1 + e y ) y y
Si ha e x/y = e x − e y : gli errori si accumulano additivamente
3 Nei calcoli sono trascurabili le potenze maggiori o uguali a due per e
x e ey
4 Possiamo scrivere 1 1
= (1 − e y + e 2y + . . .) come risultato della formula polinomiale di Taylor della funzione f (e y ) = di
1 + ey 1 + ey
centro 0.
27
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
Quando andiamo a fare la sottrazione le prime p cifre buone si annullano. Da p + 2 cifre buone, ne abbiamo
ora solo 2 e tutte le altre sono quelle corrotte. Con la normalizzazione il risultato diventa del tipo (ora q q q q q
sono le cifre corrotte):
00
f l (x − y) = 1.b −1 00
b −2 q q q q q q × 2e
Ricordiamo, infine, che in aritmetica di macchina non valgono più la proprietà distributiva o associativa
del prodotto.
Esempio 3.6.2 Sia da risolvere l’equazione ax 2 +bx+c = 0 con a = 1, b = −56 e c = 1, quindi x 2 −56x+1 = 0,
in una macchina a 4 cifre decimali (normalizzata).
p
−b ± b 2 − 4ac p
Applicando la formula x 1/2 = abbiamo x 1/2 = 28 ± 783 = 28 ± 27.98213716 =
( 2a
0.01786284073
. L’arrotondamento delle due radici in virgola mobile normalizzata a 4 cifre decimali
55.98213716
dà: x 1 = 1.7863 · 10−2 e x 2 = 5.5982 · 101 .
28
3.6. Propagazione degli errori
La radice x 2 è arrotondata correttamente, mentre la variabile x 1 no, per effetto della cancellazione.
Per ricavare x 1 con l’arrotondamento corretto, applichiamo la formula x 1 x 2 = c/a, che, nel nostro caso, vale
x 1 x 2 = 1 da cui x 1 = 1/x 2 = 1/(5.5982 · 101 ) = 1.7863 · 10−2 . Abbiamo fatto un’operazione che non risente del
fenomeno di cancellazione numerica!
Esempio 3.6.3 Vediamo come non valga più la relazione (a − b)2 = a 2 − 2ab + b 2 .
Sia a = 15.6 e b = 15.7 e la macchina sia a 3 cifre decimali (questa volta lavoriamo su una macchina non
normalizzata, per cui scriveremo la parte frazionaria come 0.qual cosa. Ripetere poi l’esempio lavorando
su una macchina a 2 cifre decimali normalizzata e su una macchina a 3 cifre decimali normalizzata. Cosa
si osserva?)
(a − b) = (a − b)∗ + e a−b . Abbiamo (a − b)∗ = 15.6 − 15.7 = −0.1.
Quindi (a − b)2 = +0.01 = 0.1 · 10−1 .
Consideriamo ora a 2 − 2ab + b 2 = 243.36 − 489.84 + 246.49 = 0.24336 · 103 − 0.48984 · 103 + 0.24649 · 103
Considerando la macchina a 3 cifre decimali, abbiamo: 0.243 · 103 − 0.490 · 103 + 0.246 · 103 = −0.1 · 101
I risultati sono completamente diversi!
Esempio 3.6.4 Consideriamo il problema di approssimare la derivata della funzione f (x) = sin x nel punto
x = 1.2.
Supponiamo di non poter valutare direttamente la derivata della f e di volerla approssimare applicando
la formula polinomiale di Taylor:
h 2 00 h 3 000 h4 I V
f (x 0 + h) = f (x 0 ) + h f 0 (x 0 ) + f (x 0 ) + f (x 0 ) + f (x 0 ) + . . .
2 6 24
Allora
f (x 0 + h) − f (x 0 ) h h 2 000 h3 I V
f 0 (x 0 ) = − ( f 00 (x 0 ) + f (x 0 ) + f (x 0 ) + . . .)
h 2 6 24
f (x 0 + h) − f (x 0 )
Approssimiamo, quindi, la f 0 (x 0 ) calcolando .
h
L’errore, detto errore di discretizzazione, che si commette è
f (x 0 + h) − f (x 0 ) h h 2 000 h3 I V
| f 0 (x 0 ) − | = | f 00 (x 0 ) + f (x 0 ) + f (x 0 ) + . . . |
h 2 6 24
Supponendo di conoscere il valore della derivata seconda in x 0 , per piccoli valori di h possiamo dare una
stima dell’errore di discretizzazione,
f (x 0 + h) − f (x 0 ) h
| f 0 (x 0 ) − | ≈ | f 00 (x 0 )|
h 2
Ci aspettiamo, anche senza conoscere il valore di f 00 (x 0 ) (purchè diverso da 0) che l’errore di discretizzazione
diminuisca proporzionalmente con il passo h, al decrescere di h.
Nel nostro caso, in cui f (x) = sin (x), noi conosciamo il valore esatto della derivata in 1.2, cos (1.2) =
0.362357754476674... e possiamo dunque calcolare l’errore esatto che commettiamo approssimando la
derivata di sin x con la formula che abbiamo ricavato.
29
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
Per h = 0.1 non abbiamo un’approssimazione accurata. Ci aspettiamo che diminuendo il passo h l’errore
che commettiamo diminuisca.
Riportiamo gli errori della formula (in valore assoluto) e confrontiamoli con l’errore di discretizzazione
h 00
| f (x 0 )| (i conti sono fatti in singola precisione):
2
h 00
h errore | f (x 0 )|
2
1.e-1 4.7167e-2 4.6602e-2
1.e-2 4.6662e-3 4.6602e-3
1.e-3 4.6608e-4 4.6602e-4
1.e-4 4.6603e-5 4.6602e-5
1.e-5 4.6602e-6 4.6602e-6
1.e-6 4.6597e-7 4.6602e-7
h 00
L’errore commesso dall’algoritmo decresce come h e, in particolare, come | f (1.2)| = 0.46602h.
2
Possiamo pensare di ottenere un’accuratezza grande quanto vogliamo a condizione di prendere valori di h
sempre più piccoli. In realtà, per valori di h molto piccoli, gli errori iniziano ad aumentare!
h 00
h errore | f (x 0 )|
2
1.e-8 4.3611e-10 4.6602e-9
1.e-9 5.5947e-8 4.6602e-10
1.e-10 1.6697e-7 4.6602e-11
1.e-11 4.6603e-5 4.6602e-12
1.e-12 1.3006e-4 4.6602e-13
1.e-13 4.2505e-4 4.6602e-14
1.e-16 3.6236e-1 4.6602e-16
1.e-18 3.6236e-1 4.6602e-19
In Figura 3.4 vediamo come la curva dell’errore inizialmente segue la retta descritta dall’errore di discretiz-
zazione ma poi si allontana da essa. Perchè questo diverso comportamento per valori di h molto piccoli?
Dobbiamo tenere presente che l’errore che noi valutiamo non è semplicemente l’errore di discretizzazione
ma la somma dell’errore di discretizzazione e dell’errore di arrotondamento! Per valori di h grandi, l’errore
di discretizzazione descresce al diminuire di h e domina sull’errore di arrotondamento. Ma quando l’errore
di discretizzazione diventa molto piccolo, per valori di h minori di 10−8 , allora l’errore di arrotondamento
inizia a dominare e ad aumentare sempre più al diminuire di h. Questo è un motivo per cui si deve cercare
di far prevalere l’errore di discretizzazione in un procedimento numerico. Nell’errore di arrotondamento,
per h via via più piccoli, si verifica un errore di cancellazione: f (x 0 + h) è praticamente uguale a f (x 0 ) per
h molto piccoli! per cui l’errore che calcoliamo è | f 0 (x 0 ) − 0| = f 0 (x 0 ) = 0.3623577544....
Una strategia per evitare la cancellazione è di scrivere diversamente la differenza f (x 0 +h)− f (x 0 ). Nel caso
φ+ψ φ−ψ
di f (x) = sin (x) ricorriamo alla formula trigonometrica per cui sin (φ) − sin (ψ) = 2 cos ( ) sin ( ).
2 2
Vediamo come migliorano le cose inserendo nel grafico 3.5 anche la curva dell’errore che otteniamo uti-
lizzando questa espressione trigonometrica. L’errore continua a diminuire anche quando la formula pre-
cedente dà un errore crescente. Sempre in Figura 3.5, e in riferimento alla formula “non buona”, abbia-
mo considerato la curva dell’errore di arrotondamento in modo da confrontare l’andamento effettivo del-
l’errore con un limite superiore teorico dell’errore computazionale totale dato dalla somme degli errori di
discretizzazione e di arrotondamento.
30
3.7. Instabilità e malcondizionamento
La rappresentazione di f (x) è affetta da errore per cui avremo: f (x) = f ∗ (x)+e x . L’errore di arrotondamento
f (x 0 + h) − f (x 0 ) f ∗ (x 0 + h) − f ∗ (x 0 ) e x0 +h − e x0
è = + . Maggiorando e x con la precisione di macchina ²,
h h h
l’errore di arrotondamento è dato da 2²/h: per h piccoli è l’errore che predomina!
3.7.1 Instabilità
In generale è impossibile evitare un accumulo lineare degli errori di arrotondamento durante un calcolo,
ed è accettabile che ci sia una crescita lineare moderata, del tipo
E n ≈ c 0 nE 0
dove E n misura l’errore relativo dell’n-sima operazione dell’algoritmo5 e c 0 sia una costante non molto
grande.
Se invece avviene una crescita di tipo esponenziale
E n ≈ c 1n E 0
con c 1 > 1, allora l’algoritmo è instabile. Algoritmi del genere devono essere evitati!
5 Per algoritmo intendiamo un procedimento di calcolo. Per una definizione più approfondita si veda pag. 163 al Capitolo 11.
31
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
Definizione 3.7.1 Un procedimento numerico si dice instabile se gli errori che vi sono associati non rimangono
limitati ma crescono fino a distruggere completamente la soluzione.
32
3.7. Instabilità e malcondizionamento
Infatti
y 1 = 1 − 10y 0
1 1
y 2 = − 10(1 − 10y 0 ) = − 10 + (−10)2 y 0
2 2
1 1
y 3 = − 10( − 10 + 10 y 0 ) = −103 y 0 + cost ant e
2
3 2
....
..
y n = (−10)n y 0 + cost ant e n
L’algoritmo quindi, considerati gli errori di arrotondamento, presenta un errore E n con crescita di tipo
esponenziale. Difatti otteniamo valori che via via si allontanano dall’intervallo di ammissibilità [0, 1].
I risultati che ricaviamo sono i seguenti (osserviamo che sono leggermente diversi a seconda dal linguaggio
usato, proprio per effetto dell’instabilità).
Da un programma in Fortran: Da un programma Matlab:
n yn n yn
0 9.5310e-2 0 9.5310e-2
1 4.6898e-2 1 4.6898e-2
2 3.1021e-2 2 3.1018e-2
3 2.3122e-2 3 2.3154e-2
4 1.8778e-2 4 1.8465e-2
... .... ... ....
7 -3.0229e-1 7 1.1481-2
8 3.1479e+0 8 1.0194e-2
9 -3.1368e+1 9 9.1673e-3
10 3.1378e+2 10 8.3270e-3
18 3.1377e+10 18 -9.1694e+1
27 -3.1377e+19 27 -9.1699e+9
30 3.1377e+22 30 -9.1699e+13
1 1
Se invece, consideriamo y n−1 = ( − y n ), partendo da un valore di n molto grande e andando a ritroso,
10 n
l’errore diminuisce. Perciò, dato un valore di accuratezza ² > 0 e fissato un intero n 1 è possibile determinare
l’intero n 0 tale che, partendo da y n0 = 0 e andando a ritroso, gli integrali y n saranno valutati con un errore
in valore assoluto minore di ² per 0 < n ≤ n 1 . Infatti:
y n0 = 0
1 1
y n0 −1 =
10 n 0
1 1 1 1 1
y n0 −2 = ( − )= + cost ant e
10 n 0 − 1 10 n 0 (−10)2 n 0
....
..
1
yn = n
+ cost ant e n0 −n
(−10) 0 −n n 0
1
L’errore al passo n dipende, quindi, (in valore assoluto) da .
10n0 −n
33
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
Se richiediamo una tolleranza ² = 10−6 , e fissiamo un valore n 1 , per calcolare n 0 dovrà essere
1
< ² cioè 10n1 −n0 < ²
10n0 −n1
Passando al logaritmo in base 10:
n 1 − n 0 < log ² =⇒ n 0 > n 1 − log ²
Fissato n 1 = 20 si ricava n 0 = 26.
Questa volta i calcoli danno gli stessi risultati sia in Matlab sia in Fortran:
n yn n yn
26 0.000000 11 7.62944e-3
25 3.84615e-3 10 8.32797e-3
24 3.61538e-3 9 9.16720e-3
23 3.80513e-3 8 1.01944e-2
22 3.96731e-3 7 1.14806e-2
21 4.14872e-3 6 1.31377e-2
20 4.34703e-3 5 1.53529e-2
19 4.56530e-3 4 1.84647e-2
18 4.80663e-3 3 2.31535e-2
17 5.07489e-3 2 3.10180e-2
16 5.37486e-3 1 4.68982e-2
15 5.71251e-3 0 9.53102e-2
14 6.09542e-3
13 6.53332e-3
12 7.03898e-3
L’esempio appena visto ci porta a dare alcune considerazioni sui criteri su cui si deve basare un algorit-
mo: un algoritmo deve essere accurato, efficiente e robusto, accurato nel senso che bisogna essere in grado
di sapere la grandezza dell’errore che si commette nell’algoritmo stesso; efficiente in termini di velocità di
esecuzione e di richiesta di spazio di memoria per le variabili utilizzate; robusto nel dare il risultato corretto
entro un livello di tolleranza dell’errore che sia accettabile.
3.7.2 Malcondizionamento
Definizione 3.7.2 Un problema si dice malcondizionato se a piccole variazioni nei dati di input del problema
corrispondono forti variazioni nei dati di output.
Quando il problema è molto sensibile alle variazioni dei dati di input, producendo risultati molto diversi tra
loro, allora nessun algoritmo, per quanto robusto e stabile, potrà dare una soluzione robusta al problema
stesso.
Esempio 3.7.2 Il problema del calcolo delle radici di un polinomio p(x) di grado n è un esempio di
problema malcondizionato.
Sia p(x) = a 0 + a 1 x + a 2 x 2 + . . . + a n x n . I dati di input del problema sono i coefficienti a 0 , a 1 , . . . , a n . I dati di
output sono le radici del polinomio.
Si può provare che a piccole variazioni sui dati iniziali, corrispondono grandi variazioni sui risultati.
34
3.7. Instabilità e malcondizionamento
Vediamo il caso del polinomio p(x) = (x − 1)(x − 2) · · · (x − 10). Chiaramente, tale polinomio ha radici
1, 2, . . . , 10. Se perturbiamo il polinomio variando il coefficiente a 9 del valore di 0.00001, considerando quin-
di il polinomio p(x) + 0.00001x 9 , le radici corrispondenti si discostano di poco da quelle del polinomio di
partenza, come si può notare in Figura 3.6. Ma se variamo il coefficiente a 9 del valore 0.0001, considerando
cioè il polinomio p(x) + 0.0001x 9 allora le radici corrispondenti a x 7 , x 8 , x 9 , x 10 non saranno più reali ma
avranno anche una parte immaginaria. La piccola variazione sui dati di ingresso, quindi, provoca una
grande variazione sui dati in uscita, proprio perchè il problema è malcondizionato.
Una quantità che misura il grado di sensibilità di un problema – fornendoci indicazioni sul fatto che a
piccole variazioni sui dati di ingresso del problema ci possono essere piccole o grandi variazioni sui dati di
uscita – si chiama indice di condizionamento (o numero di condizionamento) del problema. indice di
Diamo la definizione nel caso in cui il nostro problema si possa identificare come una funzione f : R −→ condiziona-
mento
R. Il valore y = f (x) è il valore di uscita del problema f . Vogliamo vedere cosa succede se il dato di ingresso
non è più x ma x + ∆x. ∆x rappresenta quindi una perturbazione sul dato iniziale. Assumiamo x 6= 0, y 6= 0.
Applichiamo la formula di Taylor di centro x. Si ha:
La variazione sul dato d’uscita è data dalla differenza f (x + ∆x) − f (x). Chiamiamo questa differenza con
∆y. Quindi ∆y = f (x + ∆x) − f (x) ≈ f 0 (x)∆x (utilizziamo il risultato ottenuto dalla formula di Taylor).
35
3. R APPRESENTAZIONE DEI NUMERI NEL CALCOLATORE
∆y f 0 (x)∆x
≈
y f (x)
Moltiplico poi numeratore e denominatore a secondo membro per x
∆y x f 0 (x) ∆x
≈
y f (x) x
Al limite per ∆x → 0, questa uguaglianza approssimata (abbiamo usato il simbolo ≈) diventa una vera
uguaglianza. Questo suggerisce di definire l’indice di condizionamento di f mediante la formula
¯ 0 ¯
¯ x f (x) ¯
(cond f )(x) = ¯¯ ¯
f (x) ¯
Questo numero ci dice quanto grandi sono le perturbazioni relative per y confrontate con le relative
perturbazioni di x.
∆x
Per x = 0 e y 6= 0, non ha senso considerare l’errore relativo , e si considera l’errore assoluto su x. In tal
x
caso, si definisce indice di condizionamento la quantità
¯ 0 ¯
¯ f (x) ¯
(cond f )(x) = ¯¯ ¯
f (x) ¯
Per x = y = 0 si considera invece l’errore assoluto sia per x che per y, dimodochè l’indice di
condizionamento diventa
Esempio 3.7.3 Sia f (x) = x 1/α , con x > 0 e α > 0. Calcoliamo l’indice di condizionamento applicando la
formula (poichè abbiamo supposto x > 0, si ha f (x) 6= 0). Risulta
¯ 0 ¯ ¯¯ x 1 x 1/α−1 ¯¯
¯ ¯
¯ x f (x) ¯ ¯ α ¯ 1
(cond f )(x) = ¯¯ ¯=¯ ¯=
f (x) 1/α ¯ α
¯ x
¯ ¯
¯
Per α grande, (cond f )(x) tende a zero, quindi abbiamo un problema bencondizionato. Se, invece α è molto
10
piccolo si ha un problema malcondizionato (se α = 10−10 , si ha f (x) = x 10 e (cond f )(x) = 1010 , un valore
molto grande).
36
CAPITOLO
4
Z ERI DI FUNZIONE
Isaac Newton
4.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
4.2 Metodo delle Bisezioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
4.3 Metodo del Punto Fisso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.4 Il Metodo di Newton-Raphson . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.5 Convergenza di un metodo iterativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.6 Complessità computazionale di uno schema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.7 Il metodo delle secanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
4.8 Confronto tra i metodi di Newton-Raphson e la Regula Falsi . . . . . . . . . . . . . . . . . . . . . . 50
4.9 Metodo di Newton-Raphson per radici multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.10 Controllo sugli scarti e grafici di convergenza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
4.11 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1 Introduzione
Il problema di calcolare la radice quadrata di un numero è un problema molto antico. Già p gli antichi
Babilonesi, intorno al 1700 a.C., se lo erano posto e avevano trovato la soluzione: per calcolare b, partivano
da un certo valore x che si avvicinava alla soluzione, dividevano b per questo numero, e facevano poi la
media, iterando il procedimento.p L’algoritmo si può schematizzare nel modo seguente:
G partire da x 0 prossimo a b;
G 1 b
considerare x 1 = (x 0 + );
2 x0
G 1
generalizzando: x n+1 = (x n +
2
b
xn
).
37
4. Z ERI DI FUNZIONE
p
Per esempio, per calcolare 2 ≈ 1.41421356237310, sapendo che il valore che dobbiamo approssimare è
compreso tra 1 e 2, possiamo partire da x 0 = 1.5, ottenendo:
x 0 = 1.5
2
x 1 = 12 (1.5 + ) = 1.41666667
1.5
2
x 2 = 12 (1.41666667 + ) = 1.41421569
1.41666667
2
x 3 = 12 (1.41421569 + ) = 1.41421356
1.41421569
Il metodo usato dai Babilonesi non è altro che il metodo di Newton-Raphson (che vedremo più avanti)
per trovare gli zeri della funzione f (x) = x 2 − b.
I metodi numerici discussi in questo Capitolo servono per trovare approssimazioni numeriche ad
equazioni del tipo f (x) = 0.
b−a
|ξ − c n | ≤ .
2n
Da questa relazione, si può determinare il numero di iterazioni n necessarie per calcolare un’approssimazio-
ne della radice ξ entro una certa tolleranza t ol l richiesta. Infatti
b−a
≤ t ol =⇒ |ξ − c n | ≤ t ol
2n
Ma
b−a
µ ¶
log
b−a b−a t ol
≤ t ol ⇐⇒ 2n ≥ =⇒ n ≥ .
2n t ol log(2)
L’algoritmo di bisezione può essere descritto nel modo seguente (sotto forma di pseudo-codice). Se il
metodo non converge (perchè, ad esempio, la funzione che abbiamo scelto non assume segno opposto agli
38
4.3. Metodo del Punto Fisso
39
4. Z ERI DI FUNZIONE
³ x ´2 ³ x ´2
Ad esempio, da f (x) = −sin (x) = 0, aggiungendo ad ambo i membri x, otteniamo −sin (x)+x = x
³ x ´22 2
da cui poniamo g (x) = − sin (x) + x. Le radici della f coincidono con i punti fissi della g .
2
Definizione 4.3.1 Data una funzione g , si definisce punto fisso della g , quel punto
ξ che soddisfa la relazione g (ξ) = ξ
Una funzione può ammettere uno o più punti fissi o non ammetterne affatto.
Un modo per calcolare un punto fisso di una funzione g è dato da iterazioni successive sulla funzione g
stessa.
Esempio 4.3.1 Supponiamo che la funzione g sia g (x) = cos (x). Prendiamo come valore iniziale x 0 = 1.
Con una calcolatrice, andiamo a calcolare (in modalità radianti!) il suo coseno: ricaviamo x 1 = cos (x 0 ) =
g (x 0 ) = 0.54030230. Successivamente, calcoliamo il coseno di x 1 , ottenendo x 2 = cos (x 1 ) = 0.857553216.
Osserviamo che x 2 = cos (x 1 ) = cos (cos (x 0 )) e non cos2 (x 0 )! Abbiamo innescato, in questo modo, un proce-
dimento iterativo per cui x n+1 = cos (x n ) = g (x n ). Con la calcolatrice, basta digitare sulla funzione cos ogni
volta in modo da avere i nuovi valori della successione x n+1 . I primi numeri che otteniamo non sono molto
importanti. Quelli importanti sono quelli che si hanno dopo 15, 30 o 100 passi. Nel nostro caso, abbiamo
n xn
5 0.7013687746
11 0.7356047404
13 0.7414250866
14 0.7375068905
15 0.7401473356
29 0.7390893414
30 0.7390822985
56 0.7390851333
57 0.7390851332
58 0.7390851332
Perchè i valori di x tendono a 0.7390851332? Cosa ha di speciale questo numero? È un punto fisso per la
funzione cos (x).
1
Esempio 4.3.2 Consideriamo la funzione g (x) = x + 2. Partendo da x 0 = 0 si ha
2
n xn
1 x 1 = 12 · 0 + 2 = 2
2 x 2 = 21 · 2 + 2 = 3
3 x 3 = 21 · 3 + 2 = 3.5
4 x 4 = 21 · 3.5 + 2 = 3.75
5 x 5 = 21 · 3.75 + 2 = 3.875
6 x 6 = 12 · 3.875 + 2 = 3.9375
I numeri 2, 3, 3.5, 3.75, 3.875, 3.9375 sembrano avvicinarsi a ξ = 4. Difatti, per valori crescenti di n, per x n
1 1 1
che tende a ξ, si ha, da una parte ξ = limn→∞ x n+1 = limn→∞ x n + 2 = ξ + 2 da cui, ξ = ξ + 2, cioè ξ = 4.
2 2 2
40
4.3. Metodo del Punto Fisso
Scopriamo quindi che se l’iterazione x n+1 = g (x n ) converge a ξ, ξ è punto fisso per la funzione g .
Da un punto di vista geometrico, i grafici di y = x (bisettrice del primo e terzo quadrante) e di y = g (x) si
intersecano in ξ.
Tuttavia, non sempre questo schema iterativo, applicato a funzioni che ammettono uno o più punti fissi,
converge. Vediamo con un esempio.
Esempio 4.3.3 Sia g (x) = x 2 . Analiticamente troviamo due punti fissi per questa funzione. Dovendo essere
ξ = ξ2 , si ricava ξ2 − ξ = 0, vale a dire ξ(ξ − 1) = 0: quindi ξ = 0 e ξ = 1 sono i due punti fissi per questa
funzione.
Partendo da x 0 = 0.5, si ha la successione di valori 0.25, 0.0625, 0.00390625, rapidamente il metodo converge
aξ=0
Se si prende come punto iniziale un valore x 0 ∈] − 1, 1[, la successione converge a ξ = 0. Le sole successioni
che convergono a ξ = 1 solo le ovvie successioni generate da x 0 = ±1. Se si prende come punto iniziale x 0 tale
che |x 0 | > 1 allora lo schema iterativo x n+1 = x n2 diverge a +∞. Partendo da x 0 = 2, si ha 4, 16, 256, 65536...
Questo esempio è significativo per capire come ciascun punto fisso ξ abbia un proprio bacino di attra-
zione: se si prende x 0 in questo bacino, allora i valori x n tendono a ξ. Un punto fisso può dunque attirare o
respingere i valori x n prodotti dallo schema iterativo.
Prima di passare a studiare quando lo schema di punto fisso converge, ricordiamo che una funzione può
ammettere più di un punto fisso, ammetterne uno solo o non ammetterne affatto. Ci sono due teoremi (2.5.4
e 2.5.5) che ci dicono quando una funzione può ammettere punti fissi. Il primo assicura l’esistenza di almeno
un punto fisso (ciò vuol dire che vi possono essere più punti fissi) quando la funzione g , definita e continua
in [a, b], è tale che a ≤ g (x) ≤ b per ogni x ∈ [a, b]. Il secondo teorema aggiunge, a queste ipotesi, quelle che g
sia di classe C 1 e, inoltre, |g 0 (x)| ≤ m < 1 per ogni x ∈ [a, b]: in tal caso esiste un unico punto fisso.
È importante osservare che, data una funzione che ammette punto fisso, le ipotesi dei due teoremi 2.5.4
e 2.5.5 possono essere rilassate dall’intervallo [a, b] ad un intorno del punto fisso.
Possiamo ora provare un teorema di convergenza per lo schema iterativo del punto fisso.
Teorema 4.3.1 A partire da un punto iniziale x 0 , lo schema iterativo x n+1 = g (x n ) converge al punto fisso ξ di
g se e solo se |g 0 (x)| < 1 in un intorno di ξ.
ξ = g (ξ)
x n+1 = g (x n )
sottraendo membro a membro e, applicando il teorema del Valore Medio 2.5.2 (con ξn un opportuno punto
del segmento che congiunge ξ a x n ), otteniamo:
ξ − x 1 = g 0 (ξ0 )(ξ − x 0 )
ξ − x 2 = g 0 (ξ1 )(ξ − x 1 )
ξ − x 3 = g 0 (ξ2 )(ξ − x 2 )
.. ..
.=.
ξ − x n = g 0 (ξn−1 )(ξ − x n−1 )
41
4. Z ERI DI FUNZIONE
1
Figura 4.2: Il metodo di punto fisso: esempi con g (x) = cos (x) (a sinistra), e g (x) = x + 2 (a destra)
2
|ξ − x 1 | · |ξ − x 2 | · . . . · |ξ − x n | =
|g 0 (ξ0 )| · |g 0 (ξ1 )| · |g 0 (ξ2 )| · . . . · |g 0 (ξn−1 )| · |ξ − x 0 | · |ξ − x 1 | · . . . · |ξ − x n−1 |
La relazione appena trovata può essere semplificata, dividendo ambo i membri per |ξ − x 1 | · |ξ − x 2 | · . . . ·
|ξ − x n−1 | ottenendo:
Assumiamo, ora che |g 0 (x i )| ≤ m per i = 0, 1, . . . , n − 1. Abbiamo dunque una relazione che lega l’errore
assoluto al passo n con l’errore assoluto iniziale.
|ξ − x n | ≤ m n |ξ − x 0 |
Perchè il metodo converga, l’errore deve tendere a zero per n che tende all’infinito. Se m < 1 è assicurata la
convergenza (quindi, se in un intorno del punto fisso, la derivata prima è minore di 1, lo schema converge).
Se invece m > 1 in un intorno del punto fisso, lo schema non può convergere al punto fisso.
Se vale m = 1 nulla si può dire a priori, ma bisogna vedere caso per caso cosa succede nell’intorno del
punto fisso. 4
Negli esempi precedenti:
g (x) g 0 (x)
cos (x) − sin (x)
1 1
x +2
2 2
2
x 2x
Nel primo caso (esempio 4.3.1) − sin (0.7390851332) = −0.673612, perciò in un intorno del punto fisso la
derivata è minore di 1 in valore assoluto e si ha convergenza.
1
Nell’esempio 4.3.2 g 0 (x) = qualunque sia x: si ha convergenza.
2
Nel terzo caso (esempio 4.3.3), g 0 (x) = 2x da cui g 0 (0) = 0 e g 0 (1) = 2. In un intorno del primo punto fisso,
vale m < 1, in un intorno del secondo punto fisso m > 1 e non si potrà mai avere convergenza ad esso.
Il bacino di attrazione si ha quindi se vale m < 1.
Da un punto di vista grafico, le iterazioni dello schema di punto fisso si possono vedere sotto forma di
ragnatela. Le iterazioni, infatti, si muovono avanti e indietro tra il grafico della y = g (x) e il grafico della
bisettrice y = x. L’esempio 4.3.1, con g (x) = cos (x), è rappresentato in Figura 4.2 (a sinistra): partendo da
(x 0 , x 0 ) sulla retta y = x, applicando l’algoritmo si ha x 1 = g (x 0 ). Perciò:
42
4.3. Metodo del Punto Fisso
Figura 4.3: Il metodo di punto fisso: esempio con g (x) = x 2 . Si noti la convergenza monotona a ξ = 0 (a
sinistra) e la divergenza monotona da ξ = 1 (a destra)
Esempio 4.3.4 Consideriamo ora g (x) = x −sin (x) nell’intervallo [0, 2π]. Data la periodicità della funzione
seno, g ammette più di un punto fisso. Infatti da ξ = ξ − sin (ξ) si ha 0 = sin (ξ) da cui ξ = 0, ξ = π e ξ = 2π.
Studiamo ora la derivata prima g 0 (x) = 1 − cos (x). Si ha g 0 (0) = 1 − 1 = 0, g 0 (π) = 1 − (−1) = 2 e g 0 (2π) =
1−1 = 0. Da queste informazioni, deduciamo che qualunque sia il punto iniziale x 0 la successione generata
dallo schema del punto fisso non potrà mai convergere a π, come si vede anche dalla Figura 4.4.
Nel caso in cui il metodo di punto fisso converge, si possono ricavare maggiorazioni per l’errore che si
commette approssimando ξ mediante x n . Vale infatti la disuguaglianza
m
|ξ − x n | ≤ |x n − x n−1 |
1−m
43
4. Z ERI DI FUNZIONE
Figura 4.4: Il metodo di punto fisso: esempio con g (x) = x − sin (x). ξ = 0 e ξ = 2π sono punti fissi attrattivi, al
contrario di ξ = π in cui g 0 (ξ) = g 0 (π) = 2
Abbiamo una maggiorazione dell’errore che lega l’errore al passo n con il valore assoluto della differenza
tra due iterazioni successive |x n − x n−1 | (quest’ultima quantità prende il nome di scarto).
Generalmente, per vedere se il metodo di punto fisso converge al punto fisso entro una certa tolleranza
prestabilita, il controllo da fare è proprio sullo scarto d n = |x n − x n−1 |. Sfruttiamo questo fatto per vedere
come implementare l’algoritmo dello schema di punto fisso (sotto forma di pseudo-codice; per i dettagli
sull’implementazione in Fortran si vada a pag. 172):
44
4.4. Il Metodo di Newton-Raphson
0 = f (ξ) = f (x n ) + f 0 (x n )(ξ − x n )
f (x n )
ξ = xn −
f 0 (x n )
45
4. Z ERI DI FUNZIONE
f (x n )
x n+1 = x n − , n = 0, 1, 2, . . . (4.2)
f 0 (x n )
L’interpretazione geometrica del metodo di Newton è che x n+1 è l’intercetta, sull’asse delle x, della
tangente della f a x n (vedi figura 4.5).
Figura 4.5: Il metodo di Newton-Raphson applicato alla funzione f (x) = (x/2)2 − sin (x) con x 0 = 1.3
Lo schema di Newton-Raphson si può vedere come un caso particolare dello schema del punto fisso ap-
plicato alla funzione g (x) = x − f (x)/ f 0 (x). Perchè lo schema del punto fisso converga, deve essere |g 0 (x)| < 1
in un intorno di ξ. Nel caso specifico abbiamo:
f 0 (x)2 − f (x) f 00 (x) f (x) f 00 (x)
|g 0 (x)| = |1 − 2
|=| |
0
f (x) f 0 (x)2
Supponendo f 0 (ξ) 6= 0 (che è il caso in cui la radice non è multipla), si ha |g 0 (ξ)| = 0, poichè al numeratore
f (ξ) = 0 (essendo ξ radice della f ). Per continuità, allora, vale |g 0 (x)| < 1 in un intorno di ξ. Pertanto il metodo
di Newton-Raphson è generalmente convergente.
Per vedere come si riduce l’errore via via che le approssimazioni si avvicinano a ξ, consideriamo l’errore
cambiato di segno ²n , per cui x n = ξ + ²n . Sostituendo in (4.2) abbiamo
f (ξ + ²n )
²n+1 + ξ = ²n + ξ −
f 0 (ξ + ²n )
f (ξ + ²n )
²n+1 = ²n − 0
f (ξ + ²n )
46
4.5. Convergenza di un metodo iterativo
non sarà più quadratica ma avremo una convergenza di tipo lineare, come vedremo meglio in seguito.
Se in ξ vi è un punto di flesso, non orizzontale, per cui f (ξ) = 0, f 0 (ξ) 6= 0, f 00 (ξ) = 0, allora A = 0 e ci
aspettiamo una convergenza superiore a quella quadratica.
G a convergenza quadratica se esiste una costante M tale che, per n sufficientemente grande, vale
|x n+1 − ξ| ≤ M |x n − ξ|2
47
4. Z ERI DI FUNZIONE
Esempio 4.5.1 Consideriamo l’equazione f (x) = 2x − cos (x) + 1 = 0 che ammette come unica radice ξ = 0.
Poichè f 0 (x) = 2 + sin (x), il metodo di Newton-Raphson diventa:
2x n − cos (x n ) + 1
x n+1 = x n −
2 + sin (x n )
Partendo da x 0 = 0.5 e richiedendo una tolleranza pari a 10−10 nei risultati (interrompiamo l’algoritmo
quando d n < 10−10 ), si ha:
n xn dn
0 0.5
1 0.4730746270E-01 0.4526925E+00
2 0.5462695134E-03 0.4676119E-01
3 0.7458221874E-07 0.5461949E-03
4 0.1395426403E-14 0.7458222E-07
5 0.7647622253E-17 0.1387779E-14
Ma in condizioni di convergenza, d n+1 < d n da cui, per l’errore, vale la maggiorazione ²n < d n .
Perciò gli scarti sono molto vicini agli errori e possono essere utilizzati sia per controllare il numero di
iterazioni da effettuare per approssimare la radice entro una certa tolleranza sia per approssimare M .
Nel nostro esempio
d2 d3 d4 d5
2
= 0.2282 2
= 0.2498 2
= 0.2500 = 0.2495
(d 1 ) (d 2 ) (d 3 ) (d 4 )2
48
4.7. Il metodo delle secanti
f (x n )(x n − x n−1 )
x n+1 = x n −
f (x n ) − f (x n−1 )
Notiamo che, per innescare il metodo occorrono due valori iniziali, x 0 e x 1 . Ma è richiesta solo la
valutazione della funzione f a ciascun passo (nessuna conoscenza della derivata prima).
Da un punto di vista geometrico, nel metodo delle secanti il valore x n+1 è dato dall’intercetta sull’asse
delle x della retta passante per x n , f (x n ) e x n−1 , f (x n−1 ). Per quanto riguarda l’accumulo degli errori di arro-
tondamento, conviene utilizzare la formula così come è stata scritta in quanto è più sicura rispetto alla forma
compatta in cui vengono raccolti i termini, data da
x n−1 f (x n ) − x n f (x n−1 )
x n+1 =
f (x n ) − f (x n−1 )
in quanto in quest’ultima, si può avere il fenomeno della cancellazione numerica per x n ≈ x n−1 e
f (x n ) f (x n−1 ) > 0.
Per quanto riguarda l’ordine di convergenza si può dimostrare che si ha convergenza superlineare poichè
vale la relazione
p
p p
²n+1 = M + 1 ²n
p
1+ 5
dove p = = 1.618 e A è la costante asitontica del metodo di Newton-Raphson, da cui
2
²n+1 = M 0.618 ²1.618
n
2 Attenzione! In letteratura viene descritto un altro metodo (simile ma non lo stesso) con il nome della Regula Falsi o Falsa Posizione
che genera i valori x n+1 in modo che la radice ξ sia sempre compresa tra le iterazioni successive.
49
4. Z ERI DI FUNZIONE
Figura 4.6: Il metodo della Regula Falsi applicato alla funzione f (x) = (x/2)2 − sin (x) con x 0 = 1.3 e x 1 = 1.35
Metodo p s E
p
Newton-Raphson 2 2 2 ≈ 1.414
Regula Falsi 1.618 1 1.618
Esempio 4.8.1 Consideriamo la funzione f (x) = 0 con f (x) = (x/2)2 − sin (x). La derivata prima è f 0 (x) =
(x/2) − cos (x) Consideriamo come x 0 = 1.3 per entrambi i metodi e x 1 = 1.35 per la Regula Falsi. Come
criterio di arresto, consideriamo una tolleranza t ol = 1.e − 8, cioè andremo avanti con le iterazioni fino a
quando troveremo che lo scarto d n = |x n − x n−1 | sarà minore di t ol . Otteniamo i seguenti risultati per il
metodo di Newton-Raphson
n xn f (x n ) f 0 (x n ) dn 2
d n /d n−1
0 1.3 -0.541058185 0.382501171
1 2.714526871831 1.42796213 2.26744846 1.41452687
2 2.084760792766 0.215754599 1.53401376 0.629766079 0.314743565
3 1.944113685369 0.0137718957 1.33676314 0.140647107 0.35462739
4 1.933811265085 7.60156095E-05 1.32199993 0.0103024203 0.520808008
5 1.933753764621 2.37200355E-09 1.32191743 5.7500464E-05 0.541742396
6 1.933753762827 -1.00668172E-16 1.79436599E-09 0.542710632
50
4.8. Confronto tra i metodi di Newton-Raphson e la Regula Falsi
Attraverso gli scarti, abbiamo fatto una stima della costante asintotica dell’errore, considerando che, al
2 1.618
limite per k → ∞, x n → ξ. Le ultime colonne delle tabelle, infatti, valutano i rapporti d n /d n−1 e d n /d n−1 .
Diamo un’ulteriore stima di tali costanti facendo uso della definizione teorica e considerando ξ ≈ x n .
| f 00 (ξ)|
Per il metodo di Newton-Raphson dobbiamo calcolare M = mentre per la Regula Falsi dobbiamo
2| f 0 (ξ)|
0.618
considerare il valore M .
Poichè f 00 (x) = 1/2+sin (x), abbiamo, per ξ ≈ x 6 (di Newton-Raphson) o, equivalentemente per ξ ≈ x 9 (della
Regula Falsi), in pratica ξ ≈ 1.933753762827, f 0 (ξ) = 1.32191743 e f 00 (ξ) = 1.4348509. Otteniamo quindi:
M ≈ 0.542715784 e M 0.618 ≈ 0.685434221
Esempio 4.8.2 Sia data f (x) = sin (x). Nell’intervallo ] − π/2, π/2[ la f ha esattamente una radice, ξ = 0.
Il metodo di Newton applicato alla funzione f , diventa:
x n+1 = x n − tan (x n ), n = 0, 1, 2, . . .
Se scegliamo come valore iniziale x 0 = x ∗ tale che tan (x ∗ ) = 2x ∗ , allora x 1 = −x 0 , x 2 = −x 1 = x 0 ... Si ha una
situazione di stallo: i valori della successione saranno, alternativamente, x ∗ e −x ∗ e non avremo convergen-
za alla radice ξ = 0. Il valore critico x ∗ vale 1.165561185207 e lo si può trovare numericamente applicando
il metodo del punto fisso a alla funzione g (x) = arctan (2x).
Vediamo dunque cosa accade applicando il metodo di Newton-Raphson e la Regula Falsi utilizzando come
x 0 = x ∗ ( e x 1 = −x 0 nella Regula Falsi). Facciamo i conti in singola precisioneb , richiedendo un’accuratezza
dell’ordine ² = 10−8 .
a Se si considera g (x) = tan (x)/2 si trova il punto fisso 0 in quanto g 0 (x ∗ ) > 1 per g (x) = tan (x)/2.
b Lavorando in doppia precisione non si riesce a osservare il comportamento ciclico ma si ha convergenza o divergenza a
seconda che si abbia un’iterata |x k | < o > x ∗ .
51
4. Z ERI DI FUNZIONE
n xn f (x n ) f 0 (x n ) dn
0 1.1655612 0.919009745 0.394234866
1 -1.1655612 -0.919009745 0.394234866 2.3311224
2 1.1655612 0.919009745 0.394234866 2.3311224
3 -1.1655612 -0.919009745 0.394234866 2.3311224
.. .. .. .. ..
. . . . .
n 1.1655612 0.919009745 0.394234866 2.3311224
n+1 -1.1655612 -0.919009745 0.394234866 2.3311224
Poche iterazioni sono necessarie perchè la Regula Falsi converga alla soluzione esatta.
Perchè il metodo di Newton-Raphson converga il valore iniziale x 0 deve essere scelto tale che |x 0 | < x ∗ .
Questo esempio ci permette di capire il significato di metodo generalmente convergente e il fatto che le pro-
prietà di convergenza di un metodo possono valere localmente, cioè quando si è sufficientemente vicini alla
radice.
Quando Da un punto di vista pratico occorre prestare molta attenzione anche alla scelta del punto iniziale per il
Newton- metodo di Newton-Raphson. Dal momento che la formula richiede una divisione per f 0 (x n ), occorre evitare
Raphson dà
risultati di prendere un punto iniziale in cui la f abbia una tangente (e quindi f 0 ) con pendenza vicina allo zero. In tal
scarsi caso, infatti, ci si può allontanare dalla radice e il metodo può non convergere.
Figura 4.7: Il metodo di Newton-Raphson applicato alla funzione f (x) = sin (x) con x 0 = x ∗ (a sinistra). La
funzione f (x) = x 5 − 6 (a destra)
52
4.9. Metodo di Newton-Raphson per radici multiple
Esempio 4.8.3 Consideriamo f (x) = x 5 − 6, per la quale f 0 (x) = 5x 4 , il cui grafico è in Figura 4.7 (a destra).
Se partiamo da un punto iniziale prossimo allo zero, poichè la tangente alla f è quasi orizzontale, non si
riesce ad avere convergenza se non dopo molte iterazioni: partendo da x 0 = 0.01 e richiedendo una tolleran-
za 10−8 , sono necessarie 88 iterazioni per arrivare a ξ = 1.430969081115725849. Vediamo in tabella, come
cambia il numero delle iterazioni al variare di x 0 :
x0 0.05 0.1 0.5 0.8 1.0 1.4 1.5 2. 3. 10. 20. 100.
iterazioni 59 46 18 10 7 4 4 6 8 14 17 24
Quando si ha una radice multipla, il metodo di Newton-Raphson diventa un metodo del primo ordine in
quanto la formula che lega l’errore al passo n + 1 con l’errore al passo n diventa3 :
r −1
²n+1 = ²n
r
r −1
da cui la costante asintotica è M = . Per poter avere un metodo che sia di nuovo a convergenza
r
quadratica, occorre modificare l’algoritmo, ottenendo la formula di Newton-Raphson modificata, nel modo
seguente:
f (x n )
x n+1 = x n − r
f 0 (x n )
²n+1 ≈ M ²n
Quindi
3 Il procedimento da seguire è del tutto simile a quanto è stato fatto nell’ipotesi in cui f 0 (ξ) 6= 0. Come esercizio, si consiglia di provare
a ricavare questo risultato.
53
4. Z ERI DI FUNZIONE
M M
²n+1 ≤ d n+1 ≤ t ol l
1−M 1−M
M
Perciò, per < 1 (quindi per M < 1/2), se d n+1 ≤ t ol l anche ²n+1 ≤ t ol l . Se, invece, M ≥ 1/2, allora
1−M
l’errore può essere più grande della tolleranza richiesta.
Per quanto riguarda il metodo della secante variabile, poichè è superlineare, in base alla definizione,
²n+1 ≈ M n+1 ²n con M n+1 → 0, perciò si può vedere come un caso limite di convergenza lineare con fattore di
convergenza che tende a zero, e quindi il controllo dello scarto permette un buon controllo dell’errore.
Quando si implementa un metodo iterativo, si può fare il grafico semilogaritmico di convergenza del
metodo, ponendo sull’asse delle ascisse i valori delle iterazioni e sull’asse delle ordinate i logaritmi (in base
10) degli scarti.
Asintoticamente possiamo sostituire l’errore con lo scarto, nella definizione di ordine di convergenza di
p
un metodo, per cui d n ≈ Md n−1 .
Nel caso in cui p = 1, si ha:
d n ≈ Md n−1
d n−1 ≈ Md n−2
d n−2 ≈ Md n−3
....
..
d 2 ≈ Md 1
d 1 ≈ Md 0
Abbiamo un’equazione del tipo y = ax + b dove y = log10 (d n ) e x = n, che rappresenta l’equazione della retta
nel nostro grafico semilogaritmico, e la pendenza della retta vale a = log10 (M ). Dalla pendenza della retta
possiamo dunque risalire al valore della costante asintotica M .
Nel caso in cui p 6= 1 il discorso si fa più complicato (e non staremo qui ad analizzarlo nei dettagli). Per
esempio, per p = 2, si trova una curva che dipende da 2n .
Esempio 4.10.1 In Figura 4.8, riportiamo un esempio di grafico con i profili di convergenza per i meto-
di di Newton-Raphson, secante variabile e punto fisso per trovare lo zero della funzione f (x) = x + ln (x)
(applicando lo schema di punto fisso alla funzione g (x) = e −x ).
54
4.11. Esercizi
4.11 Esercizi
Esercizio 4.11.1 Si vuole risolvere l’equazione x = g (x) con lo schema del punto fisso; sapendo che
g (x) = x 2 − 5x + 9
(a) calcolare analiticamente il valore del punto fisso;
(b) determinare il fattore di convergenza M dello schema del punto fisso;
(c) calcolare le approssimazioni x 1 , x 2 e x 3 partendo prima da x 0 = 1 e poi da x 0 = 2.5 e giustificandone
il diverso comportamento.
Svolgimento
(a) ξ è punto fisso della funzione g se verifica g (ξ) = ξ.
Imponiamo dunque la condizione g (ξ) = ξ. Ricaviamo ξ2 − 5ξ + 9 = ξ, ovvero ξ2 − 6ξ + 9 = 0, cioè
(ξ − 3)2 = 0, da cui ξ = 3 è punto fisso della g .
(b) Il fattore di convergenza è M = g 0 (ξ).
Poichè g 0 (x) = 2x − 5, si ha g 0 (ξ) = g 0 (3) = 1.
Osserviamo che, a priori, non si può dire se lo schema del punto fisso converge o meno proprio
perchè nel punto fisso la derivata prima vale esattamente 1, ma bisogna vedere caso per caso a seconda
del punto iniziale da cui si fa partire il metodo.
Per x 0 = 1 si ha Per x 0 = 2.5 si ha
k x k g (x k ) k xk g (x k )
0 1 5 0 2.5 2.75
(c)
1 5 9 1 2.75 2.8125
2 9 45 2 2.8125 2.84765625
3 45 1809 3 2.84765625 2.870864868
55
4. Z ERI DI FUNZIONE
Per x 0 = 1 il metodo non converge, mentre per x 0 = 2.5 il metodo converge. La diversità di com-
portamento si giustifica graficamente, come si può vedere dalla Figura 4.9, osservando che per x 0 = 1 i
valori ottenuti dallo schema si allontanano sempre più dal punto fisso. Nel secondo caso, al contrario,
i valori si avvicinano con monotonia al punto fisso.
Esercizio 4.11.2 Si vuole risolvere l’equazione f (x) = 0 con f (x) = (x − 1)2 + 3 ln (x), nell’intervallo [0.5, 2]
con gli schemi di Newton-Raphson e della Regula Falsi.
(a) Dimostrare esistenza e unicità della soluzione nell’intervallo considerato.
(b) Calcolare le approssimazioni x 1 , x 2 e x 3 con lo schema di Newton-Raphson, partendo da x 0 = 0.5;
(c) Calcolare le approssimazioni x 2 e x 3 con lo schema della Regula-Falsi partendo da x 0 = 0.5 e x 1
calcolato al punto b).
Stimare, inoltre il fattore di convergenza del metodo di Newton-Raphson assumendo ξ ≈ x 3 .
Svolgimento
(a) La funzione ammette valori opposti all’estremo dell’intervallo. Infatti f (0.5) = −1.82944154 e f (2) =
3.07944154. Quindi, per il teorema del valor intermedio, esiste almeno una radice. Inoltre f 0 (x) = 2(x −
3 2x 2 − 2x + 3
1) + = è sempre positivo nell’intervallo dato, (la parabola 2x 2 − 2x + 3 ha discriminante
x x
negativo e quindi è sempre positiva). Perciò, da f 0 (x) > 0 concludiamo che la f è crescente. Di qui
l’unicità della radice.
(b) Partendo da x 0 = 0.5, il metodo di Newton-Raphson fornisce i seguenti valori:
k xk f (x k ) f 0 (x k )
0 0.50000000E+00 -0.18294415E+01 0.50000000E+01
1 0.86588831E+00 -0.41401211E+00 0.31964267E+01
2 0.99541173E+00 -0.13775443E-01 0.30046517E+01
3 0.99999643E+00
Dalla tabella sembra che i valori della successione tendano a 1. E, infatti, si vede facilmente che
f (1) = 0 e quindi 1 è il valore che stiamo cercando. Per stimare la costante asintotica dell’errore del
56
4.11. Esercizi
| f 00 (x 3 )|
M≈
2| f 0 (x 3 )|
3 3
e f 00 (x) = 2 − 2 .
dove, nel caso specifico, vale f 0 (x) = 2(x − 1) +
x x
Usando il valore trovato per x 3 si ricava M ≈ 0.16667004E + 00.
(c) Partendo da x 0 e x 1 del metodo di Newton-Raphson, la Regula Falsi dà:
f (x n ) − f (x n−1 )
k xk f (x k )
x n − x n−1
0 0.50000000E+00 -0.18294415E+01 -
1 0.86588831E+00 -0.41401211E+00 0.38684741E+01
2 0.97291038E+00 -0.81656072E-01 0.31054906E+01
3 0.99920448E+00
Svolgimento
Graficamente, da f (x) = 0 si ha sin (x) = 1 − x. Se si studia l’intersezione delle due curve, sin (x) e 1 − x
nell’intervallo [0, 1], si può osservare una sola intersezione, cioè una sola radice della f (fare il grafico delle
due funzioni).
Analiticamente, la funzione f (x) assume valori di segno opposto agli estremi dell’intervallo dato:
La derivata prima della f è f 0 = cos (x)+1: è funzione continua e sempre positiva nell’intervallo [0, 1]. Quindi
f è una funzione crescente e interseca l’asse delle x solo una volta in [0, 1], vale a dire ammette un’unica
radice.
(a) Da f (x) = 0 si ha sin (x) + x − 1 = 0 o, equivalentemente, sin (x) = 1 − x, da cui x = arcsin (1 − x).
Consideriamo perciò lo schema del punto fisso con g (x) data da g (x) = arcsin (1 − x). La derivata di
1
g (x) è g 0 (x) = p .
1 − (1 − x)2
Nell’intervallo [0, 1] valgono le seguenti disuguaglianze:
0 ≤ x ≤ 1 =⇒ 0 ≥ −x ≥ −1 =⇒ 1 ≥ 1 − x ≥ 0 =⇒
=⇒ 1 ≥ (1 − x)2 ≥ 0 =⇒ −1 ≤ −(1 − x)2 ≤ 0 =⇒ 0 ≤ 1 − (1 − x)2 ≤ 1 =⇒
p 1
=⇒ 0 ≤ 1 − (1 − x)2 ≤ 1 =⇒ 1 ≤ p
1 − (1 − x)2
Perciò g 0 (x) è sempre maggiore di 1 e lo schema del punto fisso non può convergere.
(b) Da f (x) = sin (x) + x − 1 si ha f 0 (x) = cos (x) + 1 e f 00 (x) = − sin (x). Il metodo di Newton-Raphson è:
sin (x) + x − 1
x k+1 = x k − .
cos (x) + 1
57
4. Z ERI DI FUNZIONE
Utilizziamo la notazione M 1 e M 2 per indicare la stima della costante asintotica dell’errore mediante le
formule
|x k+1 − x k | | f 00 (x k )|
M1 = o M2 =
|x k − x k−1 |2 2| f 0 (x k )|
Partendo da x 0 = 0.1 si ottengono i seguenti valori:
k xk f (x k ) f 0 (x k ) |x k − x k−1 |
0 0.1 -0.80016658E+00 0.19950042E+01 -
1 0.50108517E+00 -0.18537249E-01 0.18770618E+01 0.40108517E+00
2 0.51096084E+00 -0.23565955E-04 0.18722750E+01 0.98756733E-02
3 0.51097343E+00 -0.38737166E-10 - 0.12586802E-04
(c) La stima del fattore di convergenza è dato da M 1 = 0.12905712E+00 o da M 2 = 0.13059731E+00, a
seconda della strada scelta per dare la stima.
Svolgimento
(a) Da f (x) = 0 si ricava ln (x) = x − x 2 , per cui graficamente si può vedere che le due curve si intersecano
in un solo punto, che vale ξ = 1.
Analiticamente, invece, la funzione f (x) assume valori di segno opposto agli estremi dell’intervallo
dato:
f (0.7) = −0.566674943938732
f (2.3) = 3.8229091229351
Inoltre f è continua, quindi ammette almeno una radice nell’intervallo dato. La derivata prima è:
1 1 + 2x 2 − x
f 0 (x) = + 2x − 1, che possiamo anche scrivere come f 0 (x) = : numeratore e denominatore
x x
2
sono entrambi sempre positivi nell’intervallo dato, (la parabola 2x − x + 1 ha discriminante negativo
∆ = −7, di conseguenza, per ogni x reale si ha 2x 2 − x + 1 > 0). Da f 0 (x) > 0 per ogni x segue che f è
crescente e, quindi, ammette un’unica radice.
(b) Applichiamo il metodo delle bisezioni a partire dall’intervallo dato (utilizziamo la notazione x s per
indicare l’estremo sinistro dell’intervallo, x d per indicare l’estremo destro dell’intervallo, x c , il punto
medio dell’intervallo considerato):
iter. x s f (x s ) segno x d f (x d ) segno x c f (x c )
1 0.7 -0.566674944 - 2.3 3.822909123 + 1.5 1.155465108
2 0.7 -0.566674944 - 1.5 1.155465108 + 1.1 0.205310180
Il valore x 0 è dunque x 0 = 1.1.
f (x k )
(c) Il metodo di Newton-Rapshon è x k+1 = x k − 0 dove f 0 = 1/x +2x −1. Partendo da x 0 = 1.1, si ricava
f (x k )
0.20531018
x 1 = 1.1 − = 1.002654656
2.1090909
58
4.11. Esercizi
59
CAPITOLO
5
I NTERPOLAZIONE
Victor Hugo
5.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.2 Interpolazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.3 Interpolazione polinomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.3.1 Funzioni base monomiali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
5.3.2 Polinomi di Lagrange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
5.3.3 Formula dell’errore . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
5.3.4 Differenze divise e formula di Newton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.4 Considerazioni sull’interpolazione polinomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.4.1 Fenomeno di Runge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
5.4.2 Malcondizionamento nell’interpolazione con funzioni base monomiali . . . . . . . . . . 72
5.5 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.1 Introduzione
Il censimento della popolazione italiana, dall’unità d’Italia al 2001, ha visto un incremento della
popolazione, come si può vedere in Tabella 5.1. Gli stessi dati sono riportati in Figura 5.1.
Ci si può chiedere se questi dati possono essere utili (considerandoli tutti o solo una parte) per dare una
ragionevole stima della popolazione nel 1975 o nel 1995 o per predire a quanto ammonterà nel 2015. Per far
ciò, possiamo seguire due strade:
G cercare una funzione che passi esattamente per i dati assegnati (detti anche punti di appoggio): questo
procedimento prende il nome di interpolazione ed è il soggetto di questo Capitolo;
61
5. I NTERPOLAZIONE
G cercare una funzione che, “in qualche modo” passi vicino ai dati assegnati: si parla di approssimazione
(che vedremo nel prossimo Capitolo).
In particolare, dato l’insieme dei punti (x i , y i ), i = 0, 1, . . . , n, dove y i è il valore assunto da una funzione f
in x i o il valore di un dato sperimentale, cerchiamo una funzione v(x) che, in maniera ragionevole si addica
all’insieme dei dati. Se i dati sono accurati, ha senso richiedere che la funzione interpoli i dati (cioè passi
esattamente per le coppie di punti): v(x i ) = y i . Nell’approssimazione, invece, si cerca una funzione più
semplice v(x) che sia vicina ad una funzione più complicata f (x) o ad una serie di dati.
5.2 Interpolazione
Una funzione di interpolazione v(x) serve per vari scopi.
G Possiamo usare la v(x) per trovare valori approssimati y in punti x diversi da quelli assegnati
x 0 , x 1 , . . . x n . Se x si trova all’interno dell’intervallo che contiene le ascisse dei dati assegnati si parla
di interpolazione. Se invece x si trova all’esterno dell’intervallo si ha estrapolazione. Nell’esempio della
popolazione italiana, si interpolano i dati per stimare la popolazione nel 1975 o nel 1995, si applica
invece un procedimento di estrapolazione se si vuole stimare la popolazione del 2012.
G
Se le coppie di dati assegnati si riferiscono ad una funzione f (x), la funzione di interpolazione può
essere utile per approssimare le derivate o gli integrali della f .
Assumiamo che la funzione v di interpolazione sia una combinazione lineare di funzioni base di un
qualche appropriato spazio di funzioni, cioè si possa scrivere come
62
5.3. Interpolazione polinomiale
p n (x) = c 0 + c 1 x + . . . + c n x n
xi 1 2
yi 1 3
Cerchiamo quindi un polinomio di primo grado (una retta) che passi per i punti assegnati, della forma
p(x) = p 1 (x) = c 0 + c 1 x.
Le condizioni di interpolazione diventano:
p 1 (x 0 ) = y 0 ⇐⇒ c 0 + 1c 1 = 1
p 1 (x 1 ) = y 1 ⇐⇒ c 0 + 2c 1 = 3
1 Le funzioni φ , φ , . . . , φ si dicono linearmente indipendenti se vale: c φ (x) + . . . c φ (x) ≡ 0 per ogni x se e solo se tutti i
0 1 n 0 0 n n
coefficienti sono nulli c 0 = . . . = c n = 0.
63
5. I NTERPOLAZIONE
Esempio 5.3.2 Consideriamo adesso un ulteriore coppia di punti per cui i dati che abbiamo sono n + 1 = 3
e
xi 1 2 4
yi 1 3 3
Il problema è ora diverso rispetto a quello appena risolto, perchè la terza coppia di punti specifica una
valore y 2 ben diverso da quello predetto da p 1 in x 2 = 4. Difatti p 1 (x 2 ) = 7, nell’esempio precedente, mentre
ora al valore di x 2 = 4 deve corrispondere y 2 = 3.
Cerchiamo il polinomio di grado 2, quindi, della forma p 2 (x) = c 0 + c 1 x + c 2 x 2 che passa attraverso i punti
dati.
Le condizioni di interpolazione adesso sono:
p 2 (x 0 ) = c 0 + 1c 1 + 1c 2 = 1
p 2 (x 1 ) = c 0 + 2c 1 + 4c 2 = 3
p 2 (x 2 ) = c 0 + 4c 1 + 16c 2 = 3
Generalizzando gli esempi precedenti, date n + 1 coppie di punti, il polinomio di interpolazione di grado
n sarà costruito risolvendo un sistema lineare di n equazioni nelle n incognite c 0 , c 1 , . . . , c n :
p n (x 0 ) = y 0 ⇐⇒ c 0 + c 1 x 0 + c 2 x 02 + . . . + c n x 0n = y 0
p (x ) = y 1 ⇐⇒ c 0 + c 1 x 1 + c 2 x 12 + . . . + c n x 1n = y 1
n 1
p n (x 2 ) = y 2 ⇐⇒ c 0 + c 1 x 2 + c 2 x 22 + . . . + c n x 2n = y 2
.
..
p (x ) = y ⇐⇒ c + c x + c x 2 + . . . + c x n = y
n n n 0 1 n 2 n n n n
64
5.3. Interpolazione polinomiale
In forma compatta, sotto forma matriciale2 le equazioni del sistema si possono scrivere come
1 x 0 x 02 . . . x 0n
c0 y0
1 x
1 x 12 . . . x 1n
c y
1 x x 22 . . . x 2n 1 1
2 . = .
. . . . . .
. .. .. .. . .
.
2 n cn yn
1 xn xn . . . xn
La matrice dei coefficienti è una matrice ben nota in letteratura e prende il nome di matrice di Van-
dermonde.3 È una matrice con determinante diverso da zero, e quindi il sistema ammette una ed una sola
soluzione. Osserviamo che la prima colonna ha tutti gli elementi uguali a 1, la seconda colonna ha le ascisse
dei punti di appoggio, la terza colonna ha i quadrati di esse, e così via.
Tuttavia, la matrice di Vandermonde non ha buone proprietà: difatti è una matrice malcondizionata, e
questo lo si osserva al crescere di n in quanto la soluzione del sistema diventa inaccurata4 , qualunque metodo
venga utilizzato per risolverlo.
Questo approccio ci è servito per dimostrare che il polinomio di interpolazione esiste ed è unico, ma
non è utile nella pratica a causa del malcondizionamento. Sarebbe preferibile, quindi, poter usare funzioni
base diverse dai monomi in modo da evitare il malcondizionamento, avere meno operazioni dal punto di
vista computazionale e poter manipolare in maniera più efficiente le funzioni basi φi in vista di una loro
applicazione nella differenziazione e integrazione numerica.
Una base di funzioni che ci permette una simile rappresentazione è data dai polinomi di Lagrange.5
I polinomi di Lagrange L j (x), per j = 0, 1, . . . , n sono polinomi di grado n che, nei nodi x i , soddisfano la
relazione
(
0 se i 6= j
L j (x i ) =
1 se i = j
Allora il polinomio p n (x) = nj=0 L j (x) · y j è tale che p n (x i ) = y i cioè soddisfa la condizione di
P
65
5. I NTERPOLAZIONE
Esempio 5.3.3 Siano date le tre coppie di punti dell’esempio precedente (1, 1), (2, 3), (4, 3). I polinomi di
Lagrange sono:
(x − 2)(x − 4) (x − 2)(x − 4)
L 0 (x) = =
(1 − 2)(1 − 4) 3
(x − 1)(x − 4) (x − 1)(x − 4)
L 1 (x) = =−
(2 − 1)(2 − 4) 2
(x − 1)(x − 2) (x − 1)(x − 2)
L 2 (x) = =
(4 − 1)(4 − 2) 6
Raccogliendo i termini ritroviamo p 2 (x) = (−2x 2 + 12x − 7)/3, lo stesso polinomio ottenuto con le funzioni
base monomiali, e ciò è dovuto all’unicità del polinomio interpolatore.
f (n+1) (ξ(x)) Y
n
f (x) − p(x) = (x − x i )
(n + 1)! i =0
6 Ricordiamo che, dati n valori w , w , . . . , w usiamo la seguente simbologia per indicare la loro somma e il loro prodotto, rispetti-
1 2 n
vamente:
n
X n
Y
wi = w1 + w2 + w3 + . . . + wn wi = w1 · w2 · w3 · . . . · wn
i =1 i =1
.
66
5.3. Interpolazione polinomiale
Abbiamo quindi una formula per l’errore, detta anche formula del resto. Il resto normalmente è incognito
ma se conosciamo la f e una maggiorazione della f (n+1) , allora possiamo maggiorare il resto.
Allo stesso modo, possiamo limitare l’errore di interpolazione se troviamo un limite superiore per |F (x)|.
67
5. I NTERPOLAZIONE
Esempio 5.3.4 Consideriamo sempre le tre coppie di punti degli esempi precedenti, (1, 1), (2, 3) e (4, 3).
Per costruire p 2 (x) abbiamo bisogno di φ0 , φ1 e φ2 :
φ0 (x) = 1
φ1 (x) = (x − x 0 ) = (x − 1)
φ2 (x) = (x − x 0 )(x − x 1 ) = (x − 1)(x − 2)
68
5.3. Interpolazione polinomiale
f (x 2 ) − f (x 1 )
Ma = f [x 1 , x 2 ] è la differenza divisa del primo ordine tra x 1 e x 2 da cui
x2 − x1
f [x 1 , x 2 ] − f [x 0 , x 1 ]
f [x 1 , x 2 ] − f [x 0 , x 1 ] = c 2 (x 2 − x 0 ) =⇒ c 2 =
x2 − x0
La quantità chiamata c 2 prende il nome di differenza divisa del secondo ordine e si indica con
f [x 1 , x 2 ] − f [x 0 , x 1 ]
f [x 0 , x 1 , x 2 ] = .
x2 − x0
4 2
Facendo le opportune sostituzioni si ricava c 2 = − = − . Quindi, p 2 (x) = f (x 0 ) + f [x 0 , x 1 ](x − x 0 ) +
6 3
2
f [x 0 , x 1 , x 2 ](x − x 0 )(x − x 1 ) Nell’esempio considerato: p 2 (x) = 1 + 2(x − 1) − (x − 1)(x − 2)
3
Date le stesse coppie di punti, abbiamo visto come cambia la rappresentazione (usando come funzioni
base i monomi, poi i polinomi di Lagrange e ora la formulazione di Newton) ma il polinomio finale è sempre
lo stesso essendo unico il polinomio interpolatore.
Da questo esempio, si può vedere come la rappresentazione secondo Newton sia di tipo ricorsivo: il po-
linomio p 1 (x) = f (x 0 ) + f [x 0 , x 1 ](x − x 0 ) (che si ha arrestandosi ai primi due passi del procedimento appena
effettuato) è un polinomio, in tal caso una retta, che interpola i dati (x 0 , y 0 ), e (x 1 , y 1 ). Il polinomio p 2 (x) è da-
to dalla somma di p 1 (x) e del termine f [x 0 , x 1 , x 2 ](x − x 0 )(x − x 1 ). Quindi, una volta determinato il polinomio
p n−1 che interpola i primi n dati, possiamo usare questa rappresentazione per costruire p n che interpola i
dati precedenti cui si aggiunge la coppia (x n , y n ).
Il coefficiente c j del polinomio interpolatore di Newton si chiama differenza divisa di ordine j e viene
indicata con f [x 0 , x 1 , . . . , x j ].
Perciò:
f [x 0 ] = c 0 , f [x 0 , x 1 ] = c 1 , . . . , f [x 0 , x 1 , . . . , x n ] = c n
La notazione utilizzata ci permette di capire anche da quali coppie di punti dipende il coefficiente c j .
f [x i ] = f (x i )
f [x i +1 , . . . x j ] − f [x i , . . . , x j −1 ]
f [x i , . . . , x j ] =
x j − xi
Da un punto di vista computazionale i coefficienti si ricavano mediante la tabella delle differenze di-
vise, tenendo presente che per calcolare f [x 0 , x 1 , . . . , x n ] dobbiamo aver calcolato tutte le differenze divise
f [x j −k , . . . , x j ], con 0 ≤ k ≤ j ≤ n.
69
5. I NTERPOLAZIONE
I coefficienti della diagonale principale sono i coefficienti c j del polinomio interpolatore di Newton.
Esempio 5.3.5 Costruiamo la tabella delle differenze divise per i dati (1, 1), (2, 3) e (4, 3).
2
Il polinomio p 2 (x) si scrive: p 2 (x) = 1 + 2(x − 1) − (x − 1)(x − 2).
3
Se vogliamo aggiungere altri dati, per esempio, la coppia (5, 4), dobbiamo aggiungere una riga alla tabella
della differenza divisa e un termine al polinomio che abbiamo già ricavato per ottenere quello di grado
superiore interpolante tutti i dati che abbiamo a disposizione.
1
Il polinomio p 3 (x) è p 3 (x) = p 2 (x) + (x − 1)(x − 2)(x − 4).
4
Il concetto di differenza divisa può essere visto come un’estensione del concetto di derivata di una fun-
zione. Si ha, infatti, che, per f derivabile, la diffenza divisa del primo ordine f [x 0 , x 1 ] può essere vista come
un rapporto incrementale e quindi, al limite per x 1 → x 0 , si ha f 0 (x 0 ).
70
5.4. Considerazioni sull’interpolazione polinomiale
Derivata La differenza divisa k-sima e la derivata k-sima di f sono legate tra loro. Si può provare, infatti, per k ≥ 1
k-sima della che vale la relazione
f
f (k) (ξ)
f [x 0 , x 1 , . . . , x k ] =
k!
dove ξ è un punto appartente all’interno dell’intervallo individuato dagli estremi di x 0 , . . . , x k . Quando i punti
coincidono, si ha
f (k) (x 0 )
f [x|0 ,x{z
0 ,...,x 0 ] =
} k!
k+1 volte
Questa formula serve per calcolare il polinomio di interpolazione che interpola non solo una certa funzione
f ma anche le sue derivate in alcuni punti assegnati (si veda l’esercizio 5.5.3 a fine Capitolo).
Se al polinomio p n (x) aggiungiamo la coppia di dati (x, f (x)) si ha p n+1 (x) = f (x) = p n (x) + Formula
f [x 0 , x 1 , . . . , x n , x](x − x 0 )(x − x 1 ) · . . . (x − x n ). L’ultima differenza divisa non si può calcolare, poichè dipende dell’errore
da x (che è la nostra variabile), ma ci è utile per capire quanto vale l’errore che commettiamo nell’approssi-
mare f (x) mediante il polinomio interpolatore, applicando la rappresentazione di Newton. Inoltre, dato che
il polinomio interpolatore è unico (fissate le coppie di dati del problema), anche l’errore che si commette è lo
stesso, qualunque sia la strategia utilizzata per arrivare ad esso. Quindi possiamo eguagliare l’errore trovato
utilizzando i polinomi di Lagrange con l’errore trovato nella rappresentazione di Newton, ottenendo:
f (n+1) (ξ(x)) Y
n Y n
(x − x i ) = f [x 0 , x 1 , . . . , x n , x] (x − x i )
(n + 1)! i =0 i =0
71
5. I NTERPOLAZIONE
Figura 5.5: Funzione di Runge e polinomio interpolante di grado 16 su tutto l’intervallo [−5, 5] (a sinistra) e in
un sottointervallo (a destra)
Confrontando i vari algoritmi di interpolazione, osserveremo che gli algoritmi di Lagrange e delle diffe-
renze divise di Newton danno buoni risultati. Al contrario, il metodo che porta alla costruzione della matrice
di Vandermonde dà risultati disastrosi, come si può vedere in Figura 5.6. Eppure, dal punto di vista teorico i
risultati dovrebbero essere identici.
72
5.5. Esercizi
Perchè si hanno questi risultati? Bisogna tener conto di tre aspetti: il calcolo della matrice di Vandermon-
de; la soluzione del sistema lineare per ricavare i coefficienti del polinomio con funzioni base monomiali; il
calcolo dei valori del polinomio.
La matrice di Vandermonde consiste di colonne che crescono di colonna in colonna - 1, x i , x i2 , x i3 , . . .,
x i . Per questo caso test, si va da 1 a elementi dell’ordine di 1015 . La matrice è molto mal condizionata.
5
Perciò la soluzione del sistema lineare non può dare risultati affidabili e il vettore che fornisce i coefficienti del
polinomio interpolatore è completamente errato. Ciò porta anche al fenomeno della cancellazione numerica
nel calcolo del polinomio di interpolazione, per cui si ha una significativa perdita di accuratezza e il grafico
risultante presenta un profilo altamente oscillante.
5.5 Esercizi
xi -1 0 2 3 4
f (x i ) 9 0 0 15 84
Svolgimento
(a) La tabella delle differenza divise è:
(b) Il polinomio di Newton di grado 4 che interpola i dati assegnati è dunque (prendendo i valori della
73
5. I NTERPOLAZIONE
0−0 0+9
2 0 =0 = 3
2−0 2 − (−1)
15 − 0 15 − 0 5−3
3 15 = 15 =5 = 0.5
3−2 3−0 3 − (−1)
84 − 15 69 − 15 27 − 5 11 11/2 − 1/2
4 84 = 69 = 27 = =1
4−3 4−2 4−0 2 4 − (−1)
Svolgimento
(a) La tabella delle differenza divise è:
74
5.5. Esercizi
p 0 (x) = 1
p 1 (x) = 1 − 5.2x
p 2 (x) = 1 − 5.2x + 8x(x − 0.1) = 8x 2 − 6x + 1
p 3 (x) = 1 − 5.2x + 8x(x − 0.1) + 0x(x − 0.1)(x − 0.8) = 1 − 5.2x + 8x(x − 0.1) = p 2 (x)
Il polinomio p 3 (x) coincide con p 2 (x) in quanto p 2 (x 3 ) = p 2 (1.2) = f (1.2) = f (x 3 ) cioè il polinomio
di grado 2 interpola non solo i dati (x 0 , f (x 0 )), (x 1 , f (x 1 )) e (x 2 , f (x 2 )) ma anche (x 3 , f (x 3 )).
(c) Per le derivate di p n (x), n = 0,1,2 si ha
p 00 (x) = 0
p 10 (x) = −5.2
p 20 (x) = 16x − 6
Il polinomio è:
e raccogliendo i termini
p 2 (x) = 8x 2 − 6x + 1
Esercizio 5.5.3 Trovare il polinomio di grado non superiore a 4 che interpola i dati seguenti: f (0) =
2, f 0 (0) = 7, f 00 (0) = 18, f (1) = 27 f 0 (1) = 60. Stimare f (0.2) e f 0 (0.2).
Svolgimento
75
5. I NTERPOLAZIONE
Costruiamo la tabella delle differenze divise tenendo presente che le derivate di una funzione f si possono
avere come limite delle differenze divise:
f 00 (0)
f [0, 0] = f 0 (0) = 7 f [0, 0, 0] = =9 f [1, 1] = f 0 (1) = 60
2!
Tenendo conto di queste relazioni tra differenze divise e derivate, nella tabella delle differenzi divise,
dobbiamo ripetere per tre volte l’ascissa 0 e due volte l’ascissa 1. Si ottiene:
0 2
f 0 (0)=7
0 2 f 00 (0)/2=9
18 − 9
f 0 (0)=7 =9
1−0
25 − 7 17 − 9
0 2 =18 =8
1−0 1−0
27 − 2 35 − 18
=25 =17
1−0 1−0
60 − 25
1 27 =35
1−0
f 0 (1)= 60
1 27
p(x) = 8x 4 + x 3 + 9x 2 + 7x + 2.
76
CAPITOLO
6
A PPROSSIMAZIONE
Platone
6.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
6.2 Retta di regressione lineare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
6.3 Approssimazione polinomiale ai minimi quadrati . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
6.4 Approssimazioni di tipo esponenziale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.5 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
6.1 Introduzione
La legge di Hooke stabilisce che l’allungamento subito da una molla, costruita con materiale uniforme,
è direttamente proporzionale alla forza applicata: F (x) = kx dove k è la costante di proporzionalità, detta
costante elastica, e x rappresenta l’allungamento della molla.
Supponiamo di voler determinare k per una molla che, quando è a riposo, esercita una forza di
1.4724811N . Se applichiamo una forza pari a 2.418165N si misura un allungamento pari a 0.042m. Siano
effettuate diverse misure, ricavando i dati di Tabella 6.1. I dati raccolti non giacciono esattamente su una
linea retta. Per approssimare la costante elastica k, potremmo prendere una qualunque coppia di dati e fare
il rapporto tra la forza e l’allungamento. In questo modo, tuttavia, non terremmo conto di tutte le misure
effettuate. È più ragionevole trovare la linea retta che meglio approssima tutti i dati sperimentali e utilizzarla
per approssimare il valore di k. Questo tipo di approssimazione sarà l’argomento di questo Capitolo.
A differenza dell’interpolazione, in cui si cerca una funzione che passi esattamente per i dati assegnati,
nell’approssimazione si cerca una funzione (più semplice di quella data, se vi è una funzione di partenza) che
approssimi al meglio i dati assegnati, senza passare esattamente per questi.
Alcuni dei motivi che spingono a cercare una funzione di approssimazione piuttosto che di interpolazione
sono questi:
77
6. A PPROSSIMAZIONE
xi 1 2 3 4 5 6 7 8 9 10
yi 1.2 2.3 4.5 5.1 7 8.5 10.2 13.1 12.5 16.5
Tabella 6.2: Dati sperimentali
G vogliamo che la funzione dipenda da pochi parametri, sebbene questi siano determinati considerando
tutti i dati a disposizione.
Nel seguito studieremo l’approssimazione ai minimi quadrati.
78
6.2. Retta di regressione lineare
Figura 6.2: Dati sperimentali (a sinistra) della Tabella 6.2 e polinomio di interpolazione (a destra).
Per minimizzare questa funzione, occorre porre le derivate parziali della S rispetto ad a 0 e a 1 uguali a zero.2
Si pone dunque
∂S(a 0 , a 1 ) ∂ X n £ ¤2 X n £ ¤
0= = (a 0 + a 1 x i ) − y i = 2 (a 0 + a 1 x i ) − y i
∂a 0 ∂a 0 i =0 i =0
∂S(a 0 , a 1 ) ∂ X n £ ¤2 X n £ ¤
0= = (a 0 + a 1 x i ) − y i = 2 (a 0 + a 1 x i ) − y i x i
∂a 1 ∂a 1 i =0 i =0
Nell’esempio proposto, per calcolare la retta di approssimazione ai minimi quadrati, dobbiamo calcolare
i coefficienti delle equazioni normali. In Tabella 6.3 poniamo i valori che servono per risolvere il sistema: la
soluzione è a 0 = −0.87333333 e a 1 = 1.62969697. La retta è rappresentata in Figura 6.3.
La retta che abbiamo appena costruito è la retta che minimizza gli scarti verticali, supponendo affetti
da errore le ordinate delle coppie di punti a disposizione. Essa prende pure il nome di retta di regressione
lineare sugli scarti verticali.
Osserviamo che il baricentro dei punti assegnati giace sulla retta ai minimi quadrati, in quanto conside- Sul
rando la prima equazione del sistema si ha, per X = ni=0 x i /(n + 1) e Y = ni=0 y i /(n + 1) (le coordinate del baricentro
P P
a0 + a1 X = Y
2 Per funzioni f (x) di una variabile reale, i punti di massimo o minimo si trovano tra i punti critici della f , per i quali f 0 (x) = 0,
studiando il segno della f 00 . Analogo procedimento si segue per funzioni di due variabili. Per la funzione S(a 0 , a 1 ) che stiamo studiando,
si può provare che i valori (a 0 , a 1 ) che annullano le derivate parziali della S rappresentano i valori che minimizzano la S stessa. Questo
argomento viene approfondito nei corsi di Analisi Matematica.
79
6. A PPROSSIMAZIONE
xi yi x i2 xi y i
1 1.2 1 1.2
2 2.3 4 4.6
3 4.5 9 13.5
4 5.1 16 20.4
5 7 25 35
6 8.5 36 51
7 10.2 49 71.4
8 13.1 64 104.8
9 12.5 81 112.5
10 16.5 100 165
A 12 = 55 b 1 = 80.9 A 22 = 385 b 2 = 579.4
Tabella 6.3: Tabella per il calcolo della retta di approssimazione ai minimi quadrati
Se invece sono affetti da errore le ascisse delle coppie di punti, si può cercare la retta che minimizza gli
scarti orizzontali, detta anche retta di regressione lineare sugli scarti orizzontali, (basta scambiare il ruolo
delle x con quello delle y per ricavare, con lo stesso procedimento, la retta p 1 (y) = b 0 + b 1 y). Il baricentro dei
punti assegnati giace anche su questa retta, da cui possiamo concludere che esso è il punto di intersezione
delle due rette che minimizzano gli scarti verticali e orizzontali.
80
6.4. Approssimazioni di tipo esponenziale
La funzione da minimizzare è
n £ ¤2
(a 0 + a 1 x i + a 2 x i2 + . . . + a m x im ) − y i
X
S(a 0 , a 1 , . . . , a m ) =
i =0
La procedura seguita per la retta viene generalizzata. Questa volta bisogna porre uguali a zero le m+1 derivate
parziali della S rispetto ai coefficienti del polinomio p m .
∂S
=0 j = 0, 1, . . . , m
∂a j
Ricaviamo, quindi
n
j
(a 0 + a 1 x i + . . . + a m x im − y i )x i = 0
X
2 per j = 0, 1, . . . , m
i =0
Poichè queste equazioni si hanno per j = 0, 1 . . . , m, si ha da risolvere un sistema, che, scritto in forma
matriciale, è:
A T Aa = A T b
1 x 0 x 02 . . . x 0m
1 x
1 x 12 . . . x 1m
A = .
.. .. ..
.. . . .
1 xn x n2 ... x nm
Le equazioni del sistema sono dette equazioni normali. Si può provare che la matrice Q = A T A è
simmetrica, definita positiva3 ed è non singolare, quindi il sistema ammette soluzione.
con a e b opportune costanti. Per ricavare a e b si passa ai logaritmi ricavando l’equazione di una retta i cui
coefficienti sono ottenuti con la procedura di minimizzazione ai minimi quadrati. Da questi, si ritorna poi ai
coefficienti delle funzioni di partenza. Vediamo come.
G Nel caso del modello esponenziale, passando ai logaritmi (in base naturale) si ha:
ln (y) = ln (a) + bx
81
6. A PPROSSIMAZIONE
G Nel caso del modello potenza, passando ai logaritmi (qualunque sia la base usata, il risultato non
cambia) si ha:
Ponendo X = log (x), Y = log (y), a 0 = log (a) e a 1 = b, si ha un’equazione del tipo Y = a 0 + a 1 X .
Quindi, dalle coppie di dati (x i , y i ) i = 0, 1, . . . , n, si deve passare alle coppie (X i = log (x i ), Yi =
log (y i )) e su queste coppie si costruisce la retta di approssimazione ai minimi quadrati. Una volta
ricavati i coefficienti a 0 e a 1 , si ha b = a 1 mentre, con gli opportuni passaggi, si trova il valore di a.
6.5 Esercizi
xi -1 0 2 3 4
f (x i ) 9 0 0 15 84
(a) Trovare la retta ai minimi quadrati che minimizza la somma dei quadrati degli scarti verticali.
(b) Trovare la retta ai minimi quadrati che minimizza la somma dei quadrati degli scarti orizzontali.
(c) Calcolare il punto di intersezione delle due rette e dire di che punto si tratta.
Svolgimento
(a) Il sistema da risolvere per ottenere la retta di approssimazione ai minimi quadrati è:
(
(n + 1)a 0 + ni=0 x i a 1 = ni=0 y i
P P
Pn Pn 2 Pn
i =0 x i a 0 + i =0 x i a 1 = i =0 x i y i
P4 P4 2 P4 P4
dove n + 1 = 5. Poichè i =0 x i = 8, i =0 x i = 30, i =0 y i = 108 e i =0 x i y i = 372, si ha il sistema
(
5a 0 + 8a 1 = 108
8a 0 + 30a 1 = 372
82
6.5. Esercizi
xi 4.0 4.2 4.5 4.7 5.1 5.5 5.9 6.3 6.8 7.1
yi 102.56 113.18 131.2 142 168 196.2 225 256.8 299.51 325.6
Svolgimento Per trovare la curva di approssimazione del tipo y = ax b , dobbiamo prima passare ai logaritmi:
log(y) = log(ax b ) = log(a) + b log(x)
In questo modo ci riconduciamo ad una retta di approssimazione ai minimi quadrati sui logaritmi dei punti
assegnati. Consideriamo il logaritmo naturale (ma i risultati non cambiano con i logaritmi in un’altra base).
I dati su cui lavorare sono dunque:
log(x i ) log(y i )
1.386294361 4.630447993
1.435084525 4.728979472
1.504077397 4.876722876
1.547562509 4.955827058
3.931825633 5.123963980
1.704748092 5.279134547
1.774952351 5.416100402
1.840549633 5.548297572
1.916922612 5.702147806
1.960094784 5.785669634
Calcoliamo la retta di approssimazione ai minimi quadrati, ponendo X i = log(x i ) e Yi = log(y i ). Il sistema
da risolvere è
(
(n + 1)a 0 + ni=0 X i a 1 = ni=0 Yi
P P
Pn Pn 2 Pn
i =0 X i a 0 + i =0 X i a 1 = i =0 X i Yi
dove n + 1 = 10.
Si ha ni=0 X i = 16.6995268, ni=0 X i2 = 28.2537116, ni=0 Yi = 52.0472913, ni=0 X i Yi = 87.6541085
P P P P
83
CAPITOLO
7
M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
Ennio De Giorgi
7.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.2 Elementi di Algebra Lineare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.3 Metodo di eliminazione di Gauss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3.1 Sostituzione all’indietro e in avanti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.3.2 Eliminazione di Gauss: esempio particolare . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.3.3 Eliminazione di Gauss: caso generale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
7.4 Strategie di pivoting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
7.5 Fattorizzazione triangolare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.5.1 Fattorizzazione LDU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.5.2 Fattorizzazione di Gauss senza pivoting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
7.5.3 Fattorizzazione di Cholesky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
7.6 Esercizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
7.1 Introduzione
Si consideri la capacità C di un conduttore. Dall’elettrostatica, sappiamo che vale q = C φ dove q rappre-
senta la carica del conduttore e φ il suo potenziale elettrostatico, quando il conduttore è isolato. Nel caso in
cui il conduttore non sia isolato, la situazione cambia. Supponiamo di avere 4 conduttori in equilibrio elet-
trostatico all’interno di una cavità collegata a terra (a terra il potenziale elettrostatico vale zero). Supponendo
di collegare i conduttori 2, 3 e 4 a terra, si ha φ2 = φ3 = φ4 = 0 e φ1 6= 0. Il conduttore 1 induce carica sugli altri
conduttori, per cui, per ciascun conduttore vale, rispettivamente:
85
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
q 1 = C 11 φ1
q 2 = C 21 φ1
q 3 = C 31 φ1
q 4 = C 41 φ1
Si ripete lo stesso discorso supponendo φ2 6= 0 e tutti gli altri potenziali nulli. Poi sia φ3 6= 0 e gli altri potenziali
nulli. Infine φ4 6= 0 e tutti gli altri nulli.
La sovrapposizione dei 4 stati considerati corrisponde alla situazione in cui φ1 , φ2 , φ3 , φ4 sono tutti diversi
da zero. Si ha perciò:
q 1 = C 11 φ1 +C 12 φ2 +C 13 φ3 +C 14 φ4
q 2 = C 21 φ1 +C 22 φ2 +C 23 φ3 +C 24 φ4
q 3 = C 31 φ1 +C 32 φ2 +C 33 φ3 +C 34 φ4
q 4 = C 41 φ1 +C 42 φ2 +C 43 φ3 +C 44 φ4
può essere usata al posto dell’equazione i -sima di partenza: la soluzione del sistema non cambia.
G Le equazioni i -sima e j -sima possono essere scambiate: la soluzione del sistema non cambia.
In questa maniera, un sistema lineare può essere trasformato in uno di più facile soluzione, come
vedremo nell’algoritmo di eliminazione di Gauss.
Poichè le operazioni da fare coinvolgono i coefficienti a i j e b i , conviene scrivere il sistema di equazioni
lineari utilizzando una forma compatta mediante matrici e vettori.
Matrice
Definizione 7.2.1 Una matrice n × m è una griglia rettangolare (o array) di elementi disposti su n righe e m
colonne.
86
7.2. Elementi di Algebra Lineare
Generalmente, una matrice si denota con una lettera maiuscola, per esempio A, mentre i suoi valori si
indicano con la corrispondente lettera minuscola e i pedici che si riferiscono alla riga e colonna in cui si trova
quel valore, per esempio a i j si riferisce all’elemento di riga i e colonna j della matrice A.
a 11 a 12 a 13 ... a 1n
a a 22 a 23 ... a 2n
21
£ ¤ a a 32 a 33 ... a 3n
A = ai j = 31
. .. .. ..
.
. . . ... .
a n1 a n2 a n3 ... a nn
Esempio 7.2.1
µ ¶
2 10 5
A=
3 1 0
è una matrice 2 × 3 con elementi a 11 = 2, a 12 = 10, a 13 = 5, a 21 = 3, a 22 = 1 e a 23 = 0.
Per indicare che una matrice A ha n righe e m colonne, diremo che A ha dimensione n × m. Quando
lavoreremo con matrici quadrate di n righe e n colonne, parleremo di dimensione n della matrice per indicare
che il numero di righe è uguale al numero di colonne e vale n.
I vettori si possono vedere come un caso particolare delle matrici. Si parla di vettore riga se ci riferiamo a Vettori
una matrice 1 × n e si parla di vettore colonna se ci si riferisce a una matrice n × 1.
Per indicare un vettore colonna e un vettore riga si usa, rispettivamente, la notazione
x1
x
2
x ¡ ¢
x= 3 x = x1 x2 x3 ... xn
.
.
.
xn
G Due matrici A e B , di dimensione n × m, sono uguali se hanno lo stesso numero di righe e di colonne,
e, inoltre, vale, a = b per i , = 1, 2, . . . , n e j = 1, 2, . . . , m.
G Date due matrici A e B , entrambe n × m, si definisce la matrice somma di A e B la matrice n × m A + B
ij ij
Teorema 7.2.1 Date A, B e C tre matrici n × m, e λ e µ due numeri reali, valgono le seguenti proprietà:
GA + B = B + A G(A + B ) +C = A + (B +C )
GA + O = O + A = A G A + (−A) = −A + A = O
Gλ(A + B ) = λA + λB G(λ + µ)A = λA + µA
Gλ(µA) = (λµ)A G1A = A
87
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
G In generale, AB 6= B A.
i =1 i i
scalare tra
vettori
Matrice
G Una matrice D si dice diagonale se è quadrata con d = 0 per i 6= j . Gli elementi diversi da zero si
ij
trovano quindi sulla diagonale (detta diagonale principale) che si può tracciare partendo dall’elemento
diagonale
in alto a sinistra (di posto 11) e arrivando all’elemento in basso a destra (di posto nn).
Esempio:
1 0 0 0
0 2 0 0
D =
0
0 5 0
0 0 0 −1
Matrice
Identità
G Si chiama matrice identità e si indica con I , una matrice diagonale i cui elementi diagonali valgono 1.
Esempio:
1 0 0 0
0 1 0 0
I =
0
0 1 0
0 0 0 1
Matrice
tridiagonale
G Una matrice si dice tridiagonale se gli elementi non nulli si trovano sulla diagonale principale e sugli
elementi delle diagonali che si trovano sopra e sotto la diagonale principale.
Esempio:
−2 1 0 0 0
1 −2 1 0 0
0
A= 1 −2 1 0
0 0 1 −2 1
0 0 0 1 −2
G Una matrice si dice triangolare se ha tutti gli elementi nulli ad eccezione di quelli che si trovano tutti
sopra (o tutti sotto) la diagonale principale.
Matrice – Si definisce matrice triangolare superiore U (U sta per upper) di dimensione n, la matrice per la
triangolare quale, per j = 1, 2, . . . , n, si ha
superiore
u i j = 0 per i = j + 1, j + 2, . . . , n
Matrice – Si definisce matrice triangolare inferiore L (L sta per lower) di dimensione n, la matrice per la
triangolare quale, per i = 1, 2, . . . , n, si ha
inferiore
l i j = 0 per j = i + 1, i + 2, . . . , n
88
7.2. Elementi di Algebra Lineare
Esempi
1 −2 5.3 1 0 0
U = 0 3.2 −4 L= 2 −21 0
0 0 10 −3.4 5.7 −4
A questo punto, il sistema lineare (7.1) può essere scritto in forma matriciale come
Ax = b
Definizione 7.2.2 Data una matrice A di dimensione n, A si dice nonsingolare (o invertibile o regolare) se Matrice
esiste una matrice, che indichiamo come A −1 di dimensione n tale che inversa
A A −1 = A −1 A = I
La matrice A −1 si chiama matrice inversa della A. Una matrice che non ha inversa si dice, invece, singolare (o
non invertibile).
Definizione 7.2.3 La trasposta di una matrice A di dimensione n × m è la matrice indicata con A T , di di- Trasposta di
mensione m × n, per la quale la colonna i della trasposta coincide con la riga i della matrice A di partenza: una matrice
a iTj = a j i .
Esempio:
µ ¶ 1 2
1 2 3
A= A T = 2 5
2 5 6
3 6
Esempio:
1 4 8 1 4 8
A = 4 2 6 A T = 4 2 6
8 6 5 8 6 5
Teorema 7.2.4 Valgono le seguenti proprietà (per matrici per cui è possibile eseguire le seguenti operazioni):
89
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
G(A ) T T
=A G(A + B ) = A + B
T T T
G(AB ) T
= B T AT GSe esiste A allora (A
−1 −1 T
) = (A T )−1
Il determinante di una matrice permette di stabilire esistenza e unicità della soluzione nei sistemi lineari.
Data una matrice quadrata A, il suo determinante si indica mediante la notazione d et (A) o |A|.
Il calcolo del determinante di una matrice di dimensione n richiede O (n!) moltiplicazioni. Quindi, anche per
valori piccoli di n, le operazioni da fare diventanto proibitive.
G
d et (A)
Se A è una matrice trangolare superiore o trangolare inferiore o diagonale, allora d et (A) = ni=1 a i i
Q
90
7.3. Metodo di eliminazione di Gauss
La soluzione del sistema Ax = b può dunque procedere dal basso verso l’alto, a partire dall’ultima riga. Le
equazioni, infatti, sono
a 11 x 1 + a 12 x 2 + a 13 x 3 + . . . a 1n x n = b 1
a 22 x 2 + a 23 x 3 + . . . a 2n x n = b 2
a 33 x 3 + . . . a 3n x n = b 2
.. .
. = ..
a nn x n = b n
b i − nj=i +1 a i j x j
P
xi =
ai i
Un analogo algoritmo si ricava quando la matrice è triangolare inferiore. In tal caso, si parte dalla prima
equazione per ricavare x 1 e poi si va avanti nell’equazione successiva.
Si ha l’algoritmo di sostituzione in avanti:
2x 1 + x 2 + 2x 3 = 10
4x 1 + x 2 + 2x 3 = 12
x 1 + 2x 2 + 5x 3 = 20
91
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
G Al primo passo del metodo, cerchiamo di annullare tutti i coefficienti dell’incognita x1 nella seconda e
terza equazione.
– Dividiamo il coefficiente 4 che moltiplica x 1 nella seconda equazione con il coefficiente 2 che
4
moltiplica x 1 nella prima equazione. Otteniamo il valore = 2. Adesso moltiplichiamo per questo
2
valore (2) la prima equazione, ricavando
2 (2x 1 + x 2 + 2x 3 = 10) =⇒ 4x 1 + 2x 2 + 4x 3 = 20
Se ora facciamo la sottrazione tra la seconda equazione del sistema e questa che abbiamo ricavato
otteniamo
4x 1 + x 2 + 2x 3 = 12 −
4x 1 + 2x 2 + 4x 3 = 20 =
−x 2 − 2x 3 = −8
Sostituiamo questa equazione alla seconda del sistema (il sistema rimane equivalente), ricavando
2x 1 + x 2 + 2x 3 = 10
−x 2 − 2x 3 = −8
x 1 + 2x 2 + 5x 3 = 20
x 1 + 2x 2 + 5x 3 = 20 −
1 1
(2x 1 + x 2 + 2x 3 = 10) ⇐⇒x 1 + x 2 + x 3 = 5 =
2 2
3
x 2 + 4x 3 = 15
2
Sostituiamo questa equazione alla terza del sistema.
– A questo punto il sistema è
2x 1 + x 2 + 2x 3 = 10
−x 2 − 2x 3 = −8
3
x 2 + 4x 3 = 15
2
92
7.3. Metodo di eliminazione di Gauss
3 3
coefficiente (cioè per − ) e poi sottraiamo la terza equazione dalla seconda moltiplicata per − :
2 2
3
x 2 + 4x 3 = 15 −
2
3 3
− (−x 2 − 2x 3 = −8) ⇐⇒ x 2 + 3x 3 = 12 =
2 2
x3 = 3
– Sostituiamo questa equazione alla terza del sistema, ricavando il sistema equivalente
2x 1 + x 2 + 2x 3 = 10
−x 2 − 2x 3 = −8
x3 = 3
Con tutte le trasformazioni effettuate, abbiamo trasformato il sistema di partenza in uno equivalente, che
si può risolvere facilmente mediante sostituzioni all’indietro. Dall’ultima equazione abbiamo x 3 = 3. Sosti-
tuendo questo valore nella seconda equazione otteniamo −x 2 − 6 = −8 da cui x 2 = 2. Infine, sostituendo i
valori di x 3 e x 2 nella prima equazione abbiamo 2x 1 + 2 + 6 = 10 da cui x 1 = 1.
a 21 a 21 a 21 a 21
(a 22 − a 12 )x 2 + (a 23 − a 13 )x 3 + . . . + (a 2n − a 1n )x n = b 2 − b1
a 11 a 11 a 11 a 11
a 31
– sottraiamo la prima equazione moltiplicata per dalla terza equazione.
– ... a 11
a n1
– sottraiamo la prima equazione moltiplicata per dalla n-sima equazione.
a 11
Come risultato di questa operazione avremo una nuova matrice con gli elementi della prima
colonna, eccetto quello di posto 11, tutti uguali a zero.
a 11 a 12 ... a 1n x1 b1
(1) (1) (1)
0
a 22 ... a 2n x 2 b 2
. = .
. .. ..
.
. . ... . .. ..
(1) (1)
0 a n2 ... a nn xn b n(1)
93
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
G Al secondo passo, consideriamo il sistema ridotto che si ha ignorando la prima equazione del sistema
e la prima colonna della nuova matrice che abbiamo ottenuta (che ha tutti 0 al di sotto dell’elemento
diagonale).
A questa sottomatrice applichiamo lo stesso procedimento di prima, sottraendo, quindi, la prima
a (1)
equazione della sottomatrice moltiplicata per 32 (1)
dalla seconda equazione della sottomatrice, e così
a 22
via.
Dopo questo passo, il sistema sarà equivalente a:
a 11 a 12 ... ... a 1n x b 1
(1) (1) (1) 1
0 a 22 a 23 ... a 2n x2 b (1)
.
2
. (2) (2) x 3 b (2)
. 0 a 33 ... a 3n 3 =
. .
.. .. .. .. . .
. . . ... . . .
0 0 (2)
a n3 ... a (2) x n b n(1)
nn
G Dopo aver applicato questo procedimento n − 1 volte, avremo un sistema triangolare superiore
semplice da risolvere utilizzando l’algoritmo di sostituzione all’indietro.
a 11 a 12 ... ... a 1n x b 1
(1) (1) (1) 1
0 a 22 a 23 ... a 2n x2 b (1)
.
2
. (2) (2) x 3 b (2)
. 0 a 33 ... a 3n = 3
. .
.. .. .. . .
. . ... ... . . .
x (n−1)
0 0 ... 0 a (n−1) n bn
nn
Gli elementi diagonali generati ad ogni passo del metodo di eliminazione a i(k) i
sono detti elementi
pivotali.
Nel descrivere il metodo di eliminazione di Gauss abbiamo supposto, per semplicità, che tutti gli elemen-
ti diagonali fossero diversi da zero. Ma una matrice può essere non singolare senza che gli elementi della
diagonale principale siano tutti diversi da zero.
Inoltre, andando avanti nel procedimento di eliminazione, può succedere che un elemento pivotale di-
venti nullo – e quindi la corrispondente incognita non può essere eliminata attraverso quella equazione nel
procedimento di sostituzione all’indietro.
C’è, infine, da considerare il fatto che si possono avere grossi errori numerici quando un elemento
pivotale è molto piccolo.
Cosa fare in queste circostanze? In che modo applicare l’eliminazione di Gauss?
Si hanno le cosiddette strategie di pivoting:
G pivoting parziale
Mano mano che si va avanti nell’eliminazione, per i = 1, 2, . . . , n −1 a ciascuno stadio si sceglie il più
piccolo intero q tale che
(i −1)
|a qi | = max |a (ij i−1) |
i ≤ j ≤n
e si scambiano le righe i e q.
Si opera, dunque, un controllo sulla colonna i -sima dalla posizione i fino alla posizione n, andando
a cercare il coefficiente massimo in modulo.
G pivoting totale
Nel pivoting totale, invece, la ricerca dell’elemento più grande avviene in tutta la sottomatrice che
si ha considerando le colonne e le righe rispettivamente a destra e sotto l’elemento diagonale i -simo.
94
7.4. Strategie di pivoting
Si opera, quindi, uno scambio non solo di righe ma anche di colonne in modo da portare l’ele-
mento pivotale dalla riga e colonna qr al posto i i . Di questo scambio di colonne bisogna conservare
traccia perchè vengono scambiate anche le componenti del vettore soluzione, in modo da effettuare lo
scambio inverso una volta risolto il sistema.
Il maggiore sforzo computazionale garantisce maggiore accuratezza e stabilità nei risultati, nel senso che
gli errori di arrotondamento non sono così amplificati come potrebbe succedere senza l’adozione di una
tecnica di pivoting.
e, infine, a
x 1 + x 2 +x 3 = 1
0.0001x 2 + 1x 3 = 1
−9999x 3 = −10000
Se usiamo un’aritmetica in base 10 con 3 cifre decimali, allora la sostituzione all’indietro ci darà
−10000 1−1
x3 = = 1.000, quad x 2 = = 0, x 1 = 0.
−9999 0.0001
La soluzione è completamente sbagliata.
Se, invece, facciamo lo scambio della seconda e terza riga adottando il pivoting parziale, allora avremo il
sistema:
x 1 + x 2 +x 3 = 1
1x 2 + 1x 3 = 0
0.0001x 2 + 1x 3 = 1
e, infine,
x 1 + x 2 +x 3 = 1
1x 2 + 1x 3 = 0
0.9999x 3 = 1
Questa volta si ha (sempre lavorando con 3 cifre decimali) x 3 = 1.000, x 2 = −1.000, x 1 = 1.000, che è la
soluzione corretta a 3 cifre decimali.
95
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
Minore Definizione 7.5.1 Data una matrice A si definisce minore principale di dimensione k (con 1 ≤ k ≤ n), la
principale sottomatrice che si ha prendendo le prime k righe e k colonne di A.
a 11 ... a 1k
.. ..
. .
a k1 ... a kk
Teorema 7.5.1 (LDU ) Nell’ipotesi che tutti i minori principali di A, (per i = 1, 2, . . . , n) siano non-singolari,
allora la matrice A è decomponibile in maniera univoca nel prodotto A = LDU
96
7.5. Fattorizzazione triangolare
Qualsiasi matrice non singolare può essere condotta sotto una forma tale da soddisfare il teorema LDU
mediante opportuni scambi di righe e di colonne (abbiamo visto cosa fare quando un elemento pivotale è
nullo). Fare uno scambio di righe o di colonne significa moltiplicare la matrice A con un’opportuna matrice
di permutazione.
Una matrice di permutazione P è una matrice ottenuta dalla matrice identità operando scambi di righe o
di colonne in modo che la matrice risultante abbia esattamente un unico valore diverso da zero su ogni riga
e colonna, e tale valore sia uguale a 1. Matrice di
permutazio-
ne
Quindi, il teorema LDU si può applicare alla matrice A o ad un’opportuna matrice P A, se si effettua il pivoting
parziale, o a P AQ se si effettua il pivoting totale (e quindi si considerano due matrici di permutazioni P e Q).
In genere, la matrice D viene inglobata nella L o nella U (post-moltiplicando o pre-moltiplicando le L e le
U definite prima per la D).
G Nel caso in cui la matrice D viene inglobata nella matrice L, la L ha elementi diagonali l ii 6= 0, mentre
G Nel caso in cui la matrice D viene inglobata nella matrice U , la U ha elementi diagonali u
la U ha elementi diagonali unitari. Si parla di fattorizzazione di Crout.
ii 6= 0, mentre
la L ha elementi diagonali unitari. Si parla di fattorizzazione di Doolittle.
Scriviamo in forma estesa il prodotto tra matrici, nell’ipotesi di operare la fattorizzazione di Crout:
a 11 a 12 . . . a 1n l 11 0 ... 0 1 u 12 . . . u 1n
a
21 a 22 . . . a 2n l 21 l 22 . . . 0 0 1 . . . u 2n
.
. .. =
.. ..
.. .. ..
.. ..
. . . . . . . . .
a n1 a n2 ... a nn l n1 l n2 ... l nn 0 0 ... 1
Moltiplichiamo la prima riga di L per le colonne di U ed eguagliamo i termini con gli elementi della prima
riga di A. Otteniamo:
l 11 · 1 = a 11
l 11 · u 1k = a 1k , k = 2, . . . , n
Quindi: l 11 = a 11 e u 1k = a 1k /l 11 . Abbiamo ricavato gli elementi della prima riga di L e U .
Moltiplicando le successive righe di L per le colonne di U ed uguagliando i termini ai corrispondenti
termini di A, abbiamo:
jX
−1
l i j = ai j − l i m um j i = 1, 2, . . . n j = 1, 2, . . . , i
m=1
1 iX
−1
ui j = (a i j − l i m um j ) i = 1, 2, . . . , n − 1 j = i + 1, . . . n
li i m=1
97
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
Si calcolano prima gli elementi della riga i -sima di L e poi quelli della riga i -sima di U , per i = 1, 2, . . . , n.
Trovate le matrici L e U , il sistema di partenza Ax = b è equivalente a LU x = b.
Si pone, dunque, y = U x, ottenendo il sistema Ly = b. Si ricava facilmente y mediante sostituzione in
avanti e da U x = y si ricava x mediante sostituzione all’indietro.
Lo sforzo computazionale maggiore è quindi quello per il calcolo dei coefficienti di L e U .
Nell’eliminazione di Gauss noi ricaviamo espressamente solo la U mentre le modifiche operate sulla
colonna dei termini noti è equivalente al prodotto L −1 b (quindi da LU x = b risolviamo U x = L −1 b).
Matrice dia- Una matrice A di dimensione n si dice diagonalmente dominante in senso stretto per colonne se vale la
gonalmente relazione
dominante in
senso stretto n
X
per colonne |a j j | > |a i j | per ogni j = 1, 2, . . . , n.
i =0
i 6= j
Esempio 7.5.2
7 3 1
A = 2 10 −2
5 0 6
A è una matrice diagonalmente dominante in senso stretto per righe poichè vale:|7| > |3| + |1| = 4, |10| >
|2| + | − 2| = 4 e |6| > |5| + |0|. Non è diagonalmente dominante in senso stretto per colonne in quanto sulla
prima colonna si ha |7| = |2| + |5|.
Esempio 7.5.3
6 3 −4
A= 3 9 5
−4 5 11
A non è diagonalmente dominante in senso stretto per righe poichè, sulla prima riga si ha |6| < |3| + | − 4| =
7. Essendo simmetrica, la matrice non può essere neanche diagonalmente dominante in senso stretto per
colonne, perchè la relazione che abbiamo sulla prima riga vale sulla prima colonna.
98
7.5. Fattorizzazione triangolare
Una matrice A di dimensione n si dice diagonalmente dominante per righe se vale la relazione
n
X
|a i i | ≥ |a i j | per ogni i = 1, 2, . . . , n.
j =0
j 6=i
Matrice dia-
Analoga è la definizione di matrice diagonalmente dominante per colonne (basta applicare la definizione gonalmente
dominante
di matrice diagonalmente dominante per righe sulla matrice A T )
Si hanno i seguenti teoremi.
Teorema 7.5.2 Se A è una matrice diagonalmente dominante e non singolare, allora il metodo di eliminazione
di Gauss può essere implementato senza alcuno scambio di righe e di colonne e i calcoli sono stabili rispetto
alla crescita degli errori di arrotondamento.
Teorema 7.5.3 Se A è una matrice diagonalmente dominante in senso stretto (per righe o per colonne), allora
A è non singolare. In questo caso il metodo di eliminazione di Gauss può essere implementato senza alcuno
scambio di righe e di colonne e i calcoli sono stabili rispetto alla crescita degli errori di arrotondamento.
G indefinita altrimenti.2
positiva
Si ha un’analoga definizione per matrici definite negative e semidefinite negative. Una matrice A di
dimensione n si dice
G definita negativa se è simmetrica e vale xT Ax < 0 qualunque sia il vettore x 6= 0,
G
Matrice
semidefinita negativa se xT Ax ≤ 0 qualunque sia il vettore x. definita
negativa
Dalla definizione di matrice definita positiva, deve essere xT Ax > 0 qualunque sia il vettore x, vale a dire:
a 11 a 12 . . . a 1n x1
a a . . . a x
¡ ¢ 21 22 2n 2
x1 x2 . . . xm .. .. ..
.
. . ... . ..
a n1 a n2 ... a nn xm
Pn
j =1 a 1 j x j
n
P
¢ j =1 a 2 j x j X
n n
¡ X
= x1 x2 ... xm .. =
ai j xi x j > 0
. i =1 j =1
Pn
j =1 a n j x j
Basarsi sulla definizione per verificare che una matrice sia o meno definita positiva può essere molto
difficile. Fortunatamente, ci sono molti criteri che ci permettono di dire se una matrice è definita positiva
oppure no.
IL seguente risultato ci permette di eliminare certe matrici dalla classe delle matrici definite positive, se
non soddisfano certi requisiti.
99
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
Quindi se una matrice ha elementi a i i ≤ 0, non è una matrice definita positiva, perché, se lo fosse, in base al
teorema avrebbe elementi diagonali tutti positivi.
Vediamo ora una condizione necessaria e sufficiente per matrici definite positive.
Teorema 7.5.5 Una matrice A simmetrica di dimensione n è definita positiva se e solo se tutti i suoi minori
principali hanno determinante positivo.
Teorema 7.5.6 Una matrice A simmetrica di dimensione n con elementi diagonali tutti positivi e
diagonalmente dominante è definita positiva.
Anche per matrici simmetriche definite positive, si può applicare il metodo di eliminazione di Gauss
senza operare scambi di righe e di colonne e i calcoli rimangono stabili rispetto alla crescita degli errori di
arrotondamento. Questo risultato ci serve per la fattorizzazione di Cholesky.
Teorema 7.5.7 (LDU per matrici simmetriche) Se A è una matrice simmetrica e nessuno dei suoi minori
principali è singolare, allora A si può decomporre nel prodotto A = LDL T , dove L è triangolare inferiore con
elementi diagonali unitari ed è univocamente determinata, L T è la sua trasposta e D è matrice diagonale.
Dimostrazione. Intanto valgono le ipotesi del teorema LDU e quindi si può scrivere in maniera univoca
A = LDU con L matrice triangolare inferiore, D diagonale e U triangolare superiore. Inoltre, poichè A è
simmetrica, e quindi A = A T , si ha pure LDU = (LDU )T vale a dire LDU = U T D T L T = U T DL T . Si deduce,
dall’uguaglianza, che U = L T e la decomposizione diventa A = LDL T . 4
Nel caso particolare in cui A sia simmetrica e definita positiva, da xT Ax > 0 vale pure
Essendo A è definita positiva, risulta anche D definita positiva. Perciò gli elementi di D (che è una matrice
diagonale) devono necessariamente essere tutti positivi. In tal caso, si considera la matrice D 1/2 che è la
matrice diagonale con elementi dati dalle radici quadrate degli elementi diagonali di D (si prende il valore
positivo della radice quadrata, e il risultato è un numero reale in virtù del fatto che gli elementi diagonali di
D sono tutti positivi). Si pone, quindi, M = LD 1/2 e si ottiene A = M M T : abbiamo il prodotto di una matrice
triangolare inferiore con coefficienti tutti reali per la sua trasposta. Se D non fosse definita positiva (ma avesse
qualche elemento negativo), allora neanche A sarebbe definita positiva e la matrice M sarebbe non reale.
Quindi se A è simmetrica, si ha la decomposizione nel prodotto LL T (chiamiamo di nuovo con L la
matrice M ) con L reale se e solo se A è definita positiva.
I coefficienti della matrice L si trovano facendo il prodotto righe per colonne ed eguagliando i termini ai
corrispondenti elementi di A.
Si ricava:
p
l 11 = a 11
l i 1 = a i 1 /l 11 i = 2, 3, . . . , n
v
iX
−1
u
u
l i i = t(a i i − l i2k ) i = 2, 3, . . . , n
k=1
jX
−1
1
li j = (a i j − li k l j k ) j = 2, . . . , n i = j + 1, . . . , n
li i k=1
100
7.6. Esercizi
7.6 Esercizi
Esercizio 7.6.1
Sia data
la matrice
1 0 2
A = 0 4 8
2 8 29
Provare che verifica le condizioni del teorema LDU e trovare i fattori L e L T tali che A = LL T .
µ ¶
1 0
Svolgimento La matrice A è simmetrica e soddisfa le ipotesi del teorema LDU ( infatti |a 11 | = 1, d et =
0 4
T
4 e d et (A) = 116 − 16 − 64 = 36) per cui è possibile scrivere la matrice A come A = LL . Si ha, quindi:
2
l 11 0 0 l 11 l 21 l 31 l 11 l 11 l 21 l 11 l 31
l 21 2 2
l 22 0 0 l 22 l 32 = l 21 l 11 l 21 + l 22 l 21 l 31 + l 22 l 32
2 2 2
l 31 l 32 l 33 0 0 l 33 l 31 l 11 l 31 l 21 + l 32 l 22 l 31 + l 32 + l 33
La matrice L è dunque
1 0 0
0 2 0
2 4 3
Esercizio 7.6.2
Data la matrice
0.2 1 0.2
A = 1 6.5 1.75
0 2 2.25
(a) verificare che A soddisfa le condizioni del teorema LDU ;
(b) fattorizzare secondo Crout A = LU (prendendo u i i = 1);
(c) usare la fattorizzazione per calcolare det (A −2 );
(d) usare la fattorizzazione per risolvere il sistema Ax = b, con bT = (2.8 19.25 10.75)T .
Svolgimento
(a) La matrice verifica le condizioni del teorema LDU in quanto i minori principali costruiti a partire
dall’angolo superiore sinistro hanno tutti determinante diverso da zero:
µ ¶
0.2 1
a 11 = 0.2 6= 0 det = 0.3 6= 0 det A = 0.375 6= 0
1 6.5
101
7. M ETODI DIRETTI PER LA SOLUZIONE DI SISTEMI LINEARI
l 11 = 0.2
0.2u 12 = 1 =⇒ u 12 = 5
0.2u 13 = 0.2 =⇒ u 13 = 1
l 21 = 1
1 · 5 + l 22 = 6.5 =⇒ l 22 = 1.5
1 · 1 + 1.5u 23 = 1.75 =⇒ u 23 = 0.5
l 31 = 0
0 · 5 + l 32 = 2 =⇒ l 32 = 2
0 · 1 + 2 · 0.5 + l 33 = 2.25 =⇒ l 33 = 1.25
Le matrici L e U sono:
0.2 0 0 1 5 1
L= 1 1.5 0 U = 0 1 0.5
0 2 1.25 0 0 1
(c) Si ha det A = det LU = det L detU = det L = 0.375. Quindi det (A −2 ) = det (A)−2 = 0.375−2 = 7.11111111.
(d) Da Ax = b si ha LU x = b.
Si pone U x = y e si hanno i due sistemi da risolvere per sostituzione in avanti e all’indietro: Ly = b e
U x = y.
y 1 = 2.8/0.2 = 14
0.2 0 0 y1 2.8
1 1.5 0 y 2 = 19.25 =⇒ y 2 = (19.25 − 14)/1.5 = 3.5
0 2 1.25 y 3 10.75
y 3 = (10.75 − 2 · 3.5)1.25 = 3
x 3 = 3
1 5 1 x1 14
0 1 0.5 x 2 = 3.5 =⇒ x 2 = 3.5 − 3 · 0.5 = 2
0 0 1 x3 3
x 1 = 14 − 3 − 5 · 2 = 1
Esercizio 7.6.3
È dato il sistema
lineare
Ax = b dove:
16 −8 4 20
A = −8 20 4 b = 28
4 4 12.25 28.25
(a) Provare che la matrice è definita positiva.
(b) Fattorizzare la matrice secondo Cholesky: A = LL T .
(c) Usare la fattorizzazione per risolvere il sistema Ax = b e per calcolare det(A 3 ).
Soluzione
102
7.6. Esercizi
(a) La matrice è simmetrica, definita positiva in quanto gli elementi della diagonale principale sono tutti
positivi e la matrice è diagonalmente dominante in senso stretto:
16 > | − 8| + |4| = 12
20 > | − 8| + |4| = 12
12.25 > |4| + |4| = 8
La matrice L è dunque
4 0 0
L = −2 4 0
1 1.5 3
(c) Per risolvere il sistema Ax = b, adoperiamo il metodo di sostituzione in avanti e all’indietro risolvendo
i sistemi: Ly = b e poi L T x = y.
Il primo sistema dà:
4 0 0 y1 20
−2 4 0 y 2 = 28
1 1.5 3 y3 28.25
103
CAPITOLO
8
M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
Malcom X
8.1 Introduzione
L’equazione che governa la conduzione del calore in una piastra metallica piana, omogenea e isotropa
prende il nome di equazione di Poisson e si scrive come
∂2 T ∂2 T f (x, y)
+ =
∂x 2 ∂y 2 ρcK H
Si tratta di un’equazione alle derivate parziali dove T [ o C ] è la temperatura, K H [m 2 /s] è il coefficiente di dif-
fusività termica, ρ [K g /m 2 ] è la densità della piastra, c [C al /K g o C ] è il calore specifico, f (x, y) [C al /m 2 s] è il
calore aggiunto o sottratto alla piastra per unità di tempo e di area. In letteratura diverse tecniche numeriche
permettono di risolvere il problema (ricordiamo i metodi alle differenze finite e i metodi agli elementi finiti),
105
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
in determinati punti (detti nodi) della piastra. Qualunque sia il metodo utilizzato, si arriva ad un sistema di
equazioni lineari del tipo
HT = q
dove H rappresenta la matrice di discretizzazione del metodo, T rappresenta il vettore delle temperature nei
nodi e q è il vettore dei termini noti che deriva dal metodo applicato.
La matrice H puó avere una dimensione molto elevata ma ha la caratteristica di essere sparsa, cioè di
avere pochi elementi diversi da zero per ogni riga.
Per risolvere sistemi lineari di questo tipo, si preferisce usare metodi iterativi piuttosto che diretti. In
questo Capitolo presentiamo alcuni dei metodi iterativi per la risoluzione di sistemi lineari.
106
8.4. Norme di matrici
2
Figura 8.1: Vettori in R con norma unitaria nelle norme 1, ∞ e 2.
n
X
kx − yk1 = |x i − y i |
i =1
kx − yk∞ = max |x i − y i |
1≤i ≤n
s
Xn
kx − yk2 = |x i − y i |2
i =1
107
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
Alcune norme su matrici sono generate da norme su vettori: si parla allora di norma naturale o indotta
n
Norma dalla norma di vettori. In particolare, se k · k è una norma su vettori in R , allora kAk = maxkxk=1 kAxk è la
naturale norma naturale o indotta dalla norma k · k su vettori.
Le norme di matrici indotte dalla norma 1 e dalla norma infinito su vettori sono:
G Norma 1: kAk1 = max j ni=1 |a i j | (data dal massimo sulla somma delle colonne)
P
G Norma infinito: kAk∞ = maxi nj=1 |a i j | (data dal massimo sulla somma delle righe)
P
La norma di matrice indotta dalla norma 2 è più complicata e vedremo in seguito come è definita.
È facile vedere che le norme naturali sono norme compatibili con la norma di vettori da cui sono costruite.
Una norma di matrici, che non è indotta, ma compatibile con la norma 2 è la cosiddetta norma euclidea
traccia di una (o di Frobenius). Tenendo presente che, data una matrice A, si chiama traccia della matrice o t r (A) la somma
matrice degli elementi della diagonale principale di A, la norma euclidea è data da
G N (A) = pt r (A T A) =
p
t r (A A T ) =
rP
n 2
i =1 |a i j | .
j =1
Ax = λx
(A − λI )x = 0
Poichè x 6= 0 e il termine noto del sistema è il vettore di tutti zeri, il determinante della matrice del sistema
deve necessariamente essere uguale a zero, cioè det (A − λI ) = 0.
Lo sviluppo del determinante porta a un polinomio di grado n nell’incognita λ:
Polinomio Questo polinomio si chiama polinomio caratteristico. Le sue n radici, che chiamiamo λ1 , λ2 , . . . , λn , sono gli
caratteristico n autovalori della matrice A.
Per le proprietà dei polinomi vale:
n n
λi = t r (A) = a 11 + a 22 + . . . + a nn λi = det (A)
X Y
e
i =1 i =1
108
8.5. Autovalori e autovettori
G Gli autovalori di una matrice A e della sua trasposta A sono gli stessi (ma gli autovettori sono, in
T
G Se A e B sono due matrici arbitrarie regolari, allora gli autovalori di AB sono gli stessi di B A.
genere, diversi).
G kAk =
q
2 ρ(A T A).
Inoltre, per ogni norma naturale, vale il risultato
ρ(A) ≤ kAk
Nello studiare i metodi iterativi per risolvere i sistemi lineari, sarà di particolare importanza sapere quan-
do le potenze di una matrice tendono alla matrice nulla. Matrici A, per cui (A k )i j → 0 per k → ∞, qualunque
sia i , j = 1, 2, . . . , n, (consideriamo A · A · · · A k volte e gli elementi della matrice risultante tendono a zero per
k → ∞) si dicono matrici convergenti. Diciamo che una matrice A di dimensione n è convergente se Matrice
convergente
lim (A k )i j = 0, i , j = 1, 2, . . . , n
k→∞
Si ha il seguente teorema.
Teorema 8.5.1 Data una matrice A di dimensione n, sono equivalenti le seguenti proposizioni
1. A è una matrice convergente.
2. limk→∞ kA k k = 0, per qualche norma naturale.
3. limk→∞ kA k k = 0, per tutte le norme naturali.
4. ρ(A) < 1.
5. limk→∞ A k x = 0, qualunque sia il vettore x.
1 Dati n vettori linearmente indipendenti di Rn Rn
, u(1) , u(2) , . . . u(n) , ogni vettore di si può scrivere come una loro combinazione
lineare. Quindi esistono n coefficienti α1 , α2 , . . . , αn per cui x = α1 u(1) +α2 u(2) +. . .+αn u(n) . Inoltre, per vettori linearmente indipendenti
vale il risultato: α1 u(1) + α2 u(2) + . . . + αn u(n) = 0 se e solo se tutti i coefficienti αi sono uguali a zero, per i = 1, 2, . . . , n.
109
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
O, equivalentemente,
x(k+1) = (I − M −1 A)x(k) + M −1 b k = 0, 1, . . .
Notiamo che, ad ogni passo, non dobbiamo calcolare esplicitamente M −1 , perchè risolviamo problemi del
tipo M p(k) = r(k) = b − Ax(k) in modo da porre x(k+1) = x(k) + p(k) . La matrice E = I − M −1 A è detta matrice di
iterazione del metodo. Nel seguito, per semplicità, poniamo q = M −1 b.
Lo schema iterativo appena descritto è un metodo stazionario (cioè non dipende dall’iterazione k) e
può essere visto come caso particolare di uno schema di punto fisso per equazioni nonlineari: la funzio-
ne g tale che x(k+1) = g (x(k) ) converga alla soluzione del sistema Ax = b, è data da g (x) = x + M −1 (b − Ax) o
equivalentemente da g (x) = E x(k) + q.
8.6.1 Convergenza
Per studiare la convergenza di un metodo iterativo, consideriamo, per ogni vettore x(k) , il residuo r(k) =
b − Ax(k) e l’errore e(k) = x − x(k) . Osserviamo che si ha la relazione r(k) = Ae(k) . Infatti
Lo schema converge quando la successione x(k) converge alla soluzione x per k → ∞, ovvero quando
limk→∞ e(k) = 0 qualunque sia il vettore iniziale x(0) .
Consideriamo lo schema iterativo x(k+1) = E x(k) + q.
È facile vedere che per la soluzione esatta x vale la relazione x = E x + q.
Consideriamo x − x(k) . Si ha
x = Ex+q
x(k)
= E xk−1 + q
e sottraendo si ricava
(k)
e = E e(k−1)
La relazione appena trovata vale, alla stessa maniera, tra l’errore e(k−1) e l’errore e(k−2) per cui possiamo
scrivere e(k−1) = E e(k−2) .
Scriviamo queste relazioni dall’iterazione k fino ad arrivare all’iterazione 0.
110
8.6. Metodi classici
e(k) = E e(k−1)
e(k−1) = E e(k−2)
e(k−2) = E e(k−3)
.. ..
.=.
e(2) = E e(1)
e(1) = E e(0)
Partendo, ora, dalla prima relazione e, andando a sostituire, ogni volta, a secondo membro, la relazione
successiva, si ha:
e(k) = E e(k−1) = E (E e(k−2) ) = E 2 e(k−2) = E 2 (E e(k−3) ) = E 3 e(k−3) = . . . = E k e(0)
Osserviamo che E k rappresenta la potenza k della matrice E , cioè la E · E · · · E k volte.
Il metodo converge se e(k) → 0 per k → ∞. Poichè l’errore iniziale è arbitrario, si ha che limk→∞ e(k) =
limk→∞ E k e(0) = 0 se e solo se limk→∞ E k = 0.
Per il teorema sulla convergenza di matrici (si veda pag. 109), questo si ha se e solo se ρ(E ) < 1. Si può
dunque stabilire il seguente teorema.
Questo risultato lo si può provare facilmente, nel caso in cui la matrice di iterazione E abbia n autovalori
distinti e, quindi, possieda n autovettori linearmente indipendenti, per cui l’errore iniziale e(0) si può scrivere
come e(0) = α1 u(1) + α2 u(2) + . . . + αn u(n) , dove α1 , α2 , . . . , αn sono delle costanti, mentre u(1) , u(2) . . . u(n) sono
gli autovettori associati, rispettivamente, a λ1 , λ2 , . . . , λn . Supponiamo che gli autovalori siano in ordine de-
crescente in modulo, cioè: |λ1 | > |λ2 | > . . . > |λn |, per cui ρ(E ) = |λ1 |. In tal caso si può scrivere (ricordando
che, se λ è un autovalore associato alla matrice A, con u un autovettore ad esso associato, si ha A k u = λk u)
e(k) = E k e(0) = E k (α1 u(1) + α2 u(2) + . . . + αn u(n) )
= α1 E k u(1) + α2 E k u(2) + . . . + αn E k u(n)
= α1 λk1 u(1) + α2 λk2 u(2) + . . . + αn λkn u(n)
mettiamo in evidenza λk1
λk2 (2)
à !
k (1) λkn (n)
= λ1 α1 u + α2 k u + . . . + αn k u
λ1 λ1
λki
per k → ∞ si ha → 0 per i = 2, 3, . . . , n
λk1
≈ λk1 α1 u(1)
Perciò limk→∞ e(k) = limk→∞ λk1 α1 u(1) = 0 se e solo se λk1 → 0 e questo si ha se e solo se |λ1 | < 1. Ma |λ1 | = ρ(E ):
ritroviamo il risultato visto prima.
111
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
Scrivendo l’equazione (8.1) per l’iterazione k − 1 e facendo il rapporto tra le norme degli errori a due passi
successivi si ha:
ke(k) k
≈ ρ(E )
ke(k−1) k
Ricaviamo, quindi, che il metodo iterativo ha convergenza lineare con costante asintotica uguale al raggio
spettrale della matrice di iterazione.
La relazione appena trovata è utile per stabilire quanto veloce è il metodo iterativo per approssimare la
soluzione del sistema con una certa accuratezza. Ad esempio, vogliamo stabilire a priori quante iterazioni
occorrono per ridurre la norma dell’errore iniziale di un certo fattore, ad esempio 10 (il che vuol dire ridurre
l’errore di un ordine di grandezza). Vogliamo dunque capire quale deve essere il valore di k per cui ke(k) k =
ke(0) k
. Ma ke(k) k ≈ ρ(E )k ke(0) k da cui
10
ke(0) k 1
ρ(E )k ke(0) k ≈ =⇒ ρ(E )k ≈
10 10
Applicando il logaritmo in base 10 ad ambo i membri si ha
1
k log10 (ρ(E )) ≈ −1 =⇒ k ≈ −
log10 (ρ(E ))
cioè occorrono k iterazioni con k dato dal più piccolo intero che soddisfa la relazione appena scritta. Meno
iterazioni occorrono fare, più veloce è il metodo.
Velocità Si definisce perciò velocità asintotica di convergenza
asintotica di
convergenza − log10 (ρ(E k ))
R = − log10 (ρ(E )) =
k
Osserviamo che, essendo ρ(E ) < 1, nelle ipotesi in cui il metodo converge, log10 (ρ(E )) < 0 e, di conseguenza,
R > 0. Se vogliamo ridurre l’errore iniziale di una certa quantità ², rifacendo i conti come prima, da una parte
vogliamo che sia ke(k) k ≤ ²ke(0) k, dall’altra sappiamo che ke(k) k ≈ ρ(E )k ke(0) k. Uguagliando i termini abbiamo
112
8.6. Metodi classici
8.6.3 I metodi
Si scriva la matrice A come somma della matrice che ha i soli elementi diagonali di A (che chiamiamo
D), della matrice costituita dai soli elementi della parte triangolare bassa di A (che chiamiamo L) e dai soli
elementi della parte triangolare alta di A (che denotiamo con U ),
A = L + D +U
In questo modo è facile ricavare i metodi iterativi di Jacobi, Gauss-Seidel e di rilassamento, che sono i metodi
iterativi classici per la soluzione di sistemi lineari.
L’ipotesi da fare è che A abbia elementi diagonali diversi da zero (a i i 6= 0 per i = 1, 2, . . . , n, n, da cui la
matrice diagonale D è invertibile).
Se la matrice A è simmetrica, definita positiva, necessariamente a i i 6= 0. Altrimenti, poichè A è non singo-
lare (se così non fosse non potremmo risolvere il sistema), le equazioni del sistema possono essere riordinate
in modo da avere la matrice risultante con elementi diagonali diversi da zero.
Il metodo di Jacobi
x(k+1) = E J x(k) + D −1 b
x(k+1) = −D −1 (L +U )x(k) + D −1 b
Per ricavare questo schema, si può partire dal sistema lineare Ax = b e scrivere la matrice A come L+D+U .
Si ha
(L + D +U )x = b
si porta a secondo membro (L +U )x
Dx = −(L +U )x + b
si moltiplicano ambo i membri per l’inversa della matrice D
x = −D −1 (L +U )x + D −1 b
si innesca il metodo iterativo considerando il vettore x a primo membro dell’equazione
all’iterazione k + 1 e quello a destra all’iterazione k
(k+1)
x = −D −1 (L +U )x(k) + D −1 b
3 Carl Gustav Jacob Jacobi (1804-1851) fu un grande matematico tedesco. Tra i suoi numerosi studi ricordiamo quelli sulle funzioni
ellittiche, sulla teoria dei numeri e sulla meccanica celeste.
113
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
o, equivalentemente,
(Lx(k) )i
(D −1 )i i (U x(k) )i
1 iX
−1 n
x i(k+1) = a i j x (k) a i j x (k)
X
b i − − per i = 1, . . . , n
ai i j j
j =1 j =i +1
⇑
⇑ ⇑
La formula la si può ricavare direttamente, scrivendo, equazione per equazione, il sistema da risolvere
Ax = b:
a 11 x 1 + a 12 x 2 + a 13 x 3 + . . . + a 1n x n = b 1
a 21 x 1 + a 22 x 2 + a 23 x 3 + . . . + a 2n x n = b 2
.. .
. = ..
ai 1 x1 + ai 2 x2 + ai 3 x3 + . . . + ai n xn = bi
.. .
. = ..
a n1 x 1 + a n2 x 2 + a n3 x 3 + . . . + a nn x n = b n
Dalla prima equazione “isoliamo” la prima incognita rispetto a tutte le altre; dalla seconda equazione
“isoliamo” la seconda incognita e così via per le altre equazioni, ottenendo:
a 11 x 1 = b 1 − (a 12 x 2 + a 13 x 3 + . . . + a 1n x n )
a 22 x 2 = b 2 − (a 21 x 1 + a 23 x 3 + . . . + a 2n x n )
.. ..
.= .
a i i x i = b i − (a i 1 x 1 + a i 2 x 2 + . . . + a i i −1 x i −1 + a i i +1 x i +1 + . . . + a i n x n )
.. ..
.= .
a nn x n = b n − (a n1 x 1 + a n2 x 2 + a n3 x 3 + . . . + a nn−1 x n−1 )
1
x1 = [b 1 − (a 12 x 2 + a 13 x 3 + . . . + a 1n x n )]
a 11
1
x2 = [b 2 − (a 21 x 1 + a 23 x 3 + . . . + a 2n x n )]
a 22
.. ..
.= .
1
xi = [b i − (a i 1 x 1 + a i 2 x 2 + . . . + a i i −1 x i −1 + a i i +1 x i +1 + . . . + a i n x n )]
ai i
.. ..
.= .
1
xn = [b n − (a n1 x 1 + a n2 x 2 + a n3 x 3 + . . . + a nn−1 x n−1 )]
a nn
114
8.6. Metodi classici
Se pensiamo di partire da un vettore inziale x(0) , il vettore x(1) si ottiene dalle equazioni precedenti, po-
nendo a secondo membro di ciascuna equazione le componenti del vettore x(0) . Si ricava, in tal modo, la
formula ricorsiva dello schema di Jacobi:
1 h ³ ´i
x 1(k+1) = b 1 − a 12 x 2(k) + a 13 x 3(k) + . . . + a 1n x n(k)
a 11
1 h ³ ´i
x 2(k+1) = b 2 − a 21 x 1(k) + a 23 x 3(k) + . . . + a 2n x n(k)
a 22
.. ..
.= .
1 h ³ ´i
x i(k+1) = b i − a i 1 x 1(k) + a i 2 x 2(k) + . . . + a i i −1 x i(k)
−1
+ a i i +1 x i(k)
+1
+ . . . + a i n x n(k)
ai i
.. ..
.= .
1 h ³ ´i
x n(k+1) = b n − a n1 x 1(k) + a n2 x 2(k) + a n3 x 3(k) + . . . + a nn−1 x n−1 (k)
a nn
Il Metodo di Gauss-Seidel
Lo schema di Gauss-Seidel si può ricavare a partire dal sistema lineare Ax = b nel modo seguente:
Ax = b
(L + D +U )x = b
si porta a secondo membro U x
(D + L)x = −U x + b
si moltiplicano ambo i membri per l’inversa della matrice (D + L)
x = −(D + L)−1U x + (D + L)−1 b
si innesca il metodo iterativo considerando il vettore x a primo membro dell’equazione
all’iterazione k + 1 e quello a destra all’iterazione k
(k+1)
x = −(D + L)−1U x(k) + (D + L)−1 b
(D + L)x(k+1) = b −U x(k)
Dx(k+1) = b − Lx(k+1) −U x(k)
da cui
³ ´
x(k+1) = D −1 b − Lx(k+1) −U x(k)
115
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
" #
1 iX−1 n
x i(k+1) (k+1) (k)
X
= bi − ai j x j − ai j x j per i = 1, . . . , n
ai i j =1 j =i +1
Il metodo è detto anche degli spostamenti successivi, in quanto il calcolo delle componenti del vettore
x(k+1) è fatto utilizzando le componenti già calcolate del vettore stesso. Infatti, per i > 1, è ragionevole pensare
che i valori già calcolati x 1(k+1) , x 2(k+1) , . . . , x i(k+1)
−1
possano essere utilizzati per dare una migliore approssimazio-
ne del valore x i(k+1) . Dalle equazioni del sistema, ragionando come per il metodo di Jacobi, possiamo quindi
scrivere:
³ ´
a 11 x 1(k+1) = b 1 − a 12 x 2(k) + a 13 x 3(k) + . . . + a 1n x n(k)
³ ´
a 22 x 2(k+1) = b 2 − a 21 x 1(k+1) + a 23 x 3(k) + . . . + a 2n x n(k)
.. ..
.= .
³ ´
a i i x i(k+1) = b i − a i 1 x 1(k+1) + a i 2 x 2(k+1) + . . . + a i i −1 x i(k+1)
−1
+ a i i +1 x i(k)
+1
+ . . . + a i n x n(k)
.. ..
.= .
³ ´
a nn x n(k+1) = b n − a n1 x 1(k+1) + a n2 x 2(k+1) + a n3 x 3(k+1) + . . . + a nn−1 x n−1
(k+1)
1 h ³ ´i
x 1(k+1) = b 1 − a 12 x 2(k) + a 13 x 3(k) + . . . + a 1n x n(k)
a 11
1 h ³ ´i
x 2(k+1) = b 2 − a 21 x 1(k+1) + a 23 x 3(k) + . . . + a 2n x n(k)
a 22
.. ..
.= .
1 h ³ ´i
x i(k+1) = b i − a i 1 x 1(k+1) + a i 2 x 2(k+1) + . . . a i i −1 x i(k+1)
−1
+ a i i +1 x (k)
i +1
+ . . . + a i n x (k)
n
ai i
.. ..
.= .
1 h ³ ´i
x n(k+1) = b n − a n1 x 1(k+1) + a n2 x 2(k+1) + a n3 x 3(k+1) + . . . + a nn−1 x n−1 (k+1)
a nn
Il metodo di rilassamento
Ciascuno dei metodi di Jacobi e Gauss-Seidel può essere anche rilassato tramite un fattore ω in modo che
la nuova approssimazione x(k+1) sia ottenuta come una combinazione di x(k+1) e x(k) mediante il fattore ω. In
pratica:
Questa operazione viene fatta direttamente nel momento in cui si stabilisce il metodo iterativo con
rilassamento.
Si può osservare che il metodo di Jacobi rilassato non produce effettivi miglioramenti rispetto al metodo
non rilassato. Invece, il metodo di Gauss-Seidel rilassato può produrre un metodo molto più veloce in termini
116
8.6. Metodi classici
di convergenza e, quindi, preferibile rispetto al metodo senza rilassamento. Come metodo di rilassamento,
dunque, consideriamo il metodo di rilassamento ottenuto da Gauss-Seidel. Per scelte di ω nell’intervallo
]0, 1[ si parla di metodo Sotto-Rilassato, o Under-Relaxation (e in genere è usato per ottenere convergenza
nella soluzione di sistemi che non convergono con il metodo di Gauss-Seidel). Per valori di ω nell’intervallo
[1, 2[ si ha, invece, il metodo noto come metodo di sovra-rilassamento o SOR (Successive Over-Relaxation) –
usato per accelerare la convergenza in sistemi che sono convergenti con il metodo di Gauss-Seidel.
Lo schema di rilassamento, applicato al metodo di Gauss-Seidel, è dato da
" #
ω iX−1 n
x i(k+1) = (1 − ω)x i(k) + (k+1) (k)
X
bi − ai j x j − ai j x j per i = 1, . . . , n
ai i j =1 j =i +1
La matrice di iterazione del metodo di rilassamento si ricava scrivendo in forma matriciale l’algoritmo
appena descritto
³ ´
x(k+1) = (1 − ω)x(k) + ωD −1 b − Lx(k+1) −U x(k)
A questo punto, ci si può chiedere quale sia l’ω ottimale nel metodo di rilassamento. L’ω ottimale è quello
che fa sì che il metodo di rilassamento converga nel minor numero di iterazioni (quindi, l’ω ottimale rende
minimo il raggio spettrale della matrice di iterazione). Vedremo, per particolari matrici A, quando è possibile
stabilire a priori quale sia l’ω ottimale per risolvere il sistema lineare Ax = b.
metodo matrice
Jacobi E J = I − D −1 A = −D −1 (L +U )
Gauss-Seidel E S = I − (D + L)−1 A = −(D + L)−1U
rilassamento E ω = I − ω(D + ωL)−1 A
Tabella 8.1: Matrici di iterazione dei metodi di Jacobi, Gauss-Seidel, rilassamento
convergenza, il raggio spettrale della matrice di iterazione deve essere minore di uno.
Per i metodi di Jacobi e di Gauss-Seidel si può provare la convergenza del metodo, se la matrice A ha una
delle seguenti caratteristiche:
G A è diagonalmente dominante in senso stretto
117
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
Teorema 8.6.2 (Ostrowski-Reich) Se A è definita positiva e ω è un numero reale nell’intervallo ]0, 2[, allora il
metodo di rilassamento è convergente.
G La convergenza del metodo di rilassamento si ha, inoltre, per A simmetrica con elementi diagonali
positivi ed elementi extra-diagonali negativi o nulli, se e solo se A è definita positiva.
Un altro interessante teorema mette in relazione il metodo di rilassamento con i metodi di Jacobi e di Gauss-
Seidel, sia per quanto riguarda la convergenza, sia per quanto riguarda il valore ottimale del parametro ω, in
corrispondenza di matrici A che godono della cosidetta proprietà A e che siano coerentemente ordinate.
Definizione 8.6.1 Una matrice A, di dimensione n, si dice che ha proprietà A se esiste una matrice di
permutazione P tale che la matrice P AP T abbia la forma
µ ¶
D1 A1
P AP T =
A2 D2
118
8.6. Metodi classici
0 0 −1 2
ha proprietà A (o è biciclica): permutando la prima e quarta riga e la prima e quarta colonna, mediante la
0 0 0 1
0 1 0 0
matrice di permutazione P = 0 0 1 0 si ha
1 0 0 0
2 0 −1 0
µ ¶
T
0 2 −1 −1 2 0
P AP = =⇒ D 1 = D 2 =
−1 −1 2 0 0 2
0 −1 0 2
Possiamo scegliere S = {1, 3} e T = {2, 4}.
Definizione 8.6.2 Una matrice si dice coerentemente ordinata in relazione ad un vettore di ordinamento q, di
lunghezza n, se per ogni coefficiente a i j non nullo, con i 6= j , si verifica:
G se j > i allora q j − q i = 1
G se j < i allora q j − q i = −1
Un’altra definizione di matrice con coerente ordinamento considera la matrice A data non dalla scompo-
sizione A = L + D +U che abbiamo visto fino ad ora ma come A = D(L A + I +U A ), (osserviamo che, rispetto
alla prima scomposizione, abbiamo messo in evidenza la matrice diagonale D e quindi le matrici triango-
lari superiore e inferiore sono L A = D −1 L e U A = D −1U ). Sia D non singolare. Allora la matrice A è detta
coerentemente ordinata se gli autovalori della matrice J (α) = αL A + α−1U A , con α 6= 0 sono indipendenti dal
parametro α. µ ¶
D 1 A1
Le matrici con proprietà A (o bicicliche) nella forma A = (P = I nella definizione di proprietà
A2 D 2
A) sono coerentemente ordinate.
Le matrici tridiagonali sono un esempio di matrici bicicliche e coerentemente ordinate.
Per il metodo di rilassamento si può provare il seguente risultato.
Teorema 8.6.3 (Young) Se A è una matrice con proprietà A e coerente ordinamento e 0 < ω < 2, allora:
G se µ è autovalore della matrice di iterazione di Jacobi E J , ogni λ che verifica la relazione (λ + ω − 1)2 =
λω2 µ2 è autovalore di E ω ;
G se λ è autovalore non nullo di E ω , allora ogni µ che verifica la relazione precedente è autovalore di E J ;
G se gli autovalori di E J sono reali e il metodo di Jacobi converge (ρ(E J ) < 1), esiste uno ed uno solo ωopt
che rende ottimale il metodo di rilassamento, tale cioè che ρ(ωopt ) = min0<ω<2 ρ(E ω ). Risulta
2
ωopt = e ρ(E ωopt ) = ωopt − 1
1 − ρ(E J )2
p
1+
Per ω = 1 il metodo di rilassamento coincide con il metodo di Gauss-Seidel. Allora, per matrici con pro-
prietà A e coerentemente ordinate, nelle ipotesi del teorema di Young, valendo la relazione (λ + ω − 1)2 =
λω2 µ2 , si trova, per ω = 1, λ2 = λµ2 da cui ρ(E S ) = ρ(E J )2 . Come conseguenza, si ha che il metodo di
Gauss-Seidel ha velocità doppia rispetto al metodo di Jacobi.
119
8. M ETODI I TERATIVI PER LA SOLUZIONE DI SISTEMI LINEARI
8.7 Esercizi
Esercizio 8.7.1
Sia dato
il sistema
lineare Ax = b, dove
8 2 6 30
A = 7 5 0 b = 34
1 0 5 7
(a) Provare che gli schemi di Jacobi e di Seidel convergono e calcolare la velocità asintontica di
convergenza di entrambi gli schemi.
(b) A partire dallo stesso vettore iniziale x(0) = (0 0 0)T , calcolare le approssimazioni x(1) e x(2) che si
ottengono applicando lo schema di Jacobi e lo schema di Seidel.
Svolgimento
(a) La matrice A non è diagonalmente dominante nè per righe nè per colonne (vedasi la seconda riga e
la terza colonna). Non possiamo usare il criterio di matrice diagonalmente dominante per provare la
convergenza dei due metodi. La matrice µ ¶A è biciclica e coerentemente ordinata (si veda lo schema a
5 0
croce che individua D 1 = (8) e D 2 = ):
0 5
8 2 6
7 5 0
1 0 5
Quindi se proviamo che lo schema di Jacobi converge, cioè che l’autovalore di massimo modulo della
matrice di Jacobi è reale e in modulo minore di 1, allora, poichè per matrici bicicliche e coerentemen-
te ordinate vale ρ(E J )2 = ρ(E S ), allora anche il metodo di Gauss-Seidel convergerà alla soluzione (da
ρ(E J ) < 1 segue ρ(E S ) < 1). La matrice di Jacobi è E J = I − D −1 A cioè
0 −2/8 −6/8 0 −1/4 −3/4
E J = −7/5 0 0 = −7/5 0 0
−1/5 0 0 −1/5 0 0
¯ ¯
¯ −µ −1/4 −3/4¯¯
3 1 1 7
0 ¯¯ = −µ3 + · µ + · µ = 0
¯
¯−7/5 −µ
¯ 4 5 4 5
¯−1/5 0 −µ ¯
3 7
Si ha: 0 = det (E J − µI ) = −µ3 + ( + )µ,
20 20 p p
Una radice è µ = 0, e le altre due sono µ = ± 1/2 = ± 0.5 = 0.707106781.
Gli autovalori sono tutti reali e quello di massimo modulo è µ = 0.707106781 < 1.
C’è, dunque, convergenza per i metodi di Jacobi e di Gauss-Seidel (ρ(E S ) = ρ(E J )2 = 0.5). Le velocità
di convergenza valgono
120
8.7. Esercizi
Lo schema di Jacobi è:
1 Partendo dal vettore x (0) con com-
(k+1) (k) (k)
x = (30 − 2x − 6x )
1
8 2 3 ponenti tutte nulle, abbiamo
1 2 3
k x (k) x (k) x (k)
(b)
1
x 2(k+1) = (34 − 7x 1(k) ) 0 0 0 0
5 1 3.75 6.8 1.4
2 1.0 1.55 0.65
1
x (k+1) = (7 − x (k) )
3 1
5
Lo schema di Seidel è:
1 Partendo dal vettore x (0) con com-
x 1(k+1) = (30 − 2x 2(k) − 6x 3(k) )
8 ponenti tutte nulle, abbiamo
x 1(k) x 2(k) x 3(k)
k
1 0 0 0 0
x 2(k+1) = (34 − 7x 1(k+1) )
5 1 3.75 1.55 0.65
2 2.875 2.775 0.825
(k+1) 1
x (k+1)
3 = (7 − x 1 )
5
Esercizio 8.7.2
Dato il sistema Ax = b con
5 0 10
A = 0 3 15
2 1 α
(a) dire per quali valori di α il metodo di Jacobi converge.
(b) trovare il valore di α in corrispondenza del quale il metodo SOR ha un valore di omega ottimo ωopt =
3/2. Per tale valore trovare la velocità asintotica di convergenza del metodo SOR.
Svolgimento
(a) La matrice dipende dal parametro α quindi a priori non possiamo dire se Jacobi converge o meno.
Scriviamo la matrice di iterazione del metodo di Jacobi come
1/5 0 0 0 0 10 0 0 −2
E J = −D −1 (L +U ) = − 0 1/3 0 0 0 15 = 0 0 −5
0 0 1/α 2 1 0 −2/α −1/α 0
Gli autovalori si calcolano imponendo det (E J − µI ) = 0, vale a dire
¯ ¯
¯ −µ 0 −2 ¯¯
9µ
−5 ¯¯ = 0 vale a dire − µ3 +
¯
¯ 0 −µ =0
¯
¯−2/α −1/α −µ¯ α
3
Ricaviamo gli autovalori µ = 0 e µ = ± p .
α
3 p
Perchè ci sia convergenza deve dunque essere p < 1 ovvero 3 < α. Ricaviamo la relazione α > 9.
α
2
(b) Dalla relazione dell’ωopt , ωopt = , valida perchè la matrice è biciclica e coerentemente
1 + 1 − ρ(E J )2
p
ordinata, si ha:
2 3 1 p −8 9 81
p = =⇒ = 1 − 9/α =⇒ = − =⇒ α = = 10.125
1 + 1 − 9/α 2 3 9 α 8
3
Da ωopt = = 1.5 segue λopt = ωopt − 1 = 0.5, da cui R = − log10 (λopt ) = 0.3010299957.
2
121
CAPITOLO
9
I NTEGRAZIONE NUMERICA
Albert Einstein
9.1 Introduzione
Un’automobile effettua il giro di una pista in 84 secondi. La velocità dell’auto viene misurata ogni 6 se-
condi usando un’apparecchiatura radar per il controllo della velocità, ricavando i valori che si trovano in
Tabella 9.1.
In base ai dati in possesso, quanto è lunga la pista?
ds
Sapendo che la velocità v è data da v(t ) = (dove s rappresenta lo spostamento e t il tempo), per calco-
dt
lare la lunghezza della pista (data dallo spostamento effettuato dall’auto), dobbiamo integrare la velocità tra
123
9. I NTEGRAZIONE NUMERICA
Tempo 0 6 12 18 24 30 36 42 48 54 60 66 72 78 84
Velocità 38 41 45 48 45 41 37 33 30 26 24 27 32 35 37
Tabella 9.1: Dati della velocità misurati ogni 6 secondi. Il tempo è espresso in secondi e la velocità è data in
metri al secondo.
Quindi, se riusciamo a risolvere l’integrale in cui la funzione integranda è la velocità, per le uguaglianze
date, sapremo dire quanto vale L, essendo
Z 84
v(t )d t = L
0
Sfruttando i dati della velocità misurati ogni 6 secondi, dobbiamo essere in grado di poter risolvere
numericamente questo integrale.
In questo Capitolo studieremo come fare. Ci occuperemo, infatti, di approssimare l’integrale definito
Z b
I= f (x)d x
a
dove f è una funzione definita nell’intervallo [a, b] (e f può essere nota oppure data su determinati punti
dell’intervallo, come nell’esempio appena visto).
Una formula di integrazione numerica (detta anche formula di quadratura numerica) approssima
Rb
l’integrale esatto I = a f (x)d x mediante nj=0 a j f (x j ):
P
Z b n
X
I= f (x)d x ≈ a j f (x j )
a j =0
dove x j , j = 0, . . . , n sono le ascisse o punti di appoggio della formula di quadratura e a j sono i pesi della
formula.
a f (a)
f (b) − f (a)
b f (b)
b−a
Il polinomio di interpolazione (retta) che interpola la f in a e in b (gli estremi dell’intervallo di integrazione)
è dato da
f (b) − f (a)
p(x) = f (a) + (x − a)
b−a
124
9.3. Formule di Newton-Cotes
f 00 (ξx )
E (x) = (x − a)(x − b)
2
dove ξx è un punto dell’intervallo [a, b]. Per quanto abbiamo studiato sull’interpolazione, sappiamo che la
funzione f (x) si può scrivere come somma del polinomio e dell’errore: f (x) = p(x) + E (x). Nel nostro caso,
abbiamo
f 00 (ξx )
Z b Z bµ Z b
f (b) − f (a)
¶
f (x)d x = f (a) + (x − a) d x + (x − a)(x − b) dx
a a b−a a 2
ovvero
Z b f (a) + f (b) 1
Z b
f (x)d x = (b − a) + (x − a)(x − b) f 00 (ξx ))d x
a 2 2 a
Poichè il prodotto (x −a)(x −b) ha segno costante in [a, b], per il teorema del Valor Medio del calcolo integrale
(si veda il Teorema 2.5.6) si ha
1 b 1 00 b 1 (b − a)3
Z Z
(x − a)(x − b) f 00 (ξx ))d x = f (ξ) (x − a)(x − b)d x = − f 00 (ξ)
2 a 2 a 2 3!
(b − a)3
|E i nt | ≤ M
12
b−a
I t r ap = [ f (a) + f (b)]
2
n x −x
Y j
L i (x) =
j =0 xi − x j
j 6=i
125
9. I NTEGRAZIONE NUMERICA
Figura 9.1: Formula dei trapezi: l’integrale della funzione f (zona tratteggiata in blu) viene approssimata
mediante l’area del trapezio sotteso alla retta di interpolazione per f (a) e f (b) (zona verde).
Se i nodi sono equidistanti con passo h, possiamo scrivere x j = x 0 + j h, con j = 0, 1, . . . , n e per un generico
punto x compreso tra x 0 e x n vale x = x 0 + sh con 0 ≤ s ≤ n, s numero reale.
Quindi x − x j = x 0 + sh − (x 0 + j h) = (s − j )h e x i − x j = (i − j )h, da cui il polinomio di Lagrange si può
scrivere come
Y n s−j
L i (x) = = L i (s)
j =0 i − j
j 6=i
Da f (x) = p n (x) + E (x) dove E (x) è l’errore della formula di interpolazione, passando all’integrale,
abbiamo
Z b Z b Z b
f (x)d x = p n (x)d x + E (x)d x
a a a
Il primo integrale a secondo membro rappresenta la formula che approssima l’integrale della f mentre il
secondo integrale rappresenta l’errore della formula di quadratura.
La formula di quadratura è quindi data dal valore dell’integrale di p n :
Z b Z n
bX n
X Z b
I= f (x)d x ≈ f (x i )L i (x)d x = f (x i ) L i (x)d x
a a i =0 i =0 a
Rb
La formula di quadratura ha dunque come nodi i punti x i e come pesi gli integrali a L i (x)d x.
Sia x 0 = a e x n = b, tenendo presente che L i (x) = L i (s) con x = x 0 + sh, da cui d x = hd s abbiamo
Z b Z xn Z n Z n
L i (x)d x = L i (x)d x = L i (s)hd s = h L i (s)d s
a x0 0 0
Allora
Z b n
X Z n
I= f (x)d x ≈ h f (x i ) L i (s)d s
a i =0 0
126
9.3. Formule di Newton-Cotes
1 n
Z
C i(n) = L i (s)d s i = 0, 1, . . . , n
n 0
La formula precedente si scrive, quindi, come
Z b n n
f (x i )C i(n) = (x n − x 0 ) f (x i )C i(n)
X X
I= f (x)d x ≈ nh (9.1)
a i =0 i =0
1 1
Z 1
(s − 1) 1
Z
C 0(1) = L 0 (s)d s = ds =
1 0 0 −1 2
Z 1 Z 1
1 s 1
C 1(1) = L 1 (s)d s = ds =
1 0 0 1 2
127
9. I NTEGRAZIONE NUMERICA
Figura 9.2: Formula di Cavalieri-Simpson: l’integrale della funzione f (zona tratteggiata in blu) viene
approssimata mediante l’area della regione sottesa alla parabola passante per f (a), f (c) e f (b) (zona verde).
1 2 1 2 (s − 1)(s − 2) 1
Z Z
C 0(2) = L 0 (s)d s = ds =
2 0 2 0 (−1)(−2) 6
1 2 1 2 (s)(s − 2) 4
Z Z
C 1(2) = L 1 (s)d s = ds =
2 0 2 0 (1)(−1) 6
Z 2
1 1 2 (s)(s − 1) 1
Z
C 2(2) = L 2 (s)d s = ds =
2 0 2 0 (2)(1) 6
Con la formula di Cavalieri-Simpson, dunque, l’integrale della f viene approssimato con l’integrale della
parabola passante per i due estremi a e b e per il punto centrale dell’intervallo.
Per quanto riguarda l’errore che si commette approssimando l’integrale della f con la formula di
Cavalieri-Simpson, consideriamo, seguendo l’approccio visto per la formula dei trapezi, l’integrale dell’errore
del polinomio di interpolazione di Lagrange.
f 000 (ξx )
Per il polinomio di secondo grado p 2 che interpola la f , l’errore è dato da E (x) = (x−a)(x−c)(x−b).
3!
128
9.3. Formule di Newton-Cotes
Quando facciamo l’integrale, l’errore nell’approssimare l’integrale esatto con la formula di Cavalieri-
Simpson è dunque dato da
b f 000 (ξx )
Z
E i nt = (x − a)(x − c)(x − b)d x
a 3!
Questa volta, la funzione (x − a)(x − c)(x − b) cambia segno all’interno dell’intervallo [a, b] e non possiamo
più applicare il teorema del Valor Medio come nella formula dei trapezi. In maniera più laboriosa, tuttavia, si
ricava per l’errore la seguente formula:
f I V (u) b − a 5 f I V (u)
µ ¶
E i nt = − =− (b − a)5
90 2 2880
f (I V ) (ξx )
E (x) = (x + t )x 2 (x − t )
4!
Quindi da f (x) = p(x) + E (x), andando a integrare tra −t e t si ha:
Z t Z t Z t
f (x)d x = p(x)d x + E (x)d x
−t −t −t
Nell’integrazione del polinomio p(x) è facile vedere che i termini che dipendono da f 0 (0) portano un
contributo nullo. Infatti
x3
Z tµ 0
f 0 (0)
Z t 0
f (0) f (0) 2
¶ µ ¶
(x + t )x − 2 (x + t )x 2 d x = x +tx − − x2 d x
−t t t −t t t
0 · 2 4 ¸t
f (0) x x
= t − =0
t 2 4t −t
129
9. I NTEGRAZIONE NUMERICA
Gli integrali degli altri termini del polinomio p(x) portano alla formula di Cavalieri-Simpson. Infatti
(omettendo i passaggi matematici) si ha
Z t µ
f (0) − f (−t ) f (−t ) − f (0) f (t ) − f (−t )
¶
2
f (−t ) + (x + t ) + (x + t )x + (x + t )x d x =
−t t t2 2t 3
2t
= ( f (−t ) + 4 f (0) + f (t ))
6
Allora l’errore della formula di Cavalieri-Simpson coincide con l’integrale di E (x).
R t f (I V ) (ξx )
Quindi E i nt = −t (x + t )x 2 (x − t )d x
4!
La funzione (x + t )x 2 (x − t ) = (x 2 − t 2 )x 2 non cambia mai segno all’interno dell’intervallo [−t , t ], quindi si
può applicare il teorema del Valore Medio del calcolo integrale, per cui
¸t
f (I V ) (ξ) t f (I V ) (ξ) x 5 x3 f (I V ) (ξ) 5
Z ·
E i nt = (x 2 − t 2 )x 2 d x = − t2 =− t
24 −t 24 5 3 −t 90
f (I V ) (ξ) h 5 f (I V ) (ξ) 5
E i nt = − ( ) =− h
90 2 2880
Troviamo la formula dell’errore per Cavalieri-Simpson.
130
9.4. Formule composte
L’errore che si commette è dato dalla somma degli errori commessi sui singoli sottointervalli
n h3
− f 00 (ξi )
X
E i nt =
i =1 12
Supponendo che la derivata seconda della f sia continua e limitata in [a, b] e chiamando con m e M
rispettivamente il minimo e il massimo di f 00 in [a, b], si ha:
m ≤ f 00 (ξi ) ≤ M i = 1, . . . , n
131
9. I NTEGRAZIONE NUMERICA
1
Quindi per n → ∞ l’errore tende a zero come h 2 o, equivalentemente, come .
n2
In tal modo
Z b X n h¡ ¢
f (x)d x ≈ f (a i ) + 4 f (c i ) + f (b i )
a i =1 6
132
9.4. Formule composte
Quindi i nodi pari corrispondono agli estremi dei sottointervalli, mentre i nodi dispari sono
i punti centrali di ogni sottointervallo. Per la formula di quadratura otteniamo
Z b n−1
X Z x2i +2
I= f (x)d x = f (x)d x
a i =0 x 2i
n−1
X h
≈ [ f (x 2i ) + 4 f (x 2i +1 ) + f (x 2i +2 )]
i =0 6
h
= [ f (x 0 ) + 4 f (x 1 ) + 2 f (x 2 ) + 4 f (x 3 ) + . . . + 2 f (x 2n−2 ) + 4 f (x 2n−1 ) + f (x 2n )]
6
h n−1
X n−1
X
= [ f (x 0 ) + 4 f (x 2i +1 ) + 2 f (x 2i ) + f (x 2n )]
6 i =0 i =0
Per quanto riguarda l’errore, facendo la somma degli errori di integrazione sugli n sottointervalli,
nell’ipotesi che la derivata quarta sia continua e limitata, si ha3 :
1 h 5 IV
µ ¶
E i nt =− ( f (ξ1 ) + f I V (ξ2 ) + . . . + f I V (ξn ))
90 2
h 5 n−1
X IV (b − a)5 n−1 X IV
=− f (ξi ) = − f (ξi )
2880 i =0 2880n 5 i =0
1X n
f I V (ξ) = f I V (ξi )
n i =1
(b − a)5 I V (b − a)h 4 I V
E i nt = − f (ξ) = − f (ξ)
2880n 4 2880
1
Quindi per n → ∞ l’errore tende a zero come 4 o, equivalentemente, come h 4 . Nella formula dei trape-
n
1
zi l’errore invece decresce come 2 . Ci aspettiamo quindi che il maggiore sforzo computazionale dia una
n
maggiore accuratezza nei risultati quando si applica la formula di Cavalieri-Simpson rispetto alla formula dei
trapezi.
3 Ricordiamo che h = b − a .
n
4 Si ripete lo stesso ragionamento fatto sulla derivata seconda nella formula composta dei trapezi, questa volta però sulla derivata
quarta. Per esercizio, si consiglia di ripetere tutti i passaggi per arrivare al risultato.
133
9. I NTEGRAZIONE NUMERICA
limn→∞ n
P
i =0
f (a + i h(n)) · h(n), con h(n) = (b − a)/n, e considerare come approssimazione dell’integrale la somma parziale
Pn 7 otteniamo il valore 0.74682420125254.
i =0
f (a + i h(n)) · h(n) con un valore di n molto grande. Per esempio, con n = 10
134
9.4. Formule composte
Suddividiamo l’intervallo [0, 1] in 4 sottointervalli. Sia h = 1/4 = 0.25. Per la formula composta dei trapezi
abbiamo
h 2 2 2 2
I t r ap = [e 0 + 2e −h + 2e −(2h) + 2e −(3h) + e −(4h) ]
2
2 2 2
= 0.125[1 + 2e −0.125 + 2e −0.5 + 2e −0.75 + e −1 ]
= 0.742984
Esempio 9.4.3 Riprendiamo l’esempio visto all’inizio del Capitolo, in cui è misurata la velocità di
un’automobile ogni 6 secondi e si vuole calcolare la lunghezza percorsa dalla macchina.
In base ai dati in possesso, possiamo applicare la formula composta dei trapezi su 14 intervalli di ampiezza
h = 6 secondi. Abbiamo (ponendo v 1 = v(0), v 2 = v(6), . . . , v 13 = v(78), v 14 = v(84)):
³v +v ´
1 14
L=6 + v 2 + v 3 + . . . + v 13 = 3009 metri
2
Possiamo anche applicare la formula di Cavalieri-Simpson, considerando ora 7 intervalli di ampiezza pari
a h = 12 secondi. In tal caso, otteniamo:
L = 2 (v 1 + 4v 2 + 2v 3 + 4v 4 + 2v 5 + . . . + 2v 12 + 4v 13 + v 14 ) = 3010 metri
In questo caso entrambi i risultati sono accettabili.
Se la funzione integranda ha le derivate che sono facili da determinare e da maggiorare, la formula del-
l’errore può essere utile per determinare il numero di sottointervalli su cui applicare una formula composta
di quadratura in modo da ottenere un’approssimazione con un errore minore di una tolleranza prefissata.
R1 2
Esempio 9.4.4 Consideriamo 0 e −x d x. In quanti sottointervalli bisogna suddividere l’intervallo di inte-
grazione per applicare la formula dei trapezi e di Cavalieri-Simpson e ottenere un errore che sia minore di
una tolleranza ² = 10−5 ?
Per i trapezi, l’errore è maggiorato da
max0≤x≤1 | f 00 (x)| (b − a)3
|E t r ap | ≤
12 n2
Per Cavalieri-Simpson si ha
max0≤x≤1 | f I V (x)| (b − a)5
|EC −S | ≤
2880 n4
135
9. I NTEGRAZIONE NUMERICA
2
Da f (x) = e −x abbiamo, per le derivate:
2
f 0 (x) = −2xe −x
2
f 00 (x) = (−2 + 4x 2 )e −x
2
f 000 (x) = (12x − 8x 3 )e −x
2
f I V (x) = (12 − 48x 2 + 16x 4 )e −x
Si trova che il massimo di | f 00 | e | f I V | in [0, 1] è dato dal loro valore in x = 0, quindi abbiamo:
2 1 12 1
|E t r ap | ≤ 2
= 2
|EC −S | ≤ 4
=
12n 6n 2880n 240n 4
Per i trapezi, il primo intero n che verifica la disuguaglianza è n = 130, per Cavalieri-Simpson si ha, invece,
n = 5.
Applicando le formule su 130 intervalli per i trapezi e su 5 intervalli per Cavalieri-Simpson, otteniamo i
risultati:
I t r ap = 0.74682050480289 IC −S = 0.7468249482544
f I V (ξ1 ) b − a 5 f I V (ξ1 )
µ ¶
E1 = − =− (b − a)5
90 2 2880
Suddividiamo ora l’intervallo [a, b] in due sottointervalli e applichiamo la formula composta di Cavalieri-
Simpson. L’errore che otteniamo vale
f I V (ξ2 ) (b − a)5
E2 = −
2880 24
E1
e, supponendo che le derivate quarte della f non siano molto diverse tra loro, si ha E 2 ≈ .
16
L’errore, quindi, diventa 16 volte più piccolo passando dalla formula di Cavalieri-Simpson in un intervallo
alla formula applicata in due sottointervalli.
Sia I il valore esatto dell’integrale e Q 1 e Q 2 i due valori approssimati ottenuti considerando la formula
di Cavalieri-Simpson con n = 1 e n = 2 sottointervalli. Sia ² l’errore, cambiato di segno, che si ha con n = 2,
² = −E 2 ≈ −E 1 /16. Possiamo scrivere
I + ² = Q 2 per n = 2
I + 16² = Q 1 per n = 1
136
9.6. Approssimazione di Romberg
Q 1 −Q 2
²=
15
Quindi
Q 2 −Q 1
I ≈ Q2 +
15
Utilizzando le due approssimazioni Q 1 e Q 2 possiamo approssimare l’integrale esatto con una maggiore ac-
curatezza mediante la formula appena scritta. Questo procedimento prende il nome di estrapolazione di
Richardson. Può essere utilizzato per migliorare l’approssimazione di un integrale ma è basato sull’ipotesi
che le derivate quarte della funzione integranda siano circa uguali e, quindi, va usato con cautela.
I + ² = Am
I + 4² = A m−1
A m − A m−1
Bm = Am + .
3
Per m = 1 si ha:
b−a
A0 = [ f (a) + f (b)] è la formula dei trapezi applicata su un unico intervallo
2
b − a f (a) a +b f (b)
A1 = [ +f( )+ ] è la formula dei trapezi su 2 sottointervalli
2 2 2 2
a +b
f (a) 4 f ( 2 ) f (b)
B 1 = (b − a)[ + )+ ] troviamo la formula di Cavalieri-Simpson!
6 6 6
Si ha dunque che B 1 (e quindi ciascun B m ) corrisponde al valore ottenuto con la formula di Cavalieri-
Simpson. L’errore ottenuto con B m è dunque proporzionale a 1/n 4 . Nel passo successivo, utilizzando i valori
B m , otteniamo la nuova approssimazione data da
B m − B m−1
Cm = Bm + per m ≥ 2
15
Si può dimostrare che C m coincide con la formula di Newton-Cotes con n = 4, dove l’errore è proporzionale
a 1/n 6 e alla derivata sesta di f.
La nuova approssimazione è data da:
C m −C m−1
Dm = Cm + per m ≥ 3
63
137
9. I NTEGRAZIONE NUMERICA
L’errore ora diventa proporzionale a 1/n 8 ma D m non è più un risultato delle formule di Newton-Cotes. Il
procedimento può andare avanti per calcolare E m , F m , etc tenendo presente che al denominatore dobbiamo
mettere il valore 4(d + 1) − 1 dove d è il valore del denominatore della formula precedente.
Il vantaggio dell’approssimazione di Romberg si vede solo ai primi livelli dell’applicazione (in particolare
passando da A m a B m ). Inoltre, a causa della precisione finita con cui sono eseguiti i calcoli, le formule di
Romberg di ordine elevato diventano inefficaci se il risultato iniziale A m è già abbastanza accurato rispetto
alla precisione numerica consentita.
Teorema 9.7.1 (di W. Gautschi) Dato un intero k con 0 < k ≤ n + 1, la formula di quadratura
Z b n
X
f (x)w(x) d x = w i f (x i ) + E i nt ( f )
a i =0
ha grado di precisione (esattezza) d = n + k se e solo se sono soddisfatte entrambe le condizioni (a) e (b):
138
9.7. Introduzione alle formule di quadratura di Gauss
G fa sì che k non possa essere maggiore o uguale a n + 2.R Se fosse infatti k = n + 2, il punto (b) sarebbe:
b
(b) il polinomio dei nodi F (x) soddisfa la relazione a F (x)p(x)w(x)d x = 0 per ogni polinomio p di
grado ≤ k − 1 = n + 1.
Allora, si potrebbe prendere come polinomio p(x) esattamente F (x) (che ha grado n + 1) e, per la
Rb
(b) sarebbe a (F (x))2 w(x)d x = 0: ma questo è un assurdo perchè l’integrale di una funzione positiva
non può essere nullo, e, nel nostro caso, w(x) è positiva e (F (x))2 , essendo il quadrato di un polinomio,
è pure essa una funzione positiva.
Il caso ottimale (il più alto grado di precisione che si può ottenere), si ha per k uguale al valore massimo che
può assumere, vale a dire k = n + 1. In tal caso d = n + k = n + n + 1 = 2n + 1. Si hanno le cosiddette formule
di Gauss.
A seconda della scelta della funzione peso w e dell’intervallo [a, b] abbiamo diverse formule di Gauss.
5 Per definizione, infatti, due funzioni u e v si dicono ortogonali rispetto alla funzione peso w (positiva), se b u(x)v(x)w(x) d x = 0.
R
a
139
9. I NTEGRAZIONE NUMERICA
Rb
Di conseguenza a F (x)p(x)w(x) d x = ni=0 F (x i )p(x i )w i = 0 e quindi il punto (b) è provato.
P
Supponiamo ora che siano vere le condizioni (a) e (b) e dimostriamo che d = n + k (sufficienza). Sia p un
polinomio di grado n +k. Dobbiamo provare che E i nt (p) = 0. Dividiamo il polinomio p per il polinomio F :
possiamo scrivere p(x) = F (x)q(x) + r (x) dove q(x) (quoziente) è un polinomio di grado k − 1 e r (x) (resto) è
un polinomio di grado n. Nel fare l’integrale, abbiamo
Z b Z b Z b
p(x)w(x) d x = q(x)F (x)w(x) d x + r (x)w(x) d x
a a a
Il primo integrale a secondo membro vale zero a motivo dell’ipotesi (b) (q(x) è un polinomio di grado k − 1
e quindi quell’integrale è zero). Il secondo integrale, invece, per la (a) può essere calcolato esattamente
andando ad applicare la formula di quadratura (essendo r di grado n ed essendo la formula interpolatoria
si ha E i nt (r ) = 0 ). Si ha
Z b Z b n
X
p(x)w(x) d x = r (x)w(x) d x = r (x i )w i
a a i =0
Ma r (x i ) = p(x i ) − q(x i )F (x i ) = p(x i ) (essendo F (x i ) = 0). Quindi
Z b Z b Xn
p(x)w(x) d x = r (x)w(x) d x = p(x i )w i
a a i =1
L’errore è dunque zero e la dimostrazione è completata. 4
Da un punto di vista teorico la condizione (a) del teorema permette di calcolare i pesi delle formule di Gauss:
Rb
essendo la formula interpolatoria si ha w i = a L i (x)w(x) d x.
La condizione (b) permette di calcolare i nodi x i della formula (imponendo l’ortogonalità tra F (x) e i
polinomi di grado k = 0, 1, 2, . . . , n si ricava un sistema di n + 1 equazioni nelle incognite dei coefficien-
ti del polinomio F (x). Una volta trovato il polinomio F (x) ricaviamo le radici, che sono appunti i nodi di
integrazione6 .
Le formule di Gauss si possono ricavare mediante interpolazione (detta di Hermite) sui nodi x i contati
ciascuno come nodo doppio nel senso che su ciascun nodo imponiamo la condizione di interpolazione non
solo sulla f ma anche sulla derivata prima della f . Una volta che abbiamo ricavato il polinomio di interpo-
Rb
lazione p(x) (che interpola quindi per ogni nodo sia la f sia la f 0 ) e approssimato a f (x)w(x) d x mediante
Rb
a p(x)w(x) d x, dalla formula che ricaviamo imponiamo che i termini che contengono la derivata prima
siano uguali a zero (questa osservazione è dovuta a Markov, matematico russo, nel 1885).
La formula che otteniamo (considerando che il polinomio interpola la f e la f 0 ) avrà termini del tipo:
Rb Pn Pn 0 G
a f (x)w(x) d x = i =0 w i f (x i ) + i =0 C i f (x i ) + E i nt (x)
6 Ricordiamo che un polinomio di grado n + 1 lo possiamo scrivere come a n+1 + a x n + · · · + a ma possiamo anche dividere
n+1 x n 0
per il coefficiente di grado massimo e scriverlo in forma cosiddetta monica x n+1 + b n x n + b n−1 x n−1 + . . . + b 0 , e avere quindi solo n + 1
coefficienti (b 0 , b 1 , . . . , b n ) : le radici dei due polinomi non cambiano.
140
9.7. Introduzione alle formule di quadratura di Gauss
f (2(n+1)) (ξ) b
Z
E iGnt (x) = (F (x))2 w(x) d x
(2(n + 1))! a
n +1 nodi pesi
2 x 0,1 = ±0.57735026918962576 w 0 = w 1 = 1.0
3 x 0 = −0.77459666924148338 w 0 = 5/9 = 0.5555555556
x1 = 0 w 1 = 8/9 = 0.8888888889
x 2 = 0.77459666924148338 w 2 = 5/9 = 0.5555555556
4 x 0 = −0.86113631159405257 w 0 = 0.3478548451374538
x 1 = −0.33998104358485626 w 1 = 0.6521451548625461
x 2 = 0.33998104358485626 w 2 = 0.6521451548625461
x 3 = 0.86113631159405257 w 3 = 0.3478548451374538
I polinomi di Legendre (e, come essi, anche tutti gli altri polinomi le cui radici sono i nodi delle altre
formule di Gauss) hanno la caratteristica di essere polinomi mutuamente ortogonali (nel senso che presi
due polinomi di Legendre, che chiamiamo ωn (x) e ωm (x), rispettivamente di grado n e m, con n 6= m, si ha
Rb
a ωn (x)ωm (x)w(x) d x = 0).
I polinomi di Legendre (e, come essi, i polinomi delle altre formule di Gauss), si ricavano mediante for-
mule ricorsive, cioè ogni polinomio di Legendre di grado n è legato (mediante una relazione opportuna) ai
polinomi di Legendre di grado n − 1 e n − 2.
G Con w(x) = p(11− x ) e [a, b] = [−1, 1] si hanno le formule di Gauss-Chebychev (prima specie) in
2
quanto i nodipdi integrazione sono le radici dei cosiddetti polinomi di Chebychev di prima specie.
G Con w(x) = (1 − x 2 ) e [a, b] = [−1, 1] si hanno le formule di Gauss-Chebychev (seconda specie) in
quanto i nodi di integrazione sono le radici dei cosiddetti polinomi di Chebychev di seconda specie.
G Con w(x) = (1 − x)α (1 + x)β (per α > −1 e β > −1) e [a, b] = [−1, 1] si hanno le formule di Gauss-Jacobi.
G Con w(x) = x α e −x (per α > −1) e [a, b] = [0, +∞] si hanno le formule di Gauss-Laguerre.
G 2
Con w(x) = e −x e [a, b] = [−∞, +∞] si hanno le formule di Gauss-Hermite.
141
9. I NTEGRAZIONE NUMERICA
Figura 9.5: Funzioni peso per le formule di quadratura di Gauss-Chebycev di prima e seconda specie (a
sinistra e a destra rispettivamente)
Figura 9.6: Funzioni peso per le formule di quadratura di Gauss-Jacobi (con α = 2 e β = 4) e di Gauss-Laguerre
(con α = 2) (a sinistra e a destra rispettivamente)
142
9.8. Esercizi
9.8 Esercizi
Z 0
Esercizio 9.8.1 Sia dato l’integrale I = e −x (x + 1) dx.
−2
(a) Approssimare il valore dell’integrale applicando la formula dei trapezi con n = 5 suddivisioni in parti
uguali dell’intervallo di integrazione.
(b) Trovare una maggiorazione dell’errore commesso e, dopo aver calcolato analiticamente l’integrale
esatto, confrontare tale stima con l’errore esatto.
Svolgimento
(a) Applichiamo la formula dei trapezi con n = 5 suddivisioni dell’intervallo dato. Vale, dunque, h = 0.4. I
punti da considerare e il valore della f (x) = e −x (x + 1), sono:
i xi f (x i )
0 -2 -7.3890561
1 -1.6 -2.97181945
2 -1.2 -0.664023385
3 -0.8 0.445108186
4 -0.4 0.895094819
5 0 1
143
9. I NTEGRAZIONE NUMERICA
f (x 0 ) + f (x 5 )
I t r ap = h( + f (x 1 ) + f (x 2 ) + f (x 3 ) + f (x 4 )) = −2.19606715
2
(b) Per calcolare una maggiorazione dell’errore commesso, dobbiamo calcolare la derivata seconda della
f.
Da f (x) = e −x (x + 1) segue f 0 (x) = −e −x (x + 1) + e −x = −e −x x e f 00 (x) = e −x x − e −x = e −x (x − 1).
Poichè f 00 (x) è sempre negativa nell’intervallo di integrazione e a noi interessa la funzione valore
assoluto della f 00 (x), studiamo la funzione g (x) = | f 00 (x)| = e −x (1 − x). Si ha che g 0 (x) = e −x (x − 2) < 0
in [−2, 0], quindi g è decrescente e ha valore massimo per x = −2. Si ha dunque che M = max | f 00 (x)| =
| f 00 (−2)| = 22.1671682968
|(b − a)3 |
Quindi |E t r ap | ≤ M = 0.591124488
12 · 52
Analiticamente, è facile calcolare l’integrale esatto (per parti):
Z 0 Z 0
I= f (x) dx = −e −x (x + 1)|0−2 + e −x dx = −e −x (x + 2)|0−2 = −2
−2 −2
Svolgimento
(a) Suddividendo l’intervallo di integrazione [0, 2] in n = 4 parti si trova un passo h = 2/4 = 1/2 = 0.5.
La formula dei trapezi è:
b − a f (a) + f (b)
IT = ( + f (x 1 ) + f (x 2 ) + f (x 3 ))
n 2
f (0) + f (2)
= 0.5( + f (0.5) + f (1) + f (1.5))
2
−0.5 − 1
= 0.5( − 0.571428571 − 0.666666667 − 0.8)
2
= −1.39404762
f 00 (ξ) (b − a)3
(b) Consideriamo la formula dell’errore: E = −
12 n2
2 0 −2 00 4
Da f (x) = segue f (x) = e f (x) = .
x −4 (x − 4)2 (x − 4)3
Per maggiorare l’errore dobbiamo considerare che vale
max0≤x≤2 | f 00 (x)| (b − a)3
|E | ≤ , da cui dobbiamo calcolare M = max0≤x≤2 | f 00 (x)|.
12 n2
144
9.8. Esercizi
4
La funzione (x −4)3 è continua, crescente e sempre negativa nell’intervallo [0, 2]. Quindi | |=
(x − 4)3
4 4
: osserviamo il cambiamento al denominatore. Poniamo g (x) = . Risulta g 0 (x) =
(4 − x)3 (4 − x)3
12
> in [0, 2], quindi la g è crescente e ha valore massimo per x = 2. Perciò M = max0≤x≤2 | f 00 (x)| =
(4 − x)4
4 M 23 1
| f 00 (2)| = 3 = 1/2 = 0.5. Si ha allora la maggiorazione dell’errore |E | ≤ 2
= = 0.0208333333
2 12 4 48
(c) L’integrale esatto si calcola facilmente:
Z 2 2
I= d x = 2 ln (|x − 4|)|20 = 2 ln (| − 2|) − 2 ln (| − 4|) = 2 ln (1/2) = ln (1/4) − 1.386294361
0 x −4
L’errore esatto commesso con la formula dei trapezi, in valore assoluto, è |I − I T | = 0.00775325793
M 23
(d) Perchè la maggiorazione dell’errore sia minore della tolleranza ² = 10−5 deve essere |E | ≤ ≤ 10−5
12 n 2
M 3 5 105
cioè n 2 ≥ 2 10 = = 33333.333333. Quindi n > 182.574186, vale a dire n = 183.
12 3
Svolgimento
(a) Applichiamo la formula di Cavalieri-Simpson su tutto l’intervallo, considerando che l’ampiezza
dell’intervallo è b − a = 0.5 e h = 0.25
0.25
Q1 = ( f (0) + 4 f (0.25) + f (0.5)) = 0.523823565
3
Si ha, infatti, f (0) = 1, f (0.25) = 1.03279556 e f (0.5) = 1.15470054.
Suddividendo l’intervallo in due parti uguali, abbiamo h = 0.125, da cui i punti: x 0 = a = 0, x 1 =
0.125, x 2 = 0.25, x 3 = 0.375, e x 4 = b = 0.5.
h
Q2 = ( f (x 0 ) + 4( f (x 1 ) + 4 f (x 3 )) + 2 f (x 2 ) + f (x 4 )) = 0.523616326
3
dove f (0.125) = 1.00790526, f (0.375) = 1.07871978 (essendo già in possesso degli altri valori, calcolati
per Q 1 )
Q 2 −Q 1
(b) La formula di estrapolazione di Richardson è: Q 3 = Q 2 + da cui ricaviamo Q 3 = 0.5236025101
15
(c) Analiticamente l’integrale esatto è:
Z 0.5 1
I= p d x = arcsin (x)|0.5
0 = π/6 − 0 = 0.523598775
0 1 − x2
L’errore esatto commesso con l’estrapolazione di Richardson, in valore assoluto, è: |I −Q 3 | = 3.7351·
10−6 .
145
9. I NTEGRAZIONE NUMERICA
R5 p
Esercizio 9.8.4 Sip calcoli I = 2 sinp ( x) d x utilizzando il metodo di Gauss-Legendre con 3 punti di
appoggio (x 1 = − (3/5), x 2 = 0, x 3 = (3/5); w 1 = w 3 = 5/9, w 1 = 8/9).
Svolgimento
Applichiamo la formula, ricordandoci che dobbiamo utilizzarla non in [2, 5] ma in [−1, 1]. Considerando
b−a
che la trasformazione dall’intervallo [2, 5] all’intervallo [−1, 1] porta al cambiamento di variabili x = t+
2
b +a 5−2 5+2 3 7 3
= t+ = t + si ha d x = d t . La formula di Gauss-Legendre deve essere applicata sui nodi
2 2 2 2 2 2
3 7
trasformati dati da x i + . Perciò abbiamo
2 2
µ ¶
3 3 7 3 7 3 7
IG = w 1 f ( x1 + ) + w 2 f ( x2 + ) + w 3 f ( x3 + )
2 2 2 2 2 2 2
¡ ¢
= 1.5 (5/9) f (−1.161895004 + 3.5) + (8/9) f (3.5) + (5/9) f (1.161895004 + 3.5)
= 1.5 (0.5550723689 + 0.8491794877 + 0.4621443545) = 2.799594317
146
CAPITOLO
10
E QUAZIONI ALLE DERIVATE ORDINARIE
L’universo è un’equazione
differenziale.
10.1 Introduzione
All’inizio del ’900, van der Pol1 studiò fenomeni non lineari e propose l’equazione differenziale
1 Balthasar van der Pol (1889-1959) fu un fisico e matematico olandese. Nel 1916 lavorò per un anno con l’ingegnere John Ambrose
Fleming a Londra (Fleming aveva già inventato il diodo nel 1904). Si trasferì successivamente a Cambridge e iniziò una collaborazione
con John Joseph Thomson al Cavendish Laboratory (Thomson aveva scoperto l’elettrone nel 1897). Qui divenne amico di Edward Ap-
pleton che, nel 1947, ricevette il premio Nobel per la fisica per i suoi contributi alla conoscenza della ionosfera – studi fatti insieme a
van der Pol. La loro collaborazione riguardò anche lo studio di fenomeni non lineari usando circuiti triodi per verificare le loro teorie.
Quando van del Pol rientrò in Olanda, continuò a occuparsi di ottica, elettromagnetismo, onde radio e fisica atomica. Il nome di van
der Pol è associato con l’equazione differenziale che porta il suo nome. Questa equazione apparve per la prima volta sul suo articolo On
relaxation oscillation pubblicato sulla rivista Philosophical Magazine nel 1926.
147
10. E QUAZIONI ALLE DERIVATE ORDINARIE
Problemi in cui abbiamo equazioni alle derivate ordinarie di ordine più elevato possono essere trasformati
in sistemi equivalenti di equazioni del primo ordine.
Esempio 10.2.2 La seconda legge del moto di Newton dice che la forza F è uguale al prodotto della massa
m per l’accelerazione a: F = ma. Questa equazione è una ODE del secondo ordine in quanto l’accelerazione
a è data da a = y 00 , dove y è la coordinata della posizione. L’ODE può essere riscritta come:
y 00 = F /m
Definendo u 1 = y e u 2 = y 0 si ha il sistema (equivalente all’equazione di prima) di due equazioni del primo
ordine di ODE: µ 0¶ µ ¶
u1 u2
0 =
u2 F /m
Per risolvere il sistema, possiamo usare metodi che vanno bene per risolvere equazioni differenziali del pri-
mo ordine. La prima componente della soluzione u 1 corrisponde alla posizione y dell’equazione da cui
siamo partiti. La seconda componente u 2 fornisce la velocità y 0 .
148
10.3. Metodo di Eulero esplicito
Sistemi di
Sistemi del primo ordine di ODE hanno la forma ODE
y0 (t ) = f(t , y)
n n+1 dy n
dove y : R −→ R con y = (y 1 y 2 . . . y n ), f : R −→ R e y0 (t ) =
denota la derivata rispetto a t (per cui la
dt
d y i (t )
i -sima componente del vettore derivata è data da y i0 (t ) = ). La funzione f è assegnata e noi vogliamo
dt
determinare il vettore di funzioni y che soddisfa l’ODE.
Per semplicità noi studieremo il caso di una singola equazione scalare, n = 1. Ma l’approccio è del tutto
simile nel caso di sistemi di equazioni del primo ordine.
Sia data l’ODE
y 0 = f (t , y(t )) a ≤t ≤b
y(a) = y a .
Per risolvere questa ODE discretizziamo l’intervallo [a, b] in n + 1 punti, equidistanti per semplicità: t i =
a + i h, h = 0, 1, . . . , n, con h = (b − a)/n.
Il passo di discretizzazione (temporale se t assume il significato della variabile temporale) è dunque h.
Nelle applicazioni pratiche, il passo h è variabile (cioè i punti non sono equidistanti), tuttavia, per capire
meglio come funzionano i metodi, noi useremo sempre un passo h costante.
Sia y(t ) la soluzione esatta del nostro problema a valori iniziali. Allora y(t i ) è il valore esatto della
soluzione calcolata nel punto t i .
Indichiamo invece con y i il valore approssimato al tempo t i che ricaviamo applicando un metodo
numerico che risolve il problema proposto.
(t − t i )2 00
y(t ) = y(t i ) + (t − t i )y 0 (t i ) + y (ξi )
2
(t − t i )2 00
La quantità y (ξi ) è il resto della formula di Taylor con ξi un punto opportuno nel segmento di
2
estremi t e t i .
Prendiamo come t il valore t i + h vale a dire t i +1 , da cui si ha t − t i = t i +1 − t i = h. Sostituendo si ottiene:
h 2 00
y(t i +1 ) = y(t i ) + h y 0 (t i ) + y (ξi )
2
Esplicitando y 0 (t i ) rispetto agli altri termini si ha:
y(t i +1 ) − y(t i ) h 00
y 0 (t i ) = − y (ξi )
h 2
Ora si sostituisce il valore trovato per y 0 (t i ) nella ODE y 0 = f (t , y(t )) per t = t i :
y(t i +1 ) − y(t i ) h 00
− y (ξi ) = f (t i , y(t i ))
h 2
2 Leonhard Euler (1707-1783) fu un matematico svizzero. Fu studente di Johann Bernoulli che comprese le sue grandi potenzialità
e favorì i suoi studi. Eulero è noto soprattutto per i suoi contributi nel campo della geometria, della teoria dei numeri, delle equazioni
differenziali, del calcolo delle variazioni. È lui che introdusse il simbolo f (x) per indicare le funzioni, e per la base naturale, i per la
radice quadrata di −1, di π, il simbolo di sommatoria e altri ancora.
P
149
10. E QUAZIONI ALLE DERIVATE ORDINARIE
h 00
Trascurando il termine y (ξi ) non abbiamo più i valori della soluzione esatta, ma otterremo i valori della
2
soluzione approssimata. Scriviamo dunque:
y i +1 − y i
= f (t i , y i )
h
La formula è di tipo esplicito perchè per passare dal livello i al livello i + 1 sfruttiamo i dati che già
conosciamo del livello i .
Si parte infatti da y 0 = y(t 0 ) = y(a) = y a e si ricava:
y 1 = y 0 + f (t 0 , y 0 )
y 2 = y 1 + f (t 1 , y 1 )
.. ..
.=.
Un altro Si arriva alla stessa formula integrando l’ODE e approssimando l’integrale della f mediante il valore in
approccio f (t 0 , y(t 0 )): da y 0 = f (t , y(t )) integrando ambo i membri da t 0 a t , otteniamo
Z t dy
Z t Z y(t ) Z t
dt = f (t , y(t )) d t =⇒ dy = f (t , y(t )) d t
t0 dt t0 y0 t0
Rt
Al secondo membro, approssiamo t0 f (t , y(t )) d t mediante il valore (t − t 0 ) f (t 0 , y(t 0 )) (approssimiamo la f
mediante la retta f (t 0 , y(t 0 ))).
Abbiamo:
y(t ) = y 0 + (t − t 0 ) f (t 0 , y 0 )) + errore della formula di quadratura.
Per t = t 1 , numericamente: y 1 = y 0 + h f (t 0 , y 0 )).
Ai passi successivi: y i +1 = y i + h f (t i , y i ))
Esempio 10.3.1 Supponiamo di applicare il metodo di Eulero esplicito alla ODE y 0 = −y con passo h a
partire dal punto iniziale t 0 = 0 e avanziamo al tempo t 1 = t 0 + h
y 1 = y 0 + h f (t 0 , y 0 ) = y 0 − h y 0 = (1 − h)y 0
Il valore y 1 che otteniamo è affetto da errore: y 1 6= y(t 1 ) Per esempio, se per t 0 si ha y 0 = 1, la soluzione esatta
è y(t ) = e −t . Per h = 0.5, si ha y 1 = 0.5 mentre y(0.5) = e −0.5 ≈ 0.60653
Interpretazione Da un punto di vista geometrico (si veda la Figura 10.1), il valore in t i +1 è approssimato utilizzando il valore
geometrica della retta la cui pendenza è data da f (t i , y i ): è come se ad ogni passo cercassimo di risolvere il problema a
valori iniziali:
y 0 (t ) = f (t , y(t ))
y(t i ) = y i
per cui il valore che otteniamo per il tempo t i +1 è tangente alla traiettoria della soluzione di questo IVP.
150
10.4. Metodo di Eulero implicito
Figura 10.1: Interpretazione geometrica del metodo di Eulero esplicito. Si è considerato il problema y 0 = −y
con y(0) = 1 la cui soluzione esatta è y(t ) = e −t . I valori numerici ottenuti dal metodo di Eulero esplicito sono
cerchiati e si trovano sulla linea spezzata che li interpola. La linea spezzata è tangente, all’inizio di ogni passo,
alla traiettoria che passa per il corrispondente punto, soluzione del problema y 0 = −y con y(t i ) = y i .
(t − t i +1 )2 00
y(t ) = y(t i +1 ) + (t − t i +1 )y 0 (t i +1 ) + y (ξi )
2
Per t = t i , si ha t − t i +1 = t i − t i +1 = t i − (t i + h) = −h. Sostituendo, abbiamo:
h 2 00
y(t i ) = y(t i +1 ) − h y 0 (t i +1 ) + y (ξi )
2
Otteniamo quindi
y(t i +1 ) − y(t i ) h 00
y 0 (t i +1 ) = + y (ξi )
h 2
Andando a sostituire nella ODE al tempo t i +1 , si ha :
y(t i +1 ) − y(t i ) h 00
+ y (ξi ) = f (t i +1 , y(t i +1 ))
h 2
h 00
Trascurando il termine del resto di Taylor y (ξi ) abbiamo:
2
y i +1 − y i
= f (t i +1 , y i +1 ))
h
151
10. E QUAZIONI ALLE DERIVATE ORDINARIE
La differenza rispetto alla formula esplicita è che la f è valutata non più al tempo t i ma al tempo t i +1 Quindi
il calcolo di y i +1 dipende implicitamente da y i +1 stesso! La valutazione di y i +1 diventa quindi più laboriosa
e complicata (se si ha un’equazione non lineare in y i +1 , la si risolve tramite un metodo di punto fisso o di
Newton-Raphson). In termini di accuratezza si hanno risultati migliori.
Esempio 10.4.2 Si abbia l’equazione y 0 = −y 3 con condizione iniziale y(0) = 1. Usando il metodo di Eulero
implicito con passo h = 0.5, per ricavare y 1 otteniamo l’equazione implicita
y 1 = y 0 + h f (t 1 , y 1 ) = 1 − 0.5y 13
Questa equazione non lineare in y 1 può essere risolta mediante metodo di punto fisso (x = g (x) = 1 − 0.5x 3 )
oppure utilizzando il metodo di Newton-Raphson per F (x) = 0 con F (x) = x −1+0.5x 3 ) . L’approssimazione
iniziale per ottenere y 1 può essere o la soluzione al passo precedente, y 0 , oppure usare il metodo di Eulero
esplicito, che dà y 1 = y 0 − 0.5y 03 = 0.5. Otteniamo, come y 1 il valore finale y 1 ≈ 0.7709.
y i +1 = y i + h f (t i , y i ) = y i + h(−y i2 ) = y i − h y i2
Partendo da y 0 = 1 si ricava:
y 1 = 1 − 0.1(12 ) = 0.9
y 2 = 0.9 − 0.1(0.92 ) = 0.819
1
Per confronto, calcoliamo la soluzione esatta y(t ) = , ottenendo:
t +1
y(t 1 ) = y(0.1) = 1/(0.1 + 1) = 0.9090909090
y(t 2 ) = y(0.2) = 1/(0.2 + 1) = 0.8333333333
y i +1 = y i + h f (t i +1 , y i +1 ) = y i − h y i2+1
Per ricavare y 1 la formula diventa:
y 1 = y 0 + h f (t 1 , y 1 ) = 1 − 0.1(y 12 )
152
10.4. Metodo di Eulero implicito
Abbiamo un’equazione non lineare in y 1 . Per trovare y 1 , possiamo pensare di applicare lo schema di punto
fisso alla funzione g (y) = 1 − 0.1(y 2 ) partendo da y (0) = y 0 = 1, in quanto y 1 = g (y 1 ) è punto fisso per la
funzione g . Applichiamo tre passi dello schema di punto fisso:
y (1) = g (y (0) ) = 1 − 0.1(12 ) = 0.9
y (2) = g (y (1) ) = 1 − 0.1(0.92 ) = 0.919
y (3) = g (y (2) ) = 1 − 0.1(0.9192 ) = 0.9155439
Se prendiamo y (3) come approssimazione di y 1 ricaviamo y 1 = 0.9155439 (per confronto, il valore esatto è
0.90909090).
Calcoliamo ora y 2 :
y 2 = y 1 + h f (t 2 , y 2 ) = 0.9155439 − 0.1(y 22 )
Ora la funzione di punto fisso diventa g (y) = 0.9155439 − 0.1(y 2 ). Applichiamo lo schema di punto fisso
partendo da y (0) = y 1 = 0.9155439.
y (1) = g (y (0) ) = 0.9155439 − 0.1(0.91554392 ) = 0.8317218367
y (2) = g (y (1) ) = 0.9155439 − 0.1(0.83172183672 ) = 0.8463677786
y (3) = g (y (2) ) = 0.9155439 − 0.1(0.84636777862 ) = 0.8439100583
Quindi y 1 = 0.9161779367.
Al secondo passo, lo schema di punto fisso è dato dalla funzione g (y) = y 1 − h(y 2 ) = 0.9161779367 − 0.1y 2 .
Come approssimazione iniziale prendiamo y (0) = y 1 + h f (t 1 , y 1 ) = g (y 1 ) = 0.8322397355. Si ha:
Ricaviamo y 2 = 0.8448681324.
153
10. E QUAZIONI ALLE DERIVATE ORDINARIE
h
y i +1 − y i = [ f (t i , y i ) + f (t i +1 , y i +1 )]
2
h
Si ha la formula di Crank-Nicolson: y i +1 = y i + [ f (t i , y i ) + f (t i +1 , y i +1 )]
2
Altro
approccio La stessa formula la si può ricavare prendendo la media aritmetica delle formule di Eulero esplicito e
implicito:
y i +1 − y i = h f (t i , y i )
y i +1 − y i = h f (t i +1 , y i +1 )
h h
y i +1 − y i = [ f (t i , y i ) + f (t i +1 , y i +1 )] =⇒ y i +1 = y i + [ f (t i , y i ) + f (t i +1 , y i +1 )]
2 2
Esempio 10.5.1 Lo stesso esempio di prima (y 0 = −y con y(0) = 1) risolto con Crank-Nicolson dà: y i +1 =
h
y i + [−y i − y i +1 )] cioè
2
h h 2−h
µ ¶
(1 + )y i +1 = (1 − )y i =⇒ (2 + h)y i +1 = (2 − h)y i =⇒ y i +1 = yi
2 2 2+h
Per h = 0.5, confrontiamo i valori ottenuti dai metodi di Eulero esplicito, implicito e Crank-Nicolson, con la
soluzione esatta:
ti y(t i ) y i Eul. Espl. y i Eul. Impl. y i C-N
0.0 1.000000 1.0000000 1.000000 1.000000
0.5 0.606531 0.5000000 0.666667 0.600000
1.0 0.367879 0.2500000 0.444444 0.360000
1.5 0.223130 0.1250000 0.296296 0.216000
2.0 0.135335 0.0625000 0.197531 0.129600
2.5 0.082085 0.0312500 0.131687 0.077760
3.0 0.049787 0.0156250 0.087791 0.046656
3.5 0.030197 0.0078125 0.058528 0.027994
4.0 0.018316 0.0039062 0.039018 0.016796
3 John Crank (1916-2006) è stato un matematico inglese che si è dedicato soprattutto allo studio di soluzioni numeriche di equazioni
alle derivate parziali, in particolare di problemi di conduzione del calore. È noto soprattutto per il lavoro svolto con Phyllis Nicolson.
Phyllis Nicolson (1917-1968) è stata una matematica inglese. Negli anni della seconda guerra mondiale lavorò sulla teoria del
magnetron. È nota, appunto, per il metodo di Crank-Nicolson.
154
10.6. Studio dell’errore
y(t i +1 ) − y(t i ) h
di = − f (t i , y(t i )) = y 00 (ξi ) = O (h)
h 2
Questa quantità ci dice di quanto la soluzione esatta “fallisce” nel soddisfare la relazione della formula di
Eulero esplicito e rappresenta l’errore di troncamento locale.
εi = y(t i ) − y i .
Ci aspettiamo che sia dello stesso ordine di grandezza dell’errore di troncamento locale.
Definizione 10.6.2 Per effetto dell’arrotondamento, al tempo t i al posto di y i otteniamo il valore arrotondato
y i . Si definisce errore totale di arrotondamento la quantità:
εi = y i − y i
Definizione 10.6.3 L’errore globale dello schema numerico è dato dal contributo dell’errore totale di
troncamento e dell’errore totale di arrotondamento
²i = y(t i ) − y i = εi + εi
Gli errori di arrotondamento nell’approssimare la derivata prima di una funzione si comportano come
1
O ( ) (si veda l’esempio fatto sulla propagazione degli errori a pag. 29). Tuttavia questo aspetto diventa se-
h
condario nella risoluzione delle ODE sia perchè il passo h nelle applicazioni non è mai troppo (esagerata-
mente) piccolo per ragioni di efficienza sia perchè è la y e non la y 0 la funzione che dobbiamo approssimare.
Inoltre, nell’eseguire i calcoli in doppia precisione (come si fa nei moderni linguaggi di programmazione),
l’aspetto dovuto all’arrotondamento si vede poco rispetto ad altri fenomeni che influenzano la propagazione
degli errori.
155
10. E QUAZIONI ALLE DERIVATE ORDINARIE
G Nel metodo di Crank-Nicolson (derivando la formula dai trapezi e includendo il termine dell’errore):
h f 00 (ξi , τi ) 3
y(t i +1 ) − y(t i ) = [ f (t i , y(t i )) + f (t i +1 , y(t i +1 ))] − h
2 12
dove ξi e τi sono opportuni punti. Ma f = y 0 da cui f 0 = y 00 e f 00 = y 000 .
Perciò
h y 000 (ξi ) 3
y(t i +1 ) − y(t i ) = [ f (t i , y(t i )) + f (t i +1 , y(t i +1 ))] − h
2 12
y(t i +1 ) − y(t i ) 1 y 000 (ξi ) 2
di = − [ f (t i , y(t i )) + f (t i +1 , y(t i +1 ))] = − h = O (h 2 )
h 2 12
Esempio 10.8.1 Vediamo come, fissato un certo istante t , possiamo fare tendere h a zero e far crescere i
all’infinito in modo che t 0 + i h sia sempre uguale a t . Sia t 0 = 0 e t = 0.5:
h i ih
0.5 1 0.5
0.25 2 0.5
0.125 4 0.5
0.0625 8 0.5
.. .. ..
. . .
2.4414e-4 2048 0.5
Definizione 10.8.2 Un metodo si dice stabile se l’errore iniziale si mantiene limitato al crescere di i (per i → ∞):
|²i | ≤ M |²0 |
con M costante positiva.
y 1 = y 0 + h f (t 0 , y 0 ) = y 0 − h y 0 = (1 − h)y 0
y 2 = y 1 + h f (t 1 , y 1 ) = y 1 − h y 1 = (1 − h)y 1
..
.
y i = y i −1 + h f (t i −1 , y i −1 ) = y i −1 − h y i −1 = (1 − h)y i −1
156
10.8. Convergenza e stabilità
y 1 = (1 − h)y 0
y 2 = (1 − h)y 1 = (1 − h)2 y 0
..
.
y i = (1 − h)y i −1 = (1 − h)i y 0
1 ln (1 − h)
α
Ricordiamo la proprietà per la quale x α = e ln (x ) = e α ln (x) . Perciò: (1 − h) h = e ln (1−h)
(1/h)
=e h
Quando facciamo il limite per h → 0 e per i → +∞ consideriamo che, per il teorema dell’ Hôpital, vale
ln (1 − h) −1
lim = lim = −1
h→0 h h→0 1 − h
ln (1 − h)
Di conseguenza limh→0 e h = e −1
Allora
1 t
lim y i = lim y 0 (1 − h)i = lim y 0 (1 − h) h = y 0 e −t = y(t )
h→0 h→0 h→0
i →+∞ i →+∞ i →+∞
In questo modo abbiamo provato che il metodo converge. Il discorso si ripete in maniera del tutto simile,
per λ 6= 1.
157
10. E QUAZIONI ALLE DERIVATE ORDINARIE
Quindi
y0
y1 =
(1 + hλ)
y1 y0
y2 = =
(1 + hλ) (1 + hλ)2
y2 y0
y3 = =
(1 + hλ) (1 + hλ)3
..
.
y i −1 y0
yi = =
(1 + hλ) (1 + hλ)i
In tal caso
1 −i h
y0
lim y i = lim = lim y 0 (1 + hλ)−i = y 0 (1 + hλ) h = y 0 e −t λ = y(t )
h→0 h→0 (1 + hλ)i h→0
i →+∞ i →+∞ i →+∞
(i passaggi sono del tutto simili a quelli visti per Eulero esplicito).
Abbiamo provato la convergenza.
i h t
¶1 ¶1
¶i
2 − hλ hλ hλ
µ µ µ
2 − h 2 − h
= =
2 + hλ 2 + hλ 2 + hλ
Ma
¶1 1 2 − hλ
2 − hλ h
µ
ln ( )
=e h 2 + hλ
2 + hλ
158
10.8. Convergenza e stabilità
Nel fare il limite per h → 0 e i → +∞ della quantità che si trova all’esponente, applichiamo l’Hôpital e
2 − hλ −λ(2 + hλ) − (2 − hλ)λ −4λ
ricordiamo che la derivata di vale = :
2 + hλ (2 + hλ)2 (2 + hλ)2
2 − hλ
ln ( )
lim 2 + hλ = lim 2 + hλ −4λ = lim −4λ
= −λ
h→0 h h→0 2 − hλ (2 + hλ)2 h→0 (2 + hλ)(2 − hλ)
i →+∞ i →+∞ i →+∞
Quindi
i h
¶1
¶i
2 − hλ 2 − hλ h
µ µ
−t λ
lim y i = lim y 0 = lim y 0 = y0e = y(t )
h→0 h→0 2 + hλ h→0 2 + hλ
i →+∞ i →+∞ i →+∞
La convergenza è provata.
Esempio 10.8.2 Consideriamo il metodo di Eulero esplicito e applichiamolo all’equazione test. Sappiamo
che y i +1 = y i + hλy i .
Per la soluzione esatta, sappiamo che vale y(t i +1 ) = y(t i ) + hλy(t i ) + hd i (con d i l’errore di troncamento
locale).
Sottraendo la prima equazione dalla seconda abbiamo
²i +1 = ²i + hλ²i + hd i
h
Considerato che d i = y 00 (ξi ) e che, per studiare la stabilità, h è fissato mentre i tende a +∞, il termine hd i
2
non influisce sull’andamento dell’errore e possiamo trascurarlo. Si ha allora la relazione:
²i +1 = ²i + hλ²i
Ricaviamo ²i = ²0 (1 + hλ)i .
Il ragionamento da fare è lo stesso che abbiamo fatto in precedenza e troviamo gli stessi risultati. Dobbiamo
infatti verificare quando ²i tende a zero per i che tende a +∞. . .
159
10. E QUAZIONI ALLE DERIVATE ORDINARIE
Figura 10.2: Confronto dei metodi di Eulero esplicito, implicito e Crank-Nicolson sull’equazione test y 0 = −y,
prendendo come h il valore h = 2 (a sinistra) e h = 0.5 (a destra).
10.9 Esercizi
Esercizio 10.9.1 Studiare la stabilità del metodo di Eulero esplicito applicato all’equazione differenziale
e −2t + 1
y 0 = −2y + 1, con y(0) = 1 (soluzione esatta y(t ) = )
2
Svolgimento
Per provare la stabilità del metodo dobbiamo verificare che l’errore iniziale si mantiene limitato per valori
crescenti del tempo.
Il metodo di Eulero esplicito applicato all’ODE del problema diventa
y i +1 = y i + h(−2y i + 1) = (1 − 2h)y i + h
²i +1 = (1 − 2h)²i + hd i
160
CAPITOLO
11
I NTRODUZIONE AL FORTRAN 77
Zoolander
161
11. I NTRODUZIONE AL FORTRAN 77
compi l at or e
Programma sorgente −−−−−−−−−→ Programma eseguibile
162
11.3. Problemi e Algoritmi
Notiamo l’ordine dei comandi. L’importante è che la scrittura -o sia immediatamente precedente il nome
del file eseguibile!
Possiamo scrivere anche
prova
oppure
./prova
a seconda del calcolatore.
Altri tipi di compilatore sono f77, gfortran.
163
11. I NTRODUZIONE AL FORTRAN 77
o parte di un problema.6
Un algoritmo si può paragonare ad una ricetta di cucina: la ricetta consiste di due parti
G la lista degli ingredienti
G la sequenza dei passi da fare per realizzare la ricetta.
Nel realizzare una ricetta si possono avere problemi nel cercare alcuni ingredienti. Una parte dell’esecuzione
richiederà poco tempo, altre parti richiederanno più tempo. Alcuni passi non richiedono che si segua un
certo ordine, altri passi richiedono che si mantenga l’ordine scritto sulla ricetta. . . Le stesse analogie troviamo
in un algoritmo.
6 La parola algoritmo è entrata in uso negli anni ’50 in sostituzione di algorismo, termine con cui si indicava il processo di calcolo
utilizzando i numeri arabi. Il termine algoritmo deriva dal nome di “al-Khwarizmi”, importante matematico arabo del nono secolo grazie
al quale l’Europa imparò ad usare i numeri arabi, oltre alla notazione in base 10. Le procedure che permettevano di effettuare calcoli in
notazione decimale presero il nome di algorismi o algoritmi. Anche la parola algebra viene da questo matematico e, in particolare, dalla
sua opera “Al-mukhtasar fi hisab al-jabr wa al-muqabala”.
Nel medioevo (e forse anche per qualche studente di oggi!!!), si pensava che questa parola derivasse dal greco algiros (panico, dolore)
e arithmos (numero).
164
11.6. Le variabili
11.6 Le variabili
Scriviamo ora un programma più complicato
program a r e a t r i a
C programma per c a l c o l a r e l ’ area di un t r i a n g o l o
C dando in input i v a l o r i d e l l a base e d e l l ’ a l t e z z a
i m p l i ci t none
real * 8 a , b , area
write ( * , * ) ’ base a ’
read ( * , * ) a
write ( * , * ) ’ base ’ , a
write ( * , * ) ’ a l t e z z a b ’
read ( * , * ) b
write ( * , * ) ’ a l t e z z a ’ , b
area =( a * b ) * 0 . 5
write ( * , * ) ’ area del triangolo ’ , area
stop
end
G L’istruzione implicit none dice che nessuna variabile può essere dichiarata implicitamente: dobbiamo
dichiarare tutte le variabili che utilizziamo all’interno del programma!
G Introduciamo tre variabili di tipo reale in doppia precisione, mediante real*8 a,b,c.
7 Questo limite è dovuto al fatto che fino alla fine degli anni settanta, la programmazione veniva fatta utilizzando schede per-
forate, dei cartoncini rettangolari di dimensione standard, ciascuna delle quali era suddivisa in un numero fisso di colonne e righe
(generalmente 80 colonne e 12 righe).
165
11. I NTRODUZIONE AL FORTRAN 77
G Con read(*,*) a si impone al calcolatore di prendere un valore e memorizzarlo nella variabile a, e que-
sto valore lo si dà tramite tastiera. Analogamente potremmo scrivere read(5,*) a : il numero 5 indica
che l’acquisizione dei dati avviene da tastiera.
G Prima dell’istruzione di read c’è una write che ci indica quale valore dobbiamo mettere: è importante
altrimenti vedremmo che l’elaboratore si mette in attesa di un valore e rimane così fino a quando non
lo riceve. Ma se noi non sappiamo che valore dargli, possiamo aspettare anche ore. . . . (vedere cosa
succede togliendo le istruzioni di write!)
G Una volta dati i valori di input, si effettua un’istruzione di assegnazione: si prende il valore memorizzato
nella variabile a lo si moltiplica per il valore di b e per 0.5 e il risultato viene memorizzato in una nuova
variabile chiamata area. Il simbolo * è il simbolo di moltiplicazione.
G Quando effettuiamo un’assegnazione, il valore contenuto nella variabile a sinistra del segno = viene
perso. Nel nostro caso, in area non era memorizzato nessun valore, ma se avessimo posto in area un
qualche valore iniziale, esso andrebbe perso perchè sostituito dall’operazione a*b*0.5. I valori di a e
b non cambiano.
G Nel momento in cui viene lanciato il programma, il valore delle variabili è incognito. Mediante tastiera,
noi diamo i valori ad a e b. Mediante assegnazione, diamo il valore ad area. Una volta terminata
l’esecuzione del programma, il valore delle variabili viene perso. Perciò ci facciamo stampare il loro
valore prima dell’istruzione di stop. torna ad essere incognitoo
G Osserviamo che in FORTRAN una variabile può essere scritta con i caratteri maiuscoli o minuscoli
senza distizioni: XOLD è la stessa cosa di xold o XoLd.
166
11.9. I predicati elementari
∗∗ elevamento a potenza
∗ moltiplicazione
/ divisione
+ addizione
− sottrazione
Tabella 11.2: Operazioni aritmetiche
usati per ciascuna di queste operazioni). Quando due operatori hanno la stessa priorità vengono eseguite
le operazioni partendo da sinistra e andando verso destra. Tuttavia, quando le espressioni sono abbastan-
za complicate e c’è il rischio di non capire bene quali operazioni vanno fatte prima e quali dopo, conviene
mettere sempre le parentesi.
In FORTRAN ci sono già molte funzioni matematiche che possiamo utilizzare per i nostri programmi. In
Tabella 11.3, ne vediamo elencate alcune.
167
11. I NTRODUZIONE AL FORTRAN 77
Tabella 11.4: Operatori logici ( È la stessa cosa scrivere .GT. o .gt. .GE. o .ge. e così via.)
Riassumendo
G Negare un predicato falso dà come risultato un predicato vero.
G Negare un predicato vero dà come risultato un predicato falso.
G Congiungere (con .and.) due predicati veri dà come risultato un predicato vero.
G Congiungere (con .and.) due predicati falsi dà come risultato un predicato falso.
168
11.9. I predicati elementari
G Congiungere (con .and.) due predicati, uno vero ed uno falso, dà come risultato un predicato falso.
G Disgiungere (con .or.) due predicati veri dà come risultato un predicato vero.
G Disgiungere (con .or.) due predicati falsi dà come risultato un predicato falso.
G Disgiungere (con .or.) due predicati, uno vero ed uno falso, dà come risultato un predicato vero.
Importanti sono da ricordare le regole di De Morgan. Dati due predicati P1 e P2
program p r e d i c a t i l o g i c i
C programma di esempio s u l l e proposizioni l o g i c h e
i m p l i ci t none
real * 8 a , b , c
l o g i c a l p1 , p2 , p
write ( * , * ) ’ s c r i v i i l valore di a ’
read ( * , * ) a
write ( * , * ) ’ a= ’ , a
write ( * , * ) ’ s c r i v i i l valore di b ’
read ( * , * ) b
write ( * , * ) ’b= ’ , b
write ( * , * ) ’ s c r i v i i l valore di c ’
read ( * , * ) c
write ( * , * ) ’ c= ’ , c
p1= ( a . l t . b)
p2=(b . gt . c )
write ( * , * ) ’ p1= a . l t . b ’ , p1
write ( * , * ) ’ p2= b . gt . c ’ , p2
p= p1 . and . p2
write ( * , * ) ’ p1 and p2 ’ , p
p= . not . ( p1 . and . p2 )
write ( * , * ) ’ not ( p1 and p2 ) ’ , p
p= p1 . or . p2
write ( * , * ) ’ p1 or p2 ’ , p
p= . not . ( p1 . or . p2 )
write ( * , * ) ’ not ( p1 or p2 ) ’ , p
stop
end
169
11. I NTRODUZIONE AL FORTRAN 77
i f ( espressione l o g i c a ) then
{ istruzione 1a }
{ istruzione 2a } Se è vera l’espressione logica allora si
{ .... } eseguono le istruzioni 1a, 2a, . . . .
el se Altrimenti – cioè se è falsa l’espressione
{ istruzione 1b } logica – allora si eseguono le istruzioni 1b,
{ istruzione 2b } 2b, . . .
{ .... }
end i f
i f ( espressione l o g i c a ) then
{ i s t r u z i o n e 1a } Se è vera l’espressione logica allora si ese-
{ i s t r u z i o n e 2a } guono le istruzioni 1a, 2a, . . . , altrimenti
{ .... } non si fa nulla.
end i f
Ciclo if –
struttura più
generale
i f ( espressione l ogica1 ) then
{ i s t r u z i o n e 1a }
{ i s t r u z i o n e 2a }
{ .... }
el se i f ( espressione l ogica2 ) then
{ i s t r u z i o n e 1b }
{ i s t r u z i o n e 2b }
{ .... }
....
el se
{ i s t r u z i o n e 1z }
{ i s t r u z i o n e 2z }
{ .... }
end i f
170
11.10. Struttura alternativa
d e l t a =b ** 2 − 4 . * a * c
i f ( d e l t a . l t . 0 ) then
write ( * , * ) ’ l e r a d i c i sono complesse ’
else
x1= ( −b + s q r t ( d e l t a ) ) / ( 2 . * a )
write ( * , * ) ’ x1 = ’ , x1
x2= ( −b − s q r t ( d e l t a ) ) / ( 2 . * a )
write ( * , * ) ’ x2 = ’ , x2
end i f
stop
end
Complichiamo la seconda parte del programma, andando a scrivere le radici coincidenti nel caso in cui
∆ = 0 e utilizzando la formula alternativa (dalla considerazione che x 1 x 2 = c/a) per evitare il fenomeno di
cancellazione numerica.
i f ( d e l t a . l t . 0 ) then
write ( * , * ) ’ l e r a d i c i sono complesse ’
e l s e i f ( d e l t a . eq . 0 . d0 ) then
x1= −b / ( 2 . 0 d0 * a )
x2=x1
write ( * , * ) ’ l e r a d i c i sono : ’ , x1 , x2
else
x1= ( −b + s q r t ( d e l t a ) ) / ( 2 . * a )
x2= ( −b − s q r t ( d e l t a ) ) / ( 2 . * a )
write ( * , * ) ’ l e r a d i c i sono : ’ , x1 , x2
i f ( ab ( x1 ) . gt . abs ( x2 ) ) then
x2= c / ( x1 * a )
write ( * , * ) ’ x2 con formula a l t e r n a t i v a ’ , x2
else
x1= c / ( x2 * a )
write ( * , * ) ’ x1 con formula a l t e r n a t i v a ’ , x1
end i f
end i f
Ciclo do
Il ciclo if non basta per scrivere tutti i nostri programmi. Pensiamo ad un blocco di istruzioni da ripe- while
tere molte volte, fino a quando è vera una determinata condizione. In questo caso, si usa il ciclo do while
(pensiamo all’algoritmo visto per il metodo di bisezione, o allo schema di punto fisso).
171
11. I NTRODUZIONE AL FORTRAN 77
do while ( espressione l o g i c a )
{ istruzione 1 }
{ istruzione 2 } Fintantochè è vera l’espressione logica
{ ... } allora esegui istruzione 1, 2, . . . , n.
{ istruzione n }
end do
Le istruzioni 1, 2, . . . vengono ripetute ciclicamente (non una volta sola come nel ciclo if). Quando si
esegue l’ultima istruzione posta all’interno del ciclo, si torna all’espressione logica e si controlla se è vera o
falsa. Se è vera, si eseguono di nuovo le istruzioni 1, 2, . . . ,n. Se non è vera, si esce dal ciclo while. Occorre
dunque prestare attenzione a non creare cicli infiniti!
x n+1 = cos(x n )
e proviamo a scrivere un programma FORTRAN che ci permetta di trovare una buona approssimazione del
punto fisso ξ (sempre che lo schema converga). I dati di input che dobbiamo dare al programma sono:
G l’approssimazione iniziale x 0
G la tolleranza ε con cui vogliamo approssimare il punto fisso
G il numero massimo di iterazioni entro cui cercare la convergenza dello schema (per evitare cicli infiniti).
I dati di output che possiamo chiedere al programma sono:
G l’approssimazione x n+1 ad ogni passo
G l’iterazione n
G lo scarto ad ogni passo: |x n+1 − x n |
G una stima della costante asintotica dell’errore M .
Cerchiamo ora di capire come gestire le variabili per x n e x n+1 e per gli scarti ad ogni passo. Con il metodo
di punto fisso, si crea una successione di valori: x 0 , x 1 , x 2 , . . . x n . . . . Nella teoria, per n che tende all’infinito,
la successione può convergere al punto fisso. Nella pratica ci si arresta quando lo scarto (il valore assoluto tra
due iterazioni successive) è minore di una certa tolleranza. A priori, tuttavia, non sappiamo quante iterazioni
dobbiamo fare. Potremmo pensare di memorizzare le varie approssimazioni x n in un vettore che abbia una
dimensione molto elevata. Ma ci sono due inconvenienti:
1. Non sappiamo ancora come scrivere in un programma FORTRAN un vettore.
2. Supposto di saperlo fare, possiamo e dobbiamo evitarlo perchè non serve conservare in memoria tutti
le approssimazioni che generiamo (x n+1 dipende dal valore x n e basta). Se ci interessano i valori gene-
rati dall’algoritmo, li possiamo scrivere di volta in volta sul video (meglio su un file! vedremo poi come
scrivere dati di output su un file).
Lavoreremo facendo uso di due variabili: xold che corrisponde a x n e xnew che corrisponde a x n+1 . Diamo
in input il valore iniziale x 0 . Dobbiamo effettuare la prima iterazione cioè trovare x 1 = cos(x 0 ).
G Porremo xold=x0 e poi xnew= cos(xold) per l’iterazione iter=1. xnew ha il significato di x 1 .
G Una volta fatta la prima iterazione, il valore di xold=x0 non ci interessa più. Per iter=iter+1=2,
ci serve calcolare x 2 = cos(x 1 ). Proprio perchè il valore di xold non serve più assegniamo a xold il
valore calcolato per x 1 =xnew in modo da poter sfruttare la relazione di prima. Applicheremo di nuovo
la formula xnew= cos(xold) dove ora xnew ha il significato di x 2 e xold di x 1 .
G Alla fine del secondo passo, quindi xnew=x 2 e xold=x 1
G Ora x 1 non serve più. Per iter=iter+1=3, ci serve solo x 2 . Perciò faremo xold=xnew,
xnew=cos(xold) e avremo xnew=x 3 . E così via. . .
172
11.11. Programma sul metodo di punto fisso
xold=x0
i t e r =0
scartonew =2.0d0 * t o l l
do while ( ( scartonew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
i t e r = i t e r +1
xnew=cos ( xold )
scartonew=abs (xnew− xold )
write ( * , * ) i t e r , xnew
xold=xnew
end do
La variabile scartonew ha il significato dello scarto x n − x n−1 | e, difatti, viene di volta in volta aggiornata
come scartonew=abs(xnew−xold). Prima di iniziare il ciclo do while è posto scartonew=2.0d0*toll, una quan-
tità più grande della tolleranza, perchè così, la prima volta che si entra nel ciclo do while, la proposizione
logica ad essa legata è vera. Difatti, quando si entra nel ciclo do while scartonew=2.0d0*toll > toll
e iter=0< itmax. Si eseguono le istruzioni del ciclo do while fino a quando rimane vera la proposizio-
ne (scartonew.ge.toll) .and. (iter . le .itmax) . Si esce dal ciclo do while quando scartonew < toll oppure
quando iter > itmax.
|ξ − x n |
Sappiamo che, per lo schema di punto fisso, vale limn→∞ = M = |g 0 (ξ)|. Poichè non conosciamo
|ξ − x n−1
l’errore, ma possiamo calcolare lo scarto e, per n → ∞, vale |ξ − x n | ≈ |x n − x n−1 |, abbiamo due modi per
stimare M :
1. calcolare il rapporto tra gli scarti a due passi successivi
2. calcolare |g 0 (x n )|.
Per calcolare il rapporto tra gli scarti a due passi successivi introduciamo un’altra variabile, che chiamia-
mo scartold, che corrisponde allo scarto |x n−1 −x n−2 |. L’aggiornamento di scartonew e scartold viene
fatto in maniera del tutto analoga a quanto visto per xold e xnew.
Nel codice calcoliamo quindi due stime di M , utilizzando le variabili che chiamiamo asint1 e asint2.
Vediamo il codice completo.
program puntofisso
C programma per i l c a l c o l o del punto f i s s o per g ( x )= cos ( x ) in [ 0 , pi / 2 ]
i m p l i ci t none
C
C significato delle variabili
C i t e r : i t e r a z i o n e del metodo del punto f i s s o
C itmax : numero massimo di i t e r a z i o n i
C t o l l : t o l l e r a n z a p r e f i s s a t a per l ’ approssimazione
C del punto f i s s o
C x0 : punto i n i z i a l e d e l l a s u c c e s s i o n e
C xold : approssimazione al passo n−1
C xnew : approssimazione al passo n
C s c a r t o l d : s c a r t o a l l ’ i t e r a t a precedente
C scartonew : valore a s s o l u t o t r a l ’ i t e r a t a c o r r e n t e e quella al
C passo precedente
C asint1 : scartonew / s c a r t o l d − approssimazione di M
C asint2 : abs(− sin (xnew ) ) − approssimazione di M
integer i t e r , itmax
real * 8 x0 , xold , xnew , scartold , scartonew , t o l l
real * 8 asint1 , asi nt2
write ( * , * ) ’ approssimazione i n i z i a l e ’
read ( * , * ) x0
write ( * , * ) ’ x0 = ’ , x0
itmax=100
t o l l =1.d−10
173
11. I NTRODUZIONE AL FORTRAN 77
scartonew =2.0 * t o l l
s c a r t o l d =scartonew
iter = 0
xold=x0
write ( * , * ) ’ i t xnew scarto
1 asi nt1 asint2 ’
write ( * , * ) i t e r , xold , scartonew
do while ( ( scartonew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
i t e r = i t e r +1
xnew=cos ( xold )
scartonew=abs (xnew− xold )
asi nt1 = scartonew / s c a r t o l d
asi nt2 =abs(− sin (xnew ) )
write ( * , * ) i t e r , xnew , scartonew , asint1 , asi nt2
xold=xnew
s c a r t o l d =scartonew
end do
stop
end
11.12 I sottoprogrammi
Quando l’algoritmo e il problema su cui stiamo lavorando sono complicati, conviene spezzare il problema
in sottoproblemi in modo da semplificare la programmazione.
Analogamente, al posto di avere un unico programma in FORTRAN, conviene scrivere il programma
facendo uso di sottoprogrammi. Si hanno due tipi di sottoprogrammi in FORTRAN:
G subroutines,
G functions.
In tal modo un programma FORTRAN può risultare composto da:
G programma principale,
G una o più subroutines,
G una o più functions.
11.12.1 Le functions
Il programma che abbiamo scritto funziona bene ma ha un punto debole: se vogliamo applicare lo
schema di punto fisso ad un’altra funzione g , dobbiamo andare a cambiare le istruzioni xnew=cos(xold) e
asint2=abs(−sin(xnew)). E se la funzione è complicata? E se dobbiamo valutare la stessa funzione (o le stesse
funzioni) anche su altre parti del programma?
Introduciamo il concetto di function in FORTRAN. Una function è del tutto simile al concetto di
n
funzione scalare, che può essere definita in un sottoinsieme di R ma ha valori in R. Difatti una function
può avere uno o più dati di input e un solo dato di output.
Vediamo come scrivere il programma precedente facendo uso delle functions.
Nello stesso file (per semplicità) in cui abbiamo scritto il programma principale fisso.f, dopo le istruzioni
stop e end che chiudono il programma principale, dopo aver lasciato qualche riga bianca per mostrare che
Esempio di finisce il programma principale, andremo a scrivere la nostra prima function
function gfun
stop
end
C f i n e del programma p r i n c i p a l e
174
11.12. I sottoprogrammi
real * 8 x
gfun=cos ( x )
return
end
La funzione che stiamo scrivendo è di tipo real*8 ed è la prima cosa che scriviamo per identificarla. C’è poi
la parola function e poi gfun(x). gfun ha un duplice significato: è il nome della function ma è anche
il nome della variabile che contiene il risultato dell’esecuzione della function gfun.
Il corpo della function è del tutto analogo a quello che si ha in un programma principale: implicit none,
dichiarazione delle variabili, istruzioni. Tutte le istruzioni servono ad assegnare il valore alla variabile gfun.
La function termina con le istruzioni return (per ritornare nel programma da cui è stata chiamata) e
end.
La funzione in questo caso dipende da una sola variabile, che chiamiamo x. La variabile (o le variabili)
da cui dipende una function deve essere dello stesso tipo (dichiarata allo stesso modo) sia all’interno della
function sia nel programma principale, ma può avere nomi diversi (x, xold). Esempio di
Per la derivata prima la function è la seguente: function
dgfun
real * 8 function dgfun ( x )
C derivata d e l l a funzione di punto f i s s o
i m p l i ci t none
real * 8 x
dgfun= −sin ( x )
return
end
Un’altra istruzione (opzionale) è dire che ci sono due sottoprogrammi esterni al programma principale,
subito dopo la dichiarazione delle variabili:
integer i t e r , itmax
real * 8 x0 , xold , xnew , scartold , scartonew , t o l l
real * 8 asint1 , asi nt2
real * 8 gfun , dgfun
external gfun , dgfun
Infine, nel ciclo while, dove abbiamo bisogno della funzione di punto fisso e della sua derivata, si ha:
do while ( ( scartonew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
i t e r = i t e r +1
xnew=gfun ( xold )
scartonew=abs (xnew− xold )
a s int1 = scartonew / s c a r t o l d
a s int2 =abs ( dgfun (xnew ) )
write ( * , * ) i t e r , xnew , scartonew , asint1 , asi nt2
xold=xnew
s c a r t o l d =scartonew
end do
175
11. I NTRODUZIONE AL FORTRAN 77
Esempio 11.12.1 Supponiamo p di dover scrivere un semplice programma che, dati in input, due valori a e
b, valuta la funzione f (x) = x 2 + 1 + e −x per x = a e per x = b, stampando i risultati. Per la funzione f (x)
si deve utilizzare una function che chiameremo fun. Il programma può essere di questo tipo
program esempiousofunzioni
i m p li ci t none
real * 8 a , b , c , d
real * 8 fun
write ( * , * ) ’ s c r i v i valore a ’
read ( * , * ) a
write ( * , * ) ’ s c r i v i valore b ’
read ( * , * ) b
C la v a r i a b i l e c ha i l valore d e l l a funzione fun in a
c=fun ( a )
C la v a r i a b i l e d ha i l valore d e l l a funzione fun in b
d=fun (b)
write ( * , * ) ’ a = ’ , a , ’ f ( a )= ’, c
write ( * , * ) ’b = ’ , b , ’ f (b)= ’, d
return
end
Un errore molto comune, nel fare programmi di questo tipo, in cui una function viene chiamata più volte in
modo sequenziale (cioè non all’interno di un ciclo while) è quello di scrivere la stessa function tante volte
quante viene chiamata all’interno del programma!!! In questo caso un programma ERRATO sarebbe scritto
in questo modo
program esempiousofunzioni
C ATTENZIONE ! ! ! ! ! ! ! ! !
C QUESTO E ’ UN ESEMPIO DI PROGRAMMA NON CORRETTO ! ! ! !
C Durante la compilazione s i ha i l seguente messaggio di e r r o r e :
C Global name ’ fun ’ at ( 1 ) i s already being used as a FUNCTION at ( 2 )
i m p li ci t none
real * 8 a , b , c , d
real * 8 fun
write ( * , * ) ’ s c r i v i valore a ’
read ( * , * ) a
write ( * , * ) ’ s c r i v i valore b ’
read ( * , * ) b
C la v a r i a b i l e c ha i l valore d e l l a funzione fun in a
176
11.12. I sottoprogrammi
c=fun ( a )
C la v a r i a b i l e d ha i l valore d e l l a funzione fun in b
d=fun (b)
write ( * , * ) ’ a = ’ , a , ’ f ( a )= ’ , c
write ( * , * ) ’b = ’ , b , ’ f (b)= ’ , d
stop
end
La function fun è sempre la stessa. Perchè riscriverla due volte? All’interno del programma principale,
la function viene dapprima chiamata per essere valutata nel punto a e poi per essere valutata nel punto b.
La function fun va scritta solo una volta (noi l’abbiamo fatta dipendere da una generica variabile scalare
x, ma potremmo farla dipendere anche da una variabile che chiamiamo a o b). Sottolineiamo il fatto che
le variabili da cui dipende la function devono avere lo stesso significato nel programma principale, ma non
necessariamente gli stessi nomi.
Quello che succede nel programma potrebbe essere descritto sinteticamente nel modo seguente:
programma
..
.
..
.
..
.
Il programma chiama la
function fun.
Nella function x = a.
c=fun(a) −→
La function restituisce in c
il valore
fun(a).
Il programma chiama la
function fun.
Nella function x = b.
d=fun(b) −→
La function restituisce in c
il valore
fun(b).
..
.
..
.
177
11. I NTRODUZIONE AL FORTRAN 77
11.12.2 Le subroutines
Possiamo pensare di cambiare ancora il programma per l’approssimazione del punto fisso, utilizzando
un diverso approccio: la parte che riguarda le iterazioni dello schema del punto fisso la facciamo fare ad un
sottoprogramma che chiameremo, in qualche modo, nel programma principale. Scomporre il programma
principale in più sottoprogrammi ha il suo vantaggio nel momento in cui gli algoritmi che dobbiamo imple-
mentare diventano via via più complicati, oppure se una parte di un programma viene ripetuta più volte (e
anzichè scrivere righe e righe di istruzioni da eseguire, le scriviamo solo una volta nel sottoprogramma e poi
le richiamiamo dove occorre).
program puntofisso
i m p li ci t none
integer i t e r , itmax
real * 8 x0 , xnew , t o l l
external i t e r p f i s s o
write ( * , * ) ’ approssimazione i n i z i a l e ’
read ( * , * ) x0
write ( * , * ) ’ x0 = ’ , x0
itmax=100
t o l l =1.d−10
iter = 0
c a l l i t e r p f i s s o ( i t e r , itmax , x0 , t o l l , xnew)
write ( * , * ) ’ approssimazione f i n a l e ’ , xnew
write ( * , * ) ’ i t e r a z i o n i e f f e t t u a t e ’ , i t e r
stop
end
scnew=2.0 * t o l l
scold=scnew
xold=x0
write ( * , * ) ’ i t xkp1 scarto
1 asint1 asint2 ’
write ( * , * ) i t e r , xold , scnew
do while ( ( scnew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
i t e r = i t e r +1
xnew=gfun ( xold )
178
11.12. I sottoprogrammi
Il fatto che noi chiamiamo una subroutine nel programma principale (call ) dice che la subroutine non è un
programma a sè stante. Quando termina l’esecuzione di ciò che è scritto all’interno della subroutine si torna
indietro nel programma principale e si continua l’elaborazione da quel punto. L’istruzione return fa tornare
al programma principale. Le variabili non devono avere necessariamente lo stesso nome nel programma
principale e nella subroutine. Per esempio, possiamo scrivere:
call iterpfisso( iter ,itmax,x0,toll,xnew) nel programma principale
subroutine iterpfisso(it,itmassime,x0,toll,xnew) nella subroutine.
L’importante è che le variabili abbiamo lo stesso significato (stesso tipo di variabile, ma anche stes-
sa valenza di variabile) e devono essere messe nello stesso ordine: se nel programma principale scrivia-
mo call iterpfisso(itmax,iter,x0, toll ,xnew) ma poi nella subroutine scambiamo il ruolo di itmax e di iter,
subroutine iterpfisso(it,itmassime,x0,toll,xnew) ,
all’interno della subroutine è assegnato a it il valore di itmax, mentre a itmassime è assegnato il valore di iter
(che è zero all’inizio). . . ..
All’interno della subroutine si possono utilizzare altre variabili oltre a quelle che sono presenti tra i pa-
rametri della stessa. L’importante è dichiararle nella subroutine. Tali variabili non passano nel programma
principale ma sono usate solo nella subroutine. In questo esempio xold, scnew, scold, asint1, asint2, gfun,
dgfun sono usate solo nella subroutine.
Vediamo un altro esempio di programma con uso di subroutines.
Esempio 11.12.2 Scriviamo un programma che, assegnate tre variabili, che chiamiamo a, b e c, considera
le possibili coppie di punti che si possono formare e calcola la corrispondente media geometrica e media
aritmetica. Le possibili coppie di punti sono: a-b, a-c, b-c. Per calcolare il valor medio di ciascuna coppia,
utilizziamo una subroutine che chiamiamo medie. Un possibile programma è il seguente.
program medie_arit_geom
i m p l i ci t none
real * 8 a , b , c
real * 8 media1 , media2
write ( * , * ) ’ s c r i v i t r e numeri a , b , c ’
read ( * , * ) a , b , c
c a l l medie ( a , b , media1 , media2 )
write ( * , * ) ’ coppie di punti : ’ , a , b
write ( * , * ) ’ media ari tme ti ca ’ , media1
write ( * , * ) ’ media geometrica ’ , media2
179
11. I NTRODUZIONE AL FORTRAN 77
11.13 Il formato
Fino ad ora abbiamo stampato i risultati dei nostri programmi su video e senza aver dato nessuna
indicazione su come visualizzare i dati.
Per avere un output elegante e ordinato, conviene usare l’istruzione format.
Vediamo questa istruzione direttamente all’interno di un programma d’esempio (quello del punto fisso
Programma appena visto nelle le righe di codice relative al ciclo do while, il resto rimane invariato)
di punto fisso
con do while ( ( scartonew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
l’istruzione i t e r = i t e r +1
format xnew=gfun ( xold )
scartonew=abs (xnew− xold )
asint1 = scartonew / s c a r t o l d
asint2 =abs ( dgfun (xnew ) )
write ( * , 1 0 0 ) i t e r , xnew , scartonew , asint1 , asint2
xold=xnew
s c a r t o l d =scartonew
end do
100 format (1 x , i4 , 1 x , f15 . 1 2 , 1 x , e14 . 6 , 1x , 2e13 . 5 )
Nell’istruzione write, non abbiamo scritto write(*,*) ma write(*,100). Al posto del secondo simbolo *
abbiamo messo un numero (un’etichetta).
Questo numero lo si trova scritto alla fine del ciclo while (ma possiamo metterlo ovunque all’interno del
programma – dopo la dichiarazione delle variabili e prima della end finale) a partire dalla seconda colonna.
Dopo aver scritto il numero che contraddistingue il formato, abbiamo l’istruzione format e, tra pa-
rentesi, abbiamo tutte le indicazioni su come rappresentare le variabili della stampa cui ci si riferisce:
format(1x,i4,1x,f15.12,1x,e14.6,1x,2e13.5)
Nell’esempio particolare:
180
11.13. Il formato
formato Significato
i formato intero
e esponenziale
f fisso
a alfanumerico
x spazi bianchi
Tabella 11.6: Il formato
formato Esempio
i i5 – 5 caratteri per un intero
e e14.6 – 14 caratteri, 6 per la mantissa
e18.10 – 18 caratteri, 10 per la mantissa
f f14.6 – 14 caratteri, 6 per le cifre decimali
f15.12 – 15 caratteri, 12 per le cifre decimali
a a5 – una stringa di al più 5 caratteri
x 1x – 1 carattere bianco
3x – 3 caratteri bianchi
Tabella 11.7: Esempi di formato
Specificando il formato, occorre prestare attenzione al fatto che non tutti i numeri possono essere stam-
pati correttamente. Per esempio se un intero ha più di 5 caratteri (per esempio 100150) ma il formato per esso
è i5, vengono stampati degli * o altri caratteri a seconda del compilatore. Se si hanno strani risultati in output
usando un formato, togliere il formato, compilare e rieseguire il programma per verificare se l’errore dipende
dal formato!
Lo stesso formato può essere utilizzato da più righe di write se il formato si riferisce a variabili dello
stesso tipo. Le stringhe di caratteri possono essere scritte mediante un formato opportuno.
Vediamo di nuovo il programma di prima:
iter = 0
xold=x0
write ( * , 9 8 ) ’ i t ’ , ’ xk ’ , ’ scarto ’ , ’ asint1 ’ , ’ asint2 ’
write ( * , 9 9 ) i t e r , xold , scartonew
do while ( ( scartonew . ge . t o l l ) . and . ( i t e r . l e . itmax ) )
C t u t t o i n vari ato come prima
write ( * , 1 0 0 ) i t e r , xnew , scartonew , asint1 , asint2
xold=xnew
s c a r t o l d =scartonew
end do
98 format (1 x , a4 , 1 x , a15 , 1 x , a14 , 1 x , 2 a13 )
99 format (1 x , i4 , 1 x , f15 . 1 2 , 1 x , e14 . 6 )
100 format (1 x , i4 , 1 x , f15 . 1 2 , 1 x , e14 . 6 , 1x , 2e13 . 5 )
181
11. I NTRODUZIONE AL FORTRAN 77
stop
end
Per le stringhe è stato usato un formato riservando a ciascuna stringa lo stesso numero di caratteri riser-
vati alle variabili corrispondenti cui si riferiscono le stringhe. In tal modo, si riesce a creare una tabellina di
risultati messi in colonna l’uno dopo l’altro in maniera ordinata.
Una volta che il programma è stato compilato correttamente ed eseguito, la stampa dei risultati non sarà
più sul video ma verrà generato un file (con il nome che abbiamo dato all’interno del programma) sul quale
troveremo i risultati che prima erano sul video.
Se rieseguiamo il programma questo file sarà riscritto da capo. Quindi se dobbiamo eseguire il
programma più volte per diverse simulazioni, il file di output conviene rinominarlo in modo da non perderlo.
11.15 Vettori
Quando si programma in FORTRAN, un vettore va dichiarato in un certo modo e usato in maniera quasi
simile a come li abbiamo studiati.
Supponiamo di voler calcolare la media di un vettore x.
Nello scrivere il programma, dobbiamo pensare ad una lunghezza massima per il vettore che dobbiamo
dare in input: questo perchè in FORTRAN77 si ha un’allocazione statica delle variabili (e non dinamica).
Se diamo 20 come lunghezza massima del vettore, il programma che scriveremo potrà essere eseguito su
vettori che avranno al più dimensione 20.
182
11.16. Ciclo do
Ci sono vari modi per dare questa dimensione massima ai vettori. Noi partiremo dal modo più semplice.
Supponiamo di voler scrivere un programma che calcola la media delle componenti di un vettore. Come
procedere?
G I dati di input sono: n, la dimensione effettiva del vettore e x i per i = 1, 2, . . . n le componenti del vettore
x.
G ( n xi )
P
L’output è la variabile med i a = i =1
n
Per calcolare la variabile med i a faremo la somma in questo modo (med i a è la cosiddetta variabile di
accumulo):
partiamo da med i a = 0
quindi facciamo med i a = med i a + x 1 (prima componente della somma)
poi med i a = med i a + x 2 (il risultato è x 1 + x 2 )
poi med i a = med i a + x 3 (avremo x 1 + x 2 + x 3 )
e così via fino a med i a = med i a + x n (in med i a avremo tutta la somma dei vettori)
Dopo si fa med i a = med i a/n e avremo il risultato finale.
11.16 Ciclo do
Per applicare la formula per ottenere la variabile med i a possiamo pensare a un ciclo do while scritto
come:
media =0.d0
i =0
do while ( i . l e . n)
i = i +1
media = media + x ( i )
end do
media= media/n
Noi non useremo questo approccio ma una struttura equivalente ad essa che prende il nome di ciclo do:
media = 0 . d0
do i =1 ,n
media = media + x ( i )
end do
media= media/n
Programma
sulla media
program mediavettori
dei vettori
C programma che c a l c o l a la media d e l l e componenti di un v e t t o r e
i m p l i ci t none
integer n , i
real * 8 x ( 2 0 ) , media
write ( * , * ) ’ lunghezza e f f e t t i v a del v e t t o r e ’
read ( * , * ) n
write ( * , * ) ’ lunghezza del v e t t o r e ’ , n
i f (n . gt . 2 0 ) then
write ( * , * ) ’n > massimo consentito ’ , n
stop
endif
do i =1 ,n
write ( * , * ) ’componente ’ , i , ’−sima del vettore ’
read ( * , * ) x ( i )
end do
do i =1 ,n
write ( * , * ) ’ elemento ’ , i , ’ = ’ , x ( i )
end do
media=0.d0
183
11. I NTRODUZIONE AL FORTRAN 77
do i =1 ,n
media = media + x ( i )
end do
media =media/n
write ( * , * ) ’ media ’ , media
stop
end
G Il vettore è stato dichiarato come real*8 x(20): il vettore può avere al più 20 componenti.
Osserviamo che questo tipo di dichiarazione non fa distinzione tra vettore riga e vettore colonna.
G La dimensione effettiva del vettore è data dalla variabile intera n che viene data in input (per il
momento da tastiera);
G Le singole componenti vengono inserite da tastiera tramite un’applicazione del ciclo do;
G Facciamo un controllo su n, se è più piccolo o più grande della dimensione massima. Attenzione: il
ciclo if si può usare anche per interrompere il programma! Se n > 20 interrompiamo bruscamente il
programma mediante l’istruzione stop all’interno del ciclo if.
Con il ciclo do che abbiamo visto, la variabile intera i varia da 1 a n (la dimensione del vettore).
In generale la struttura del ciclo do è la seguente:
do indice= v a l o r e i n i z i a l e , v a l o r e f i n a l e , incremento
{ istruzioni }
end do
Esempio 11.16.1 Vogliamo fare la somma delle componenti di indice pari del vettore x:
sommapari=0.d0
do i =2 ,n, 2
sommapari=sommapari + x ( i )
end do
L’indice i vale i = 2, i = 2 + 2 = 4, i = 4 + 2 = 6. . . .
Attenzione: se valoreiniziale > valorefinale e l’incremento è positivo, non si entra nel ciclo do.
Si può anche trovare il ciclo do scritto nella forma (ormai obsoleta, ma può capitare di trovarlo su vecchi
programmi):
do l a b e l indice= v a l i n i z i a l e , v a l f i n a l e , incremento
{ istruzioni }
l a b e l continue
dove label è un numero (etichetta) che si trova all’inizio del ciclo e poi alla fine per chiuderlo (label
continue). La label dell’istruzione label continue va scritta a partire dalla seconda colonna.
184
11.16. Ciclo do
Attenzione a come si passano i vettori nelle functions! Abbiamo scritto real*8 function norma2(n,x). Nel
programma principale (che qui non abbiamo scritto) la function sarà chiamata, ad esempio, tramite le
istruzioni
a l f a =norma2(n , x )
beta=norma2(n , y )
In questo caso, nel programma principale calcoliamo la norma dei vettori x e y e il valore di queste norme è
assegnato alle variabili alfa e beta.
Attenzione! Un errore frequente nell’uso di functions o di subroutines è di passare i vettori con la loro
dimensione! Nel programma principale si scrive (in maniera non corretta!!!):
alfa=norma2(n,x(n))
Nella function, in maniera non corretta, si scrive:
real*8 function norma2(n,x(n))
Non si deve scrivere x(n): la dimensione del vettore viene passata mediante la variabile n che è già tra i
parametri della function. Si deve scrivere solo x.
185
11. I NTRODUZIONE AL FORTRAN 77
media= funmedia (n , x )
write ( * , * ) ’ media ’ , media
close ( 1 0 )
stop
end
Per la lettura dei dati di input si può utilizzare sia il ciclo do che abbiamo visto fino ad ora sia quello che è
chiamato do implicito.
Essenzialmente quando si devono leggere dei dati da un file, il compilatore FORTRAN leggerà delle
stringhe di caratteri e le convertirà in numeri.
Ci sono delle differenze sulle modalità di come avviene la lettura mediante il do esplicito o implicito, ma
non entriamo nei dettagli. Ciò che importa ricordare è che ci deve essere corrispondenza nell’ordine in cui le
variabili sono scritte sul file di dati e la lettura delle variabili stesse nel programma FORTRAN.
Conviene, poi, lasciare almeno uno spazio bianco tra un valore e il successivo se li scriviamo sulla stessa
riga nel file di dati.
Le variabili di tipo reale vanno scritte con il punto decimale. Le variabili di tipo intero vanno scritte senza
il punto decimale.
Le componenti di un vettore vanno scritte o su una riga o in colonna componente per componente, in
maniere del tutto indifferente se usiamo il ciclo do implicito nel programma principale. Vanno scritte in
Esempi di file colonna, se usiamo il ciclo do esplicito.
vettorein- Se usiamo il do implicito per la lettura dei dati del vettore, possiamo scrivere indifferentemente il file dei
put.dat
dati nei due modi seguenti.
Il primo modo è di scrivere sul file di dati, sulla prima riga il valore di n e sulla seconda riga le componenti
del vettore.
4
1. 2. 3. 4.
Il secondo modo è di scrivere sulla prima riga il valore di n e sulle righe successive le componenti del
vettore.
4
1.
2.
3.
4.
Se usiamo il ciclo do esplicito per la lettura dei dati di input, il vettore deve essere scritto come vettore
colonna, quindi dobbiamo usare il secondo approccio.
186
11.17. Matrici in FORTRAN
187
11. I NTRODUZIONE AL FORTRAN 77
end do
end do
write ( 1 1 , * ) ’ v e t t o r e y=Ax ’
write ( 1 1 , * ) ( y ( i ) , i =1 ,n)
stop
end
G La matrice è stata dichiarata come real*8 A(20,20): significa che il programma va bene per matrici che
possono avere al massimo 20 righe per 20 colonne.
G Abbiamo usato un ciclo do i=1, n e un ciclo do j=1,n concatenato al primo per fare il prodotto
matrice-vettore.
G Per calcolare le componenti del prodotto matrice-vettore abbiamo prima posto y(i)=0.d0 in modo
da poter fare la somma dei vari termini “accumulandoli” di volta in volta.
G Abbiamo letto i dati di input da file. Ricordiamo che il numero che scriviamo all’interno dell’istruzione
che apre il file open(10, file=’nomefile.dat’) lo scegliamo noi. Se apriamo più files a ciascun
file deve essere associato un numero diverso, in modo da poter leggere (se il file è di lettura) o scrivere
(se il file è di scrittura) in modo appropriato.
C l e t t u r a d e l l a dimensione n
read ( 1 0 , * ) n
C l e t t u r a d e l l a matrice A
C usiamo un c i c l o do i =1 ,n e s p l i c i t o e un c i c l o do i m p l i c i t o
C leggiamo g l i elementi che s i trovano s u l l a r i g a i−sima e
C la l e t t u r a viene f a t t a r i g a per r i g a
do i =1 ,n
read ( 1 0 , * ) (A( i , j ) , j =1 ,n)
end do
write ( 1 1 , * ) ’ dimensione ’ , n
write ( 1 1 , * ) ’ matrice A ’
do i =1 ,n
write ( 1 1 , * ) (A( i , j ) , j =1 ,n)
end do
c a l l trasposta (n , A , B)
188
11.17. Matrici in FORTRAN
subroutine trasposta (n , A , B)
i m p l i ci t none
integer i , j , n
real * 8 A( 2 0 ,n ) , B( 2 0 ,n)
do i =1 ,n
do j =1 ,n
B( i , j )=A( j , i )
end do
end do
return
end
Anche per le matrici, vale la stessa osservazione che abbiamo fatto per i vettori: quando si lavora con
functions o subroutines, le matrici vanno passate con il nome della loro variabile. È corretto scrivere
subroutine trasposta(n,A,B). Non è corretto scrivere subroutine trasposta(n,A(20,n),B(20,n)).
11.17.2 Parameter
Supponiamo di dover scrivere più sottoprogrammi che richiamano matrici e vettori. Per le matrici, in
ciascuno dei sottoprogrammi dobbiamo dare la dimensione massima delle righe: per esempio A(20,20)
nel programma principale e A(20,n) o A(20,20) (vanno bene entrambe le forme) nei sottoprogrammi.
Supponiamo però di voler eseguire il programma già fatto, e che funziona bene, per una matrice di di-
mensione 50 × 50. Possiamo andare ad aumentare la dimensione massima delle matrici e dei vettori da 20 a
50, ricompilare il programma ed eseguirlo.
Cosa può succedere? Se da qualche parte ci siamo dimenticati di correggere il 20 con il 50. . . il codice
darà risultati sbagliati. . . Per evitare questo inconveniente possiamo usare una variabile che si chiama para-
meter per indicare la dimensione massima delle matrici. Nel programma principale (supponiamo di voler
modificare il programma della trasposta di una matrice), scriveremo
program matrtrasposta
C programma che crea la matrice B=A^T
C t u t t i g l i a l t r i commenti come prima
C
i m p l i ci t none
integer nmax
parameter (nmax=20)
integer i , j , n
real * 8 A(nmax, nmax) , B(nmax, nmax)
C t u t t o i l r e s t o i n a l t e r a t o f i n o a l l a chiamata d e l l a subroutine
c a l l trasposta (nmax, n , A , B)
189
11. I NTRODUZIONE AL FORTRAN 77
return
end
Parameter
nmax La variabile nmax è un parametro che viene definito una volta per tutte mediante l’istruzione
parameter (nmax=20): all’interno del programma noi non possiamo cambiare il valore dato a nmax.
Al posto di scrivere A(20,20) noi scriviamo A(nmax,nmax). Se ci sono vettori, li dichiariamo come
x(nmax).
Nei sottoprogrammi, dove ci sono matrici, passiamo nmax nella lista delle variabili di input del
sottoprogramma e dichiariamo A(nmax,n).
In questo modo, se vogliamo cambiare la dimensione massima, andiamo a cambiare solo l’istruzione
parameter (nmax=20) Per esempio scriviamo parameter (nmax=50), compiliamo il programma e possiamo ese-
guirlo per matrici e vettori al più di dimensione 50. Ma andiamo a cambiare solo una riga di codice e non
tutte le righe in cui sono dichiarate le matrici e i vettori. . .
1 7 13 19 25 31
2 8 14 20 26 32
3 9 15 21 27 33
4 10 16 22 28 34
5 11 17 23 29 35
6 12 18 24 30 36
Cosa succede se la dimensione effettiva della matrice è n < nmax? All’interno del programma principale
i valori della matrice vengono memorizzati nelle celle di memoria che corrispondono alla “sottomatrice” di
dimensione n x n.
Sia n=4. Si ha:
1
7
13
19 25 31
2
8
14
20 26 32
3
9
15
21 27 33
4
10
16
22 28 34
5 11 17 23 29 35
6 12 18 24 30 36
1
5 9 13
2
6 10 14
3 7
11 15
4 8
12 16
190
11.17. Matrici in FORTRAN
Ma nelle cellette di posto 5, 6, 11 e 12 non ci sono i valori della matrice: la memorizzazione risulta non
corretta!!!
Esempio 11.17.1 Assegnate due matrici quadrate A e B di dimensione n (n ≤ 20), si vuole calcolare la
traccia delle matrici C = AB e D = B A.
Scrivere dunque un programma in linguaggio FORTRAN che:
1. legge n, A e B ;
2. calcola le matrici C = AB e D = B A servendosi della subroutine PRODMATR che esegue il prodotto di
due matrici quadrate;
3. calcola α (la traccia della matrice C ) e β (la traccia della matrice D) servendosi della function TRAC
che calcola la traccia di una matrice;
4. stampa i risultati ottenuti.
Per scrivere questo programma dobbiamo innanzitutto ricordarci la formula per fare il prodotto di due
matrici e quella per la traccia di una matrice. Date due matrici quadrate A e B si ha C = AB con elementi
n
X
ci j = a i k b k j per i , j = 1, 2, . . . , n.
k=1
abbiamo
1 traccia=0 ;
2 C inizializzo a zero la variabile traccia perchè devo fare una somma;
3 Per i=1,n
4 traccia=traccia + A(i,i)
5 Fine-Per
191
11. I NTRODUZIONE AL FORTRAN 77
program prodottomatricietraccia
i m p li ci t none
integer nmax
parameter (nmax=20)
integer n , i , j
real * 8 A(nmax, nmax) , B(nmax, nmax) , C(nmax, nmax) , D(nmax, nmax)
real * 8 trac , a l f a , beta
close ( 1 0 )
stop
end
do i =1 ,n
do j =1 ,n
C( i , j ) = 0 . d0
do k=1 ,n
C( i , j )= C( i , j ) + A( i , k ) * B( k , j )
end do
end do
end do
return
end
t r a c =0.d0
do i =1 ,n
t r a c = t r a c + A( i , i )
end do
return
end
192
11.18. La formula dei trapezi in FORTRAN
4
1. 2. 1. 0.
0. 2. 6. 1.
0. 1. 3. -1.
0. 0. -7. 4.
0. 1. 3. 5.
2. 3. 6. 8.
9. 10. 2. 4.
5. 6. 8. 1.
dove prima scriviamo n, la dimensione delle matrici (in questo caso 4), poi gli elementi della matrice A (riga
per riga) e successivamente (abbiamo lasciato anche una riga vuota) gli elementi della matrice B .
G dati di input:
– numero di suddivisioni n
– estremi di integrazione a, b
G dati di output:
– valore approssimato dell’integrale (usiamo per esso la variabile i t r ap)
– errore esatto, che chiamiamo er r t r ap.
Il programma sarà così composto:
G programma principale
G function in cui scriviamo la funzione integranda.
G function in cui scriviamo la primitiva della funzione integranda (per calcolare il valore esatto
dell’integrale)
G function in cui applichiamo la formula semplice dei trapezi e che chiamiamo trapsemplice.
Tra i dati che ci facciamo stampare sul file di output, conviene farsi stampare una specie di promemoria
sul problema che stiamo risolvendo (formula che stiamo applicando, gli estremi di integrazione a e b, il
valore esatto dell’integrale Iex e, come stringa di caratteri, anche quale è la funzione integranda). In tal
modo abbiamo “memoria” del problema che vogliamo risolvere e dei risultati ad esso associati.
Applichiamo la formula dei trapezi su ciascun intervallino. La prima volta andrà applicata sull’intervallo
[a, a + h], poi su [a + h, a + 2h] e così via, dove h è l’ampiezza dei singoli sottointervalli, che è la stessa su
b−a
tutti i sottointervalli avendo scelto di suddividere in parti uguali l’intervallo [a, b], quindi h = . Su ogni
n
sottointervallo possiamo applicare la formula semplice dei trapezi in modo da avere il valore finale dell’inte-
grale approssimato come somma dei contributi su ciascun sottointervallo. A tal scopo useremo, su ciascun
sottointervallo, una function che applica la formula semplice dei trapezi.
Possiamo quindi fare un ciclo do in modo da applicare la formula semplice all’intervallino [x0, x1], do-
ve x0 rappresenta l’estremo inferiore e x1 l’estremo superiore di ciascun sottointervallo. Ogni volta aggior-
neremo in maniera appropriata i due estremi (tenendo conto che x1 nell’intervallo successivo diventa x0:
l’estremo superiore di ogni intervallino diventa l’estremo inferiore nell’intervallino successivo).
193
11. I NTRODUZIONE AL FORTRAN 77
Per il calcolo del valore esatto dell’integrale, dobbiamo calcolare analiticamente l’integrale (faremo degli
esempi di applicazione delle formule di quadratura con integrali di cui è possibile conoscere l’integrale esatto,
quindi preliminarmente, avremo calcolato a mano l’integrale, andando a cercare una primitiva della funzio-
ne integranda). Conviene allora utilizzare una function per la primitiva, in modo da poter assegnare il valo-
re esatto dell’integrale mediante l’istruzione Iex = F pr i m(b) − F pr i m(a), dove F pr i m è il nome dato alla
function della primitiva. Nell’esempio, F pr i m(x) = π arcsin (x) e la function viene costruita di conseguenza.
real * 8 function Fprim ( x )
real * 8 pi , x
pi = 2 . * asin ( 1 . )
Fprim= pi * asin ( x )
return
end
Invece, la function trapsemplice non è nient’altro che l’applicazione della formula semplice dei trapezi
sull’intervallo di estremi x0 e x1 dati in input alla function stessa. All’interno della trapsemplice viene
chiamata la function della funzione integranda.
real * 8 function trapsemplice ( a , b)
real * 8 a , b , fun
trapsemplice =(b−a ) / 2 . * ( fun ( a )+ fun (b ) )
return
end
Proviamo ora ad applicare la formula composta dei trapezi partendo da una sola suddivisione n = 1, e poi
raddoppiando ogni volta il numero delle suddivisioni: n = 2, n = 4, n = 8, . . . In tal caso conviene modificare
il programma scritto per applicare la formula composta dei trapezi per tute le suddivisioni richieste introdu-
cendo un ciclo do while che permette di calcolare la formula composta dei trapezi prima per n = 1, poi
194
11.19. Esercizi
per n = 2 e così via, raddoppiando ogni volta il numero di suddivisioni. In questo modo, conservando i valori
dell’errore esatto tra due suddivisioni successive, possiamo calcolare il rapporto tra l’errore alla suddivisione
n/2 e l’errore alla suddivisione n. Memorizziamo questo rapporto nella variabile r at e e la stampiamo per
1
ogni suddivisione n > 1. Dai risultati saremo in grado di capire se l’errore decresce come 2 oppure no e,
n
quindi, se sono verificate le ipotesi per la formula composta dell’errore come descritto a pag. 130.
Per esempio, se vogliamo applicare la formula dei trapezi per n = 1, 2, 4, 8, . . . , 128 sotto forma di pseudo-
codice, abbiamo
Dati di input: a, b
Dati di output: i t r ap, er r t r ap, r at e per ogni suddivisione
1 n ←− 1 ;
2 Fintantochè n < 128
3 inizializzare i t r ap: i t r ap ←− 0.d 0 ;
4 porre h ←− (b − a)/n
5 ; inizializzare x0 del primo sottointervallo: x0 ←− a ;
6 applicare l’algoritmo della formula composta dei trapezi ;
7 stampare i t r ap per quel valore di n ;
8 calcolare l’errore esatto er r t r ap ;
9 Se n > 1 allora
10 calcolare il rapporto r at e tra l’errore al passo n/2 e l’errore al passo n
11 altrimenti
12 r at e ←− 1 (non ha significato per n = 1)
13 Fine-Se
14 stampare n, i t r ap, er r t r ap, r at e ;
15 aggiornare una variabile er r t r apol d che memorizza l’errore al passo precedente:
er r t r apol d ←− er r t r ap ;
16 aggiornare n: n ←− 2n ;
17 Fine-Fintantochè
11.19 Esercizi
Esercizio 11.19.1 Scrivere un programma FORTRAN che, assegnate due matrici A e B di dimensione n ≤ 30,
esegua il prodotto C=AB; memorizzi in un vettore x gli elementi della diagonale principale di C; calcoli la
norma euclidea di x.
I dati di input siano letti da un file chiamato input.dat.
Scrivere, perciò, un programma che:
a) legge la dimensione n, le matrici A e B e stampa i dati letti con commento;
b) calcola la matrice C=AB servendosi della subroutine MATRMATR;
c) salva gli elementi Ci i in un vettore chiamato x;
d) calcola la norma euclidea di x servendosi della function NORMAEUC;
e) stampa la norma euclidea di x.
(mettere a punto la subroutine MATRMATR e la function NORMAEUC.)
Svolgimento
program prodottomatrici
i m p l i ci t none
integer nmax
parameter (nmax=30)
195
11. I NTRODUZIONE AL FORTRAN 77
integer n , i , j
real * 8 A(nmax, nmax) ,B(nmax, nmax) , C(nmax, nmax) , x (nmax)
real * 8 normaeuc , euc
196
11.19. Esercizi
Esercizio 11.19.2 Si vuole ricavare un’approssimazione della soluzione del sistema lineare Ax = b
effettuando un passo del metodo del gradiente coniugato, secondo il quale
x1 = x0 + α0 r0
dove
rT r0
α0 = T0 e r0 = b − Ax0 .
r0 Ar0
Il vettore x0 sia scelto come x0 = D −1 b dove D è la matrice diagonale che si ricava da A prendendo gli
elementi della sua diagonale principale.
Scrivere quindi un programma in linguaggio FORTRAN che:
1. legge n, A e b;
2. costruisce la matrice diagonale D;
3. costruisce la matrice I NV D, che è la matrice inversa di D;
4. calcola il vettore x0 = D −1 b utilizzando la subroutine DIAGMAT che effettua il prodotto di una
matrice diagonale con un vettore.
5. calcola y = Ax0 utilizzando la subroutine MATRVETT che fa il prodotto matrice vettore;
6. calcola il vettore r0 = b − y;
7. calcola il prodotto z = Ar0 utilizzando la subroutine MATRVETT;
8. calcola d = rT0 r0 usando la function PSCAL che effettua il prodotto scalare tra due vettori;
9. calcola t = rT0 z usando la function PSCAL;
10. calcola α0 = d /t
11. calcola e stampa x1 = x0 + α0 r0 .
Svolgimento Osserviamo che la matrice diagonale D ha tutti gli elementi uguali a zero eccetto quelli
della diagonale principale, che nell’esercizio proposto, devono essere uguali agli elementi della diagonale
principale di A. Per risolvere l’esercizio, si può costruire la matrice D mediante le istruzioni
do i =1 ,n
do j =1 ,n
D( i , j ) = 0 . 0
i f ( i . eq . j ) then
D( i , j )=A( i , j )
end i f
end do
end do
Oppure, si può costruire un vettore che rappresenta la diagonale principale della matrice A. Nello
svolgimento, noi seguiamo questa seconda strada e ne terremo conto nelle subroutine INVD e DIAGMAT.
program esgradcon
i m p l i ci t none
integer nmax
parameter (nmax=40)
integer n , i , j
real * 8 A(nmax, nmax) , b(nmax) , matrd (nmax) , x0 (nmax) , r0 (nmax)
real * 8 y (nmax) , x1 (nmax) , inversad (nmax) , z (nmax)
real * 8 d , t , a l f a , pscal
C matrd e ’ i l v e t t o r e che contiene g l i elementi d e l l a diagonale p r i n c i p a l e di A
197
11. I NTRODUZIONE AL FORTRAN 77
end do
read ( 1 0 , * ) (b( i ) , i =1 ,n)
do i =1 ,n
matrd ( i )= A( i , i )
end do
c a l l invd (n , matrd , inversad )
c a l l diagmat (n , inversad , b , x0 )
c a l l matrvett (nmax, n , A , x0 , y )
do i =1 ,n
r0 ( i )=b( i )−y ( i )
end do
c a l l matrvett (nmax, n , A , r0 , z )
d=pscal (n , r0 , r0 )
t =pscal (n , r0 , z )
a l f a =d/ t
do i =1 ,n
x1 ( i )= x0 ( i )+ a l f a * r0 ( i )
write ( * , * ) x1 ( i )
end do
stop
end
subroutine diagmat (n , dd , b , x )
i m p li ci t none
integer n , i
real * 8 b(n ) , dd(n ) , x (n)
do i =1 ,n
x ( i )= dd( i ) * b( i )
end do
return
end
198
11.19. Esercizi
i m p li ci t none
integer n , i
real * 8 x (n ) , y (n)
pscal =0.d0
do i =1 ,n
pscal=pscal + x ( i ) * y ( i )
end do
return
end
199
APPENDICE
A
C ENNI SU G NUPLOT
Paul Erdös
A.1 Introduzione
Gnuplot è un programma utile per fare grafici (sia di funzioni, sia di dati), distribuito gratuitamente per
sistemi operativi Linux, Windows, e altri ancora.
Nel seguito vedremo alcuni comandi essenziali di Gnuplot al fine di poter visualizzare funzioni che di-
pendono da una sola variabile e creare grafici da tabelle di dati. Le potenzialità di Gnuplot sono molto di più
di quanto diremo e, per chi è interessato, si rimanda al sito http://www.gnuplot.info.
Ci rifacciamo alla versione 4.4 patchlevel 0, ultima modifica Marzo 2010, in ambiente Linux.
Per poter lavorare in ambiente Gnuplot, da una finestra di shell digitiamo gnuplot e poi clicchiamo il
tasto di invio. L’ambiente gnuplot si presenta come nella Figura A.1
Per uscire dall’ambiente gnuplot, si digita exit. Per avere un help on-line si digita help.
Tutte le istruzioni per fare e salvare grafici, si basano su comandi scritti sulla finestra del gnuplot. Si pos-
sono anche scrivere piú istruzioni da eseguire in un file script che viene poi lanciato in ambiente gnuplot
(vedremo successivamente come).
201
A. C ENNI SU G NUPLOT
Figura A.2: Finestra di shell dove si sta lavorando in ambiente gnuplot e grafico della funzione cos(x)
nell’intervallo [−π, π].
dove, al posto di a e b scriviamo i valori numerici degli estremi dell’intervallo in cui vogliamo visualizzare
la funzione f(x). La funzione f(x) si scrive usando le stesse notazioni del Fortran. Dopo aver scritto il
comando precedente e cliccato il tasto di invio, si apre una finestra con il grafico della funzione, come si può
vedere nella Figura A.2.
Se si scrive semplicemente plot f(x) il grafico è fatto sull’intervallo [−10, 10].
Vediamo degli esempi
G plot [-pi: pi] cos(x) : fa il grafico della funzione cos(x) nell’intervallo [−π, π]. Osserviamo
202
A.2. Grafici di funzioni
che pi ha il significato di π.
G plot x**2 -2*x+1: fa il grafico della parabola x − 2x + 1 nell’intervallo [−10, 10] (non essendo
2
stato specificato).
G plot [0:3] log(x): fa il grafico della funzione ln(x) nell’intervallo [0, 3]
Ogni volta, il grafico viene sovrascritto, perdendo quello precedente.
Per fare il grafico di più funzioni definite nello stesso intervallo, sulla stessa figura, basta scrivere le diverse
funzioni seguite da una virgola: plot [a:b], f(x), g(x), h(x)
G plot [-pi:pi] sin(x), cos(x): abbiamo i grafici delle due funzioni seno e coseno in due colori
diversi. La legenda, in alto a destra, spiega le diverse funzioni del grafico.
G plot x, x**2, x**3: abbiamo i grafici delle funzioni x, x e x nell’intervallo [−10, 10].
2 3
È possibile cambiare lo stile del grafico (linee continue, punti, linee e punti), con il seguente coman-
do: plot [a:b] f(x) with <stile> dove <stile> può essere: lines, points, linespoints, dots. Si può
anche cambiare il colore (e, in alcune modalità, il tipo della linea o del punto) usando il comando with
<stile> lt <numero> dove <numero> può variare nell’insieme {−1, 0, 1, . . . 22}. Si provi a eseguire il
comando test e vedere il grafico che viene prodotto per vedere i vari colori e stili.
Per esempio:
G plot sin(x) with linespoints, cos(x) with points produce un grafico in cui sin(x) è
rappresentata mediante linee e punti e cos(x) tramite punti (che possono essere date dal simbolo +
o da un quadratino pieno a seconda dello spessore richiesto).
G plot sin(x) with lines lt -1 produce un grafico con la linea di colore nero.
Si può variare lo spessore delle linee e dei punti mediante i comandi linewidth (o, in maniera del tutto
equivalente, lw) e pointtype (o pt) rispettivamente. Vediamo con degli esempi:
G plot sin(x) with points pt 5: i punti hanno dimensione 5 pt (si veda la Figura A.3).
G plot sin(x) with lines lw 2: la linea ha un’ampiezza pari 2 volte quella di default (si veda la
Figura A.4).
G plot sin(x) with linespoints lw 2 pt 5 : la linea è larga 2 lw mentre i punti hanno
dimensione 5 pt (si veda la Figura A.5).
Per fare un grafico semilogaritmico o logaritmico, prima di fare il grafico, si digita il comando
G set logscale: per avere un grafico logaritmico
G set logscale y: per avere un grafico semilogaritmico lungo l’asse y.
G set logscale x: per avere un grafico semilogaritmico lungo l’asse x.
203
A. C ENNI SU G NUPLOT
204
A.3. Salvare i grafici
Dopo si scrive la funzione di cui fare il grafico in scala logaritmica (o semilogaritmica), mediante il comando
plot.
Vediamo un esempio:
G set logscale y
plot [0.1:10] x**2
Per uscire dalla scala logaritmica, basta scrivere il comando unset logscale.
A volte può essere utile un grafico che abbia la stessa scala lungo l’asse x e y. Il comando da utilizzare è il
seguente:
set size ratio -1
Altri comandi utili sono i seguenti:
G Per mettere un’etichetta sull’asse delle x o delle y, si scrive il comando
set xlabel "nome da mettere su asse x"
dove tra apici si scrive l’etichetta dell’asse delle x. Se il grafico è stato già fatto, si digita il comando
replot. Analogamente, per scrivere un’etichetta sull’asse delle y si usa
set ylabel "nome da mettere su assse y"
G Si può cambiare il tipo di formato con cui sono rappresentati i numeri sull’asse delle ascisse o delle
ordinate. Il caso interessante da vedere si ha quando si hanno grafici semilogaritmi e si vuole usare una
scala esponenziale per visualizzare l’asse delle y. Un esempio è:
set format y "%4.2e"
Si ha una rappresentazione in formato esponenziale con due cifre nella mantissa e una lunghezza totale
del numero pari a quattro: per esempio 1.00e-11.
205
A. C ENNI SU G NUPLOT
1.0000 1.5403
2.0000 3.5839
3.0000 8.0100
4.0000 15.3464
5.0000 25.2837
6.0000 36.9602
7.0000 49.7539
8.0000 63.8545
9.0000 80.0889
10.0000 99.1609
Per fare il grafico, dobbiamo caricare il file nell’ambiente gnuplot e far capire che la prima colonna
corrisponde ai valori da mettere sull’asse delle x e la seconda ai valori da mettere sull’asse delle y.
Sia il file dati.dat nella directory in cui viene lanciato il programma gnuplot. In ambiente gnuplot si
digita il comando:
plot 'dati.dat'
e viene creato il grafico per punti. Se si vuole un grafico per linee o per linee e punti basta scrivere
plot 'dati.dat'with lines
oppure
plot ’dati.dat’ with linespoints. Osserviamo che sul grafico, la legenda mostra il nome del file
206
A.4. Grafici da files di dati
(nel nostro caso ’dati.dat’). Se vogliamo cambiare, si usa il comando title nel modo seguente:
plot 'dati.dat' title "nuova legenda"
dove la nuova legenda è scritta tra doppi apici. Il comando title si può usare anche per i grafici di funzioni.
Si può lavorare sul grafico così come è stato visto per le funzioni. Se si vuole un grafico semilogaritmico
o logaritmico, prima dell’istruzione plot si scrivono i comandi che abbiamo visto, set logscale ...
Analogamente a quanto visto nella Sezione precedente, si può salvare il grafico su file.
Se sul file di dati sono scritti dei commenti, le righe devono essere precedute dal simbolo cancelletto #.
Se abbiamo dati salvati su più files, da inserire nello stesso grafico, si opera nel modo seguente. Suppo-
niamo di avere i due files dati1.dat e dati2.dat. Il comando (base) in ambiente gnuplot da lanciare è:
plot 'dati1.dat', 'dati2.dat'.
Per specificare il tipo di linea, la legenda (e tutto quello che abbiamo già visto per un grafico), basta
inserire le istruzioni che servono relativamente a ciascuna curva. Per esempio:
# x y z
# sin(x) cos(x)
0.00000 0.00000 1.00000
0.31416 0.30902 0.95106
0.62832 0.58779 0.80902
0.94248 0.80902 0.58779
1.25664 0.95106 0.30902
1.57080 1.00000 0.00000
207
A. C ENNI SU G NUPLOT
Figura A.8: Grafico del file multi.dat mediante le istruzioni che personalizzano la legenda.
A.5 Script
A volte, specie se le figure devono essere salvate in un file, conviene scrivere tutte le istruzioni in uno
script, cioè in un file in cui le righe di commento sono precedute dal simbolo # mentre sulle altre righe
scriviamo i comandi che vanno eseguiti in ambiente gnuplot.
Ad esempio, scriviamo (con un editor che salva in formato testo – lo stesso che usiamo per scrivere i
programmi Fortran) il file istr.gnu (possiamo dare anche un’altra estensione che ci ricordi gnuplot, per
esempio istr.gp):
set logscale y
set terminal jpeg
208
A.6. Print
set logscale y
set terminal jpeg
set output "logfig.jpeg"
plot [1:20] exp(2)*(1/x)**2
unset logscale
set terminal wxt 0
Un’ultima osservazione riguarda l’uso degli apici nei comandi descritti precedentemente: usare il sim-
bolo 'o il simbolo "può essere usato indifferentemente là dove abbiamo usato l’uno o l’altro nei comandi di
prima (nomi dei files di dati, legende, titoli,...).
A.6 Print
Gnuplot può essere usato anche come una calcolatrice: basta scrivere print seguito dalla formula da
valutare.
Esempi
G print cos(pi)
produce il risultato -1.0
G print exp(-5)
dà 0.00673794699908547
209
B IBLIOGRAFIA
[2] B JÖRK , A. e D AHLQUIST, G. (2008), Numerical Methods in Scientific Computing, Volume II, Siam.
[4] D AHLQUIST, G. e B JÖRK , A. (2006), Numerical Methods in Scientific Computing, Volume I, Siam.
[7] G IANGRANDI , P. (2010), Dispense del corso di Storia dell’Informatica, Università degli Studi di Udine,
Italia.
[8] G IANGRANDI , P. (ultima visita: febbraio 2012), Museo on line - Breve storia degli Strumenti di Calcolo,
Tecnoteca, http://www.tecnoteca.it/museo/.
[9] K EISLER , H. J. (2009), Elementary Calculus, An Infinitesimal Approach, Creative Commons Attribution
Non-Commercial-ShareAlike License, http://www.math.wisc.edu/~Keisler/calc.html.
[10] M OORE , H. (2008), MATLAB® per l’ingegneria, Pearson Prentice Hall, Italy.
[11] O’C ONNOR , J. e R OBERTSON , E. F. (ultima visita: febbraio 2012), The MacTutor History of Mathematics
archive, University of St Andrews Scotland, http://www-gap-dcs.st-and.ac.uk/~history/.
[12] S ARTORETTO, F. e P UTTI , M. (2008), Introduzione alla Programmazione per Elaborazioni Numeriche.,
Edizioni Libreria Progetto, Padova.
[14] S WADE , D. (ultima visita: febbraio 2012), The Babbage Engine, Computer History Museum, Mountain
View, CA, http://www.computerhistory.org/babbage.
211