Guida al FORTRAN applicato
Transcript
Guida al FORTRAN applicato
Guida al FORTRAN applicato Lorenzo Zaninetti [email protected] Dipartimento di Fisica Generale Edizione III 4 marzo 2015 ii Introduzione Questa guida cerca di combinare due esigenze molto sentite al secondo anno del corso di Laurea in Fisica: un corso di introduzione ad un linguaggio di programmazione scientifica e alcuni esempi di programmi ( funzionanti ! ) per l’ elaborazione dei dati raccolti durante le esperienze di laboratorio. Abbiamo quindi dedicato il capitolo uno ad una introduzione concisa al linguaggio di programmazione FORTRAN ed il capitolo due alla descrizione dei programmi per l’ elaborazione dei dati che possono essere usati dagli studenti in ambiente MS/DOS oppure LINUX oppure UNIX. Per soddisfare le esigenze degli studenti degli anni superiori riportiamo nel capitolo tre alcune subroutine di interesse fisico-matematico che sono utilissime nei calcoli numerici di probabilità e statistica scritte in FORTRAN-77 standard. In realtà questa guida può essere anche utile agli studenti degli anni superiori e quindi dedichiamo il capitolo quattro ai programmi del frattali e il capitolo cinque a quelli dei sistemi Monte Carlo. L’ appendice A riporta le funzioni intrinseche che possono essere richiamate dai programmi, l’ appendice B alcune subroutines di interesse comune, l’ appendice C introduce alcuni cenni del sistema operativo UNIX, l’ appendice D riporta i caratteri ASCII, l’ appendice E i comandi del compilatore FORTRAN della MICROSOFT . iii CAPITOLO 0. INTRODUZIONE iv Indice Introduzione iii 1 Il Fortran-77 1.1 Alcuni libri . . . . . . . . . . . 1.2 Caratteri e linee . . . . . . . . 1.3 Lunghezza della linea . . . . . 1.4 Linea di commento . . . . . . . 1.5 Linea iniziale e di continuazione 1.6 Nomi simbolici . . . . . . . . . 1.7 Nomi locali e globali . . . . . . 1.8 Parole chiave . . . . . . . . . . 1.9 Etichette . . . . . . . . . . . . 1.10 Tipi di dati e costanti . . . . . 1.11 Unità di memoria . . . . . . . 1.12 Tipo INTEGER . . . . . . . . 1.13 Tipo REAL . . . . . . . . . . . 1.14 Tipo DOUBLE PRECISION . 1.15 Tipo COMPLEX . . . . . . . . 1.16 Tipo LOGICAL . . . . . . . . . 1.17 Tipo Character . . . . . . . . . 1.18 Vettori . . . . . . . . . . . . . 1.19 Sottostringa CHARACTER . . 1.20 Espressioni . . . . . . . . . . . 1.21 Espressioni aritmetiche . . . . 1.22 Espressioni costanti intere . . . 1.23 Espressioni CHARACTER . . 1.24 Espressioni di relazione . . . . 1.25 Espressioni logiche . . . . . . . 1.26 Struttura del programma . . . v . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 3 3 3 5 5 5 6 6 6 6 7 7 8 8 8 8 9 9 10 11 11 12 13 14 INDICE INDICE 1.27 1.28 1.29 1.30 1.31 1.32 1.33 1.34 1.35 1.36 1.37 1.38 1.39 1.40 1.41 1.42 1.43 1.44 1.45 1.46 1.47 1.48 1.49 1.50 1.51 1.52 1.53 1.54 1.55 1.56 1.57 1.58 1.59 1.60 1.61 1.62 1.63 1.64 1.65 Classi di istruzione . . . . . . . . . Ordine delle istruzioni . . . . . . . Sequenza di esecuzione . . . . . . . Unità principale del programma . Unità di programma FUNCTION Funzioni di referenza . . . . . . . . Funzioni istruzione . . . . . . . . . Funzioni intrinseche . . . . . . . . Sottoprogrammi SUBROUTINE . Istruzione CALL . . . . . . . . . . Argomenti della subroutine . . . . Dimensione tramite PARAMETER Dimensione tramite numeri . . . . Dimensione tramite * . . . . . . . Istruzione RETURN . . . . . . . . Istruzione ENTRY . . . . . . . . . Istruzioni di specificazione . . . . . Istruzione IMPLICIT . . . . . . . Istruzione PARAMETER . . . . . Dichiarazioni dei vettori . . . . . . Istruzioni tipologiche . . . . . . . . Istruzione DIMENSION . . . . . . Istruzione COMMON . . . . . . . Istruzione EQUIVALENCE . . . . Istruzione EXTERNAL . . . . . . Istruzione INTRINSIC . . . . . . . Istruzione SAVE . . . . . . . . . . Istruzione DATA . . . . . . . . . . Istruzioni di assegnazione . . . . . Assegnazioni aritmetiche . . . . . . Assegnazioni logiche . . . . . . . . Assegnazioni CHARACTER . . . . Istruzione ASSIGN . . . . . . . . . Istruzioni di controllo . . . . . . . Istruzione GO TO incondizionata . Istruzione GO TO calcolata . . . . Istruzione GO TO assegnata . . . Blocco IF . . . . . . . . . . . . . . Istruzione IF logica . . . . . . . . vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 15 17 17 17 18 19 19 19 20 20 21 21 22 22 22 23 23 23 24 25 25 25 26 26 27 27 28 28 28 29 29 29 30 30 30 31 31 32 INDICE 1.66 1.67 1.68 1.69 1.70 1.71 1.72 1.73 1.74 1.75 1.76 1.77 1.78 1.79 1.80 1.81 1.82 1.83 1.84 1.85 1.86 1.87 INDICE Istruzione IF aritmetica . . . . Istruzione DO . . . . . . . . . Istruzione DO-WHILE . . . . . Istruzione CONTINUE . . . . . Istruzione STOP . . . . . . . . Istruzione PAUSE . . . . . . . Istruzioni di INPUT/OUTPUT Nozioni generali . . . . . . . . Record . . . . . . . . . . . . . File . . . . . . . . . . . . . . . Accesso ai file . . . . . . . . . . File interni . . . . . . . . . . . Istruzione OPEN . . . . . . . . Istruzione CLOSE . . . . . . . . Istruzione INQUIRE . . . . . . Istruzioni READ/WRITE . . . Istruzione REWIND . . . . . . Istruzione BACKSPACE . . . . Istruzione ENDFILE . . . . . . La specificazione FORMAT . . Descrittori ripetibili . . . . . . Descrittori non ripetibili . . . . 2 Il Laboratorio 2.1 RETTA . 2.2 PARABO 2.3 PENDO . 2.4 CAVEN . 2.5 GAUSS . 2.6 TESTT . 2.7 TESTC2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Probabilità e statistica 3.1 Gamma . . . . . . . 3.2 Fattoriale . . . . . . 3.3 Funzione beta . . . . 3.4 Gamma incompleta . 3.5 Funzione errori . . . 3.6 Distribuzioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 32 33 34 35 35 35 36 36 37 37 38 38 39 40 40 41 42 42 43 43 45 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 47 50 52 60 74 79 80 . . . . . . 85 85 86 88 88 91 92 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INDICE INDICE 3.6.1 Distribuzione del chiquadro . . 3.6.2 Distribuzione Beta incompleta . 3.6.3 Distribuzione di Student . . . . 3.7 Numeri random . . . . . . . . . . . . . 3.7.1 Generatori di sistema . . . . . . 3.7.2 Generatore Random - portatile 3.7.3 Generatore di interi . . . . . . . 3.7.4 Distribuzione esponenziale . . . 3.7.5 Distribuzione Gaussiana . . . . 3.8 Momenti . . . . . . . . . . . . . . . . . 3.9 Test di Student . . . . . . . . . . . . . 3.10 Fit con retta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 93 95 95 95 96 97 98 99 101 103 105 4 I frattali 4.1 Henon mapping . . . . . 4.2 Feigenbaum mapping . . 4.3 Mandelbrot-set . . . . . 4.4 Implementazione dei set 4.5 Set di Julia e derivati . . 4.6 Le trasformazioni affini . 4.7 Il sistema L . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 . 109 . 112 . 115 . 116 . 120 . 120 . 128 5 Sistemi Monte Carlo 5.1 DLA . . . . . . . . . . 5.2 Aggregazione ballistica 5.3 Percolazione . . . . . . 5.4 Catene di Voronoi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A Funzioni intrinseche 135 135 144 150 158 167 B Subroutine di interesse comune 175 B.1 CLEANTOP . . . . . . . . . . . . . . . . . . . . . . . . 175 B.2 MAXMIN . . . . . . . . . . . . . . . . . . . . . . . . . . 176 C Sistema operativo UNIX C.1 Alcuni comandi UNIX . . . . C.2 Editor . . . . . . . . . . . . . C.3 Compilazione+link/esecuzione C.4 Shell Script . . . . . . . . . . viii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 . 177 . 178 . 179 . 179 INDICE INDICE C.5 Le librerie . . . . . . . . . . . . . . . . . . . . . . . . . . 180 D I caratteri ASCII 181 ix INDICE INDICE x Capitolo 1 Il Fortran-77 Il linguaggio di programmazione FORTRAN, contrazione delle parole FORmula TRANslation, è un linguaggio per la soluzione di problemi computazionali. A causa della sua somiglianza con il familiare linguaggio aritmetico semplifica enormemente la preparazione dei problemi da sottoporre alla macchina. Fu implementato per la prima volta nel 1956 e disponibile per gli utenti dal 1957. Negli anni tra il 1957 e il 1966 il linguaggio subı̀ alcuni cambiamenti e fu standardizzato dall’ American National Standards Institute (ANSI) nel 1966. Questa versione, essendo la quarta dalla nascita del linguaggio, assunse il nome di FORTRAN IV. Il FORTRAN77 è l’ ultima implementazione ufficiale del FORTRAN-IV: commissionato all’ ANSI per migliorare il linguaggio precedente e renderlo più portabile, è stato finito nel 1977 ed è stato pubblicato come ANSI standard X3-9-1978. Successivamente è stato adottato dalle maggiori compagnie e adesso funziona su tutti i PC e main frame. Infatti, in FORTRAN, sia i dati che le istruzioni sono organizzati in una sequenza di istruzioni, chiamata normalmente codice sorgente. Un codice sorgente scritto in FORTRAN può essere eseguito su qualunque computer possegga un compilatore, con poche o nessuna modifica. Queste ultime dipendono dal fatto che diverse case costruttrici forniscono implementazioni al linguaggio legate alle possibilità del tipo di computer che esse fabbricano. Occorre quindi, ad esempio, fare attenzione nel trasferimento di codici sorgente (o file) da UNIX/LINUX a personal computer. 1 1.1. ALCUNI LIBRI 1.1 CAPITOLO 1. IL FORTRAN-77 Alcuni libri Prima di continuare introduciamo brevemente una lista di libri che possono essere utili per chi volesse avventurarsi in una trattazione più completa 1. Un’ introduzione ingegneristica alla programmazione stile Politecnico si trova in [Or 86]. Troverete anche una utile serie di esercizi e l’ associazione fra metalinguaggio e codice FORTRAN. 2. Una trattazione completa viene invece sviluppata in [El 85]. Vengono svolti o proposti molti esercizi. 3. Una trattazione sommaria viene invece svolta in [Do 83]. 4. Un riassunto di tutte le istruzioni si trova invece in [Pa 83] : un manualetto tascabile in inglese. 1.2 Caratteri e linee L’ insieme dei caratteri in FORTRAN consiste di 26 lettere dalla A alla Z, le 10 cifre da 0 a 9 e dai seguenti 13 caratteri speciali: ⇒ + − ∗ ⇒ ⇒ piu‘ meno asterisco ⇒ spazio = ⇒ eguale ⇒ / ( ⇒ barra (slash) parentesi sinistra ) ⇒ parentesi destra . ⇒ punto decimale ⇒ , 0 virgola : ⇒ due punti ⇒ apostrof o 2 CAPITOLO 1. IL FORTRAN-77 < ⇒ > ⇒ $ ⇒ 1.3. LUNGHEZZA DELLA LINEA minore maggiore simbolo corrente Attualmente il simbolo corrente può avere un valore diverso a seconda della tastiera usata: non ha però una funzione precisa in FORTRAN e quindi si può usare come simbolo di continuazione. Il carattere spazio è ignorato dappertutto eccetto che nelle variabili CHARACTER e quindi può essere usato a piacere per migliorare la leggibilità dei programmi. 1.3 Lunghezza della linea Il compilatore fa uso solamente delle prime 72 colonne in ogni linea: dalla colonna 73 in poi si possono mettere dei simboli di identificazione. Nelle linee di istruzione, le colonne da 1 a 5 sono riservate come etichetta, la numero 6 ai segni di continuazione e quelle dal 7 al 72 per l’ istruzione stessa. Una linea di commento può essere adoperata dalla colonna 2 in poi. Questa tipologia deriva dall’ impostazione originaria tramite scheda, vedi figura 1.1. 1.4 Linea di commento Qualsiasi linea con i caratteri C o * in prima colonna viene considerata una linea di commento. Le linee di commento non contano nulla ai fini della compilazione ed in esse si può inserire qualsiasi tipo di carattere: di solito vengono usate per annotazioni nelle varie parti del programma. La linea composta di spazi nelle sue prime 72 colonne è equivalente ad uno spazio solo; ossia non conta ai fini della compilazione. 1.5 Linea iniziale e di continuazione Una linea di istruzione è caratterizzata da uno spazio oppure da uno zero nella colonna 6; dalla 1 alla 5 devono esserci degli spazi oppure una etichetta. Qualsiasi istruzione, eccetto l’ END, può continuare su linee seguenti fino ad un totale di 20 linee ( una iniziale e 19 di continuazione ): le linee di commento possono essere frammezzate e quindi non contano. Ogni linea di continuazione deve avere spazi dalla 3 1.5. LINEA INIZIALE E DI CONTINUAZIONE CAPITOLO 1. IL FORTRAN-77 Figura 1.1: La scheda 4 CAPITOLO 1. IL FORTRAN-77 1.6. NOMI SIMBOLICI colonna 1 alla colonna 5 e il simbolo di continuazione in colonna 6. Il simbolo di continuazione può essere qualsiasi carattere FORTRAN eccetto, chiaramente, lo spazio o lo zero. 1.6 Nomi simbolici Si può usare un nome simbolico per identificare entità FORTRAN come costanti, variabili, vettori, funzioni e subroutines, blocchi common e unità di programma. Un nome simbolico è formato da una a 6 lettere o numeri,con la condizione che il primo carattere sia una lettera. In alcuni casi, come per esempio in UNIX, i nomi possono essere più lunghi ma,di conseguenza, non sono trasportabili su tutti i sistemi. La prima lettera determina il tipo di variabile ma questa regola può essere ignorata usando una particolare specificazione. Normalmente abbiamo tipi INTEGER dalla lettera I alla N e REAL negli altri casi e questa situazione viene solitamente descritta dalla istruzione IMPLICIT. 1.7 Nomi locali e globali I nomi di tutte le unità di programma, punti di entrata e blocchi COMMON sono nomi globali, cioè comuni a tutto il programma: per questo motivo devono essere unici. Il nome di costanti, variabili, vettori e funzioni di istruzione sono locali, limitati all’ unità in uso, e quindi possono essere adoperati per un’ altro scopo in un’ altra parte del programma. Sovente, però, nome locale e globale devono essere differenti. 1.8 Parole chiave Una parola chiave è una sequenza di caratteri con un significato predefinito per il compilatore (per esempio istruzioni FORTRAN). Molte di esse ( ad esempio DATA, IF, CLOSE, ERR ) hanno la forma di un nome simbolico valido: l’ interpretazione come parola chiave o come nome simbolico dipende solo dal contesto. Nel dubbio però è meglio evitare i nomi delle istruzioni FORTRAN come nomi di variabili per evitare errori di compilazione o di esecuzione. 5 1.9. ETICHETTE 1.9 CAPITOLO 1. IL FORTRAN-77 Etichette Un’ istruzione di etichetta è un numero intero da 0 a 99999, senza segno, scritto nelle colonne da 1 a 5 della linea di istruzione. L’ etichetta non deve essere allineata a destra e caratteri (spazio) e 0 posti davanti sono ignorati; deve essere unica nel programma e non può essere messa su una linea di continuazione. Le etichette possono comparire non in ordine numerico. L’ istruzione FORMAT deve sempre avere un’ etichetta; qualsiasi altra istruzione eseguibile può avere un’ etichetta, compresa l’ istruzione END. 1.10 Tipi di dati e costanti Qualsiasi costante, variabile, vettore, espressione o funzione deve appartenere a uno di sei tipi di dati: INTEGER, REAL, DOUBLE PRECISION, COMPLEX, LOGICAL O CHARACTER. Il numero di tipi può aumentare in alcune implementazioni: si ha, ad esempio, doppia precisione sulle variabili COMPLEX ( vedi UNIX-FORTRAN). Interi, reali, doppia precisione e complessi sono tipi aritmetici e la conversione tra di essi è fatta automaticamente in assegnazioni aritmetiche, DATA e PARAMETER. La conversione invece non è automatica nelle chiamate interne tipo SUBROUTINE e FUNCTION. 1.11 Unità di memoria Ogni variabile o elemento di vettore di tipo INTEGER, REAL, DOUBLE PRECISION o LOGICAL occupa un’ unità di memoria numerica. Qualsiasi variabile o elemento di vettore in DOUBLE PRECISION o COMPLEX occupa due unità di memoria numerica. Ogni variabile oppure elemento di vettore di tipo CHARACTER occupa un’ unità di tipo CHARACTER. Il rapporto fra le due unità dipende dalla macchina usata. 1.12 Tipo INTEGER In una variabile INTEGER si memorizza un numero intero, che è rappresentato esattamente nella macchina. Il range coperto dipende da 6 CAPITOLO 1. IL FORTRAN-77 1.13. TIPO REAL macchina a macchina e nel UNIX-FORTRAN abbiamo: integer ∗ 2 integer ∗ 4 da da − 32768 a 32768 − 2147483648 a 2147483648 . In unità UNIX-FORTRAN una variabile integer*2 occupa 2 bytes mentre quella integer*4 ne occupa 4. 1.13 Tipo REAL Ogni variabile REAL memorizza un numero in virgola mobile, con o senza segno. Seppure lo zero e i numeri interi piccoli siano memorizzati in maniera corretta, i numeri con virgola mobile sono approssimati con una certa precisione che, seppure piccola, è finita e dipende dalla macchina. Nel UNIX-FORTRAN i numeri con virgola mobile variano: real ∗ 4 da 0.79E − 38 a 1.78E + 38 real ∗ 8 da 0.56E − 308 a 0.9E + 308 Una costante reale deve contenere un punto ( che rappresenta la virgola ) o un esponente che specifichi la potenza di 10 applicata alla variabile, o ambedue. Il segno è un optional da mettersi di fronte al numero o all’ esponente. Esempi di costanti espresse in maniera valida: −1. 3.14159 + 5E3 6.67E − 18 Sul UNIX-FORTRAN una variabile real *4 ( precisione singola ) occupa 4 bytes. 1.14 Tipo DOUBLE PRECISION La DOUBLE PRECISION è simile a quella REAL ma memorizza un numero in virgola mobile con una precisione maggiore. Anche quı̀la precisione dipende dalla macchina usata. Scriviamo qualche esempio: −1D0 3.141592653589793238462643D0 + 5D3 6.67D − 18 Sul UNIX-FORTRAN una variabile real*8 (o doppia precisione) occupa 8 bytes. Notiamo che l’ esponente viene preceduto dalla lettera D e deve sempre essere indicato, anche se nullo. 7 1.15. TIPO COMPLEX 1.15 CAPITOLO 1. IL FORTRAN-77 Tipo COMPLEX Una variabile COMPLEX consiste in un paio ordinato di numeri reali, rappresentanti della parte reale e immaginaria di un numero complesso ed è scritta con due costanti reali o intere separate da una virgola e contenute tra parentesi, la seconda delle quali rappresenta la parte immaginaria: (1, 50) (3.14, −2E3) (−.123, +4567) 1.16 Tipo LOGICAL Una variabile LOGICAL memorizza solo due valori, .true. oppure .f alse., ed occupa un byte: è quindi indicata per operazioni che richiedono molti bytes di memoria. 1.17 Tipo Character I dati di tipo CHARACTER sono stati introdotti per la memorizzazione e la manipolazione di testi. Ogni variabile CHARACTER può memorizzare una stringa completa di caratteri, ma la sua occupazione deve essere dichiarata all’ inizio del programma. In particolare in UNIX-FORTRAN bisogna specificare il numero di caratteri e quindi di bytes, per esempio character ∗ 6 character ∗ 15 ⇒ ⇒ 0 0 ERRORE 0 T ROP P I ELEM EN T I 0 Le stringhe sono definite da apostrofi (’) o virgolette (). La costante di Hollerith del FORTRAN-IV è stata completamente sostituita da questo tipo di variabili ( per fortuna ! ). 1.18 Vettori Un vettore è un set ordinato di dati (tutti dello stesso tipo) riferito ad un singolo nome simbolico. Il numero di dimensioni di un vettore può arrivare ad un massimo di sette. Nel FORTRAN77 qualsiasi dimensione può avere un limite inferiore diverso da uno e gli intervalli di variabilità 8 CAPITOLO 1. IL FORTRAN-77 1.19. SOTTOSTRINGA CHARACTER devono essere dichiarati nelle istruzioni COMMON o DIMENSION. L’ elemento individuale viene chiamato specificando il nome simbolico e un insieme di indici, uno per ogni dimensione. Qualsiasi indice di un vettore deve avere un valore compreso fra i due limiti dichiarati in quella dimensione. L’ indice può essere un intero complesso quanto si vuole, può includere la chiamata di un altro vettore oppure chiamate a funzioni intrinseche od esterne. Riportiamo alcuni esempi: matrice(0, −12) hyper(i, j, l, m, n) dlist(mod(npts, 4)) D(k(N (index))) 1.19 Sottostringa CHARACTER Una sottostringa specifica un set di caratteri adiacenti dislocati in una variabile CHARACTER. Una sottostringa consiste nella specificazione dell’ elemento seguito da due interi separati da : e rinchiusi fra parentesi. Facciamo un esempio concreto: CHARACT ER ∗ 8 regioni(1 : 23) regioni(55) =0 P IEM ON T E 0 regioni(55)(2 : 5) =0 IEM O0 1.20 Espressioni Essendo un linguaggio essenzialmente computazionale, un gran numero di istruzioni FORTRAN impiega espressioni. La valutazione di una espressione dà come risultato un singolo valore che può essere usato per definire una variabile, può entrare in una decisione logica, può essere scritto in un file, etc. La forma più semplice di una espressione è un valore scalare: una costante o una variabile singola. Espressioni più complesse vengono spesso formate con operazioni che coinvolgono uno o più operandi. Ci sono quattro tipi di espressioni disponibili in FORTRAN 77: aritmetiche, CHARACTER, di relazione e logiche. 9 1.21. ESPRESSIONI ARITMETICHE 1.21 CAPITOLO 1. IL FORTRAN-77 Espressioni aritmetiche Un’ espressione aritmetica è usata per specificare un calcolo numerico che deve essere svolto dal calcolatore. Consiste di uno o più operandi ( interi, reali, doppia precisione oppure complessi ) combinati con operatori aritmetici. Un’ espressione può anche contenere una sottoespressione in parentesi e referenze a funzioni standard. Il risultato di un’ espressione aritmetica è un valore numerico del tipo specificato. Elenchiamo le possibili operazioni: somma(identità) ⇒ ⇒ sottrazione(negazione) moltiplicazione divisione ⇒ + ⇒ − ∗ / elevazione a potenza ⇒ ∗∗ L’ ordine di valutazione di un’ espressione è: 1. sottoespressioni in parentesi, 2. funzioni standard, 3. esponente, 4. moltiplicazione o divisioni, 5. addizioni, sottrazioni o negazioni. In ogni gruppo la valutazione procede da sinistra verso destra eccetto che per gli esponenti che sono valutati da destra a sinistra. Cosicchè A/B/C è equivalente ad (A/B)/C mentre A**B**C è equivalente ad A** (B**C). Si possono mescolare tutte le combinazioni dei quattro tipi fondamentali tra di loro eccetto che quelle COMPLEX con quelle di DOUBLE PRECISION. Se gli operandi di una espressione aritmetica sono dello stesso tipo il risultato sarà anch’ esso dello stesso tipo. Se i tipi sono diversi, viene applicata ad uno di essi un tipo di conversione implicita. La direzione adoperata sarà: IN T EGER ⇒ REAL ⇒ COM P LEX o DOU BLE P RECISION 10 CAPITOLO 1. IL FORTRAN-77 1.22. ESPRESSIONI COSTANTI INTERE La sola eccezione a queste regole di conversione è l’ elevazione a potenza con esponente intero. Se la potenza è negativa, si valuta l’ inverso della potenza positiva: 2 ∗ ∗(−3) ⇒ 1/(2.0 ∗ ∗3) ⇒ 1/8.0 ⇒ 0.125 Altrimenti la potenza è calcolata con i logaritmi cosicchè A**B sarà calcolato con la formula EXP(B * LOG (A)) dove EXP e LOG sono funzioni standard del compilatore. La divisione fra interi produce un troncamento della parte frazionale. Esempi: −8/3 1.22 ⇒ −2 , 2 ∗ ∗(−3) ⇒ 1/(2 ∗ ∗3) ⇒ 1/8 ⇒ 0 Espressioni costanti intere Le espressioni aritmetiche in cui tutti gli operandi siano costanti o nomi simbolici, vengono chiamate espressioni aritmetiche costanti. Un’ espressione costante intera può essere usata per dichiarare i limiti di un vettore o la lunghezza di una variabile CHARACTER o usata per fissare i valori di una costante attraverso l’ istruzione PARAMETER. Per esempio: P ARAM ET ER (N P T = 50, N T OT AL = N P T ∗ ∗2) COM P LEX COEF F S (N P T S ∗ (N P T S − 1)) ARRAY (N T OT AL(2)) 1.23 Espressioni CHARACTER Una espressione CHARACTER produce un risultato di tipo CHARACTER ed è ottenuta usando operatori e operandi di tipo CHARACTER. Gli operandi di tipo CHARACTER possono essere: un valore scalare, un elemento di vettore, una sottostringa, una espressione CHARACTER chiusa tra parentesi, il risultato di una funzione CHARACTER. Esiste un unico operando CHARACTER denotato con // che permette di concatenare due stringhe. Esempio: A = 0 B = 0 ESEM P IO DI 0 P ROGRAM M A0 11 1.24. ESPRESSIONI DI RELAZIONE C = CAPITOLO 1. IL FORTRAN-77 0 SU BROU T IN E 0 A//B = 0 ESEM P IO DI P ROGRAM M A0 A//C = 0 ESEM P IO DI SU BROU T IN E 0 Ambedue gli apostrofi sono richiesti . Il valore della variabile CHARACTER è la stringa di caratteri fra gli apostrofi. Il suddetto valore non include gli apostrofi, include invece tutti gli spazi ed eventuali tabs inseriti fra i due apostrofi . Nella variable CHARACTER il carattere apostrofo è rappresentato da due apostrofi consecutivi con nessun spazio o carattere fra di loro (”) . La lunghezza della variabile CHARACTER è il numero di caratteri fra gli apostrofi, eccetto che due apostrofi consecutivi rappresentano un singolo apostrofo . La lunghezza di una variabile CHARACTER deve essere nel range da 1 a 2000 . Esempi I seguenti esempi rappresentano delle variabili CHARACTER valide ed invalide . Valide ’Cosa hai detto ?’ ’L”abbiamo trovato’ ’La risposta media è stata ”12:00” ’ Invalide ’La formula ” 1.24 Spiegazione manca l’ apostrofo finale la variabile CHARACTER deve contenere almeno un carattere Espressioni di relazione Un’ espressione di relazione dà un risultato di tipo logico (vero o falso) ed è formata da espressioni aritmetiche o CHARACTER e operatori di relazione. Abbiamo sei tipi di operatori di relazione: ⇒ .LT. .LE. ⇒ minore di minore di o uguale a 12 CAPITOLO 1. IL FORTRAN-77 .EQ. ⇒ 1.25. ESPRESSIONI LOGICHE uguale a . ⇒ .GT. .GE. ⇒ maggiore di maggiore di o uguale a ⇒ .N E. non uguale a Le variabili confrontate devono essere omogenee e ovviamente in campo complesso potremo solamente usare l’espressione .eq. o.ne.. Inoltre nei test di uguaglianza su variabili REAL o DOUBLE PRECISION, bisogna tenere conto della precisione adoperata. Il confronto tra variabili CHARACTER avviene carattere per carattere secondo la sequenza ASCII. Dato che la lettera A precede la lettera B nel codice ASCII, A è minore di B. Inoltre le lettere maiuscole hanno valori minori delle minuscole. 1.25 Espressioni logiche Un’ espressione logica consiste di operandi e operatori logici e ritorna un valore . true./.false .. Essa può essere usata nell’ espressione IF o blocco IF. Dato il termine logico lterm possiamo avere le seguenti espressioni logiche: (lterm) (.not. lterm) (lexp lop lterm) dove LTERM è la costante logica, variabile oppure elemento di vettore, LEXP un’ espressione logica e LOP uno degli operatori logici.AND.,.OR.,.EQV., o.NEQV.. Riportiamo l’ ordine di valutazione di un’ espressione di tipo logico: 1. Espressione aritmetica 2. Espressioni di relazione 3. operatore.NOT. 4. operatore.AND. 5. operatore.OR. 13 1.26. STRUTTURA DEL PROGRAMMA CAPITOLO 1. IL FORTRAN-77 Tabella 1.1: Tabella sugli operatori OR e AND L1 ed L2 sono espressioni logiche .OR. e.AND. sono operatori logici L1 L2 L1.OR.L2 L1.AN D.L2 .true. .true. .true. .f alse. .f alse. .true. .f alse. .f alse. .true. .true. .true. .f alse. .true. .f alse. .f alse. .f alse. 6. operatori.EQV. e.NEQV. L’ effetto degli operatori.OR. dà come risultato .true. se è vero uno dei due operandi mentre.AND. dà come risultato.true. se sono verificati tutti e due, vedi per esempio la seguente tabella: L’ operatore.EQV. dà come risultato.true. se entrambi gli operandi hanno lo stesso valore ( cioè entrambi veri oppure entrambi falsi ) mentre il secondo.NEQV. dà il risultato.true. se hanno valore opposto, come indicato nella tabella che segue: Attenzione che l’ operatore.EQV. (che esprime equivalenza ) logica e.NEQV. (non - equivalenza) non possono essere adoperati nella stessa espressione. Le parentesi vanno sempre utilizzate per semplificare l’ ordine di espressioni complicate. 1.26 Struttura del programma Un programma deve contenere un corpo principale, detto main. Può poi contenere diverse sottounità che possono essere di tre tipi: SUBROUTINE, FUNCTION e blocco DATA (procedura non eseguibile). 14 CAPITOLO 1. IL FORTRAN-77 1.27. CLASSI DI ISTRUZIONE Tabella 1.2: Tabella sugli operatori EQV e NEQV L1 ed L2 sono espressioni logiche EQV. e.NEQV. sono operatori logici L1 L2 .true. .true. .true. .f alse. .f alse. .true. .f alse. .f alse. 1.27 L1.EQV.L2 L1.N EQV.L2 .true. .f alse. .f alse. .true. .f alse. .true. .true. .f alse. Classi di istruzione Possiamo chiamare istruzioni tipologiche INTEGER, REAL, DOUBLE PRECISION, COMPLEX, LOGICAL e CHARACTER mentre IMPLICIT, PARAMETER, DIMENSION, COMMON, EQUIVALENCE, EXTERNAL, SAVE sono classificate come istruzioni di specificazione. PROGRAM, SUBROUTINE, FUNCTION, blocco DATA, FORMAT sono invece istruzioni di funzione e non sono eseguibili. Le istruzioni di assegnazione ( incluso ASSIGN ), tutte le forme di IF e GO TO, e inoltre ELSE, ELSEIF, END IF,DO, CONTINUE, CALL, RETURN, READ, WRITE, PRINT, OPEN, CLOSE, INQUIRE, REWIND, BACKSPACE, END FILE, STOP, PAUSE ed END sono classificate come istruzioni eseguibili. 1.28 Ordine delle istruzioni Nella scrittura del codice sorgente devono essere rispettate alcune regole di priorità con un certo ordine, vedi figura 1.2 . ♣ PROGRAM NOME ♣ Istruzioni di specificazione ♣ ........................ ♣ Istruzioni eseguibili ♣ ....................... 15 1.28. ORDINE DELLE ISTRUZIONI CAPITOLO 1. IL FORTRAN-77 +-------+--------------------------------------------------------+ | | Istruzione OPTIONS | | |--------------------------------------------------------| | | Istruzione PROGRAM, FUNCTION, SUBROUTINE,o BLOCCO DATA | | |--------+-----------------------------------------------| |COMMENT| | Istruzione IMPLICIT NONE | | Linee,| |-------------------------------+--------------| |INCLUDE|NAMELIST,| Istruzione IMPLICIT | | | Istru-| FORMAT, |------+------------------------| | | zioni,| & | | Altre Istruzioni | ISTRUZIONE | |& Gen- | ENTRY | DATA | di specificazione | PARAMETER | | erali | Istru- |Istru-| Istruzione DICTIONARY | | |Diret- | zioni | zioni|------------------------+--------------| | tive | | | Istruzioni Function Definizioni | | | | |---------------------------------------| | | | | Istruzioni Eseguibili | |-------+---------+------+---------------------------------------| | Istruzione END | +----------------------------------------------------------------+ Figura 1.2: Le priorità nelle istruzioni ♣ ♣ STOP END Questo significa, per esempio, che se si usa una istruzione di tipo IMPLICIT,questa deve precedere tutte le altre eccetto che PARAMETER, inseribile ovunque. Le linee di commento possono essere inserite in ogni punto eccetto che dopo l’ istruzione END, che deve essere sempre l’ ultima del programma. Nella figura che precede le linee verticali separano le istruzioni che possono essere mescolate. Per esempio l’ istruzione DATA può essere mescolata con istruzioni eseguibili. Le linee orizzontali invece separano istruzioni che non possono essere mescolate; per esempio le istruzioni di dichiarazione non possono essere mescolate con istruzioni eseguibili. 16 CAPITOLO 1. IL FORTRAN-77 1.29 1.29. SEQUENZA DI ESECUZIONE Sequenza di esecuzione L’ esecuzione parte con la prima istruzione eseguibile del programma main e continua sequenzialmente, soggetta però alle istruzioni di controllo come GO TO, IF, CALL, etc.. L’ esecuzione finisce con l’ istruzione END del programma principale o con uno STOP in qualsiasi parte del programma. Certi errori tipo OVERFLOW possono creare una fine prematura ma segnalata mentre altri, tipo superamento della memoria disponibile, provocano una fine non segnalata. 1.30 Unità principale del programma Il main incomincia con l’ istruzione PROGRAM e può contenere qualsiasi altra istruzione eccetto che: SUBROUTINE, FUNCTION oppure RETURN. La forma dell’ istruzione è: ♣ PROGRAM pnome dove pnome è un nome simbolico. Questa istruzione non è adoperata in altre parti del programma e quindi ha un significato principalmente di documentazione. 1.31 Unità di programma FUNCTION Una funzione ritorna un valore al punto, nell’ ambito di una espressione, in cui è stata chiamata. Quest’ unità comincia con l’ istruzione FUNCTION e può contenere qualsiasi altra istruzione eccetto che PROGRAM, SUBROUTINE o blocco DATA. Abbiamo due possibiltà di definizione: ♣ FUNCTION fnome ( a1, a2,.... an ) oppure ♣ tipo FUNCTION fnome (a1, a2,... an ) dove tipo va scelto fra INTEGER, REAL, DOUBLE PRECISION, COMPLEX, LOGICAL, CHARACTER o CHARACTER * len; fnome è il nome simbolico della funzione e a1, a2,.... an sono gli argomenti trasmessi. Si può anche non trasferire alcun argomento ma le parentesi devono ancora essere presenti. È meglio evitare che nella FUNCTION ci siano operazioni di PRINT/WRITE perchè non funzionerebbero ed 17 1.32. FUNZIONI DI REFERENZA CAPITOLO 1. IL FORTRAN-77 inoltre bisogna essere estremamente prudenti nel modificare gli argomenti indicati nell’ istruzione COMMON. Come esempio riportiamo la funzione MYSIN che calcola il seno del primo argomento con lo sviluppo in serie di Taylor e ritorna il numero dei termini dello sviluppo necessari ad avere una precisione di 10−7 . ♣ REAL FUNCTION MYSIN(P1,P2) ♣ REAL P1 ♣ DOUBLE PRECISION FACTRL ♣ INTEGER P2 ♣ MYSIN = P1 ♣ DO 10 P2 = 1,100 ♣ DELTA = (-1)**P2 * P1**(2*P2+1) / FACTRL(2*P2+1) ♣ IF (ABS(DELTA).LT. 1E-7) RETURN ♣10 MYSIN = MYSIN + DELTA ♣ RETURN ♣ END Bisogna fare attenzione a dichiarare la funzione chiamata nel programma principale; nel nostro caso dovremo mettere ♣ REAL MYSIN ♣ se poi la funzione è inserita in qualche libreria dovremo mettere EXTERNAL MYSIN 1.32 Funzioni di referenza Una funzione di referenza può occorrere come operando in qualsiasi espressione appropriata ed ha la forma del tipo: ♣ fnome ( a1,....., an) dove fnome è il nome della funzione. Quella più usate sono le funzioni matematiche che variano fortemente da macchina a macchina. Riportiamo l’ esempio dei numeri random fra 0 ed 1 in UNIX-FORTRAN: ♣ X = RAN (IGEN) dove IGEN deve essere un intero grande meglio se dispari. Le funzioni intrinsiche non vanno dichiarate perchè sono inserite nel compilatore. Per maggiori dettagli vedere l’ appendice A sulle funzioni intrinsiche. 18 CAPITOLO 1. IL FORTRAN-77 1.33 1.33. FUNZIONI ISTRUZIONE Funzioni istruzione Una istruzione di funzione può essere usata per specificare una relazione semplice ed è usata in una sola unità. Ovviamente essa deve precedere qualsiasi istruzione di esecuzione. È definita tramite una via simile alle istruzioni di assegnazione: ♣ fnome (a1,...,an) = exp dove fnome è il nome simbolico della funzione ed è seguito dagli argomenti fittizi, exp è una espressione che viene valutata utilizzando gli argomenti fittizi. Questi ultimi sono locali e possono essere usati indipendentemente nel resto del programma. Esempi: ♣ LOGICAL DIGIT ♣ CHARACTER CHAR ♣ DIGIT (CHAR ) = CHAR.GE.’0’.AND.CHAR.LE.’9’ ♣ VAB (X,Y,Z) = SQRT (XX**2 +Y**2 +Z**2) 1.34 Funzioni intrinseche Il FORTRAN contiene una quantità considerevole di funzioni incorporate, note come funzioni intrinseche, che vengono automaticamente messe a disposizione in qualsiasi parte del programma esse vengano chiamate. La maggior parte di queste funzioni ha un nome generico che elimina la necessità di cambiare nome in base al tipo di parametro usato. Su varie macchine troviamo poi funzioni intrinseche diverse a seconda del tipo di variabile utilizzata. Visto il loro numero notevole rimandiamo il lettore all’ appendice A per una lista aggiornata. 1.35 Sottoprogrammi SUBROUTINE Una subroutine è una procedura separata, definita come esterna rispetto all’ unità di programma che la chiama ed è specificata in una unità sottoprogramma. L’ istruzione SUBROUTINE seguita o meno dagli argomenti è l’ istruzione iniziale e in seguito si possono inserire tutte le istruzioni eccetto che PROGRAM, FUNCTION o blocco DATA. La forma può essere: ♣ SUBROUTINE snome (a1,....,an) oppure ♣ SUBROUTINE snome 19 1.36. ISTRUZIONE CALL CAPITOLO 1. IL FORTRAN-77 dove snome è il nome simbolico della subroutine e a1,....., an sono gli argomenti di entrata / uscita. La SUBROUTINE viene chiamata con l’ istruzione CALL e ovviamente al suo interno non può chiamare sè stessa direttamente o indirettamente. Le informazioni si possono trasferire al di fuori della subroutine mediante i suoi argomenti, i blocchi COMMON oppure file esterni. Si ritorna al main mediante l’ istruzione END oppure RETURN. 1.36 Istruzione CALL Questa istruzione è usata per eseguire una procedura specificata da una subroutine. Le forme sono del tipo: ♣ CALL SUBROUTINE snome (a1,....,an) oppure ♣ CALL SUBROUTINE snome 1.37 Argomenti della subroutine Normalmente l’ istruzione iniziale SUBROUTINE contiene una lista di parametri formali chiusi fra parentesi. La chiamata CALL ad una subroutine contiene una lista di parametri attuali che devono concordare esattamente in numero e tipo con i parametri formali. Durante l’ esecuzione di un’ istruzione CALL, le locazioni di memoria dei parametri attuali vengono passate alla subroutine in modo tale da permettere ai parametri formali di riferirsi alle stesse locazioni di memoria dei parametri attuali. Questi ultimi possono essere costituiti da: 1. una costante 2. un nome di variabile 3. il nome di un elemento di un vettore o del vettore stesso 4. una sottostringa di caratteri 5. un’ espressione 6. il nome una funzione intrinseca 7. il nome di una procedura esterna ( subroutine o funzione ) 20 CAPITOLO 1. IL FORTRAN-77 1.38. DIMENSIONE TRAMITE PARAMETER 8. il nome di una procedura formale 9. uno specificatore di ritorno alternativo ( vedi sotto ) I parametri formali possono essere invece costituiti da: • a) il nome di una variabile ( per i tipi 1 - 5 ) • b) il nome di un vettore ( per il tipo 3 ) • c) il nome di una procedura formale ( per i tipi 7 e 9 ) • d) un asterisco ( per il tipo 10 ) Se il parametro formale è una variabile di tipo CHARACTER, deve essere naturalmente dichiarato come tale e gli deve essere attribuita una certa lunghezza che deve essere inferiore o uguale alla lunghezza del parametro attuale; se è inferiore, verranno trattati come parametro formale solo i ’lun’ ( lun = lunghezza dichiarata nella SUBROUTINE ) caratteri più a sinistra del parametro attuale. Particolare attenzione va posta alle dimensioni dei vettori e possiamo avere tre tipi diversi di configurazioni: 1.38 Dimensione tramite PARAMETER ♣ SUBROUTINE LAVORO (VEC,N) ♣ DIMENSION VEC (1:N) dove VEC è il vettore di dimensione da uno ad N e N è definito nel main tramite l’ istruzione PARAMETER. 1.39 Dimensione tramite numeri ♣ SUBROUTINE LAVORO (VEC) ♣ DIMENSION VEC (1:1000) dove VEC è il vettore di dimensione da uno ad a 1000 e nel MAIN è definito nella stessa maniera. 21 1.40. DIMENSIONE TRAMITE * 1.40 CAPITOLO 1. IL FORTRAN-77 Dimensione tramite * ♣ SUBROUTINE LAVORO (A,B,C) ♣ DIMENSION A (1:*),B(0:*),C(-4:*) Questo tipo di dichiarazione è detto dichiarazione di vettore a dimensioni presunte, in quanto si suppone che il vettore sia abbastanza grande per tutti i riferimenti ad esso fatti nel corso del programma e non ha dimensioni definite. Se invece abbiamo l’ istruzione in blocchi COMMON abbiamo un associazione fra elementi corrispondenti; si abbia ad esempio ♣ SUBROUTINE SUB ( X,Y,Z) ♣ COMMON C e nell’ unità principale si abbiano le istruzioni seguenti: ♣ COMMON S ♣ CALL SUB (X1,Y1,Z1 ) Cosicchè sia X,Y,Z sono associati con X1, Y1, Z1 mentre C è associata con S. 1.41 Istruzione RETURN Questa istruzione fa terminare l’ esecuzione di una SUBROUTINE o di una FUNCTION e restituisce il controllo all’ unità di chiamata. La forma normale è: ♣ RETURN Può anche essere chiamata all’ interno di un if /end if. 1.42 Istruzione ENTRY Qualche volta può essere utile combinare due o più subroutines o funzioni in una sola per potere trarre vantaggio da una grossa porzione di codice in comune. Essa assume la forma del tipo: ♣ ENTRY enome (a1,....,an) dove enome è il nome di entrata seguito dai relativi argomenti, il cui numero deve essere uguale al numero di argomenti nella subroutine o funzione corrispondente. L’ uso di punti alternativi di ingresso è in conflitto con i principi di programmazione modulare ma può risultare conveniente in alcuni casi particolari. Bisogna evitare comunque che l’ istruzione ENTRY compaia in una qualsiasi struttura a blocchi 22 CAPITOLO 1. IL FORTRAN-77 1.43 1.43. ISTRUZIONI DI SPECIFICAZIONE Istruzioni di specificazione Le istruzioni di specificazione sono usate per definire le proprietà di entità simboliche, costanti, variabili, vettori, etc., usate in una unità di programma. Per questo motivo vengono anche chiamate istruzioni di dichiarazione e sono raggruppate nella sezione iniziale del codice sorgente, dopo l’ istruzione PROGRAM e prima di tutte le altre. Ricordiamo che non sono istruzioni eseguibili. In questo capitolo si esamineranno anche le istruzioni DATA, utilizzate per stabilire i valori iniziali di variabili e vettori presenti in un programma FORTRAN. 1.44 Istruzione IMPLICIT Il tipo di dati delle variabili o vettori usati nel programma può essere stabilito tramite un’ istruzione tipologica. La regola standard è che i nomi simbolici con la lettera iniziale da I ad N specificano variabili intere mentre gli altri sono reali. Con l’ istruzione IMPLICIT si può modificare questa situazione. Questo può essere utile per poter utilizzare allo stesso tempo variabili in precisione semplice e in doppia nelle stesse unità. Se usiamo il tipo CHARACTER deve essere specificata anche la lunghezza con un *len. Esempi: ♣ IMPLICIT REAL *4 (A-H,O-Z) ♣ oppure ♣ IMPLICIT REAL *8 (A-H,O-Z) ♣ oppure ♣ IMPLICIT REAL *4 (C-H,O-Z) ♣ IMPLICIT REAL *8 (A) ♣ IMPLICIT CHARACTER * 80 ( B) In questo ultimo esempio tutte le variabili saranno in semplice precisione eccetto che quelle inizianti con A ( precisione doppia ) e B ( variabile CHARACTER di lunghezza 80 ). 1.45 Istruzione PARAMETER Con questa istruzione si assegna un nome logico ad una costante, che può essere un numero oppure un’ espressione contenente altre costanti. Si possono trasportare le variabili cosı̀ definite in altre unità senza 23 1.46. DICHIARAZIONI DEI VETTORI CAPITOLO 1. IL FORTRAN-77 modificarle: il compilatore segnalerebbe in questo caso qualcosa di anomalo. Il tipo di costante o espressione deve chiaramente essere lo stesso del nome simbolico. Se il nome di un parametro CHARACTER ha la lunghezza specificata con un *(*), vale la lunghezza dichiarata in PARAMETER. Esempio: ♣ PARAMETER (LOGN=8, NPT = 2** LOGN) ♣ DIMENSION INDEX (1:LOGN), X(0:NPT) ♣ CHARACTER *(*) TITLE ♣ PARAMETER ( TITLE =’Tabella dei risultati’) ♣ PARAMETER ( PI = 3.14159,PI2 = 2*PI ) Esse risultano molto utili per dimensionare i vettori. 1.46 Dichiarazioni dei vettori Il nome di un vettore può comparire in più di una istruzione di specificazione ma la sua dimensione deve essere dichiarata solo una volta. Questo può essere fatto in una istruzione tipologica, in un COMMON oppure in un DIMENSION. I vettori possono avere fino a sette dimensioni, per ognuna delle quali si deve specificare un limite inferiore e superiore. Se non è specificato diversamente, il limite inferiore è uno. Esempi: ♣ PARAMETER (NPUNTI = 1000 ) ♣ REAL 8 4 (NPUNTI),Y(-5:5,0:NPUNTI -1),DUE(2,2,2,2) ♣ LOGICAL * 1 CUBO ♣ DIMENSION CUBO (1:NPUNTI,1:NPUNTI,1:NPUNTI) Se invece il vettore si trova in una subroutine abbiamo due possibilità: dimensione regolabile oppure fissa. Nel primo caso le dimensioni sono regolate dalla lista degli argomenti della subroutine oppure tramite il blocco COMMON: ♣ SUBROUTINE CALCOLA (X,NX,Y,NY, R,F) ♣ IMPLICIT REAL *8 (A-H,O-Z) ♣ COMMON NR,NF ♣ DIMENSION X (1:NX),Y(1:NY),F(0:NF),R(0:NR) Se invece vogliamo usare un vettore di dimensione fissa possiamo introdurre un * che rappresenta una dimensione indefinita. Esempio: ♣ FUNCTION ESPANDE (XX,YY) ♣ IMPLICIT REAL *8 XX, YY ♣ DIMENSION XX (*),YY(0:*) 24 CAPITOLO 1. IL FORTRAN-77 1.47 1.47. ISTRUZIONI TIPOLOGICHE Istruzioni tipologiche Queste sono usate per alterare ( o confermare ) il tipo di dati associati con un nome simbolico. Possono anche essere usate per specificare le dimensioni dei vettori. Una volta associato un tipo ad un nome simbolico, questo rimane invariato all’ interno dell’ unità di programma in cui è stato definito. Possiamo avere tipi LOGICAL, CHARACTER e aritmetici. Usando l’ istruzione CHARACTER bisogna ovviamente sempre specificare la lunghezza. Nel caso dell’ argomento fittizio di una SUBROUTINE possiamo mettere un *(*) che rappresenta una lunghezza e dimensione variabili. Esempio: ♣ DOUBLE PRECISION X, FUNZ, Z(100) ♣ CHARACTER * 30 NOME, INDIRIZZI (5)*20 ♣ LOGICAL * 1 CUBO (1:100,1:100) 1.48 Istruzione DIMENSION È usata per dare un nome simbolico e specificare la dimensione di un vettore. Il tipo di dati è implicito nel nome usato. La forma è del tipo: ♣ DIMENSION A1(D1),A2(D2)..... dove ogni An è un vettore e Dn specifica la dimensione; a sua volta Dn può essere scomposto in limite superiore e inferiore. 1.49 Istruzione COMMON Le istruzioni COMMON sono usate per dichiarare blocchi di variabili in comune con due o più unità del programma, secondo un ordine di memorizzazione consistente. Questo è possibile attraverso una struttura di dati FORTRAN chiamata blocco COMMON, che costituisce un blocco di memoria contiguo e assume la forma: ♣ COMMON /NOME/ nlist dove nome è il nome globale del blocco e nlist è la lista dei nomi delle variabili, dei vettori e dei dichiaratori di vettori locali. Si nota che un blocco COMMON non possiede un tipo. Una volta stabilito l’ ordine di memorizzazione in un blocco COMMON, qualsiasi unità di programma che dichiari lo stesso blocco COMMON, può riferirsi ai dati ivi memorizzati senza dover passare nomi simbolici attraverso liste di argomenti. L’ istruzione COMMON è un istruzione di specificazione e 25 1.50. ISTRUZIONE EQUIVALENCE CAPITOLO 1. IL FORTRAN-77 deve venire quindi dopo tutte le istruzioni IMPLICIT e precedere tutte quelle DATA. Esempio: ♣ INTEGER *2 ETA (1:50) ♣ REAL *4 LIVELLO (1:50,1:6) ♣ COMMON /ESAM/NUM,LIVELLO,ETA In questo caso nel blocco COMMON /ESAM/ abbiamo 1 + 300 + 50 = 351 unità. 1.50 Istruzione EQUIVALENCE L’ istruzione EQUIVALENCE fornisce un mezzo affinchè due o più variabili possano occupare la stessa dislocazione in memoria. Assume la forma: ♣ EQUIVALENCE (nlista1),(nlista2) Questo significa che la memorizzazione per tutti gli elementi della lista avviene con la stessa locazione di partenza. Gli elementi in questione possono essere di tipo e lunghezza differente. Facciamo un esempio: ♣ REAL *4 R(2), RL,IM ♣ COMPLEX *8 C ♣ EQUIVALENCE ( R,RL,C),(R(2),IM) Questo significa che R(1) e RL occupano la stessa dislocazione della parte reale di C mentre R(2) ed IM occupano la parte immaginaria di C. Le istruzioni COMMON ed EQUIVALENCE sono di difficile comprensione e diventano veramente utili in sistemi composti da molte subroutines tipo pacchetti grafici o matematici. 1.51 Istruzione EXTERNAL L’ istruzione EXTERNAL permette che nomi simbolici possano essere usati come argomenti in istruzioni CALL e in chiamate a funzioni, senza che il compilatore crei automaticamente una variabile nel momento della referenza. In pratica specifica che un nome è un simbolo globale definito fuori dell’ unità del programma. Si presentano due casi: • a) identificare sottoprogrammi o punti ENTRY passati come argomenti, 26 CAPITOLO 1. IL FORTRAN-77 1.52. ISTRUZIONE INTRINSIC • b) identificare un blocco DATA nel momento del link del programma. 1.52 Istruzione INTRINSIC Questa istruzione indica che un certo nome simbolico è una funzione intrinseca e può essere passata come argomento in istruzioni CALL e chiamate a funzioni. Il nome della funzione intrinseca specificato mantiene il tipo di variabile associato. Riportiamo un esempio sull’ uso di INTRINSIC/EXTERNAL: ♣ INTRINSIC SINH,COSH ♣ nna7 EXTERNAL MYFUNC ♣ CALL GRAPH (SINH) ♣ CALL GRAPH (MYFUNC) ♣ END ♣ SUBROUTINE GRAPH (FUNC) ♣ EXTERNAL FUNC ♣ CALL PLOT (FUNC,0.0, 3.14) ♣ END 1.53 Istruzione SAVE Il FORTRAN permette l’ allocazione in memoria sia dinamica che statica. Le variabili, i vettori e i blocchi COMMON dichiarati nell’ unità MAIN, sono allocati staticamente e mantengono sempre la loro definizione. Le variabili, i vettori e i blocchi COMMON dichiarati solo in sottoprogrammi vengono allocati dinamicamente al momento dell’ esecuzione del sottoprogramma. Quando questo esegue l’ istruzione RETURN o END, sono deallocati e perdono la loro definizione(e chiaramente il loro valore!). L’ istruzione SAVE permette di mantenere la definizione di queste variabili e di salvare il loro contenuto, specificandole in due diversi modi: ♣ SAVE nome1,nome2 ♣ SAVE Nel primo sono salvati nome1 e nome2, mentre nel secondo tutti gli argomenti della sottunità. IN UNIX-FORTRAN questo avviene già anche senza l’ istruzione SAVE. 27 1.54. ISTRUZIONE DATA 1.54 CAPITOLO 1. IL FORTRAN-77 Istruzione DATA Questa istruzione è adoperata per definire i valori iniziali delle variabili e dei vettori. Strettamente parlando non è un’ istruzione di specificazione, segue tutte le istruzioni di dichiarazione e prende effetto solamente quando il programma è inserito nella memoria. La forma è del tipo: ♣ DATA nlista/clista/nlista/clista/ dove ogni nlista è una lista di variabili, vettori, elementi di vettori, sottostringhe oppure liste di DO implicite; ogni clista è una lista di costanti che forniscono il valore iniziale. Le virgole separanti il simbolo / e nlista sono degli optional. I nomi di argomenti fittizi o funzioni non possono essere adoperati in codesta istruzione. Riportiamo alcuni esempi: ♣ PARAMETER (NX=64,NY=80,NTOTAL=NX*NY) ♣ REAL*4 ALLSET (NX,NY) ♣ DATA ALLSET /NTOTAL * 0.0 / ♣ CHARACTER * 8 A,B ♣ DATA A,B,C/’VOGLIAMO’/’TRONCARE’/ 1.55 Istruzioni di assegnazione Le istruzioni di assegnazione sono usate per assegnare un valore, usualmente quello di un’ espressione, ad una variabile o ad un elemento di vettore. Possono anche essere utilizzate per modificare i contenuti di locazioni di memoria assoluta. 1.56 Assegnazioni aritmetiche Le istruzioni di assegnazione aritmetica sono usate per assegnare un valore a variabili aritmetiche. Assumono la forma: v = espr dove v è una variabile o elemento di vettore di un certo tipo aritmetico ed espr è un’ espressione aritmetica. Se il tipo di espr è diverso da quello di v, allora il valore di espr viene convertito al tipo di v prima della memorizzazione: questo potrebbe causare dei troncamenti. 28 CAPITOLO 1. IL FORTRAN-77 1.57 1.57. ASSEGNAZIONI LOGICHE Assegnazioni logiche Le istruzioni di assegnazione logica assegnano un valore ad una variabile logica ed operano nello stesso modo delle assegnazioni aritmetiche: v = espr dove v è una variabile o elemento di vettore di tipo logico ed espr è un’ espressione logica o anche di tipo aritmetico. Questa ultima può contenere espressioni relazionali o espressioni di tipo CHARACTER. Se il tipo di espr non è logico, il valore assegnato a v è. false., se il valore di espr è zero, mentre è. true. se il valore di espr è diverso da zero. Esempio: ♣ LOGICAL LIMITE (1:10) ♣ REAL*4 R(1:100) ♣ LIMITE(J)=R(J).GE.RMIN.AND.R(J).LE.RMAX 1.58 Assegnazioni CHARACTER Ha la forma del tipo: v = espr dove v è una variabile o elemento di vettore o ancora sottostringa di tipo CHARACTER ed espr è un’ espressione CHARACTER. Se la lunghezza di v è maggiore di espr vengono aggiunti degli spazi alla destra di espr fino a raggiungere la lunghezza di v; se v è minore di espr i caratteri in eccesso sulla destra sono rimossi. 1.59 Istruzione ASSIGN Questa istruzione è usata per assegnare l’ indirizzo di un istruzione etichettata ad una variabile intera. La forma è del tipo: ♣ ASSIGN S TO V dove S è un’ etichetta di un istruzione eseguibile o un’ istruzione FORMAT presente nella stessa unità e V è una variabile intera. La variabile V può essere poi adoperata nello stesso programma sia in un’ istruzione GO TO sia come identificatore di FORMAT in un’ istruzione READ/ WRITE /PRINT. La variabile non può ovviamente essere richiamata in altre espressioni aritmetiche a meno che non sia riassegnata con un valore intero. Esempio: 29 1.60. ISTRUZIONI DI CONTROLLO CAPITOLO 1. IL FORTRAN-77 ♣ DIMENSION ARRAY (1:10) ♣101 FORMAT (10F10.4) ♣ ASSIGN 101 TO MYFORM ♣ WRITE ( LP, MYFORM) ARRAY 1.60 Istruzioni di controllo Le istruzioni di controllo vengono utilizzate, in FORTRAN, per dirigere il flusso dell’ elaborazione: sono inclusi in questo tipo di istruzione costrutti per il loop, diramazioni condizionate e incondizionate, strutture decisionali a scelta multipla e possibilità di pausa o interruzione dell’ esecuzione di un programma. I trasferimenti di controllo in una unità del programma si effettuano principalmente con l’ uso di istruzioni GO TO e IF e, inoltre, con l’ uso sporadico di END ed ERR in istruzioni di input/output. 1.61 Istruzione GO TO incondizionata Questa istruzione produce un trasferimento incondizionato del flusso su un’ altra istruzione etichettata: ♣ GO TO S dove S è un etichetta di un’ istruzione eseguibile presente nella stessa unità. 1.62 Istruzione GO TO calcolata Questa istruzione trasferisce il controllo ad una istruzione scelta da una lista secondo una condizione specifica. La forma è del tipo: ♣ GO TO(s1,s2,....sn) espr dove ogni sn è un etichetta di un istruzione eseguibile presente nella stessa unità ed espr è un’ istruzione di tipo intero utilizzata per selezionare,tra le sn, l’ istruzione cui trasferire il controllo. La virgola prima di espr è un optional. La scelta viene effettuata nel modo seguente: se il valore di espr è 1, il controllo viene trasferito ad s1, se espr ha valore 2, il controllo viene trasferito ad s2, e cosı̀ via. Se il valore di espr è minore di 1 o maggiore del numero di etichette nella lista, non viene 30 CAPITOLO 1. IL FORTRAN-77 1.63. ISTRUZIONE GO TO ASSEGNATA effettuato alcun trasferimento. La stessa etichetta può comparire più di una volta nella stessa lista. Esempio: ♣ GO TO(100,200,300,...100) MOD(KCONTA,5)+1 1.63 Istruzione GO TO assegnata È un’ istruzione obsoleta ma mantenuta per compatibilità con il FORTRAN IV. Trasferisce il controllo ad una istruzione che ha un’ etichetta assegnata ad un intero tramite un ASSIGN. Ha la forma: ♣ GO TO V dove V è la variabile intera cui è stato assegnato l’ indirizzo di una istruzione eseguibile etichettata. 1.64 Blocco IF Un blocco IF permette di eseguire le istruzioni in maniera condizionale. La forma è del tipo: ♣ IF (LEXP1) THEN ♣ BLOCCO1 ♣ ELSEIF (LEXP2) THEN ♣ BLOCCO2 ♣ ELSE ♣ BLOCCO3 ♣ END IF dove ogni LEXP è un’ espressione logica e ogni blocco contiene istruzioni eseguibili (eccetto l’ END), compresi altri blocchi IF. Ogni blocco di istruzioni che segue un IF / ELSEIF è eseguito solo se la corrispondente espressione logica ha il valore .true.; il blocco ELSE è eseguito solo se tutte le precedenti espressioni logiche sono risultate false. Dopo l’ esecuzione delle istruzioni contenute in un blocco, il controllo viene trasferito all’ istruzione immediatamente seguente l’ ENDIF. Le istruzioni ELSE ed ELSE IF possono essere omesse: l’ ultima in particolare può essere ripetuta quante volte si vuole. Per ogni istruzione IF-THEN deve essere sempre presente l’ END IF. Ricordiamo che non è possibile passare dal blocco in un’ altra parte dell’ unità. 31 1.65. ISTRUZIONE IF LOGICA 1.65 CAPITOLO 1. IL FORTRAN-77 Istruzione IF logica L’ istruzione logica IF permette che una singola istruzione sia eseguibile in maniera condizionale. L’ istruzione assume la forma: ♣ IF (LEXP) ISTRUZ dove LEXP è un’ espressione logica ed ISTRUZ è un istruzione eseguibile,escluso DO, IF-THEN, ELSE IF, ELSE, END IF, END o un altro IF logico. L’ istruzione ISTRUZ è eseguita solo se l’ espressione logica LEXP ha il valore.TRUE.. Esempio: ♣ IF (X.GT.0.5 ) CALL MODIFICA (X) 1.66 Istruzione IF aritmetica Quest’ istruzione è obsoleta e viene mantenuta solo per compatibilità con il FORTRAN-IV. La sua forma è del tipo: ♣ IF (ESPR)s1,s2,s3 dove ESPR è un’ espressione INTEGER, REAL o DOUBLE PRECISION, e ogni s è un etichetta relativa ad una istruzione eseguibile. Il flusso è trasferito ad s1, s2, s3 a seconda che il valore di ESPR sia negativo, zero o positivo. 1.67 Istruzione DO L’ istruzione DO è usata per definire un DO-LOOP. Questo loop può contenere un numero a piacere di istruzioni eseguibili ( eccetto l’ END ) che vengono eseguite ripetutamente con una sequenza regolare di valori di una variabile chiamata variabile del do. La forma dell’ istruzione è del tipo: ♣ DO s, v=e1,e2,e3 oppure ♣ DO s, v=e1,e2, e dove s è l’ etichetta di un’ istruzione eseguibile, v è la variabile del DO di tipo INTEGER, REAL o DOUBLE PRECISION e ogni e è un’ espressione di tipo intero, reale o doppia precisione, indicanti, rispettivamente, il valore iniziale, il valore finale e l’ incremento di v. La virgola dopo l’ etichetta è un optional ma è raccomandato contro gli errori. Esempio: 32 CAPITOLO 1. IL FORTRAN-77 1.68. ISTRUZIONE DO-WHILE ♣ DO 55, N= -100, MAX (LIMIT, 100),2 ♣ blocco istruzioni ♣55 continue Il DO-LOOP consiste nel blocco di istruzioni eseguibili dall’ istruzione DO a quella con etichetta s inclusa. Il LOOP può contenere istruzioni CALL, funzioni di referenza e blocchi IF/ END IF come altri blocchi DO. È necessario però che ogni struttura, sia blocco IF che DO-LOOP, venga interamente contenuta nel range del DO-LOOP più esterno. In alcune implementazioni, tipo UNIX-FORTRAN o MICROSOFT, è stata soppressa l’ etichetta del DO e abbiamo semplicemente: ♣ DO v=e1, e2, e3 ♣ blocco istruzioni ♣ END DO L’ esecuzione di un DO-LOOP procede nel modo seguente: 1. viene valutato e1 (valore iniziale) ed assegnato alla variabile v del loop, con appropriata conversione di tipo, se necessaria. 2. vengono valutate le espressioni e2 ed e3 ( rispettivamente valore limite ed incremento o passo ). Se e3 è stato omesso, viene considerato il valore di default 1. 3. Viene calcolato il numero di iterazioni con la seguente espressione: MAX ( INT (( e2 - e1 + e3 )/e3 ), 0 ). Si ottiene quindi il numero di volte che il blocco di istruzioni nel loop verrà eseguito. 4. se questo numero di istruzioni è nullo, il controllo dell’ esecuzione viene trasferito alla prima istruzione che segue l’ END DO o l’ etichetta del loop. 5. se il numero di iterazioni è maggiore di zero, vengono eseguite le istruzioni del blocco. 6. la variabile del loop viene incrementata di e3, il numero di iterazioni è decrementato di uno e si riprende dal passo 4. 1.68 Istruzione DO-WHILE Questa è un istruzione che esiste solo sul UNIX-FORTRAN o MICROSOFT e fornisce un metodo per il loop non necessariamente controllato 33 1.69. ISTRUZIONE CONTINUE CAPITOLO 1. IL FORTRAN-77 da un conto di iterazioni. In pratica si esegue un blocco di istruzioni fino a che il valore dell’ espressione logica è falsa. In ogni passo del LOOP viene controllata la variabile logica; se è vera (.true. ) vengono eseguite le espressioni del LOOP, se è falsa (.false. ) il controllo viene trasferito all’ istruzione dopo il LOOP. La forma dell’ istruzione è la seguente: ♣ [ DO s ] WHILE expr dove s è l’ istruzione etichettata eseguibile che definisce il range del loop: può essere anche una istruzione REPEAT o END DO. L’ espressione expr è un test di tipo logico. Il seguente esempio è tratto dalla teoria dei frattali e costituisce il loop principale dell’ insieme di Mandelbrot: ♣ IM = 0 ♣ DO I= 0,NPIX1 ♣ CY=YMIN + I*DELTA/NPIX ♣ DO J=0,NPIX1 ♣ CX=XMIN+J*DELTA/NPIX ♣ COMPLEX = CX + IMM*CY ♣ C DIMENSIONE NUMERO COMPLESSO ♣ Z=0 ♣ NDIM = 0 ♣ DO WHILE (CABS(Z).LE. 2.0.AND. NDIM .LT.ITER) ♣ Z=Z*Z+COMPLEX ♣ NDIM=NDIM+1 ♣ END DO ♣ IM = IM +1 ♣ MATRIX (IM) = NDIM ♣ END DO ♣ END DO 1.69 Istruzione CONTINUE L’ istruzione CONTINUE fornisce un punto di riferimento e, praticamente, traferisce il controllo all’ istruzione seguente. È usato principalmente come fine del vecchio DO LOOP, ma può comparire ovunque nell’ unità di programma. Esempi: ♣ GO TO 400 ♣ ........... 34 CAPITOLO 1. IL FORTRAN-77 1.70. ISTRUZIONE STOP ♣400 CONTINUE ♣ DO 600 J=1,300 ♣ .................. ♣600 CONTINUE 1.70 Istruzione STOP Questa istruzione termina l’ esecuzione del programma e produce un ritorno al sistema operativo usato. Si presentano due casi: ♣ STOP oppure ♣ STOP [disp] dove [disp] rappresenta una variabile CHARACTER oppure un numero non più grande di 5 cifre. Questa variabile può essere un messaggio da visualizzare o un numero di riferimento per errori di esecuzione del programma. Esempio: ♣ STOP ’Ci sono troppi elementi’ 1.71 Istruzione PAUSE L’ istruzione PAUSE è simile all’ istruzione dello STOP con la differenza che la sospensione dell’ esecuzione è solo temporanea. L’ esecuzione riprende con una istruzione del sistema operativo che nel caso del VMS è $ CONTINUE. Si sconsiglia l’ uso di questa istruzione quando i sistemi devono essere trasportabili. La forma è del tipo ♣ PAUSE [s] dove s è una stringa di caratteri o un numero fino a 5 cifre, inviata su uno schermo come messaggio per l’ utente. 1.72 Istruzioni di INPUT/OUTPUT Le istruzioni di Input/Output forniscono un canale di comunicazione tra il programma FORTRAN e il mondo esterno. Ci sono tre gruppi di istruzioni di input/output. Nel primo gruppo si trovano le istruzioni READ, WRITE, PRINT che attuano il trasferimento dei dati fra unità; fanno parte del secondo gruppo BACKSPACE, ENDFILE e REWIND 35 1.73. NOZIONI GENERALI CAPITOLO 1. IL FORTRAN-77 che compiono operazioni ausiliarie. Tutte queste istruzioni fanno riferimento ad unità logiche intere che si riferiscono a file ed apparati esterni ( lettori di nastri / stampanti / dischetti / terminali ). Nel terzo gruppo troviamo OPEN, CLOSE e INQUIRE che correlano le unità logiche di uscita o ingresso con il nome dei file. 1.73 Nozioni generali In questo paragrafo verranno spiegati in generale i concetti che riguardano record e file per una migliore comprensione delle istruzioni di Input / Output. 1.74 Record Tutti gli I/O del FORTRAN hanno luogo tramite una struttura chiamata RECORD. Un record può essere un singolo carattere, una sequenza di caratteri o di valori; può essere una linea di testo, le coordinate per il pennino di un plotter, i dati letti da uno scanner o ( fino a circa 10 anni fa ) una scheda perforata. Il FORTRAN usa tre tipi di record: formattato, non formattato e di fine file ( endfile ). Un record formattato è costituito da una sequenza di caratteri ASCII, terminata o meno con un carriage return , un avanzamento di linea o entrambi. Ogni singola riga di testo di questo manuale, per esempio, è un record formattato. La lunghezza minima per un record formattato è zero e la massima è 1024. Un record non formattato è una sequenza di valori e la sua interpretazione dipende dal tipo di dati. Per esempio il binario 01010111 può essere interpretato come valore intero 87 o valore carattere W a seconda del tipo di dato. La lunghezza minima di un record non formattato è zero e la massima è 1024, eccetto per i record ad accesso sequenziale ( vedi oltre ) non contenenti informazioni sulla lunghezza del record, che può quindi essere illimitata. Il record di endfile è l’ ultimo record di un file e non ha lunghezza. 36 CAPITOLO 1. IL FORTRAN-77 1.75 1.75. FILE File Un file è composto da record, può essere creato ed è accessibile anche con mezzi diversi dai programmi in linguaggio FORTRAN. Per esempio si può creare e modificare un file di testo con un editor e manipolarne le informazioni con un programma in FORTRAN. I file contenuti in nastri e dischi sono generalmenti detti esterni; i file memorizzati nella memoria principale sono chiamati file interni. La posizione all’ interno di un file si riferisce al prossimo record che sarà letto o scritto. Quando si accede ad un file ( lo si apre ) si è posizionati prima del primo record e la fine del file è subito dopo il record di endfile. Alcune istruzioni di I/O permettono di cambiare la posizione corrente in un file. 1.76 Accesso ai file Il metodo usato per trasferire record a o da file è chiamato modalità di accesso. L’ accesso ai file avviene attraverso il loro nome. I file esterni possono contenere sia record formattati che non formattati. Quando un record in un file può essere letto o scritto in modo arbitrario, casuale, la modalità di accesso è detta DIRETTA. Si accede ai singoli record attraverso un numero di record, che è un intero positivo. Tutti i record in un file ad accesso diretto hanno la stessa lunghezza e contengono solo i dati attualmente scritti su di essi; non ci sono caratteri di fine record. I record possono essere riscritti ma non cancellati. Generalmente solo i file su disco possono usare la modalità di accesso diretto per il trasferimento dei record. Quando i record vengono trasferiti in ordine, uno dopo l’ altro, la modalità di accesso è detto SEQUENZIALE. I record in un file ad accesso sequenziale possono essere di diversa lunghezza. Alcuni file, come terminali, stampanti e lettori di nastri, possono usare solo questa modalità di accesso. I file ad accesso sequenziale formattato contengono solitamente informazioni di tipo testo e ogni record ha un carattere di fine record. L‘ accesso sequenziale non formattato è generalmente utilizzato per due motivi che possono sembrare contrastanti: 1) per il controllo di plotters, terminali grafici, stampanti, etc. e per procedere su informazioni binarie non codificate come i file.OBJ. In questo caso è importante che i dati trasferiti da e al mezzo esterno siano un flusso di bytes senza informazioni sulla lunghezza del record. 2) per la comprensione dei dati e la velocità di accesso che caratterizzano 37 1.77. FILE INTERNI CAPITOLO 1. IL FORTRAN-77 questa modalità. In questo caso deve poter essere possibile determinare la lunghezza del record per letture parziali. 1.77 File interni I file interni possono contenere variabili CHARACTER, elementi di vettore di tipo CHARACTER e sottostringhe CHARACTER. Un file interno che contenga una variabile, un elemento di vettore o una sottostringa, tutti di tipo CHARACTER, ha un solo record, la cui lunghezza è quella dell’ entità CHARACTER considerata. Un file interno che contenga un vettore di tipo CHARACTER, ha tanti record quanti sono gli elementi del vettore, la cui lunghezza è uguale a quella degli elementi stessi. I dati di questi file possono essere trasferiti solo con la modalità di accesso sequenziale formattato. Solitamente questi file vengono utilizzati per la conversione del tipo di variabili da numerico a CHARACTER. 1.78 Istruzione OPEN Questa istruzione è adoperata per connettere un’ unità logica ad un file e specificare le sue caratteristiche. Può aprire un file esistente oppure crearne uno nuovo. Assume la forma del tipo ♣ OPEN ( olista ) dove OLISTA è una lista di argomenti ognuno separato da una virgola: UNIT= u Specifica il numero dell’ unità. I numeri 5, 6, (*) indicano lo standard input ( tastiera ) e lo standard output (schermo ). STATUS = cexpr Dove cexpr è un’ espressione CHARACTER che assume il valore ’OLD’ se il file è già esistente, ’NEW’ se vogliamo crearne uno nuovo, ’SCRATCH’ per inserire un file nella memoria dinamica. FILE = cexpr dove cexpr è una espressione CHARACTER che riporta il nome del file; non deve essere usata insieme a ’SCRATCH’. ACCESS = cexpr dove cexpr è un’ espressione CHARACTER che assume il valore ’SEQUENTIAL’ o ( per default ) ’DIRECT’. FORM = cexpr dove cexpr è un’ espressione CHARACTER con il valore ’FORMATTED’ oppure ’UNFORMATTED’ 38 CAPITOLO 1. IL FORTRAN-77 1.79. ISTRUZIONE CLOSE RECL = iexp dove iexp è un’ espressione intera che specifica la lunghezza del record; deve essere data per i file ad accesso DIRECT. Le unità sono CHARACTERS per i file FORMATTED. BLANK = cexpr , dove cexpr è un’ espressione CHARACTER che specifica il trattamento standard degli spazi: può essere un ’NULL’ ( gli spazi vengono ignorati ) oppure uno ’ZERO’ ( gli spazi sono sostituiti da zeri ). ERR = s dove s è una etichetta che si riferisce ad una istruzione cui viene passato il controllo dell’ esecuzione in caso di errore. IOSTAT=ios dove ios è il nome simbolico di una variabile INTEGER*4 o di un elemento di vettore. Nel caso di errori, ios assume un valore positivo; se si verifica la condizione di endfile, ios assume il valore -1 ed infine in caso di operazione conclusa senza errori ios assume il valore zero. Esempi: ♣ OPEN (unit=8, file=’espe.dat’, status=’NEW’) ♣ OPEN (unit=N+5, file=dev//dati, status=’OLD’, ♣ $ ERR = 99 ) ♣ OPEN (unit= 1,file=fnome, status=’OLD’, ♣ $ FORM=’UNFORMATTED’, IOSTAT= KODE ) 1.79 Istruzione CLOSE Tutti i file e le unità sono chiuse automaticamente alla fine del programma. Una istruzione CLOSE esplicita può servire per riassegnare successivamente un file o una unità; ♣ CLOSE ( lista ) dove lista è una serie di argomenti scelti da: UNIT = u specifica l’ unità STATUS = cexp è un’ espressione CHARACTER del tipo ’KEEP’ per conservare i file oppure ’DELETE’ per cancellarli. IOSTAT = iv ritorna il tipo di errore. ERR = s se si verifica un errore di chiusura, ritorna all’ unità s. Esempio: ♣ CLOSE (UNIT=15, STATUS=’DELETE’,ERR=’999’) 39 1.80. ISTRUZIONE INQUIRE 1.80 CAPITOLO 1. IL FORTRAN-77 Istruzione INQUIRE L’ istruzione INQUIRE è usata per ottenere informazioni sulle proprietà di unità logiche o di file. Ci sono due forme: ♣ INQUIRE (unit = u, ilist ) ♣ INQUIRE (file= cexp, ilist ) dove ilist è una lista contenente uno o più dei seguenti argomenti: ERR = s specifica un label per errore di uscita NUMBER= iv ritorna il numero dell’ unità logica RECL = iv ritorna la lunghezza del record se il file è ad accesso diretto IOSTAT= iv ritorna lo stato del codice NEXTREC =iv ritorna il numero del prossimo record da leggere o da scrivere EXIST = lv ritorna.true. oppure.false., se l’ unità o file esiste o meno OPENED = lv ritorna.true. oppure.false., se l’ unità o file è connesso o meno NAMED = lv ritorna.true. se il file ha un nome, oppure.false. NAME = variabile CHARACTER definisce il nome del file ACCESS = cv ritorna ’SEQUENTIAL’ oppure ’DIRECT’ secondo il tipo di accesso definito in OPEN FORM = cv ritorna ’FORMATTED’ oppure ’UNFORMATTED’ secondo il tipo di file connesso BLANK = cv ritorna un ’NULL’ oppure un ’BLANK’ SEQUENTIAL =cv ritorna ’YES’ oppure ’NO’oppure indefinito secondo il tipo di accesso al file DIRECT =cv ritorna ’YES’ oppure ’NO’oppure indefinito FORMATTED =cv ritorna ’YES’ oppure ’NO’ oppure indefinito secondo il tipo di FORM indicato UNFORMATTED =cv ritorna ’YES’ oppure ’NO’ oppure indefinito 1.81 Istruzioni READ/WRITE L’ istruzione READ trasferisce i dati da un file interno od esterno ad una lista di espressioni o elementi di vettori. L’ istruzione WRITE valuta una lista di espressioni o elementi di vettori e trasferisce i valori su file interni od esterni. Le istruzioni hanno la forma seguente: ♣ READ (unit= 1,FMT = fmt, REC=iexpp, ♣ $ ERR =s,END = s,IOSTAT =iv)rlista ♣ WRITE (unit= 1,FMT = fmt,REC=iexpp, ♣ $ ERR =s,END = s,IOSTAT =iv)wlista dove unit = u indica l’ unità cui è connesso il file. FMT = fmt specifica il formato in cui leggere o scrivere i dati. REC = rec 40 CAPITOLO 1. IL FORTRAN-77 1.82. ISTRUZIONE REWIND specifica il record in caso di connessioni con accesso diretto. ERR = s per ridirigere l’ esecuzione in caso di errore nell’ operazione di trasferimento dati. END = s per ridirigere l’ esecuzione in caso si verifichi la condizione di endfile durante l’ operazione di trasferimento dati. IOSTAT = ios per monitorare gli errori o lo stato di fine file. Ricordiamo che: 1. il trasferimento di dati unformatted è permesso solo con file esterni. 2. viene trasferito un record per ogni istruzione di I/O. 3. il trasferimento di dati formatted richiede la specifica del formato in cui sono stati scritti o devono essere scritti i dati. 4. per ogni istruzione di I/O possono essere trasferiti uno o più record. L’ istruzione PRINT trasferisce i dati dalla dislocazione interna al terminale in modo interattivo oppure al batch log in modo batch (ossia il comando viene posto in coda ). Prende la forma: ♣ Print fmt,list L’ istruzione TYPE è praticamente uguale al PRINT ma funziona solo per alcune implementazioni tipo UNIX-FORTRAN. Assume la forma: ♣ TYPE *,list L’ istruzione ACCEPT trasferisce i dati dal terminale alla memoria interna; l’ accesso è di tipo sequenziale. Anche questa istruzione funziona solo in UNIX-FORTRAN. Riportiamo la forma più semplice: ♣ ACCEPT *,list Esempi: ♣ WRITE (91,101)jx,jy,index(1),index(2) ♣ WRITE (5,’(A)’)TEXT 1.82 Istruzione REWIND Quest’ istruzione è usata per posizionare un file sequenziale all’ inizio del primo record. Non ha effetto se il file è già ’riavvolto’. Assume la forma: ♣ REWIND ( UNIT = u, ERR =s,IOSTAT =iv) 41 1.83. ISTRUZIONE BACKSPACE ♣ CAPITOLO 1. IL FORTRAN-77 Esempio: REWIND ( UNIT = 3,ERR =120 ) 1.83 Istruzione BACKSPACE L’ istruzione può essere usata su un file sequenziale per muovere la posizione del file indietro di un record. Assume la forma del tipo: ♣ BACKSPACE u dove u è una variabile intera che specifica l’ unità logica interessata, ad esempio un file su disco. 1.84 Istruzione ENDFILE L’ istruzione ENDFILE è usata per scrivere un record di end alla fine di un file. Questo record in UNIX-FORTRAN corrisponde ad un byte con il valore ASCII 26 ( CTRL/Z). Prende la forma: ♣ ENDFILE u dove u è una variabile intera che specifica l’ unità logica interessata. Supponiamo adesso di volere aggiungere alcuni dati su un file già esistente. Dovremo prima arrivare alla fine del file tramite un istruzione di READ, ritornare indietro di una posizione tramite BACKSPACE, inserire tramite WRITE i dati interessati, richiudere il file tramite ENDFILE e finalmente chiudere il file. Come esempio pratico riportiamo la SUBROUTINE SCRIVIDATI: 100 101 120 SUBROUTINE scrividati (ave,sdev ) implicit real *4 (a-h,o-z) LOGICAL EXST iunit = 12 iunit2 = 13 OPEN (iunit2,file=’spessore.dat ’,type=’old’) read (iunit2 , 101) spessore_par,icasi format (f10.4,f10.4,f10.4) format (f10.4,i2) INQUIRE(FILE=’risultati.dat’,EXIST=EXST ) IF (EXST) THEN OPEN(iunit ,file=’risultati.dat’,type=’old’) read (iunit , 100,end=130 )zz, xx ,yy 42 CAPITOLO 1. IL FORTRAN-77 130 1.85 1.85. LA SPECIFICAZIONE FORMAT go to 120 continue backspace iunit write (iunit , 100 )spessore_par,ave,sdev endfile iunit close (iunit ) close (iunit2) ELSE OPEN(iunit,file=’risultati.dat’,type=’new’) write (iunit , 100)spessore_par, ave, sdev close (iunit ) close (iunit2) END IF return END La specificazione FORMAT La specificazione del formato dei dati è richiesta dalle istruzioni READ/ WRITE oppure PRINT per controllarne la traduzione fra forma interna ed esterna. Un FORMAT può essere inserito in qualsiasi parte del programma ed è caratterizzato da una etichetta relativa posta nelle prime cinque colonne. Assume la forma: ♣100 FORMAT (ed1,ed2.....) dove ed1, ed2...edn sono i cosidetti descrittori di formato che si dividono come segue. 1.86 Descrittori ripetibili Ogni descrittore di questo tipo corrisponde ad una operazione di input /output. Riportiamo i più usati: IW In input, trasferisce w caratteri dal campo esterno ai valori di lista e assegna ad essi un valore intero. Il dato esterno deve essere un intero. In output trasferisce il corrispondente valore ad un carattere esterno che è lungo w elementi. Fw.d In input trasferisce w caratteri dal campo esterno e assegna ad essi, come valore reale, i corrispondenti elementi di lista ( che devono essere reali ). Se il primo carattere non 43 1.86. DESCRITTORI RIPETIBILI CAPITOLO 1. IL FORTRAN-77 Tabella 1.3: Tabella sul format Gw.d M agnitudine del dato Conversione ef f ettiva m < 0.1 Ew.d[Ee] 0.1 ≤ m < 1.0 F (w − 4).d, n(0 0 ) 1.0 ≤ m < 10.0 F (w − 4).(d − 1), n( 0 0 ) . . . . . . 10 ∗ ∗d − 2 ≤ m < 10 ∗ ∗d − 1 F (w − 4).1, n( 0 0 ) 10 ∗ ∗d − 1 ≤ m < 10 ∗ ∗d F (w − 4).0, n( 0 0 ) m ≥ 10 ∗ ∗d Ew.d[Ee] nullo è un segno -, il campo è trattato come negativo. Se invece il campo non contiene nè un numero decimale nè un esponente viene trattato come un numero reale di w cifre in cui le d cifre sono a destra rappresentate da degli zeri. In output, trasferisce la corrispondente lista arrotondata alla d posizione decimale. Il termine w deve essere grande abbastanza per includere il segno ( se necessario ), almeno una cifra alla sinistra del punto decimale e d cifre alla destra del decimale. Ew.d In input, funziona come il formato F. In output, E trasferisce il valore della corrispondente lista, arrotondata a d cifre decimali con E che specifica il valore dell’ esponente. Il termine w deve essere grande abbastanza per includere: segno,uno zero,un punto decimale, d cifre e un esponente. Quindi per tenere conto di queste esigenze il termine w deve essere maggiore o uguale a d+ 7. Dw.d Vale per i reali in doppia precisione. In output si comporta come il formato E, eccetto che la lettera D rimpiazza la lettera E precedente l’ esponente e abbiamo due cifre come esponente. Gw.d In input, funziona come il formato F. In output trasferisce la lista corrispondente in funzione della magnitudine, vedi tabella seguente. Tenendo conto delle varie possibilità w deve essere più grande o uguale a d+8. nHc1..cn In input trasferisce n caratteri dal campo esterno al descrittore medesimo.Il primo carattere appare subito dopo la H. Prende il nome di variabile di Hollerith. Lw In input trasferisce w caratteri dal campo esterno e assegna un valore logico al corrispondente elemen44 CAPITOLO 1. IL FORTRAN-77 1.87. DESCRITTORI NON RIPETIBILI to di lista. Se il primo carattere non nullo è T,t,.T,.t viene assegnato il valore.TRUE. al corrispondente elemento se invece i primo carattere non nullo vale F, f,.F, or.f, viene assegnato il valore.FALSE.. In output trasferisce la lettera T ( se la variabile è vera ) o la lettera F ( se la variabile è falsa ). La lettera T o F viene messa nella posizione più a destra preceduta da w-1 spazi. Aw Se il corrispondente elemento di I/O e di tipo CHARACTER viene trasmesso un dato character. Il valore di w deve essere minore od uguale a 32767. Il w può essere omesso e per default viene assegnato un numero di caratteri uguali a quelli dichiarati nella variabile numerica. 1.87 Descrittori non ripetibili I seguenti descrittori servono a controllare la posizione in un record o in un file, ma non corrispondono ad una operazione di I/O: ’stringa’ dove la stringa viene mandata in uscita Tn si posiziona tramite il TAB alla colonna n Trn si posiziona tramite il TAB a n colonne a destra Tln si posiziona tramite il TAB a n colonne a sinistra nX lascia n spazi SP produce un segno prima di tutti i numeri seguenti positivi SS sopprime il segno prima di tutti i numeri seguenti positivi BN tratta i blanks seguenti in input come nulli BZ tratta i blanks seguenti in input come zeri KP setta il fattore di scala per i susseguenti I/O / comincia un nuovo record Facciamo alcuni esempi: ♣ A=5 ♣ B = - 10 ♣ C = 2224 ♣ WRITE ( 5, 20 ) A, B, C ♣20 FORMAT(3I4) ♣ WRITE ( 5, 21 ) A, B, C ♣21 FORMAT(3(1X,I4)) ♣ WRITE ( 5, 22 ) A, B, C ♣22 FORMAT(1X,’A = ’,I2 ,1X,’B = ’,I3,1X,’C = ’,I5,/) ♣ A = 12 ♣ B = 25.4 ♣ C = -1.23 ♣ WRITE ( 5, 20 ) A, B, C ♣20 FORMAT(F3.0,F4.1,F5.2) 45 1.87. DESCRITTORI NON RIPETIBILI ♣ ♣21 ♣ ♣22 ♣ ♣ ♣ ♣ ♣ ♣22 ♣ ♣22 ♣ ♣22 CAPITOLO 1. IL FORTRAN-77 WRITE ( 5, 21 ) A, B, C FORMAT(F3.0,1X,2(E12.4,1X)) WRITE ( 5, 22 ) A, B, C FORMAT(F3.0,1X,E12.4,1X,D12.4) A = 1. B = 10. C = 100. D = 1000. WRITE ( 5, 22 ) A, B, C, D FORMAT(5G10.4) WRITE ( 5, 22 ).TRUE.,.FALSE. FORMAT(2L2) WRITE ( 5, 22 ) ’BUONGIORNO’ FORMAT(A6) 46 Capitolo 2 Il Laboratorio Nei prossimi capitoli verranno illustrati alcuni programmi per l’ elaborazione dei dati ricavati dalle esperienze di laboratorio. Questi programmi sono stati sviluppati in ambiente MS-DOS usando il compilatore Microsoft-FORTRAN versione 5.0. Le esercitazioni sono state concepite ed implementate in modo tale da risultare accessibili sin dalla prima volta anche agli utenti sprovvisti di ogni nozione di informatica. L’ utente è infatti guidato attraverso tutte le fasi dell’ esercitazione, dall’ immissione corretta dei dati all’ elaborazione dei parametri statistici di interesse ed infine alla presentazione finale dei risultati da istruzioni che appaiono di volta in volta sullo schermo video o grafico. Per alcuni programmi viene dapprima illustrato l’ argomento o gli argomenti a cui esso si riferisce e le formule utilizzate. Viene inoltre inserito il listato del programma in linguaggio FORTRAN,commentato nelle varie fasi, per l’ utente che desidera apportare modifiche particolari. I programmi sono quasi tutti scritti in ambiente MS-DOS in FORTRAN-77 e fanno uso di subroutines contenute nel libro [REC 92] e per semplicicità non contengono uscite grafiche. 2.1 RETTA Questo programma illustra come, date due serie di datix ey e l’ errore relativo alla variabile y in interattivo,al fine di stabilire eventuali relazioni di tipo lineare tra di esse, vengono calcolati: 47 2.1. RETTA CAPITOLO 2. IL LABORATORIO 1. valor medio: x̄ = N 1 X xi N i=1 (2.1) ȳ = N 1 X yi N i=1 (2.2) 2. deviazione standard: sx = v u u t N 1 X (xi − x̄)2 N − 1 i=1 (2.3) sy = v u u t N 1 X (yi − ȳ)2 N − 1 i=1 (2.4) 3. coefficienti della retta di regressione (coef. angolare b e intercetta a): PN (xi − x̄)(yi − ȳ) (2.5) b = i=1 PN 2 i=1 (xi − x̄) a = ȳ − bx̄ (2.6) 4. errore sui coefficienti error(b) = error(a) = v u PN 2 u i=1 (yi − a − bxi ) t PN 2 (N − 2) i=1 (xi − x̄) v u PN u t i=1 (yi − a − bxi )2 1 x̄2 [ + PN ] 2 (N − 2) N i=1 (xi − x̄) (2.7) (2.8) 5. coefficiente di correlazione r di Pearson r= PN (xi qP i=1 N i=1 (xi − x̄)(yi − ȳ) − x̄)2 PN i=1 (yi (2.9) − ȳ)2 6. Valore di χ2 2 χ (a, b) = N X ( i=1 48 (yi − a − bxi ) 2 ) σi (2.10) CAPITOLO 2. IL LABORATORIO 2.1. RETTA Segue il listato del programma che usa le subroutine FIT e PEARSN estratte dal libro [REC 92]: program retta C definizione delle variabili e dei vettori utilizzati nel programma implicit real (a-h,o-z) character ris parameter ( max =100) dimension xreal (1:max) dimension yreal (1:max) dimension sigma (1:max) print *,’Programma per il calcolo statistico ’ print *,’Media,Deviazione standard e correlazione lineare ’ print *,’Calcolo del chiquadro e del coefficiente ’ print *,’di correlazione lineare ’ call attesa print *,’riportiamo anche il parametro q che indica la bonta’ print *,’del fit , vedi Numerical Recipes I/II ’ print *,’Q = gammq ( (N-2)/2 , chi**2 /2 ) ’ print *,’N ==> numero di dati ’ print *,’dove gammq e la funzione gamma incompleta ’ print *,’ Q > 0.1 ==> fit accettabile ’ print *,’ Q > 0.001 ==> fit accettabile solo se gli ’ print *,’ errori sono non-normali oppure ’ print *,’ sottostimati ( vedi modulo Youg ’ print *,’Q < 0.001 ==> il modello non funziona !!! ’ call attesa 100 format (a) print *,’Hai messo i dati nel file retta.dat a ’ print *,’triplette x,y errore sulle y ? ’ print *,’rispondere Y/N ? ’ read 100,ris if ((ris.eq.’Y’).or.(ris.eq.’y’)) then go to 150 elseif ((ris.eq.’N’).or.(ris.eq.’n’)) then stop ’Metti i dati nel file retta.dat a triplette x,y,sy !!’ else stop ’SCEMO , risposta non valida !!!!!’ end if 49 2.2. PARABO CAPITOLO 2. IL LABORATORIO 150 continue call attesa open (unit=90,file=’retta.dat’, status=’old’) C input dati n = 0 199 continue read (90,*,end = 200)xx,yy ,sy n = n + 1 xreal ( n ) = xx yreal ( n ) = yy sigma ( n ) = sy go to 199 200 continue close ( unit = 90 ) mwt = 1 call fit (xreal,yreal,n,sigma,mwt,a,b,errora,errorb,chi2,q) call pearsn (xreal,yreal,n,r,prob,z) print *,’fit della retta y = a + b * x ’ print *,’a =’,a print *,’b =’,b print *,’errore su a = ’,errora print *,’errore su b = ’,errorb print *,’valore del chiquadro =’,chi2 print *,’valore del coefficiente lineare r =’,r print *,’valore di bonta del fit Q =’,q stop end 2.2 PARABO Questo programma viene utilizzato per l’ analisi dei dati dell’ esercitazione sulla bilancia di Cavendish (determinazione della costante di gravitazione mediante il metodo della parabola) oppure per l’ esercitazione sulla rotaia ad aria (determinazione della accelerazione di gravità). Si devono immettere il numero n di dati e, successivamente le n triplette di valori x,y e errore su y. Tramite la subroutine LFIT, ricavata dal libro [REC 92] , si calcolano i coefficienti a,b,c della curva parabolica di 50 CAPITOLO 2. IL LABORATORIO 2.2. PARABO regressione y = a + b× x + c × x2 e i relativi errori con il metodo dei minimi quadrati. Viene anche visualizzato il valore sperimentale della variabile χ2 . Segue il listato del programma. program parabo C C definizione delle variabili e dei vettori C utilizzati nel programma C implicit real (a-h,o-z) parameter ( max =50 ) parameter ( nterm = 3 ) dimension x (1:max) dimension y (1:max) dimension sig (1:max) dimension a (1:nterm) dimension covar (1:nterm,1:nterm) dimension lista (1:nterm) external funcs C print *,’Programma per il calcolo statistico ’ print *,’Fit con un polinomio di secondo grado’ 99 continue C C input dei dati da tastiera C call attesa print *,’Avete messo i dati nel file parabo.dat ?’ print *,’In sequenza , x , y , errore sulle y .....’ call attesa open (unit=11,file=’parabo.dat’,status=’old’) n = 0 199 continue read (11,*,end = 200)xx,yy,errory n = n + 1 x ( n ) = xx y ( n ) = yy sig ( n ) = errory go to 199 51 2.3. PENDO CAPITOLO 2. IL LABORATORIO 200 continue close ( unit = 11) do 201 jj = 1, nterm lista ( jj ) = jj 201 continue call lfit (x,y,sig,n,a,lista,nterm,covar,nterm,chisq,funcs) errora = sqrt ( covar (1,1)) errorb = sqrt ( covar (2,2)) errorc = sqrt ( covar (3,3)) print *,’fit del polinomio y = a + b * x + c * x**2 ’ print *,’a =’,a(1) print *,’b =’,a(2) print *,’c =’,a(3) print *,’errore su a = ’,errora print *,’errore su b = ’,errorb print *,’errore su c = ’,errorc print *,’Valore del chiquadro =’,chisq stop end 2.3 PENDO Questo programma è utile nell’ analisi dei dati dell’ esercitazione con il pendolo composto. Vengono richiesti gli errori sulle misure della variabile y (tempo) per la prima e la seconda serie di dati. Successivamenti si immettono il numero di dati e le coppie di valori x (distanza),y (tempo) per la prima serie di dati. Il programma valuta immediatamente i coefficienti della curva parabolica y = a + b × x + c × x2 , mediante chiamata alla subroutine LFIT estratta dal libro [REC 92] che usa il metodo dei minimi quadrati quando il polinomio interpolante è di secondo grado. Analogo procedimento viene seguito per la seconda serie di dati. Il programma calcola poi l’intersezione delle parabole, l’ errore sull’intersezione e finalmente il valore di g ed il suo errore. Alleghiamo il listato del programma. program pendo implicit real (a-h,o-z) parameter ( max =50 52 ) CAPITOLO 2. IL LABORATORIO 99 100 2.3. PENDO parameter ( nterm = 3 ) parameter ( inc = 3 ) parameter ( reg = 980.5343) character * 1 prova,video,rispo character * 40 messag dimension x (1:max) dimension y (1:max) dimension sig (1:max) dimension x2 (1:max) dimension y2 (1:max) dimension sig2 (1:max) dimension result(1:20) dimension a (1:nterm) dimension covar (1:nterm,1:nterm) dimension lista (1:nterm) dimension para (1: inc ) dimension epara (1: inc ) dimension messag (1: inc ) external funcs prova =’y’ el = 99.3 errl = 0.1 teta = 5.0 eteta = 1.0 nosci = 30 if (( prova.eq.’Y’).or.(prova.eq.’y’)) then print *,’Programma per il calcolo di g in CGS tramite ’ print *,’intersezione di due parabole ’ print *,’ovviamente deve essere presente l’’andamento parabolico’ print *,’nei dati ..... ’ print *,’i dati x rappresentano le distanze della massa mobile’ print *,’dal coltello e sono espresse in cm ’ print *,’i dati y rappresentano i tempi impiegati a compiere ’ print *,’n oscillazioni a vanno espressi in secondi ’ print *,’gli errori sulle y (errori tempi) pure vanno espressi ’ print *,’in secondi ! ’ continue format (a1) print *,’Hai messo i dati nel file pendo1.dat ’ 53 2.3. PENDO 150 151 199 CAPITOLO 2. IL LABORATORIO print *,’a triplette x [cm],y [sec] errore sulle y [sec] ? ’ print *,’rispondere Y/N ? ’ read 100, rispo if ((rispo.eq.’Y’).or.(rispo.eq.’y’)) then go to 150 elseif ((rispo.eq.’N’).or.(rispo.eq.’n’)) then stop ’Metti i dati nel file pendo1.dat a triplette x,y,sy !!’ else stop ’SCEMO , risposta non valida !!!!!’ end if continue print *,’Hai messo i dati nel file pendo2.dat ’ print *,’a triplette x [cm],y [sec] errore sulle y [sec] ?’ print *,’rispondere Y/N ! ’ read 100, rispo if ((rispo.eq.’Y’).or.(rispo.eq.’y’)) then go to 151 elseif ((rispo.eq.’N’).or.(rispo.eq.’n’)) then stop ’Metti i dati nel file pendo2.dat a triplette x,y,sy !!’ else stop ’SCEMO , risposta non valida !!!!!’ end if continue print*,’Inserire l(distanza fra i coltelli)in [cm] tipo 99.3’ read *,el print*,’Inserire errore l in [cm] tipo 0.1 ’ read *,errl print*,’Inserire il numero di oscillazioni tipo 30 ’ read *,nosci print*,’Inserire ampiezza iniziale [gradi] tipo 5 ’ read *,teta print*,’Inserire errore ampiezza iniziale [gradi] tipo 1 ’ read *,eteta call attesa end if open (unit=90,file=’pendo1.dat’, status=’old’) open (unit=91,file=’pendo2.dat’, status=’old’) n = 0 continue 54 CAPITOLO 2. IL LABORATORIO 200 299 300 333 2.3. PENDO read (90,*,end = 200)xx,yy ,sy n = n + 1 x ( n ) = xx y ( n ) = yy sig ( n ) = sy go to 199 continue n2 = 0 continue read (91,*,end = 300)xx,yy ,sy n2 = n2 + 1 x2 ( n2 ) = xx y2 ( n2 ) = yy sig2 ( n2 ) = sy go to 299 continue errort = sig2 (1) close ( unit = 90 ) close ( unit = 91 ) mfit = nterm do 333 j=1,mfit lista(j)= j continue call lfit (x,y,sig,n,a,lista,nterm,covar,nterm,chisq,funcs) errora = sqrt ( covar (1,1)) errorb = sqrt ( covar (2,2)) errorc = sqrt ( covar (3,3)) print *,’Risultati prima parabola ....................... ’ print *,’Minimi quadrati con y = a + b * x + c * x**2 ’ print *,’numero dati =’,n print *,’a =’,a(1) print *,’b =’,a(2) print *,’c =’,a(3) print *,’errore su a = ’,errora print *,’errore su b = ’,errorb print *,’errore su c = ’,errorc print *,’Valore del chiquadro =’,chisq if (( prova.eq.’Y’).or.(prova.eq.’y’)) then call attesa 55 2.3. PENDO 334 CAPITOLO 2. IL LABORATORIO end if result (1) = a(1) result (2) = a(2) result (3) = errora result (4) = errorb result (5) = chisq result (6) = a(3) result (7) = errorc mfit = nterm do 334 j=1,mfit lista(j)= j continue call lfit (x2,y2,sig2,n2,a,lista,nterm,covar,nterm,chisq,funcs) errora = sqrt ( covar (1,1)) errorb = sqrt ( covar (2,2)) errorc = sqrt ( covar (3,3)) print *,’Risultati seconda parabola ....................... ’ print *,’Minimi quadrati con y = a + b * x + c * x**2 ’ print *,’numero dati =’,n print *,’a =’,a(1) print *,’b =’,a(2) print *,’c =’,a(3) print *,’errore su a = ’,errora print *,’errore su b = ’,errorb print *,’errore su c = ’,errorc print *,’Valore del chiquadro =’,chisq if (( prova.eq.’Y’).or.(prova.eq.’y’)) then call attesa end if result (11) = a(1) result (12) = a(2) result (13) = errora result (14) = errorb result (15) = chisq result (16) = a(3) result (17) = errorc a1 = result (1) b1 = result (2) c1 = result (6) 56 CAPITOLO 2. IL LABORATORIO 2.3. PENDO a2 = result (11) b2 = result (12) c2 = result (16) call radici (a1,b1,c1,a2,b2,c2,val,err,errort) val = val / nosci err = err / nosci para (1) = val para (2) = el para (3) = teta epara (1) = err epara (2) = errl epara (3) = eteta messag (1)= ’peso-errore periodo =’ messag (2)= ’peso-errore lunghezza =’ messag (3)= ’peso-errore ampiezza =’ print *,’Dati di input per il calcolo di g ’ print *,’periodo come da intersezione [sec]=’,para(1) print *,’errore periodo [sec]=’,epara(1) print *,’distanza fra i coltelli [cm ]=’,para(2) print *,’errore distanza fra i coltelli[cm ]=’,epara(2) print *,’ampiezza iniziale [gradi ]=’,para(3) print *,’errore ampiezza iniziale [gradi ]=’,epara(3) print *,’************************************** ’ print *,’Dati di output ’ print*,’g=4*(pigrec**2)*(l/T**2)(1+(0.5*sen(0.5*teta))**2)**2’ call value (valore,para,inc) error = 100 * abs ((reg - valore)/reg) vero = valore print *,’g [cm/sec**2] =’,valore print *,’g vero a TORINO [cm/sec**2]=’,reg video=’N’ call errori (valore,evalo,para,inc,epara,messag,video) ippm = nint ( evalo /vero * 1.0E+6 ) print * ,’errore su g [cm/sec**2] =’,evalo print * ,’errore su g in ppm =’,ippm print * ,’errore g sul valore vero =’,error,’ %’ teta=0. para (3) = teta call value (valoresenza,para,inc) 57 2.3. PENDO CAPITOLO 2. IL LABORATORIO ippmteta=nint(((valoresenza-vero)/vero)* 10E+6) print *,’g senza teta =’,valoresenza print *,’influenza di teta su g in ppm =’,ippmteta video=’Y’ valore = vero call errori (valore,evalo,para,inc,epara,messag,video) stop end subroutine radici (a1,b1,c1,a2,b2,c2,val,err,errort) implicit real ( a-h,o-z) c = a1 - a2 b = b1 - b2 a = c1 - c2 disc = b**2 - 4 *a*c if ( disc.lt.0.0) then stop’radici immaginarie’ end if x1 = - ( b/(2*a)) + sqrt ( disc)/(2*a) x2 = - ( b/(2*a)) - sqrt ( disc)/(2*a) y1 = a1 + b1 * x1 + c1 *x1**2 y2 = a1 + b1 * x2 + c1 *x2**2 if ((y1.gt.0).and.(y2.gt.0)) then print *,’caso di due radici positive ’ val = ( y1 + y2 )/2.0 err = abs ( y1-y2) if ( err.lt.errort) then err = errort end if end if if ((y1.lt.0).and.(y2.gt.0)) then print *,’caso di una radice positiva e una negativa’ val = y2 err = errort end if if ((y2.lt.0).and.(y1.gt.0)) then print *,’caso di una radice positiva e una negativa’ val = y1 err = errort end if 58 CAPITOLO 2. IL LABORATORIO 2.3. PENDO return end subroutine value (valore,para,inc) implicit real (a-h,o-z ) parameter ( pigrec = 3.1415927 ) dimension para ( 1 : inc ) t = para (1) el = para (2) teta = para (3) tetar = 2 * pigrec * teta / 360. cor = ( 1.0 + (0.5 * sin (tetar/2.0))**2.0)**2.0 valore = (4 * pigrec**2 * el /( t **2))*cor return end 100 190 subroutine errori (valore,evalo,para,inc,epara,messag,video) implicit real (a-h,o-z) character * 40 messag character * 1 video parameter ( int = 10 ) parameter ( norma=10000 ) dimension para (1:inc ) dimension epara (1:inc ) dimension work (1:int ) dimension square (1:int ) dimension inter (1:int ) dimension messag (1:inc ) if (int.lt.inc)stop ’cambiare int’ vero = valore evalo = 0.0 do 100 j = 1 ,inc work (j) = para (j) continue quadro = 0.0 do 200 j = 1 ,inc do 190 i = 1 , inc para (i) = work(i) continue 59 2.4. CAVEN 200 205 206 207 210 2.4 CAPITOLO 2. IL LABORATORIO para (j) = para(j) + epara(j) call value (valore,para,inc) delta = valore - vero d2 = delta *delta quadro = quadro + d2 square (j) = d2 continue sq2 = 0.0 do 205 j= 1,inc sq2 = sq2 + square ( j) continue do 206 j= 1,inc inter (j) = nint ( square ( j) * (norma*1.0)/sq2) continue if (( video.eq.’Y’).or.( video.eq.’y’)) then print*,’************************************’ print *,’Peso normalizzato a’,norma,’ del’’errore delle variabili’ do 207 j= 1, inc print *,messag(j),inter(j) continue end if evalo = sqrt ( quadro) do 210 i = 1 , inc para (i) = work(i) continue return end CAVEN Questo programma valuta i parametri caratteristici dell’ oscillatore smorzato, con il quale vengono interpolati i dati delle ampiezze di oscillazione [cm] in funzione del tempo [sec] ricavati dalla esperienza con la bilancia di Cavendish. Le coppie di dati (tempi ed ampiezze) vanno memorizzate nel file CAV.DAT, mentre in fase di esecuzione viene richiesto l’ errore [cm] sulla misura delle ampiezze e la distanza [cm] fra asse della bilancia e riga per la rilevazione dati. Tramite la subroutine MRQMIN (estratta dal libro [REC 92]) vengono calcolati i cinque 60 CAPITOLO 2. IL LABORATORIO 2.4. CAVEN parametri A,T,α, τ ,Cost che caratterizzano la seguente equazione: y = A × seno(2 × π × t/T + α) × e −t τ + Cost (2.11) In seguito si ricava la costante di Cavendish utilizzando i seguenti valori caratteristici della bilancia: m = (15.0 ± 0.12) × 10−3 Kg (2.12) M = (1.503 ± 0.001) Kg (2.13) r = (4.5 ± 0.1) × 10−2 m (2.14) d = (5.0 ± 0.1) × 10−2 m (2.15) l ≈ 5.0m (misurato durante l0 esercitazione) (2.16) Riportiamo la formula utilizzata per il calcolo; G=A×B×C ×D dove A= B = ω 2 + τ −2 (2.17) d × r2 2M dove ω = (2.18) 2×π T (2.19) C = |2 − 1 | (2.20) con 1 = E1 l E1 = posizione iniziale sull0 asta graduata (2.21) 2 = E2 l E2 = posizione f inale sull0 asta graduata (2.22) 1 D= 1− (2.23) r3 3 [(2d)2 + r2 ] 2 Viene inoltre calcolato l’ errore percentuale sul valore esatto della costante dato da Errore = 100 × |Gricavato − Gvero | Gvero 61 . (2.24) 2.4. CAVEN CAPITOLO 2. IL LABORATORIO Viene calcolato poi l’ errore sulla costante G usando la legge di propagazione degli errori di Gauss: in questo caso le derivate parziali vengolo calcolate tramite algoritmo numerico. Il programma calcola poi G tramite il metodo dell’ escursione finale e quello della parabola. Per confronto viene poi riportato Riportiamo il listato del programma CAVEN: 1000 100 program caven implicit real (a-h,o-z ) character * 1 prova,video,rispo parameter(max=250,ma =5,inc=7 ) parameter(nterm = 2 ) dimension x (1:max ) dimension y (1:max ) dimension sig (1:max ) dimension a (1:ma ) dimension ia (1:ma ) dimension covar(1:ma,1:ma) dimension alpha(1:ma,1:ma) dimension erroa (1:ma ) dimension para (1:inc ) dimension epara (1:inc ) dimension ovar (1:nterm,1:nterm) dimension lista (1:nterm) external fun2c external fosci prova =’N’ format (A2) format (a1) print *,’Programma per il calcolo statistico ’ print *,’Interpolazione di una sinusoide smorzata ’ print *,’*************************************************’ if ((prova.eq.’N’).or.(prova.eq.’n’)) then print *,’Avete messo i dati nel file caven.dat ? ’ print *,’in sequenza t [sec] , ampiezze [cm] ? ’ print *, ’inserire (Y/N ) ! ’ read 100, rispo if ((rispo.eq.’Y’).or.(rispo.eq.’y’)) then go to 150 62 CAPITOLO 2. IL LABORATORIO 150 199 200 2.4. CAVEN elseif ((rispo.eq.’N’).or.(rispo.eq.’n’)) then stop ’Metti i dati nel file caven.dat a coppie !!’ else stop ’SCEMO , rispo non valida !!!!!’ end if continue end if print *,’Attenzione il programma non funziona sempre e quindi’ print *,’osservate le seguenti regole !!!!!!!!!!! ’ print *,’1)il primo dato rappresenta inizio della sinusoide’ print *,’2)il dato ultimo deve essere quello di equilibrio finale’ print *,’3)i dati anomali vanno eliminati ’ call attesa if ((prova.eq.’Y’).or.(prova.eq.’y’)) then el = 544.0 eel = 1.0 eey = 0.2 else print *,’Scrivere il valore della distanza [cm] ( circa 544)’ read *,el print *,’Scrivere errore della distanza [cm] ( circa 1 )’ read *,eel print *,’Scrivere errore lettura scala [cm] ( circa 0.2)’ read *,eey end if open (unit=90,file=’caven.dat’, status=’old’) npt = 0 continue read (90,*,end = 200)xx,yy npt = npt + 1 if ( npt.gt.max) stop ’Aumentare max !’ x ( npt ) = xx y ( npt ) = yy sig ( npt ) = eey go to 199 continue close ( unit = 90 ) a (1) = abs ( y (npt) - y (1)) a (2) = 500 63 2.4. CAVEN CAPITOLO 2. IL LABORATORIO 210 * 1 * * a (3) = asin (( y (1)- y (npt))/a(1)) a (4) = 500 a (5) = y (npt) do 210 j= 1 , ma ia (j) = 1 continue alamda=-1 call mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha, MA,chisq,fosci,alamda) k=1 itst=0 continue k=k+1 ochisq=chisq call mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha, MA,chisq,fosci,alamda) if (chisq.gt.ochisq) then itst=0 else if (abs(ochisq-chisq).lt.0.1) then itst=itst+1 endif if (itst.lt.4) then goto 1 endif alamda=0 call mrqmin(x,y,sig,NPT,a,ia,MA,covar,alpha, MA,chisq,fosci,alamda) erroa ( 1 ) = sqrt(covar (1,1)) erroa ( 2 ) = sqrt(covar (2,2)) erroa ( 3 ) = sqrt(covar (3,3)) erroa ( 4 ) = sqrt(covar (4,4)) erroa ( 5 ) = sqrt(covar (5,5)) print *,’Fittiamo i dati con la seguente funzione nonlineare’ print *,’y=a(5)+a(1)*(sin(2*pigrec*x/a(2)+a(3)))*exp(-x/a(4))’ print *,’a(1) =’,a(1),’ err a(1)=’,erroa(1) print *,’a(2) =’,a(2),’ err a(2)=’,erroa(2) print *,’a(3) =’,a(3),’ err a(3)=’,erroa(3) print *,’a(4) =’,a(4),’ err a(4)=’,erroa(4) print *,’a(5) =’,a(5),’ err a(5)=’,erroa(5) 64 CAPITOLO 2. IL LABORATORIO 2.4. CAVEN print *,’chisq =’,chisq call attesa recav = 6.67259 E-11 egran = 1.500 er = 4.652 E-02 eb = 4.500 E-02 ed = 5.0 E-02 eegran = 1.0 E-3 eer = 0.1 E-02 eed = 0.1 E-02 para(1) = egran para(2) = el para(3) = er para(4) = ed para(5) = a(1) para(6) = a(2) para(7) = a(4) epara(1) = eegran epara(2) = eel epara(3) = eer epara(4) = eed epara(5) = erroa(1) epara(6) = erroa(2) epara(7) = erroa(4) print *,’Sinopsi dei dati fisici adoperati ’ print *,’M [kg] =’,egran,’+-’,eegran print *,’r [cm] =’,er,’+-’,eer print *,’b [cm] =’,eb,’+-’,eer print *,’d [cm] =’,ed,’+-’,eed print *,’l [cm] =’,el,’+-’,eel call attesa call gtutto (cav,para,inc) ver = cav valore = cav video =’N’ cav = ver call calco (ecav,cav,para,inc,epara,video) cav = ver error = 100 * abs ((recav - cav)/recav) 65 2.4. CAVEN CAPITOLO 2. IL LABORATORIO ippm = nint ( ecav/cav * 1.0E+6 ) print *,’Metodo delle oscillazioni smorzate completo ’ print *,’Formule come in Guida alla Elaborazione dei dati ’ print *,’ oppure Guida alla Fisica del Laboratorio ’ print * ,’costante di Cavendish =’,valore print * ,’errore costante di Cavendish =’,ecav print * ,’errore costante di Cavendish in ppm=’,ippm print * ,’errore percentuale sul valore vero=’,error,’%’ video =’Y’ cav = ver call calco (ecav,cav,para,inc,epara,video) call attesa para ( 3 ) = eb call gescur (cave,caves,para,inc) valore = cave video =’N’ cave = valore call calcos (ecave,cave,para,inc,epara,video) cave = valore ippm = nint ( ecave/cave * 1.0E+6 ) error2 = 100 * abs ((recav - cave )/recav) print *,’Metodo escursione finale ( come da manuale Leybold )’ print *,’ pigrec **2 b**2 d S ’ print *,’ G = -----------------------------’ print *,’ M1 T**2 L ’ print *,’ ’ print *,’ b** 3 ’ print *,’ beta = -------------------------------------’ print *,’ (b**2 + 4 d**2 ) sqrt (b**2 + 4 d**2 ) ’ print *,’Costante di Cavendish senza correzione = ’,caves print *,’Costante di Cavendish con correzione = ’,valore print *,’Errore Costante con correzione = ’,ecave print *,’Errore costante con correzione in ppm =’,ippm print * ,’errore percentuale sul valore vero=’,error2,’%’ video =’Y’ cave = valore call calcos (ecave,cave,para,inc,epara,video) call attesa tquar = a (2) / 2.5 66 CAPITOLO 2. IL LABORATORIO 500 501 do 500 j= 1, npt if (x( j ).gt.tquar) jvec = j -1 go to 501 end if continue continue do 600 jj = 1 , nterm lista ( jj ) = jj continue 2.4. CAVEN then 600 C LAVORO print *,’Metodo dell’’ accelerazione ’ print *,’Formule come in Guida alla Fisica del Laboratorio ’ call lfit (x,y,sig,jvec,a,lista,nterm,ovar,nterm,chisq,fun2c) errora = sqrt ( ovar (1,1)) errorc = sqrt ( ovar (2,2)) print *,’fit della parabola y = a + c * x**2 ’ print *,’tempo massimo =’,tquar print *,’elementi selezionati =’,jvec print *,’a =’,a(1) print *,’c =’,a(2) print *,’errore su a =’,errora print *,’errore su c =’,errorc print *,’Valore del chiquadro =’,chisq aa = 2 * a (2) print *,’accelerazione=>2*c[cm/sec**2]=’,aa call attesa para (1) = egran para (2) = el para (3) = er para (4) = ed para (5) = aa epara(1) = eegran epara(2) = eel epara(3) = eer epara(4) = eed epara(5) = errorc * 2.0 inc2 = 5 call gpara (cav,para,inc2) 67 2.4. CAVEN CAPITOLO 2. IL LABORATORIO error = 100 * abs ((recav - cav)/recav) ippm = nint ( ecav/cav * 1.0E+6 ) vcav = cav video =’N’ cav = vcav call capa2 (ecav,cav,para,inc2,epara,video) cav = vcav error = 100 * abs ((recav - vcav)/recav) ippm = nint ( ecav/vcav * 1.0E+6 ) print *,’Metodo della parabola print *,’formule come su Guida alla Fisica del laboratorio print *,’ b**2 d a print *,’ G = -------------print *,’ 2 M L print *,’ print *,’Costante di Cavendish =’,vcav print *,’errore costante di Cavendish =’,ecav print *,’errore costante di Cavendish in ppm=’,ippm print *,’errore percentuale sul valore vero=’,error,’%’ video =’Y’ cav = vcav call capa2 (ecav,cav,para,inc2,epara,video) stop end SUBROUTINE fosci(x,a,y,dyda,na) implicit real (a-h,o-z) parameter ( pigrec = 3.1415927) dimension a (1:na) dimension dyda(1:na) y=a(5)+a(1)*(sin(2*pigrec*x/a(2)+a(3 )))* exp(-x/a(4)) dyda(1) = (sin(2*pigrec*x/a(2)+a(3 )))* exp(-x/a(4)) ccc = 2*pigrec*x/(a(2)**2.0) bbb = (cos(2*pigrec*x/a(2)+a(3 )))* exp(-x/a(4)) aaa = - a(1) dyda(2) = aaa * bbb * ccc dyda(3) = a(1)*(cos(2*pigrec*x/a(2)+a(3 )))* exp(-x/a(4)) bbb = a(1)*(sin(2*pigrec*x/a(2)+a(3 )))* exp(-x/a(4)) aaa = x /(a(4)**2.0) dyda(4) = aaa * bbb 68 ’ ’ ’ ’ ’ ’ CAPITOLO 2. IL LABORATORIO 100 2.4. CAVEN dyda(5) = 1.0 return END subroutine gtutto (cav,para,inc) implicit real (a-h,o-z) dimension para (1:inc ) pigrec = 3.1415927 egran = para(1) el = para(2) er = para(3) ed = para(4) a1 = (ed * er**2)/(2.0* egran ) a2 = (2 * pigrec / para(6))**2 + ( 1/para(7))**2 diff = abs ( atan ( para(5) /el )) aldif = diff/2.0 a3 = aldif elle = sqrt ( (2* ed)**2 + er **2 ) a4 = 1.0/(1.0 - (er/elle)**3 ) cav = a1 * a2 * a3 * a4 return end subroutine calco (ecav,cav,para,inc,epara,video) implicit real (a-h,o-z) character * 1 video parameter ( int = 10 ) dimension para (1:inc ) dimension epara (1:inc ) dimension work (1:int ) dimension square (1:int ) dimension inter (1:int ) if (int.lt.inc)stop ’cambiare int’ vero = cav do 100 j = 1 ,inc work (j) = para (j) continue quadro = 0.0 do 200 j = 1 ,inc do 190 i = 1 , inc para (i) = work(i) 69 2.4. CAVEN 190 200 205 206 210 C C C CAPITOLO 2. IL LABORATORIO continue para (j) = para(j) + epara(j) call gtutto (cavmod,para,inc) delta = cavmod - vero quadro = quadro + delta *delta square ( j )= delta * delta continue sq2 = 0.0 do 205 j= 1,inc sq2 = sq2 + square ( j) continue do 206 j= 1,inc inter (j) = nint ( square ( j) * 1000./sq2) continue if (( video.eq.’Y’).or.( video.eq.’y’)) then print *,’Peso normalizzato a 1000 dell’’errore delle variabili’ print *,’sull’’errore del valore di G-metodo completo ’ print *,’errore su M ( massa grande) =’,inter(1) print *,’errore su L ( distanza indice) =’,inter(2) print *,’errore su r ( distanza masse ) =’,inter(3) print *,’errore su d ( manubrio/2 ) =’,inter(4) print *,’errore su a(1)(ampiezza oscillazioni) =’,inter(5) print *,’errore su a(2)(periodo oscillazioni) =’,inter(6) print *,’errore su a(4)(smorzamento oscillazioni)=’,inter(7) end if ecav = sqrt ( quadro) do 210 i = 1 , inc para (i) = work(i) continue return end subroutine gescur (cave,caves,para,inc) implicit real (a-h,o-z) dimension para (1:inc ) pigrec = 3.1415927 egran = para(1) el = para(2) er = para(3) 70 CAPITOLO 2. IL LABORATORIO C C C C ed a(1) a(2) a(4) egran el er ed aa1 aa2 aa3 aa4 dd1 dd2 dd3 ages d1 d2 beta piu cave caves return end = = = = = = = = = = = = = = = = = = = = = = 2.4. CAVEN para(4) para(5) para(6) para(7) para(1) para(2) para(3) para(4) pigrec **2 er **2 ed para(5) * 0.01 egran para(6) ** 2 el / 100. aa1 * aa2 * aa3 *aa4 /( dd1 * dd2 * dd3 ) 1 + 4 * ( ed / er )**2 sqrt ( 1 + 4 * ( ed / er )**2 ) 1 /( d1 * d2 ) beta * ages ages + piu ages subroutine calcos (ecave,cave,para,inc,epara,video) implicit real (a-h,o-z) character * 1 video parameter ( int = 10 ) dimension para (1:inc ) dimension epara (1:inc ) dimension work (1:int ) dimension square (1:int ) dimension inter (1:int ) if (int.lt.inc)stop ’cambiare int’ vero = cave do 100 j = 1 ,inc work (j) = para (j) 71 2.4. CAVEN 100 190 200 205 206 210 CAPITOLO 2. IL LABORATORIO continue quadro = 0.0 do 200 j = 1 ,inc do 190 i = 1 , inc para (i) = work(i) continue para (j) = para(j) + epara(j) call gescur (cmod,caves,para,inc) delta = cmod - vero quadro = quadro + delta *delta square (j) = delta * delta continue sq2 = 0.0 do 205 j= 1,inc sq2 = sq2 + square ( j) continue do 206 j= 1,inc inter (j) = nint ( square ( j) * 1000./sq2) continue if (( video.eq.’Y’).or.( video.eq.’y’)) then print *,’Peso normalizzato a 1000 dell’’errore delle variabili’ print *,’sull’’errore del valore di G-escursione finale’ print *,’errore su M ( massa grande) =’,inter(1) print *,’errore su L ( distanza indice) =’,inter(2) print *,’errore su r ( distanza masse ) =’,inter(3) print *,’errore su d ( manubrio/2 ) =’,inter(4) print *,’errore su a(1)(ampiezza oscillazioni) =’,inter(5) print *,’errore su a(2)(periodo oscillazioni) =’,inter(6) print *,’errore su a(4)(smorzamento oscillazioni)=’,inter(7) end if ecave = sqrt ( quadro) do 210 i = 1 , inc para (i) = work(i) continue return end SUBROUTINE fun2c(X,AFUNC,MA) DIMENSION AFUNC(MA) AFUNC(1)= 1.0 72 CAPITOLO 2. IL LABORATORIO AFUNC(2)= END 2.4. CAVEN X**2.0 subroutine gpara (cav,para,inc) implicit real (a-h,o-z) dimension para (1:inc ) egran = para(1) el = para(2) er = para(3) ed = para(4) aa = para(5) cav = ( aa* ed * er**2 )/(2.0 * egran * el ) return end subroutine capa2 (ecav,cav,para,inc,epara,video) C lavoro implicit real (a-h,o-z) character * 1 video parameter ( int = 10 ) dimension para (1:inc ) dimension epara (1:inc ) dimension work (1:int ) dimension square (1:int ) dimension inter (1:int ) if (int.lt.inc)stop ’cambiare int’ vero = cav do 100 j = 1 ,inc work (j) = para (j) 100 continue quadro = 0.0 do 200 j = 1 ,inc do 190 i = 1 , inc para (i) = work(i) 190 continue para (j) = para(j) + epara(j) call gpara(cavmod,para,inc) delta = cavmod - vero quadro = quadro + delta *delta 73 2.5. GAUSS CAPITOLO 2. IL LABORATORIO 200 205 206 210 2.5 square ( j )= delta * delta continue sq2 = 0.0 do 205 j= 1,inc sq2 = sq2 + square ( j) continue do 206 j= 1,inc inter (j) = nint ( square ( j) * 1000./sq2) continue if (( video.eq.’Y’).or.( video.eq.’y’)) then print *,’Peso normalizzato a 1000 dell’’errore delle variabili’ print *,’sull’’errore del valore di G-metodo parabola ’ print *,’errore su M ( massa grande) =’,inter(1) print *,’errore su L ( distanza indice) =’,inter(2) print *,’errore su r ( distanza masse ) =’,inter(3) print *,’errore su d ( manubrio/2 ) =’,inter(4) print *,’errore su a ( accelerazione ) =’,inter(5) end if ecav = sqrt ( quadro) do 210 i = 1 , inc para (i) = work(i) continue return end GAUSS Questo programma riguarda l’ esercitazione sul viscosimetro ma puo essere usato per altri scopi. Si parte con una serie di dati inserita nel file GAUSS.DAT che vengono lette dal programma e inserite nel vettore DATI. La subroutine ISTOTUTTO provvede poi a calcolare il massimo e il minimo e, dato in modo interattivo il numero di classi, la distribuzione in frequenza. Si ottengono poi i seguenti parametri statistici caratterizzanti la distribuzione sperimentale: 1. valor medio dell’ istogramma −1 1 NX (xi )(yi ) x̄ = N i=1 74 (2.25) CAPITOLO 2. IL LABORATORIO 2.5. GAUSS 2. deviazione standard dell’ istogramma s2 = v u u t −1 1 NX yi × (xi − x̄)2 N − 1 i=1 (2.26) 3. momento di terzo ordine e asimmetria PN −1 s3 = yi × (xi − x̄)3 (N − 1) × s23 i=1 (2.27) 4. momento di quarto ordine e curtosi PN −1 s4 = yi × (xi − x̄)4 −3 (N − 1) × s24 i=1 (2.28) 5. χ2 : χ2 = N −1 X i=1 (yi − fi )2 fi (2.29) Riportiamo il listato del programma GAUSS: program gauss C C definizione delle variabili e dei vettori utilizzati dal programma C implicit real (a-h,o-z) parameter ( max = 1000) parameter ( pigrec = 3.141592653) character * 2 risp character * 1 pausa dimension xreal (1:max) dimension iyreal (1:max) dimension dati (1:max) open (unit=90,file=’gauss.dat’, status=’old’) C C input dei dati da tastiera C print *,’Programma per il calcolo statistico ’ 75 2.5. GAUSS CAPITOLO 2. IL LABORATORIO print *,’Analisi di dati con distribuzione Gaussiana ’ print *,’Avete messo i dati nel file gaussiana.dat ? ’ print *, ’se no uscite !!!!!!!!!!!!!!! ’ print *,’<CR> per continuare !’ read 1000,pausa ndati = 0 199 continue read (90,*,end = 200)dato ndati = ndati + 1 dati ( ndati ) = dato go to 199 200 continue 250 continue print *,’Scrivere il numero di intervalli desiderato ’ read *,ndiv print *,’va bene questo numero di intervalli ? <CR>/NO read 1000,risp if ((risp.eq.’NO’).or.(risp.eq.’no’)) then go to 200 end if jvec = 0 999 format (A1) 1000 format (A2) ndiv1 = ndiv + 1 call isto (dati,ndati,max,ndiv1,xreal,iyreal,delta) call mom (ndiv1,xreal,iyreal,xmedio,s2,s3,s4,nsumy) C calcolo del chi-quadro chi2 = 0. do 100 j= 1,ndiv xmezzo = (xreal(j) + xreal (j+1))/ 2.0 yteo = 1./(sqrt (2.0 * pigrec) *s2 ) yteo = yteo * exp (-((( xmezzo - xmedio)/s2 )**2)/2.0 ) yteo = yteo * nsumy * delta chi2 = chi2 + (( iyreal (j) - yteo)**2) / yteo 100 continue print *,’xmedio =’,xmedio print *,’s2 =’,s2 print *,’s3 =’,s3 print *,’s4 =’,s4 76 ’ CAPITOLO 2. IL LABORATORIO C 101 102 104 103 2.5. GAUSS print *,’nsumy =’,nsumy print *,’chi2 =’,chi2 print *,’Vuoi cambiare il numero di intervalli ? Y/N’ read 999,pausa if ((pausa.eq.’Y’).or.(pausa.eq.’y’)) then go to 250 end if stop end subroutine isto (dati,ndati,max,ndiv1,xreal,iyreal,delta) implicit real (a-h,o-z) dimension dati (1:max) dimension xreal (1:max) dimension iyreal(1:max) azzeramento variabili do 101 j= 1 ,ndiv1 xreal (j) = 0 iyreal (j) = 0 continue call maxmin (dati,ndati,xmax,xmin ) xmax = xmax + xmax/1000 ndiv = ndiv1 - 1 delta = ( xmax - xmin )/ndiv do 102 j = 1 , ndiv1 xreal (j) = xmin + ( j-1 ) * delta continue do 103 j = 1 , ndati do 104 i= 1 , ndiv xl = xreal ( i ) xu = xreal ( i + 1 ) if ( (dati (j).ge.xl).and.(dati(j).lt.xu) ) then iyreal ( i) = iyreal(i) +1 end if continue continue return end subroutine mom (k,x,ifreq,xmean,s2,s3,s4,n) implicit real (a-h,o-z) 77 2.5. GAUSS C C 100 C 101 C 102 C 103 C 104 C 105 CAPITOLO 2. IL LABORATORIO dimension x (1:k) dimension ifreq (1:k) dimension y (1:1000) azzeramento variabili xmean = 0. s2 = 0. s3 = 0. s4 = 0. n = 0 calcolo della frequenza totale do 100 i=1,k-1 n = n + ifreq (i) continue calcolo dei punti centrali do 101 j=1,k-1 y(j) = ( x(j+1) + x (j) )/2.0 continue calcolo del valor medio do 102 j=1,k-1 xmean = xmean + y (j) * ifreq (j) continue xmean = xmean/ n calcolo della deviazione standard do 103 j=1,k-1 s2 = s2 + ((y(j) - xmean )**2) * ifreq (j) continue s2 = sqrt (s2/(n-1)) calcolo della asimmetria do 104 j =1,k-1 s3 = s3 + ((y(j) - xmean )**3) * ifreq (j) continue s3 = s3 /((n-1)*( s2**3)) calcolo della curtosi do 105 j=1,k-1 s4 = s4 + ((y(j) - xmean )**4) * ifreq (j) continue s4 = ( s4 /((n-1)*( s2**4))) - 3. return end 78 CAPITOLO 2. IL LABORATORIO 2.6 2.6. TESTT TESTT Questo programma sostituisce le tabelle relative al test di Student. Si inseriscono in maniera interattiva il numero di gradi di libertà n e la probabilità considerata. Mediante la subroutine BETAI appartenente al libro [REC 92] viene poi calcolato il valore critico, xp , associato con il taglio inferiore corrispondente alla probabilità della distribuzione di Student con n gradi di libertà. Riportiamo il listato del programma TESTT: program testt implicit real (a-h,o-z) logical condiz character * 1 pausa parameter ( tmax = 1000 ,ndiv = tmax * 100) external betai print *,’Programma per il calcolo del valore critico nella ’ print *,’distribuzione della variabile casuale t di Student ’ print *,’con nu gradi di liberta , dato alfa ’ print *,’<CR> per continuare !’ read 1000,pausa 999 format (A1) 1000 format (A2) 50 continue print *,’inserire i gradi di liberta ’ read *, n 100 continue print *,’immettere alfa, livello di confidenza (0.01,0.05,0.1...)’ read *, alfa condiz = .false. delta = tmax / ndiv do 200 jj= 1, ndiv t = jj * delta prob= 1 - betai(0.5*n,0.5,n/(n+t**2)) q = ( 1 + prob ) / 2 qmeno = ( 1 - prob ) / 2 if (.not.condiz) then 79 2.7. TESTC2 CAPITOLO 2. IL LABORATORIO if 200 950 2.7 ( qmeno.lt. (alfa) ) then tuno = ( jj-1) * delta condiz =. true. end if endif if ( qmeno.lt. (alfa/2.0)) then tdue = ( jj-1) * delta go to 950 end if continue stop ’ aumentare tmax !!!’ continue print *,’gradi di liberta‘ =’,n print *,’livello di significativita‘ =’,alfa print *,’t critico ad una banda =’,tuno print *,’t critico a due bande =’,tdue print *,’Vuoi cambiare le variabili ? Y/N’ read 999,pausa if ((pausa.eq.’Y’).or.(pausa.eq.’y’)) then go to 50 end if stop end TESTC2 Questo programma sostituisce le tabelle della variabile χ2 e usa la subroutine GAMMQ estratta dal libro [REC 92]. Riportiamo il listato del programma TESTC2: 13 program testc2 implicit real (a-h,o-z) character pausa parameter ( c2max = 200 ,ndiv = c2max * 100 ) external gammq continue print *,’Abbiamo due opzioni ....................’ print *,’fissiamo chi2 e troviamo la probabilita‘ (1)’ 80 CAPITOLO 2. IL LABORATORIO 2.7. TESTC2 print *,’fissiamo alfa e troviamo chi2 (2)’ read *,numero if ( numero.eq.1 ) then go to 11 elseif( numero.eq.2 ) then go to 12 else go to 13 end if 11 continue print *,’Parte per il calcolo di un integrale ’ print *,’fra chi2 e infinito ’ print *,’della della densita‘ di probabilita‘ CHI-QUADRATO ’ print *,’con nu gradi di liberta ’ call attesa 50 continue print *,’inserire i gradi di liberta ’ read *, n 100 continue print *,’immettere il chi2 trovato (0.6,0.9,1.5 ,4...)’ read *,chi2 prob = gammq ( 0.5 * n , 0.5 * chi2 ) print *,’gradi di liberta =’,n print *,’chi2-impostato =’,chi2 print *,’integrale fra chi2 e infinito =’,prob print *,’ ’ print *,’Vuoi cambiare le variabili ? Y/N’ read 999,pausa 999 format (a1) if ((pausa.eq.’Y’).or.(pausa.eq.’y’)) then go to 50 else stop end if 12 continue print *,’Parte per il calcolo del chi2 corrispondente ’ print *,’ad un livello di significativita‘ alfa ’ print *,’della della densita‘ di probabilita‘ CHI-QUADRATO ’ print *,’con nu gradi di liberta ’ 81 2.7. TESTC2 CAPITOLO 2. IL LABORATORIO call attesa 51 continue print *,’inserire i gradi di liberta‘ ’ read *, n print *,’immettere il livello di significativa‘ (0.01,0.05,0.1)’ read *,alfa delta = c2max / ndiv if ( n .eq.1 ) then delta = 0.00001 end if do 995 jj = 1 , ndiv chi2 = jj * delta prob = gammq ( 0.5 * n , 0.5 * chi2 ) alfat = 1 - prob if ( alfat.gt.alfa ) then c2sin = chi2p go to 52 end if chi2p = chi2 995 continue 52 continue delta = c2max / ndiv do 996 jj = 1 , ndiv chi2 = jj * delta prob = gammq ( 0.5 * n , 0.5 * chi2 ) if ( prob.lt.alfa ) then chi2d = chi2p go to 54 end if chi2p = chi2 996 continue 54 continue print *,’chi2 a destra =’,chi2d print *,’chi2 a sinistra =’,c2sin print *,’gradi di liberta‘ =’,n print *,’alfa =’,alfa print *,’Vuoi cambiare le variabili ? Y/N’ read 999,pausa if ((pausa.eq.’Y’).or.(pausa.eq.’y’)) then 82 CAPITOLO 2. IL LABORATORIO 2.7. TESTC2 go to 51 else stop end if end 83 2.7. TESTC2 CAPITOLO 2. IL LABORATORIO 84 Capitolo 3 Probabilità e statistica Adesso cerchiamo di capire come sono scritte le varie subroutine che abbiamo usato in maniera nascosta perchè inserite nel link con le librerie del libro [REC 92] che sono scritte in FORTRAN-77 standard. 3.1 Gamma La funzione gamma è definita dall’ integrale Γ(z) = Z ∞ tz−1 e−t dt . (3.1) 0 Quando l’ argomento z è un intero, la funzione gamma diventa il fattoriale dell’ argomento meno uno: n! = Γ(n + 1) . (3.2) Esistono vari metodi per calcolare la funzione gamma e sembra che quello migliore sia quello derivato da Lanczos. Riportiamo adesso la FUNCTION GAMMLN che dato l’ argomento xx ritorna ln (Γ (xx)): FUNCTION gammln(xx) REAL gammln,xx INTEGER j DOUBLE PRECISION ser,stp,tmp,x,y,cof(6) SAVE cof,stp DATA cof,stp/76.18009172947146d0,-86.50532032941677d0, *24.01409824083091d0,-1.231739572450155d0,.1208650973866179d-2, 85 3.2. FATTORIALE 11 3.2 CAPITOLO 3. PROBABILITÀ E STATISTICA *-.5395239384953d-5,2.5066282746310005d0/ x=xx y=x tmp=x+5.5d0 tmp=(x+0.5d0)*log(tmp)-tmp ser=1.000000000190015d0 do 11 j=1,6 y=y+1.d0 ser=ser+cof(j)/y continue gammln=tmp+log(stp*ser/x) return END Fattoriale Riportiamo la FUNCTION che calcola il fattoriale di n distinguendo fra i vari valori e alla fine chiamando la funzione gamma: CU 11 FUNCTION factrl(n) INTEGER n REAL factrl USES gammln INTEGER j,ntop REAL a(33),gammln SAVE ntop,a DATA ntop,a(1)/0,1./ if (n.lt.0) then pause ’negative factorial in factrl’ else if (n.le.ntop) then factrl=a(n+1) else if (n.le.32) then do 11 j=ntop+1,n a(j+1)=j*a(j) continue ntop=n factrl=a(n+1) else 86 CAPITOLO 3. PROBABILITÀ E STATISTICA 3.2. FATTORIALE factrl=exp(gammln(n+1.)) endif return END Un punto interessante è notare che che il fattoriale è giusto per valori piccoli di n ma è approssimato se passiamo come vedremo adesso al logaritmo del fattoriale. Per quanto riguarda il coefficiente binomiale dobbiamo invece dobbiamo passare ai logaritmi per evitare gli overflow. Ricordiamo che il coefficiente binomiale vale: ! n n! = k!(n − k)! k 0≤k≤n , (3.3) e possiamo introdurre la FUNCTION BICO che calcola il suddetto coefficiente: CU FUNCTION bico(n,k) INTEGER k,n REAL bico USES factln REAL factln bico=nint(exp(factln(n)-factln(k)-factln(n-k))) return END la quale adopera il logaritmo del fattoriale: CU FUNCTION factln(n) INTEGER n REAL factln USES gammln REAL a(100),gammln SAVE a DATA a/100*-1./ if (n.lt.0) pause ’negative factorial in factln’ if (n.le.99) then if (a(n+1).lt.0.) a(n+1)=gammln(n+1.) factln=a(n+1) else 87 3.3. FUNZIONE BETA CAPITOLO 3. PROBABILITÀ E STATISTICA factln=gammln(n+1.) endif return END 3.3 Funzione beta Passando dagli interi al continuo arriviamo alla funzione beta che cosı̀ definiamo B(z, w) = B(w, z) = Z 1 tz−1 (1 − t)w−1 dt , (3.4) 0 questa è collegata alla funzione gamma dalla relazione B(z, w) = Γ(z)Γ(w) Γ(z + w) , (3.5) che è facilmente implementata tramite la FUNCTION beta CU 3.4 FUNCTION beta(z,w) REAL beta,w,z USES gammln REAL gammln beta=exp(gammln(z)+gammln(w)-gammln(z+w)) return END Gamma incompleta La funzione gamma incompleta è definita come P (a, x) ≡ γ(a, x) 1 Z x a−1 −t ≡ t e dt (a > 0) . Γ(a) Γ(a) 0 (3.6) Essa ha come limiti P (a, 0) = 0 e P (a, ∞) = 1 . 88 (3.7) CAPITOLO 3. PROBABILITÀ E STATISTICA3.4. GAMMA INCOMPLETA Il complemento di P (a,x) è anche chiamata in maniera confusa funzione gamma incompleta 1 Z ∞ a−1 −t Γ(a, x) ≡ t e dt (a > 0) , Q(a, x) ≡ 1 − P (a, x) ≡ Γ(a) Γ(a) x (3.8) ed ha i seguenti valori limiti Q(a, 0) = 1 e Q(a, ∞) = 0 . (3.9) La notazione P(a,x),γ(a, x) e Γ(a, x) sono standard; la notazione Q (a,x) la useremo solo in questo contesto. A questo punto riportiamo le FUNCTION che ritornano P(a,x) e Q (a,x ) usando la extra lettera p e q dopo gamm: CU CU FUNCTION gammp(a,x) REAL a,gammp,x USES gcf,gser REAL gammcf,gamser,gln if(x.lt.0..or.a.le.0.)pause ’bad arguments in gammp’ if(x.lt.a+1.)then call gser(gamser,a,x,gln) gammp=gamser else call gcf(gammcf,a,x,gln) gammp=1.-gammcf endif return END FUNCTION gammq(a,x) REAL a,gammq,x USES gcf,gser REAL gammcf,gamser,gln if(x.lt.0..or.a.le.0.)pause ’bad arguments in gammq’ if(x.lt.a+1.)then call gser(gamser,a,x,gln) gammq=1.-gamser else call gcf(gammcf,a,x,gln) 89 3.4. GAMMA INCOMPLETACAPITOLO 3. PROBABILITÀ E STATISTICA gammq=gammcf endif return END L’ argomento gln è dato tramite serie e procedura delle frazioni continue: CU 11 1 SUBROUTINE gser(gamser,a,x,gln) INTEGER ITMAX REAL a,gamser,gln,x,EPS PARAMETER (ITMAX=100,EPS=3.e-7) USES gammln INTEGER n REAL ap,del,sum,gammln gln=gammln(a) if(x.le.0.)then if(x.lt.0.)pause ’x < 0 in gser’ gamser=0. return endif ap=a sum=1./a del=sum do 11 n=1,ITMAX ap=ap+1. del=del*x/ap sum=sum+del if(abs(del).lt.abs(sum)*EPS)goto 1 continue pause ’a too large, ITMAX too small in gser’ gamser=sum*exp(-x+a*log(x)-gln) return END SUBROUTINE gcf(gammcf,a,x,gln) INTEGER ITMAX REAL a,gammcf,gln,x,EPS,FPMIN PARAMETER (ITMAX=100,EPS=3.e-7,FPMIN=1.e-30) 90 CAPITOLO 3. PROBABILITÀ E STATISTICA CU 11 1 3.5 3.5. FUNZIONE ERRORI USES gammln INTEGER i REAL an,b,c,d,del,h,gammln gln=gammln(a) b=x+1.-a c=1./FPMIN d=1./b h=d do 11 i=1,ITMAX an=-i*(i-a) b=b+2. d=an*d+b if(abs(d).lt.FPMIN)d=FPMIN c=b+an/c if(abs(c).lt.FPMIN)c=FPMIN d=1./d del=d*c h=h*del if(abs(del-1.).lt.EPS)goto 1 continue pause ’a too large, ITMAX too small in gcf’ gammcf=exp(-x+a*log(x)-gln)*h return END Funzione errori La funzione degli errori e la funzione degli errori complementari sono casi speciali della funzione gamma incompleta e sono quindi ottenute dalle procedure summenzionate. Sono cosı̀ definite 2 Z x −t2 e dt , erf (x) = √ π 0 (3.10) e 2 Z ∞ −t2 erf c(x) ≡ 1 − erf (x) = √ e dt . (3.11) π x Esse sono legate alle funzioni gamma incomplete dalle relazioni: 1 erf (x) = P ( , x2 ) (x ≥ 0) , 2 91 (3.12) 3.6. DISTRIBUZIONI CAPITOLO 3. PROBABILITÀ E STATISTICA e 1 erf c(x) = Q( , x2 ) (x ≥ 0) . 2 Quindi otteniamo facilmente le FUNCTION ERF e ERFC CU CU 3.6 (3.13) FUNCTION erf(x) REAL erf,x USES gammp REAL gammp if(x.lt.0.)then erf=-gammp(.5,x**2) else erf=gammp(.5,x**2) endif return END FUNCTION erfc(x) REAL erfc,x USES gammp,gammq REAL gammp,gammq if(x.lt.0.)then erfc=1.+gammp(.5,x**2) else erfc=gammq(.5,x**2) endif return END Distribuzioni Analizziamo ora alcune delle distribuzioni di probabilità più note. 3.6.1 Distribuzione del chiquadro P (χ2 |ν) è definita come la probabilità che il il chi-quadro osservato in un modello corretto sia minore di un certo valore χ2 . Il suo complemento Q (χ2 |ν) è la probabilità che il chi-quadro osservato ecceda il valore χ2 tramite chance anche per un modello corretto. In ambedue 92 CAPITOLO 3. PROBABILITÀ E STATISTICA 3.6. DISTRIBUZIONI i casi ν è un intero, il numero di gradi di libertà del sistema. Queste funzioni sono cosı̀ collegate alle funzioni gamma incomplete: P (χ2 |ν) = Q(χ2 |ν) = 3.6.2 P , χ2 = 2 2 ν Q χ2 = 2 2 ν , ν χ2 gammp ( , 2 2 2 ν χ gammq ( , . 2 2 (3.14) (3.15) Distribuzione Beta incompleta La funzione beta incompleta è definita come Ix (a, b) ≡ Bx (a, b) 1 Z x a−1 ≡ t (1 − t)b−1 dt (a, b > 0) . (3.16) B(a, b) B(a, b) 0 Questa funzione ha come valori limite: I0 (a, b) = 0 I1 (a, b) = 1 , (3.17) e vale la relazione di simmetria Ix (a, b) = 1 − I1−x (b, a) . (3.18) La funzione beta incompleta viene implementata attraverso la FUNCTION BETAI: CU FUNCTION betai(a,b,x) REAL betai,a,b,x USES betacf,gammln REAL bt,betacf,gammln if(x.lt.0..or.x.gt.1.)pause ’bad argument x in betai’ if(x.eq.0..or.x.eq.1.)then bt=0. else bt=exp(gammln(a+b)-gammln(a)-gammln(b)+a*log(x)+b*log(1.-x)) endif if(x.lt.(a+1.)/(a+b+2.))then betai=bt*betacf(a,b,x)/a return else betai=1.-bt*betacf(b,a,1.-x)/b return endif END 93 3.6. DISTRIBUZIONI CAPITOLO 3. PROBABILITÀ E STATISTICA la quale richiede una routine per valutare la frazione continua: 11 1 FUNCTION betacf(a,b,x) INTEGER MAXIT REAL betacf,a,b,x,EPS,FPMIN PARAMETER (MAXIT=100,EPS=3.e-7,FPMIN=1.e-30) INTEGER m,m2 REAL aa,c,d,del,h,qab,qam,qap qab=a+b qap=a+1. qam=a-1. c=1. d=1.-qab*x/qap if(abs(d).lt.FPMIN)d=FPMIN d=1./d h=d do 11 m=1,MAXIT m2=2*m aa=m*(b-m)*x/((qam+m2)*(a+m2)) d=1.+aa*d if(abs(d).lt.FPMIN)d=FPMIN c=1.+aa/c if(abs(c).lt.FPMIN)c=FPMIN d=1./d h=h*d*c aa=-(a+m)*(qab+m)*x/((a+m2)*(qap+m2)) d=1.+aa*d if(abs(d).lt.FPMIN)d=FPMIN c=1.+aa/c if(abs(c).lt.FPMIN)c=FPMIN d=1./d del=d*c h=h*del if(abs(del-1.).lt.EPS)goto 1 continue pause ’a or b too big, or MAXIT too small in betacf’ betacf=h return END 94 CAPITOLO 3. PROBABILITÀ E STATISTICA 3.6.3 3.7. NUMERI RANDOM Distribuzione di Student La distribuzione di Student, denotata con A(t|ν), è utile in parecchi contesti di probabilità, ed in particolare quando si tratta di decidere se due campioni hanno la stessa media. A(t|ν) è la probabilità, per ν gradi di libertà, che una certa statistica t (misurando la differenza osservata fra medie) sia minore del valore osservato nell’ ipotesi che le medie siano uguali.Due medie sono significativamente differenti se ad esempio A(t|ν) > 0.99. In altre parole, 1- A(t|ν) è il livello di significatività per il quale l’ ipotesi che le medie siano uguali è scartata. La definizione matematica della funzione è 1+ν Z t x2 − 1 2 dx . 1+ A(t|ν) = 1/2 1 ν ν ν B( 2 , 2 ) −t (3.19) I valori limite sono A(0|ν) = 0 A(∞|ν) = 1 . (3.20) A(t|ν) è legata alla funzione beta incompleta Ix (a,b) dalla relazione: ν A(t|ν) = 1 − I ν+t 2 1 , 2 2 ν , (3.21) e quindi adottiamo la funzione betai che abbiamo prima definito. 3.7 Numeri random Un generatore uniforme è un algoritmo capace di generare dei numeri senza una legge apparente fra 0 ed 1 mentre se vogliamo ottenere numeri estratti ad esempio da una distribuzione gaussiana caratterizzata da una certa media e distribuzione standard dobbiamo partire da un generatore uniforme e poi modificarlo opportunamente. 3.7.1 Generatori di sistema Quasi tutti i linguaggi di programmazione contengono una subroutine che con l’ indimenticabile nome RAN produce una serie di numeri random: x = ran (iseed) , (3.22) 95 3.7. NUMERI RANDOM CAPITOLO 3. PROBABILITÀ E STATISTICA All’ inizio si fissa come primo passo un iseed molto grande e poi si procede alle chiamate seguenti senza più modificare iseed. Cambiando iseed si cambia la sequenza mentre chiamate successive con lo stesso iseed producono sequenze uguali. Bisogna però fare attenzione a questi generatori di sistema perchè quasi sempre sono dei generatori lineari congruenti che generano delle sequenze di interi I1 , I2 , I3 , ognuno fra 0 ed m-1 ( un numero grande ) attraverso la relazione ricorsiva Ij+1 = aIj + c (mod m) , (3.23) dove m è chiamato modulo, a moltiplicatore e c incremento. Questa ricorrenza si ripeterà eventualmente con un periodo che non è più grande di m. Se m, a, c sono scelti in maniera appropriata allora il periodo sarà massimo ovverosia di lunghezza m. In questo caso tutti gli interi fra 0 ed m-1 saranno scelti. La sequenza parte esattamente da questo punto. Il numero reale di ritorno compreso fra 0 ed 1 è generalmente Ij+1 /m , cosicchè è generalmente minore di 1 ( eccetto che una volta in m chiamate ). Il metodo lineare congruente ha il vantaggio di essere molto veloce richiedendo solamente poche righe per chiamata e quindi è di uso universale. Ha lo svantaggio di non essere libero da correlazioni sequenziali nelle chiamate successive. Se k numeri random sono chiamati a plottare dei punti in uno spazio k-dimensionale ( con ogni coordinata compresa fra 0 ed 1 ), allora i punti non tendono a coprire uniformemente lo spazio ma piuttosto a distribuirsi su (k-1) piani. Ci saranno almeno circa m1/k piani e se le costanti m, a e c non sono scelte esattamente saranno meno di quelli. Il numero m è usualmente vicino al più largo intero rappresentabile ≈ 232 . Cosicchè ad esempio il numero di piani sui quali triple di punti giacciono in uno spazio tridimensionale è usualmente non più grande della radice cubica di 232 , circa 1600. 3.7.2 Generatore Random - portatile Tutto sommato possiamo adoperare il semplice algoritmo moltiplicativo Ij+1 = aIj (mod m) , (3.24) se il moltiplicatore a e il modulo m sono scelti con attenzione. I signori Park e Miller propongono a = 75 = 16807 m = 231 − 1 . 96 (3.25) CAPITOLO 3. PROBABILITÀ E STATISTICA 3.7. NUMERI RANDOM Non è possibile implementare direttamente questo algoritmo poichè il prodotto di a per m eccede il massimo intero possibile e quindi dobbiamo passare attraverso una fattorizzazione approssimata di m: m = aq + r , q = [m/a] , r = m mod a , (3.26) con le parentesi quadrate indicante la parte intera. Se r è piccolo ed in particolare r < q, e 0 < z < m-1 può essere dimostrato che sia a ( z mod q ) e r [ z/ q] stanno nel range 0,..., m-1 e che az mod m = a(z mod q) − r[z/q] se è ≥ 0; a(z mod q) − r[z/q] + m altrimenti. (3.27) L’ applicazione di questo algoritmo alle costanti summenzionate usa i valori q =127773 e r=2836. Questo algoritmo viene implementato attraverso la FUNCTION RAN0 FUNCTION ran0(idum) INTEGER idum,IA,IM,IQ,IR,MASK REAL ran0,AM PARAMETER (IA=16807,IM=2147483647,AM=1./IM,IQ=127773,IR=2836, *MASK=123459876) INTEGER k idum=ieor(idum,MASK) k=idum/IQ idum=IA*(idum-k*IQ)-IR*k if (idum.lt.0) idum=idum+IM ran0=AM*idum idum=ieor(idum,MASK) return END Il periodo di ran0 è 231 -1 ≈ 2.0109 . Una peculiarità e chè il valore 0 non è mai raggiunto al primo tentativo. 3.7.3 Generatore di interi Il problema consiste nel generare una distribuzione di numeri interi con un processo random fra un numero IMIN e IMAX, frontiere comprese. Il problema è di facile soluzione e consiste nel moltiplicare il numero reale random compreso fra 0 ed 1 per ∆ = IMAX - IMIN +1, dove 97 3.7. NUMERI RANDOM CAPITOLO 3. PROBABILITÀ E STATISTICA l’ addizione di uno significa che vogliamo anche gli interi sulla frontiera. L’ implementazione avviene tramite la FUNCTION G05DYFZAN che prende il nome dal tentativo di simulare una routine delle NAG. function g05dyfzan (ilower,iupper,idum) integer ilower ,iupper,iscelto,idum,g05dyfzan external ran1 real ran1 delta = iupper - ilower + 1.0 iscelto = int ( ran0 (idum) * delta ) g05dyfzan = ilower + iscelto if (g05dyfzan .lt. ilower ) stop ’errore g05dyfzan if (g05dyfzan .gt. iupper ) stop ’errore g05dyfzan return end 3.7.4 Distribuzione esponenziale Nella sezione precedente, abbiamo imparato a generare dei numeri random con una distribuzione di probabilità uniforme, cosicchè la probabilità di generare un numero compreso fra x e x + dx, denotata con p(x)dx, è data da p(x)dx = dx, e 0 < x<1; 0, altrimenti. (3.28) La distribuzione è ovviamente normalizzata che significa: Z p(x)dx = 1 . (3.29) Supponiamo adesso di generare una variabile uniforme x. La distribuzione di probabilità di y, denotata p(y)dy, è determinata dalla legge fondamentale per le trasformazioni di probabilità, che è semplicemente |p(y)dy| = |p(x)dx| , (3.30) oppure p(y) = p(x)| 98 dx | . dy (3.31) piccolo’ grande ’ CAPITOLO 3. PROBABILITÀ E STATISTICA 3.7. NUMERI RANDOM Assumiamo ora che y (x) ≡ - ln (x), e che p( x) è dato per una distribuzione uniforme. Avremo allora p(y)dy = | dx |dy = e−y dy dy , (3.32) che è distribuita esponenzialmente. Questa distribuzione occorre frequentemente nei problemi reali, ad esempio come tempo di attesa fra eventi nei fenomeni governati dalla distribuzione di Poisson. Potete anche notare che la quantità λy ha la distribuzione di probabilità λe−λy . La implementazione pratica avviene attraverso la FUNCTION EXPDEV. CU 1 3.7.5 FUNCTION expdev(idum) INTEGER idum REAL expdev USES ran1 REAL dum,ran1 dum=ran1(idum) if(dum.eq.0.)goto 1 expdev=-log(dum) return END Distribuzione Gaussiana I metodi di trasformazione possono essere generalizzati a più di una dimensione. Se x1 , x2 , x3 ,.... sono delle variabili random con una probabilità di distribuzione congiunta p ( x1 , x2 , x3 ,..... )dx1 , dx2 ,dx3 ...dxn e y1 ,y2 ,.....yn sono funzioni delle x allora la probabilità congiunta delle y vale: ∂(x1 , x2 , ....xn ) |dy1 , dy2 , .....dyn ∂(y1 , y2 , ....yn ) (3.33) dove |∂(......)/∂(....)| è il determinante Jacobiano delle x rispetto alle y. Un esempio importante della formula suddetta è il metodo di BoxMuller per generare una distribuzione Gaussiana: p(y1 , y2 , ....yn )dy1 dy2 ...dyn = p(x1 , x2 , ...xn )| 1 −y2 p(y)dy = √ e 2 dy 2π 99 . (3.34) , 3.7. NUMERI RANDOM CAPITOLO 3. PROBABILITÀ E STATISTICA Consideriamo adesso la trasformazione fra due distribuzioni uniformi su (0,1),x1 ,x2 e le due quantità y1 ,y2 : y1 = q y2 = q −2ln x1 cos(2πx2 ) , (3.35) −2ln x1 sin(2πx2 ) . (3.36) Oppure possiamo scrivere: x1 = exp[ −1 2 (y + y22 )] , 2 1 y2 1 arctan . 2π y1 Adesso il Jacobiano può essere facilmente calcolato come: x2 = exp h 1 i h 1 i ∂(x1 , x2 ) 2 2 =− e−y1 /2 × e−y2 /2 . ∂(y1 , y2 ) 2π 2π (3.37) (3.38) (3.39) Abbiamo il prodotto delle funzioni y1 e y2 e quindi y è distribuita secondo una distribuzione normale. Un ulteriore trucco consiste nel prendere v1 e v2 come ordinata ed ascissa di un punto random dentro il cerchio unitario intorno all’ origine. La somma dei loro quadrati R2 ≡ v12 + v22 è un generatore uniforme che può essere usato per x1 mentre l’ angolo che (v1 , v2 ) definisce rispetto all’ asse v1 può servire come angolo random 2πx è chè seno e coseno possono essere scritti √ 2 . Il vantaggio √ 2 2 come v1 / R e v2 / R e quindi vengono eliminate le chiamate trigonometriche. L’ implementazione pratica di questo algoritmo avviene attraverso la FUNCTION GASDEV. CU 1 FUNCTION gasdev(idum) INTEGER idum REAL gasdev USES ran1 INTEGER iset REAL fac,gset,rsq,v1,v2,ran1 SAVE iset,gset DATA iset/0/ if (iset.eq.0) then v1=2.*ran1(idum)-1. v2=2.*ran1(idum)-1. 100 CAPITOLO 3. PROBABILITÀ E STATISTICA 3.8. MOMENTI rsq=v1**2+v2**2 if(rsq.ge.1..or.rsq.eq.0.)goto 1 fac=sqrt(-2.*log(rsq)/rsq) gset=v1*fac gasdev=v2*fac iset=1 else gasdev=gset iset=0 endif return END 3.8 Momenti Se gli elementi di un campione hanno la tendenza a raggrupparsi attorno ad un valore particolare può essere utile rappresentare l’ insieme da pochi numeri che sono i momenti; il più importante è il valor medio, x= N 1 X xj N j=1 , (3.40) che stima il valore centrale. Un altro importante valore è la varianza empirica N 1 X s2 = (xj − x)2 , (3.41) N − 1 j=1 collegata ovviamente alla deviazione standard empirica √ s = s2 . (3.42) In alcuni casi, tipo distribuzione di Lorentz, la deviazione standard non esiste perchè tende ad infinito; bisogna allora ricorrere ad uno stimatore più robusto che è la deviazione assoluta N 1 X |xj − x| . ADEV (x1 .......xN ) = N j=1 (3.43) Questa definizione è stata poco adoperata dagli statistici per il fatto che essendo un valore assoluto i teoremi sono difficilmente provabili. 101 3.8. MOMENTI CAPITOLO 3. PROBABILITÀ E STATISTICA Abbiamo poi i momenti di ordine superiore che sono in realtà poco usati; sono in genere numeri adimensionali mentre ricordiamo che il valor medio e deviazione standard empirica sono dimensionali. Abbiamo quindi che la asimmetria è cosı̀ definita skew(x1 ....xN ) = N h 1 X x j − x i3 N j=1 s , (3.44) dove s è la deviazione standard empirica. Un valore positivo della asimmetria significa che abbiamo una coda che si estende verso i valori positivi e negativo viceversa. Un altro parametro importante è la curtosi N h n1 X xj − x i 4 o −3 . (3.45) Kurt(x1 ....xN ) = N j=1 s Ricordiamo che questo parametro nel caso di una distribuzione Gaussiana vale 0. Una maniera per calcolare la varianza che minimizza gli errori di arrotondamento è l’ algoritmo a due passi: prima il calcolo di x e poi quello di s2 s2 (x1 ....xN ) = N N i2 o 1 hX 1 nX . (xj − x)2 − (xj − x) N − 1 j=1 N j=1 (3.46) La seconda somma è zero nel caso in cui x è esatto altrimenti corregge gli errori di arrotondamento del primo termine. I vari momenti del campione che abbiamo testè definito sono implementati nella SUBROUTINE MOMENT 11 SUBROUTINE moment(data,n,ave,adev,sdev,var,skew,curt) INTEGER n REAL adev,ave,curt,sdev,skew,var,data(n) INTEGER j REAL p,s,ep if(n.le.1)pause ’n must be at least 2 in moment’ s=0. do 11 j=1,n s=s+data(j) continue ave=s/n adev=0. 102 CAPITOLO 3. PROBABILITÀ E STATISTICA 3.9. TEST DI STUDENT var=0. skew=0. curt=0. ep=0. do 12 j=1,n s=data(j)-ave ep=ep+s adev=adev+abs(s) p=s*s var=var+p p=p*s skew=skew+p p=p*s curt=curt+p continue adev=adev/n var=(var-ep**2/n)/(n-1) sdev=sqrt(var) if(var.ne.0.)then skew=skew/(n*sdev**3) curt=curt/(n*var**2)-3. else pause ’no skew or kurtosis when zero variance in moment’ endif return END 12 3.9 Test di Student Sovente ci troviamo di fronte due set di dati e vogliamo capire se appartengono o no alla stessa popolazione. Quando si pensa che due distribuzioni abbiano la stessa varianza empirica ma possibilmente medie diverse la variabile t di Student è calcolata in questa maniera sP sD = iA (xi − xA )2 + iB (xi − xB )2 1 1 + , NA + NB − 2 NA NB P (3.47) dove la sommatoria è estesa sui punti appartenenti ad un campione od a un altro e NA e NB sono il numero dei punti nel primo e secondo 103 3.9. TEST DI STUDENT CAPITOLO 3. PROBABILITÀ E STATISTICA campione rispettivamente. Come secondo passaggio valutiamo t come: t= xA − xB sD . (3.48) Terzo valutiamo la significatività di questo valore della t di Student con NA + NB - 2 gradi di libertà attraverso le due formule prima introdotte e la SUBROUTINE BETAI (funzione beta incompleta ). La significatività è un numero compreso fra 0 ed 1 e rappresenta la probabilità che |t| sia cosı̀ grande per caso, nell’ ipotesi che i campioni abbiano la stessa media. Quindi un valore piccolo della significatività ( 0.05 oppure 0.01 ) significa che la differenza osservata è molto significativa. Abbiamo quindi la SUBROUTINE TTEST dove data1 (1:n1 ) e data2 (1:n2 ) sono i due vettori contenenti i dati dei due campioni. CU SUBROUTINE ttest(data1,n1,data2,n2,t,prob) INTEGER n1,n2 REAL prob,t,data1(n1),data2(n2) USES avevar,betai REAL ave1,ave2,df,var,var1,var2,betai call avevar(data1,n1,ave1,var1) call avevar(data2,n2,ave2,var2) df=n1+n2-2 var=((n1-1)*var1+(n2-1)*var2)/df t=(ave1-ave2)/sqrt(var*(1./n1+1./n2)) prob=betai(0.5*df,0.5,df/(df+t**2)) return END che fa uso della SUBROUTINE AVEVAR 11 SUBROUTINE avevar(data,n,ave,var) INTEGER n REAL ave,var,data(n) INTEGER j REAL s,ep ave=0.0 do 11 j=1,n ave=ave+data(j) continue ave=ave/n 104 CAPITOLO 3. PROBABILITÀ E STATISTICA 12 3.10 3.10. FIT CON RETTA var=0.0 ep=0.0 do 12 j=1,n s=data(j)-ave ep=ep+s var=var+s*s continue var=(var-ep**2/n)/(n-1) return END Fit con retta Supponiamo di avere una serie N di punti (xi ,yi ) e di volerli fittare con una retta y = a + bx . (3.49) La misura di quanto il modello aderisce alla realtà è rappresentata dalla funzione chi-quadro: χ2 (a, b) = N X yi j=1 − a − bxi 2 si . (3.50) Annullando le derivate prime rispetto ad a e b troviamo la condizione di minimo del chi-quadro. Può essere utile introdurre le sequenti sommatorie: S≡ N X 1 2 i=1 si Sxx ≡ Sx ≡ i=1 N X x2i i=1 N X xi s2i Sy ≡ s2i Sxy ≡ N X yi i=1 N X xi y i i=1 s2i (3.51) s2i . (3.52) Ricordando che il determinante dei coefficienti vale: ∆ ≡ SSxx − (Sx )2 , (3.53) troviamo facilmente dalla teoria dei minimi quadrati che a= Sy Sxx − Sx Sxy ∆ b= S Sxy − Sx Sy ∆ 105 . (3.54) 3.10. FIT CON RETTA CAPITOLO 3. PROBABILITÀ E STATISTICA Ci restano ancora gli errori su a e b e dalla teoria della propagazione degli errori otteniamo: s2a = Sxx /∆ s2b = S/∆ . (3.55) Una stima della bontà del fit è data dalla probabilità Q che il valore del chi-quadro trovato sia casuale è Q = gammq ( N − 2 χ2 , ) . 2 2 (3.56) Ricordiamo che GAMMQ è la nostra FUNCTION per la funzione gamma incompleta Q(a,x). Se q è più grande di 0.1 il fit è accettabile. Se è più grande di 0.001 il fit può essere accettabile se gli errori non sono distribuiti in maniera normale e sono stati sottostimati. Se q è minore di 0.001 allora il modello o la procedura di stima degli errori sono sbagliati. L’ implementazione pratica di queste formule avviene attraverso la SUBROUTINE FIT dove in input abbiamo: ndata = numero di punti del campione x (1:ndata)= vettore delle x y (1:ndata)= vettore delle y sig (1:ndata)= vettore degli errori sulle y mwt = 0 allora applichiamo le formule senza errori In output abbiamo invece a,b = parametri della retta siga,sigb= errori sui parametri a e b chi2= chi-quadro finale q= parametro di bontà del fit. Se mwt = 0 allora q=1 CU SUBROUTINE fit(x,y,ndata,sig,mwt,a,b,siga,sigb,chi2,q) INTEGER mwt,ndata REAL a,b,chi2,q,siga,sigb,sig(ndata),x(ndata),y(ndata) USES gammq INTEGER i REAL sigdat,ss,st2,sx,sxoss,sy,t,wt,gammq sx=0. sy=0. st2=0. b=0. if(mwt.ne.0) then 106 CAPITOLO 3. PROBABILITÀ E STATISTICA 11 12 13 14 15 ss=0. do 11 i=1,ndata wt=1./(sig(i)**2) ss=ss+wt sx=sx+x(i)*wt sy=sy+y(i)*wt continue else do 12 i=1,ndata sx=sx+x(i) sy=sy+y(i) continue ss=float(ndata) endif sxoss=sx/ss if(mwt.ne.0) then do 13 i=1,ndata t=(x(i)-sxoss)/sig(i) st2=st2+t*t b=b+t*y(i)/sig(i) continue else do 14 i=1,ndata t=x(i)-sxoss st2=st2+t*t b=b+t*y(i) continue endif b=b/st2 a=(sy-sx*b)/ss siga=sqrt((1.+sx*sx/(ss*st2))/ss) sigb=sqrt(1./st2) chi2=0. if(mwt.eq.0) then do 15 i=1,ndata chi2=chi2+(y(i)-a-b*x(i))**2 continue q=1. sigdat=sqrt(chi2/(ndata-2)) 107 3.10. FIT CON RETTA 3.10. FIT CON RETTA 16 CAPITOLO 3. PROBABILITÀ E STATISTICA siga=siga*sigdat sigb=sigb*sigdat else do 16 i=1,ndata chi2=chi2+((y(i)-a-b*x(i))/sig(i))**2 continue q=gammq(0.5*(ndata-2),0.5*chi2) endif return END 108 Capitolo 4 I frattali In questi ultimi anni grazie all’ avvento dei calcolatori un capitolo che sembrava dimenticato della matematica ha avuto una evoluzione impressionante ed un numero molto alto di libri sui frattali ed affini è stato scritto. Diciamo grosso modo che possiamo dividere in parti il problema: 1. Enunciazione del processo; spesso un algoritmo iterativo. 2. Sviluppo di uno pseudo-codice che indica le operazioni da svolgere indipendentemente dal linguaggio adoperato. 3. Traduzione pratica dello pseudo-codice in linguaggio di programmazione 4. Uso di uno o più pacchetti grafici che permettono l’ uscita finale su terminale grafico, laser, etc... Passiamo ora in rassegna alcuni di questi algoritmi seguendo una specie di ordine cronologico. 4.1 Henon mapping All’ inizio degli anni 60 Michel Henon all’ Osservatorio di Nizza studiando le orbite delle stelle in una galassia si rese conto che lievi modifiche nei parametri iniziali portavano ad orbite irregolari. Prese quindi piede il concetto di comportamento caotico nelle orbite stellari o planetarie. 109 4.1. HENON MAPPING CAPITOLO 4. I FRATTALI Le curve di Henon non sono le classiche ellissi Newtoniane che gli astronomi usano da secoli. Nell’ universo vero l’ influenza di altri pianeti o di altre stelle portano a comportamenti poco prevedibili. Il modello di Henon che si sviluppa secondo il seguente mapping: xn+1 = yn − ax2n (4.1) yn+1 = bxn , (4.2) con a = 1.4 e b = 0.3 , (4.3) dice che le orbite planetarie possono essere non periodiche ed estremamente sensitive anche alla più piccola influenza gravitazionale. Per maggiori dettagli sull’ attrattore di Henon consultare il libro [Ol 92] . A differenza dei modelli lineari che sembrano capaci di predirre il cammino esatto dei corpi celesti per l’ eternità, gli attrattori strani offrono la possibilità di orbite stabili per molto tempo con un susseguente improvviso cambio di traiettoria vedi figura 4.1 . Riportiamo la SUBROUTINE HENON10 che implementa l’ attrattore di Henon. SUBROUTINE HENON10 (xx,yy,max,kounter,n) implicit REAL * 4 (A-H,O-Z) dimension xx (1:max ) dimension yy (1:max ) common /quadro / xmin,ymin,delta xmax=xmin + delta ymax=ymin + delta QA=1.4E+00 Qb=0.3E+00 J=0 k=0 18 continue QZ=1.0-QA*(QX**2.0)+QY QY=QB*QX QX=QZ k=k+1 IF ((QX.GT.xmin.AND.QX.LT.xmax).and. & (QY.GT.ymin.AND.QY.LT.ymax))then J=J+1 xx ( J ) = qx yy ( J ) = qy 110 CAPITOLO 4. I FRATTALI 4.1. HENON MAPPING Figura 4.1: Tipico plot di Henon 111 4.2. FEIGENBAUM MAPPING CAPITOLO 4. I FRATTALI c fase di plot end if 20 IF (K.LT.N) GO TO 18 kounter = j return END 4.2 Feigenbaum mapping Questo mapping è collegato alla crescita della popolazione che assumiamo essere x0 all’ inizio. La relazione ricorsiva già adottata da Verhulst è: xn+1 = 4λxn (1 − xn ) , (4.4) dove λ è un parametro di controllo che varia tra 0 ed 1. Questo mapping al variare di λ incomincia con una soluzione, che poi diventano due, che poi diventano quattro, etc... Questo comportamento prende il nome di teoria delle biforcazioni, vedi figura 4.2. Il famoso matematico Feigenbaum riesce poi anche a calcolare un numero che rappresenta la transizione al caos. Per maggiori dettagli sul mapping e sul numero di Feigenbaum consultare il libro [Ol 92] oppure il libro [Ba 88]. L’ implementazione pratica di questo algoritmo avviene attraverso il programma FEIGEN. program feigen c questo programma produce dei files di dati per calcolare lo splitting c di Feigenbaum........................................................ implicit REAL (A-H,R-Z) implicit real*8 (Q) character * 1 mode,risposta parameter ( nn = 200 ) parameter ( max= 1000 ) real* 8 fe ( 1 :max ) real* 4 fi ( 1 :max ) real* 4 fy ( 1:nn,1 : max ) integer *2 ify ( 1:nn ) real* 4 fx ( 1:nn ) mode =’M’ call init9 ( mode ) 112 CAPITOLO 4. I FRATTALI 4.2. FEIGENBAUM MAPPING Figura 4.2: Biforcazioni di Feigenbaum 113 4.2. FEIGENBAUM MAPPING CAPITOLO 4. I FRATTALI go to 402 400 continue type *,’Vuoi continuare Y/N ? ’ accept 1000,risposta if ((risposta.eq.’N’).or.(risposta.eq.’n’)) then go to 401 end if 1000 format (A1 ) 402 continue c qx0old ==> condizione iniziale ,ql0 ==> lambda iniziale c qld ==> delta lamda ,npunti===>numero attrattori c nn=divisioni in lamda type *,’inserire limite inferiore + limite superiore ’ accept *,ql0,qxmax qld = qxmax - ql0 qx0old=0.5 npunti=600 delta = 1.0 / max qxmax=ql0+qld qymin=0.0 qymax=1.0 do 111 ii=1,nn qx0=qx0old ql= ql0+ii*qld/nn k=0 j=0 n=3000 maxfe=N-npunti 18 continue QX=4*QL*QX0*(1.0-QX0) qx0=qx k=k+1 if (k.gt.maxfe) then j=j+1 fe(j)=qx end if 20 IF (K.LT.N) GO TO 18 k=0 do 67 j=1,npunti 114 CAPITOLO 4. I FRATTALI 4.3. MANDELBROT-SET if (fe(j).lt.1.0D-10) then fe(j)=1.0Q-10 end if 67 continue call m01apf(fe,1,npunti,k) fi(1)=fe(1) mm=1 do 4 k=2,npunti diff = abs (fe (k) - fi ( mm) ) if (diff .gt . delta) then mm=mm+1 fi(mm)=sngl ( fe(k) ) endif 4 continue do 3 j=1,mm fy ( ii,j ) = fi ( j ) 3 continue ify( ii ) = mm fx ( ii ) = sngl ( ql ) 111 continue xmin = sngl ( ql0 ) xmax = sngl ( ql0 + qld ) ymin = -0.1 ymax = 1.1 call feigengraf ( fy, fx ,nn ,max,xmin,xmax,ymin,ymax,ify) go to 400 401 continue call donepl stop END 4.3 Mandelbrot-set Sia zn = xn + i yn un numero complesso definito dalla relazione ricorsiva zn+1 = zn2 + c , 115 (4.5) 4.4. IMPLEMENTAZIONE DEI SET CAPITOLO 4. I FRATTALI dove c =a + i b è un altro numero complesso. Se incominciamo il processo da z0 = 0 e e ripetiamo più volte la relazione ricorsiva notiamo che esistono due possibilità. La prima è che il valore assoluto di zn+1 esploda la crescere di n, la seconda è che rimanga finito a dispetto di quante volte iteriamo la relazione. Il risultato finale dipende ovviamente dal valore di c usato. È quindi possibile dividere il set di tutti i numeri complessi {c} in due gruppi in accordo al loro andamento dopo un numero alto di iterazioni. L’ insieme di Mandelbrot è il gruppo che contiene tutti i c tali che lim | zn | = f inito . x→∞ 4.4 (4.6) Implementazione dei set In genere il set di Mandelbrot e derivati vengono rappresentati tramite il colore perchè in tale maniera si originano delle immagini affascinanti e ogni volta simili ma diverse nei particolari. Per maggiori dettagli sui vari set tipo Mandelbrot e Julia rimandiamo il lettore interessato al libro di [PS88] . Per semplicità tratteremo solo la situazione sul monitor di un computer. Supponiamo che il numero totale di pixels disponibile sia ( Nx × Ny ); dove Nx , ad esempio 640, sono i punti sulla linea orizzontale e Ny , ad esempio 480,sono i punti sulla linea verticale di un tipico schermo di P.C. Possiamo invece anche lavorare su di un quadrato e allora il numero di pixels (quadratini) sarà ( N × N ) dove N è il numero considerato fissabile a piacimento; in questa maniera si eliminano eventuali errori di deformazione dell’ area. Identifichiamo adesso lo schermo con il piano complesso e ogni pixel o quadratino è un punto del piano. Come al solito useremo la linea orizzontale per la parte reale e la direzione verticale per la parte immaginaria. Per inserire un numero complesso c =a + ib sullo schermo dobbiamo selezionare un origine in basso a sinistra, un ∆ considerato ed il numero di pixels. Per fini pratici dobbiamo scegliere un valore nmax come il numero massimo di iterazioni che vogliamo eseguire; questo sarà l’ infinito del nostro processo iterativo. Per generare il plot ogni numero complesso c è soggetto ad un processo ricorsivo partendo da z0 = 0. Alla fine di ogni iterazione il valore assoluto di zn è calcolato. Se | zn | > 2, il numero complesso c non fa parte del set di Mandelbrot, il processo iterativo termina e assegniamo un colore al pixel considerato secondo lo schema seguente: sia Nesc il numero di iterazioni considerato ed Nc il numero 116 CAPITOLO 4. I FRATTALI 4.4. IMPLEMENTAZIONE DEI SET di colori a disposizione, dove probabilmente Nc < Nmax ; assoceremo al pixel il colore Ic secondo la seguente relazione Ic = Nesc mod Nc , (4.7) dove Ic è un numero nel range [0, Nc ] ed ogni intero 0,1,2,.... corrisponde ad un particolare colore tipo nero, rosso,viola .... Se il valore di zn è ancora minore di due il processo si ripete e se dopo Nmax iterazioni | zn | è ancora minore di due abbiamo un elemento appartenente al set di Mandelbrot. Questo ultimo pixel può essere colorato in nero: una tipica implementazione di questo set è riportata in figura 4.3 . Riportiamo la subroutine UNO che implementa praticamente tramite tre do innestati il numero Nesc ( nel nostro caso NDIM ) per ogni pixel del piano. subroutine uno ( matrix,traspo,itraspo) implicit real* 4 (a-h,o-z) integer * 2 ndim,i,j,iterations integer * 4 im complex * 8 z,imm,complex parameter ( pixels = 600 ) parameter ( nvector = pixels * pixels) dimension matrix (1:nvector) dimension traspo (1:10) dimension itraspo (1:10) parameter(imm=(0,1)) c coordinate di partenza e valore del lato xmin = traspo (1) ymin = traspo (2) delta = traspo (3) npix = itraspo(1) iterations = itraspo (2) npix1 = npix-1 xmax = xmin + delta ymax = ymin + delta c griglia di lavoro + numero di pixels im = 0 do i= 0,npix1 cy=ymin + i*delta/npix do j=0,npix1 117 4.4. IMPLEMENTAZIONE DEI SET CAPITOLO 4. I FRATTALI Figura 4.3: Tipico set di Mandelbrot 118 CAPITOLO 4. I FRATTALI 4.4. IMPLEMENTAZIONE DEI SET cx=xmin+j*delta/npix complex = cx + imm*cy c dimensione numero complesso z=0 ndim = 0 do while (cabs(z) .le. 2.0 .AND. ndim .LT. iterations) z=z*z+complex ndim=ndim+1 end do im = im +1 matrix (im) = ndim end do end do return end Il colore viene invece calcolato dalla subroutine DUETUTTO. subroutine duetutto( matrix,matrix8,traspo,itraspo) implicit real * 4 (a-h,o-z) parameter ( npixels=800 ) parameter ( nvector = npixels*npixels) dimension matrix (1:nvector ) dimension matrix8 (1:nvector ) dimension traspo (1:10) dimension itraspo (1:10) a = traspo (1) npix = itraspo(1) ncol = itraspo(3) npix2 = npix *npix do j = 1 , npix2 ndim = matrix ( j) ndim = ndim -1 if (ndim.lt.64) then matrix8 (j) = ndim elseif (ndim.ge.64 ) then icolor = mod ( ndim,64 ) matrix8 (j) = icolor end if end do 119 4.5. SET DI JULIA E DERIVATI CAPITOLO 4. I FRATTALI return end 4.5 Set di Julia e derivati Gli insiemi di Julia si ottengono dalla stessa relazione ricorsiva del set di Mandelbrot e si tratta di selezionare dei punti alla frontiera del medesimo; questi punti dell’ altro set danno origine a successioni periodiche dalle forme strane e bizzarre. I pixels sullo schermo del computer rappresentano ora i punti nel piano complesso per tutti i possibili valori di z0 ed ogni insieme è caratterizzato da un valore di c. Riportiamo nella figura 4.4 il set di Julia corrispondente a c = -0.74543 + i 0.11301. Un’ altra relazione ricorsiva cugina di quella di Mandelbrot, che possiamo chiamare M2 , è zn+1 = zn3 + c , (4.8) che possiamo chiamare M3 . Essa origina strutture leggermente diverse dal suo parente di grado minore e riportiamo nella figura 4.5 un tipico plot. Possiamo poi passare in maniera continua da M2 a M3 attraverso la seguente relazione ricorsiva zn = tz 3 + (1 − t)z 2 + c . (4.9) Dove il parametro t varia con continuità fra 0 ed 1. Sembra che alcuni valori di t siano critici e potete partire con t =0.12595. Riportiamo in figura 4.6 un tipico plot di di questo set regolabile. 4.6 Le trasformazioni affini Il metodo IFS ( Iterated Function System ) permette di produrre immagini di curve frattali, foglie, nuvole, etc... Ricordiamo che una trasformazione affine wi è data da wi = [ xy ] = [ a bc d ] [ xy ]+[ ef ] = [ ax+ by+ ecx+ dy+ f ] . (4.10) 120 CAPITOLO 4. I FRATTALI 4.6. LE TRASFORMAZIONI AFFINI Figura 4.4: Tipico plot di Julia 121 4.6. LE TRASFORMAZIONI AFFINI CAPITOLO 4. I FRATTALI Figura 4.5: Tipico plot M**3 122 CAPITOLO 4. I FRATTALI 4.6. LE TRASFORMAZIONI AFFINI Figura 4.6: Tipico plot regolabile 123 4.6. LE TRASFORMAZIONI AFFINI CAPITOLO 4. I FRATTALI Tabella 4.1: Tabella dei coefficienti w a b c d e f 1 0 0 0 0.16 0 0 2 0.85 0.04 −0.04 −0.85 0 1.6 3 0.20 −0.26 0.23 0.22 0 1.6 4 −0.15 0.28 0.26 0.24 0 0.44 p 0.01 0.85 0.07 0.07 Inoltre ogni trasformazione è caratterizzata da una certa probabilità di avvenire pi associata a wi . Ovviamente essendo probabilità dovremo avere: p1 + p2 + .....pn = 1 e pi > 0 per i = 1, 2, ...n . (4.11) Riportiamo in tabella i valori dei coefficienti che permettono di ottenere una figura caratteristica. Per capire le componenti di queste strutture complicate possiamo studiare il significato geometrico dei coefficienti a,b,c,d,e ed f. Per partire osserviamo che e ed f sono semplici traslazioni nelle direzioni x ed y. Adesso scriviamo a = r × cos ( θ ), b = -s × sen ( ψ ), c = r× sen ( θ) e d = s × cos (ψ ). È facile realizzare che θ è l’ angolo del quale ruotiamo l’ asse x e ψ è l’ angolo del quale ruotiamo y, r è fattore per il quale sono moltiplicate le distanze lungo x ed s è il fattore per il quale moltiplicare le distanze lungo y. Prendendo θ = ψ abbiamo una riflessione attravesrso l’ asse x e prendendo s negativo si origina una riflessione attraverso l’ asse y. Possiamo quindi riesprimere i parametri a, b, c,d attraverso r, s, θ e ψ; continuando possiamo mettere h e k al posto di e ed f. Per maggiori dettagli sulle trasformazioni affini consultare il libro di [Ba 88] . Riportiamo nella figura 4.7 seguente una tipica implementazione pratica. L’ implementazione pratica avviene attraverso il programma FELCI. program felci implicit real *8 (a-h,o-z) logical * 1 prob1,prob2,prob3,prob4 real * 4 xx , yy parameter ( nvec = 150 000 ) 124 CAPITOLO 4. I FRATTALI 4.6. LE TRASFORMAZIONI AFFINI Figura 4.7: La felce 125 4.6. LE TRASFORMAZIONI AFFINI CAPITOLO 4. I FRATTALI parameter ( minimum = 100 ) dimension xx (1 : nvec ) dimension yy (1: nvec ) integer g05dyf call g05cbf ( 0 ) type *,’numero di punti ?’ accept *,npoints x = 0.0 y = 0.0 do j = 1, npoints intero = g05dyf ( 1, 100 ) prob1 = intero.eq.1 prob2 = (intero.gt.1 ).and.(intero.le.86 ) prob3 = (intero.gt.86).and.(intero.le.93 ) prob4 = (intero.gt.93).and.(intero.le.100) if ( prob1 ) then itipo = 1 call affine ( itipo,x,y,xnew,ynew ) elseif ( prob2 ) then itipo = 2 call affine ( itipo,x,y,xnew,ynew ) elseif ( prob3 ) then itipo = 3 call affine ( itipo,x,y,xnew,ynew ) elseif ( prob4 ) then itipo = 4 call affine ( itipo,x,y,xnew,ynew ) end if if ( j.gt. minimum ) then jvec = jvec + 1 xx ( jvec ) = sngl ( xnew ) yy ( jvec ) = sngl ( ynew ) end if x = xnew y = ynew end do call affinegraf ( xx, yy , jvec ,npoints,minimum,nvec) stop end 126 CAPITOLO 4. I FRATTALI 4.6. LE TRASFORMAZIONI AFFINI subroutine affine ( itipo,x,y,xnew,ynew ) implicit real *8 ( a-h,o-z) if (itipo.eq.1) then a = 0. b = 0. c = 0. d = 0.16 e = 0. f = 0. elseif (itipo.eq.2) then a = 0.85 b = 0.04 c = -0.04 d = 0.85 e = 0.0 f = 1.6 elseif (itipo.eq.3) then a = 0.2 b = -0.26 c = 0.23 d = 0.22 e = 0.0 f = 1.6 elseif (itipo.eq.4) then a = -0.15 b = 0.28 c = 0.26 d = 0.24 e = 0.00 f = 0.44 end if xnew = a * x + b * y + e ynew = c * x + d * y + f return end 127 4.7. IL SISTEMA L 4.7 CAPITOLO 4. I FRATTALI Il sistema L Questo sistema è stato inventato dal botanico tedesco Lindenmayer ( vedi il libro di [PL 90]) per spiegare teoricamente le strutture ricorrenti delle piante. Ai fini pratici possiamo sintetizzare l’ algoritmo mediante il moto di una tartaruga. Lo stato della tartaruga è definito da una tripletta ( x,y, α ), dove le coordinate cartesiane ( x, y ) rappresentano la posizione della tartaruga e l’ angolo α indica la direzione di moto della tartaruga. Dato l’ incremento d di ogni step ( possiamo porlo uguale ad uno ) e l’ incremento di angolo δ la tartaruga risponde ai seguenti comandi • F Si muove avanti di uno step d. Lo stato della tartaruga diventa ( x’, y’, α ) dove x’ = x + d cosα e y’ = y + d sin α. Una linea viene tracciata fra i punti (x,y) e (x’,y’). • f Si muove avanti di una lunghezza d senza tracciare una linea. • + Si gira a sinistra di un angolo δ. Il prossimo stato della tartaruga è (x,y, α + δ ) e quindi gli angoli crescono in senso antiorario. • - Ruota a sinistra di un angolo δ. Il prossimo stato della tartaruga è (x,y,α - δ ). • [ Congela lo stato della tartaruga. Le informazioni correnti, posizione e angolo sono memorizzate per poi essere riesumate più avanti. • ] Scongela lo stato della tartaruga. Le informazioni vengono riesumate e diventano quelle attuali della tartaruga. Non viene tirata nessuna linea e quasi sempre la tartaruga cambia posizione. Data una stringa iniziale w, lo stato iniziale della tartaruga con ( x0 , , y0 ,α0 ) e fissati i parametri d e δ, tramite una o più regole di produzione otteniamo la posizione successiva e cosı̀ via. Il problema è quindi di ideare una stringa iniziale e regole di trasformazione tali da ottenere le curve volute. Riportiamo come esempio una pianta curvata dal vento, vedi figura 4.8 . n=4 δ = 22.5 w=F 128 CAPITOLO 4. I FRATTALI 4.7. IL SISTEMA L Figura 4.8: Pianta e vento di tramontana 129 4.7. IL SISTEMA L CAPITOLO 4. I FRATTALI F → FF-[-F+F+F]+[+F-F-F] A questo punto ricordiamo che sono attualmente disponibili una quarantina di curve fra frattali e piante. Questa particolare stringa viene implementata attraverso la SUBROUTINE MAKEPIANTA3. subroutine makepianta3 (stringa,max,it,ifine) implicit real * 4 (a-h,o-z) parameter (new = 200 000 ) character * 1 stringa ,stringanew dimension stringa (1:max) dimension stringanew (1:new) ifine = 1 stringa (1) = ’F’ do jit =1,it nuovo = 0 do j = 1 ,ifine if (stringa (j).eq.’F’) then nuovo = nuovo +1 stringanew (nuovo) =’F’ nuovo= nuovo +1 stringanew (nuovo) =’F’ nuovo= nuovo +1 stringanew (nuovo) =’+’ nuovo= nuovo +1 stringanew (nuovo) =’[’ nuovo= nuovo +1 stringanew (nuovo) =’+’ nuovo= nuovo +1 stringanew (nuovo) =’F’ nuovo = nuovo +1 stringanew (nuovo )=’-’ nuovo= nuovo +1 stringanew (nuovo )=’F’ nuovo = nuovo +1 stringanew (nuovo )=’-’ nuovo= nuovo +1 stringanew (nuovo )=’F’ nuovo= nuovo +1 stringanew (nuovo )=’]’ 130 CAPITOLO 4. I FRATTALI 4.7. IL SISTEMA L nuovo= nuovo +1 stringanew (nuovo )=’-’ nuovo = nuovo +1 stringanew (nuovo) =’[’ nuovo= nuovo +1 stringanew (nuovo) =’-’ nuovo= nuovo +1 stringanew (nuovo) =’F’ nuovo= nuovo +1 stringanew (nuovo) =’+’ nuovo= nuovo +1 stringanew (nuovo) =’F’ nuovo= nuovo +1 stringanew (nuovo) =’+’ nuovo= nuovo +1 stringanew (nuovo )=’F’ nuovo= nuovo +1 stringanew (nuovo )=’]’ else nuovo = nuovo +1 stringanew (nuovo) = stringa(j) end if end do do j= 1,nuovo stringa(j) = stringanew (j) end do ifine = nuovo end do return end Invece la stringa finale risultante viene decodificata attraverso la SUBROUTINE GX. subroutine gx(stringa,max,ifine,agl,xmax,xmin,ymax,ymin,ae) implicit real * 4 (a-h,o-z) character * 1 stringa,car dimension stringa (1:max) dimension stackx ( 1:1000) dimension stacky ( 1:1000) 131 4.7. IL SISTEMA L CAPITOLO 4. I FRATTALI dimension stackae ( 1:1000) xmax = - 10.**20 xmin = 10.**20 ymax = - 10.**20 ymin = 10.**20 x = 0. y = 0. numero = 0 do j =1,ifine if (x.gt.xmax ) then xmax = x end if if (x.lt.xmin ) then xmin = x end if if (y.gt.ymax ) then ymax = y end if if (y.lt.ymin ) then ymin = y end if car = stringa (j) cccccccccccc inizio sostituzioni if (car.eq.’F’) then xnew = x + cosd ( ae ) ynew = y + sind ( ae ) x = xnew y = ynew end if if (car.eq.’f’) then xnew = x + cosd ( ae ) ynew = y + sind ( ae ) x = xnew y = ynew end if if (x.gt.xmax ) then xmax = x end if if (x.lt.xmin ) then 132 CAPITOLO 4. I FRATTALI 4.7. IL SISTEMA L xmin = x end if if (y.gt.ymax ) then ymax = y end if if (y.lt.ymin ) then ymin = y end if if (car.eq.’+’) then ae = ae - agl end if if (car.eq.’-’) then ae = ae + agl end if if (car.eq.’[’) then numero = numero + 1 stackx ( numero ) = x stacky ( numero ) = y stackae (numero ) = ae end if if (car.eq.’]’) then x = stackx ( numero ) y = stacky ( numero ) ae = stackae ( numero ) numero = numero - 1 end if ccccccccccccccc fine sostituzioni ccccccccccccccccccccccccccc cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc end do return end 133 4.7. IL SISTEMA L CAPITOLO 4. I FRATTALI 134 Capitolo 5 Sistemi Monte Carlo In questi ultimi anni abbiamo assistito ad un crescente numero di simulazioni di sistemi fisici mediante modelli al calcolatore. Il campo è enorme ed in continua evoluzione e ci limiteremo ad una scelta random di alcune topiche; ah non dimentichiamoci che il nome deriva dal famoso casinò... 5.1 DLA Il nome prende le iniziali da Diffusion Limited Aggregation ed è un tipico esempio di crescita/aggregazione che simula il comportamento di colonie di batteri, esperimenti fra fluidi con viscosità diverse e scariche elettriche nei gas. La superficie considerata viene identificata con un lattice consistente in N × N pixels. All’ inizio il nostro aggregato consiste in una sola particella al centro della griglia. La diffusione delle altre particelle viene simulata da una particella che entra da uno dei quattro lati a seconda del numero random R1 [1, 4]. La particella si muove poi di moto random sul lattice: questo significa che ad ogni step ha quattro possibili movimenti scelti con un processo random R2 [1, 4]. Le quattro direzioni di movimento sono: 1. destra, 2. alto, 3. sinistra, 4. basso. 135 5.1. DLA CAPITOLO 5. SISTEMI MONTE CARLO Ogni volta che viene raggiunta una locazione nuova viene controllato se uno dei quattro vicini ( di nuovo destra, alto, sinistra e basso ) è occupato. Se risulta occupato l’ aggregato aumenta di una unità e il cammino random ricomincia con un altra particella su di un altro lato del quadrato. Se invece il punto occupato non ha vicini appartenenti all’ aggregato il cammino random continua; il processo si ferma quando viene raggiunto un punto sulla frontiera e ricomincia ovviamente con un altra particella su di un altro lato. Si possono poi introdurre ulteriori regole che permettono di diminuire il tempo di calcolo; in particolare possiamo ingrandire progressivamente il lato del quadrato interno dal quale partiamo e idem dicasi per un cuscinetto detto killing zone più grande del quadrato delle partenze superato il quale il processo comincia di nuovo senza aspettare di raggiungere le frontiere naturali del lattice. Per maggiori dettagli sulla teoria della DLA consultare il libro [Vi 92]. Riportiamo nella figura 5.1 un tipico esempio di crescita su di un lattice con 500 pixels. Questo algoritmo viene implementato attraverso la SUBROUTINE WO: subroutine wo(griglia ,ndim ,l_dist,k_dist,m_dist,n_max,n_vero) implicit real * 4 ( a-h,o-z) logical * 1 griglia , occupato external g05dyfzan integer g05dyfzan dimension griglia(ndim,ndim) dimension ivicinox ( 1 : 4 ) dimension ivicinoy ( 1 : 4 ) dimension iarrivo ( 1 : 4 ) c zero the lattice and mark the center as occupied do i=1,ndim do j=1,ndim griglia(j,i)=.false. end do end do npts=1 mid=ndim/2 griglia(mid,mid)=.true. c define initial launching and kill boundaries lx_min=mid-l_dist 136 CAPITOLO 5. SISTEMI MONTE CARLO Figura 5.1: Tipico esempio di DLA 137 5.1. DLA 5.1. DLA CAPITOLO 5. SISTEMI MONTE CARLO lx_max=mid+l_dist ly_min=mid-l_dist ly_max=mid+l_dist kx_min=lx_min-k_dist kx_max=lx_max+k_dist ky_min=ly_min-k_dist ky_max=ly_max+k_dist c set an artificial occupation boundary at the start mx_min=mid-m_dist mx_max=mid+m_dist my_min=mid-m_dist my_max=mid+m_dist cc cccc abbiamo fissato le zone di lancio cc e quelle di killing idum = 33333 kgen = 77777 kdir = 55555 nn = 1 ilato = 0 itotale= 0 ccc inizio zona di lancio 40 continue ilato = g05dyfzan ( 1 , 4 ,idum ) itotale = itotale + 1 c ilato = ilato + 1 c if (ilato.gt.4) then c ilato = 1 c end if c c lx_min,ly_max 2 lx_max,ly_max c ------------------------c | | c | | c | zona di | c 1 | | 3 c | lancio | c | | 138 CAPITOLO 5. SISTEMI MONTE CARLO c c c ------------------------lx_min,ly_min 4 lx_max,ly_min if ( ilato.eq. 1 ) then ix = lx_min iy = g05dyfzan ( ly_min,ly_max,kgen ) elseif ( ilato.eq. 2 ) then ix = g05dyfzan ( lx_min,lx_max,kgen ) iy = ly_max elseif ( ilato.eq. 3 ) then ix = lx_max iy = g05dyfzan ( ly_min,ly_max,kgen ) elseif ( ilato.eq. 4 ) then ix = g05dyfzan ( lx_min,lx_max,kgen ) iy = ly_min end if c adesso impostiamo la direzione di moto 100 continue idir = g05dyfzan ( 1 , 4 , kdir ) c c c 3 c | c | c | c 4 ------ * ------ 2 c | c | c | c 1 c if (idir .eq . 1 ) then ! si muove giu‘ in basso ix = ix iy = iy - 1 elseif ( idir.eq.2 ) then ! si muove a destra ix = ix +1 iy = iy 139 5.1. DLA 5.1. DLA CAPITOLO 5. SISTEMI MONTE CARLO elseif ix iy elseif ix iy c cc c c c c c adesso ( idir.eq.3 ) then ! si muove in alto = ix = iy + 1 ( idir.eq.4 ) then ! si muove a sinistra = ix -1 = iy end if ci siamo mossi !!!!! adesso facciamo un controllo sulla killing zone se abbiamo raggiunto la frontiera ricominciamo dalla zona di lancio if ((iy.eq.ky_min).or.(iy.eq.ky_max)) then ! limite alto ! e basso go to 40 elseif ((ix.eq.kx_min).or.(ix.eq.kx_max))then ! limite destro ! e sinistro go to 40 end if c cc c c c c c c c c c costruzione dei quattro vicini ! ------------- ivicinox (1) ivicinoy (1) primo vicino ivicinox (2) 140 = = ix iy - 1 = ix + 1 CAPITOLO 5. SISTEMI MONTE CARLO ivicinoy secondo vicino ivicinox ivicinoy c terzo vicino ivicinox ivicinoy c quarto vicino (2) = iy (3) (3) = = ix iy (4) (4) = = ix iy 5.1. DLA c c cc c c ccc c - 1 adesso vediamo se uno dei quattro vicini e‘ occupato occupato =.false. do jj = 1, 4 if ( griglia ( ivicinox ( jj), ivicinoy (jj)) ) then if ( .not.griglia (ix,iy)) then nn = nn + 1 if ( nn.eq.( n_max+1 ) ) then nn = nn -1 type *,’Abbiamo raggiunto n_max’ go to 950 end if griglia (ix,iy) = . true . occupato = . true . iarrivo (ilato )= iarrivo ( ilato ) +1 ridefinizione dei massimi e dei minimi if if c ccc c +1 (ix.gt.mx_max) then mx_max = ix end if (ix.lt.mx_min) then mx_min = ix end if ridefinizione dei massimi e dei minimi if in x (iy.gt.my_max) then 141 in y 5.1. DLA CAPITOLO 5. SISTEMI MONTE CARLO my_max if c ccc c iy end if (iy.lt.my_min) then my_min = iy end if end if end if ridefinizione if (( go elseif (( go elseif (( go elseif (( go = eventuale della zona di mx_min -lx_min) .eq. 1 to 200 lx_max - mx_max ) .eq. 1 to 200 ly_max - my_max ) .eq. 1 to 200 my_min -ly_min ) .eq. 1 to 200 end if go to 300 200 continue c ccccccc c lx_min = lx_min - l_dist lx_max = lx_max + l_dist ly_min = ly_min - l_dist ly_max = ly_max + l_dist idum = idum +1 kgen = kgen +1 ddir = kdir + 1 c cccc ma potremmo avere raggiunto c c ccccccc c kx_min=lx_min-k_dist 142 lancio ) then ) then ) then ) then la frontiera CAPITOLO 5. SISTEMI MONTE CARLO kx_max=lx_max+k_dist ky_min=ly_min-k_dist ky_max=ly_max+k_dist cc ccccccccc ma potremmo avere raggiunto cc if (kx_min.le. 1 ) then type *,’Abbiamo raggiunto la go to 950 elseif (ky_min.le. 1 ) then type *,’Abbiamo raggiunto la go to 950 elseif (ky_max.ge. ndim ) then type *,’Abbiamo raggiunto la go to 950 elseif (kx_max.ge. ndim ) then type *,’Abbiamo raggiunto la go to 950 end if 300 le frontiere frontiera’ frontiera’ frontiera’ frontiera’ continue end do (.not.occupato ) then go to 100 end if go to 40 continue call esci ( nn,n_vero) isum = 0 do j = 1, 4 type *,’numero di arrivi dal lato ’,j,’ =’,iarrivo (j) isum = isum + iarrivo (j) end do fraz = isum * 1.0 / itotale type *,’frazione arrivata sui totali partiti =’,fraz return end if 950 5.1. DLA 143 5.2. AGGREGAZIONE BALLISTICA CAPITOLO 5. SISTEMI MONTE CARLO 5.2 Aggregazione ballistica Questo processo di aggregazione cerca di spiegare fenomeni in cui entra in gioco la gravità, tipo deposizione di zinco su di un catodo, esperimenti di soluzione chimica, depositi di ossido di manganese su calcari, neve che cade su di un vetro. Come al solito lavoriamo su di un lattice composto da N × N pixels e le particelle partono da un punto random R1 [1,N] sul lato in alto. Inizialmente l’ aggregato consiste in una particella posta sul lato in basso in posizione centrale ( deposito a cono ) oppure in più di una particella ( deposito ad alberi ). Ad ogni spostamento delle particelle in caduta vengono controllati i quattro vicini. Se un vicino è occupato l’ aggregato aumenta di una unità e il processo riparte con un’ altra particella sul lato in alto. Se invece nessuno dei quattro vicini è occupato il processo riparte con il moto random. Se vengono raggiunti i lati-frontiera sinistro oppure destro oppure inferiore il processo si ferma e riparte dall’ alto. Anche quı̀ per velocizzare il tempo di esecuzione del programma le particelle partono sul lato superiore variabile. Riportiamo nelle figure 5.2 e 5.3 due tipici esempi di aggregazione ballistica. L’ implementazione pratica avviene attraverso la SUBROUTINE BA. subroutine ba (occ ,ndim ,l_dist,k_dist,m_dist,n_max,n_vero,nba) implicit real * 4 ( a-h,o-z) logical * 1 occ , occupato external g05dyfzan integer g05dyfzan dimension occ(ndim,ndim) dimension ivicinox ( 1 : 4 ) dimension ivicinoy ( 1 : 4 ) c zero the lattice and mark the center as occupied do i=1,ndim do j=1,ndim occ(j,i)=.false. end do end do idum = 33333 do i =1 , nba ipunto = g05dyfzan ( 1 , ndim ,idum ) 144 CAPITOLO 5. SISTEMI MONTE CARLO 5.2. AGGREGAZIONE BALLISTICA Figura 5.2: Deposito ballistico con un punto iniziale 145 5.2. AGGREGAZIONE BALLISTICA CAPITOLO 5. SISTEMI MONTE CARLO Figura 5.3: Deposito ballistico con più punti iniziali 146 CAPITOLO 5. SISTEMI MONTE CARLO 5.2. AGGREGAZIONE BALLISTICA if (nba.eq.1) ipunto then = ndim / 2 end if occ (ipunto,1) =.true. end do c define initial launching and kill boundaries lx_min = 1 lx_max = ndim ly_max= 1 + l_dist ly_min= 1 ky_min = 1 ky_max= ly_max+k_dist kx_max = ndim kx_min = 1 c set an artificial occupation boundary at the start my_max= 1 + m_dist cc cccc abbiamo fissato le zone di lancio cc e quelle di killing idum = 33333 kgen = 77777 kdir = 55555 nn = 1 ccc inizio zona di lancio 40 continue c ccccccccc c lx_min,ly_max ..... lx_max,ly_max c ------------------------c | | c | | c | zona di | c | | c | lancio | c | | c ix = g05dyfzan ( lx_min,lx_max,kgen ) 147 5.2. AGGREGAZIONE BALLISTICA CAPITOLO 5. SISTEMI MONTE CARLO iy = ly_max c adesso impostiamo la direzione di moto 100 continue idir = g05dyfzan ( 1 , 3 , kdir ) c c 3 ------ * ------ 2 c | c | c | c 1 c if (idir .eq . 1 ) then ! si muove giu‘ in basso ix = ix iy = iy - 1 elseif ( idir.eq.2 ) then ! si muove a destra ix = ix +1 iy = iy elseif ( idir.eq.3 ) then ! si muove a sinistra ix = ix -1 iy = iy end if c cc c c c c c adesso ci siamo mossi !!!!! adesso facciamo un controllo sulla killing zone se abbiamo raggiunto la frontiera ricominciamo dalla zona di lancio if (iy.eq.ky_min) then ! limite alto ! e basso go to 40 elseif ((ix.eq.kx_min).or.(ix.eq.kx_max))then ! limite destro ! e sinistro go to 40 148 CAPITOLO 5. SISTEMI MONTE CARLO 5.2. AGGREGAZIONE BALLISTICA end if c cc c c c c c c c c costruzione dei tre ! ------------- ivicinox ivicinoy c primo vicino ivicinox ivicinoy c secondo vicino ivicinox ivicinoy c terzo vicino c cc c vicini (1) (1) = = ix iy (2) (2) = = ix iy + 1 (3) (3) = = ix iy - 1 - 1 adesso vediamo se uno dei quattro vicini e‘ occupato occupato =.false. do jj = 1, 3 if ( occ ( ivicinox ( jj), ivicinoy (jj)) ) then if ( .not.occ (ix,iy)) then nn = nn + 1 if ( nn.eq.( n_max+1 ) ) then nn = nn -1 call esci ( nn,n_vero) type *,’Abbiamo raggiunto n_max’ return end if occ (ix,iy) = . true . occupato = . true . c 149 5.3. PERCOLAZIONE ccc c CAPITOLO 5. SISTEMI MONTE CARLO ridefinizione del massimo if in y (iy.gt.my_max) then my_max = ly_max = iy my_max + l_dist end if if (ly_max.ge. ndim ) then call esci ( nn,n_vero) type *,’Abbiamo raggiunto la frontiera’ return end if end if end if end do if (.not.occupato ) then go to 100 end if go to 40 end 5.3 Percolazione Anche quı̀ grazie all’ avvento dei computers è stato aperto un nuovo capitolo al confine fra fisica e matematica. Prendiamo in esame un lattice quadrato con N × N occupazioni disponibili e introduciamo una probabilità di occupazione dei punti del lattice p varianti fra 0 ed 1. Questo significa che ad ogni p avremo un numero M di punti occupati sul lattice pari a: M = N IN T (p × N × N ) . (5.1) Possiamo generare queste M occupazioni con due processi random ( Ix = R1 [1, N ] Iy = R2 [1, N ] , (5.2) controllando ogni volta che il punto del lattice ( Ix , Iy ) non sia già occupato. Alla fine del processo avremo M punti occupati sul lattice ( N ×N ). Notiamo che quando P ≥ 0.59 è possibile trovare un cammino 150 CAPITOLO 5. SISTEMI MONTE CARLO 5.3. PERCOLAZIONE di siti occupati che connette alto e basso e destra e sinistra. Diciamo a questo punto che il cluster percola attraverso il sistema come l’ acqua percola attraverso una caffettiera. Questa probabilità prende il nome di probabilità critica pc e gioca un ruolo cruciale in tutta la teoria. Riportiamo nella figura 5.4 un tipico esempio di occupazione random di un cluster di 300 pixels con p= 0.1 . Le applicazioni pratiche della percolazione possono essere gli incendi nelle foreste, le transizioni di fase tipo ferro-magnetismo ↔ paramagnetismo, conduttività, etc. ; per maggiori dettagli consultate il libro [TF 92]. Praticamente possiamo implementare l’ algoritmo mediante la SUBROUTINE FAI-PUNTI. 50 subroutine fai_punti (kubo,mmm,perc) implicit real * 4 ( a-h ,o-z) logical * 1 kubo dimension kubo ( 0 : mmm , 0 : mmm ) external g05dyfzan integer g05dyfzan do ix = 0, mmm do iy = 0, mmm kubo ( ix, iy ) = .false. end do end do itotal = ( mmm + 1 ) *( mmm + 1) iselected = nint ( perc * itotal ) icambiati = 0 idum = 777777 do jj = 1 , iselected continue ix = g05dyfzan (0,mmm,idum) iy = g05dyfzan (0,mmm,idum) if ( kubo ( ix,iy )) then icambiati = icambiati + 1 go to 50 end if kubo (ix,iy) =.true. end do return end 151 5.3. PERCOLAZIONE CAPITOLO 5. SISTEMI MONTE CARLO Figura 5.4: Percolazione con p=0.1 152 CAPITOLO 5. SISTEMI MONTE CARLO 5.3. PERCOLAZIONE Il problema di trovare il cluster di connessione può essere cosı̀ risolto. Prendiamo un punto occupato del lattice, eliminiamolo dal lattice e mettiamolo in un vettore. Abbiamo adesso quattro vicini e controlliamo quali sono quelli occupati: essi finiranno nel vettore. Calcoliamo adesso i vicini occupati da tutti gli elementi del vettore e cosı̀ via. Questo è un cluster e il processo si ferma quando non troviamo più nessun vicino occupato. Il cluster di connessione viene trovato quando quattro punti di esso appartengono ai lati sinistro, destro alto e basso; vedi figura 5.5. Questo algoritmo di ricerca del cluster viene implementato attraverso la SUBROUTINE FAICLUSTER. subroutine fai_cluster ( kubo, mmm ,si ,cluster) implicit real * 4 (a-h,o-z) integer *4 ifine logical *1 kubo,condizionea,condizioneb logical *1 condizionex logical *1 condizioney logical *1 si logical *1 cluster parameter ( ipoints = 100 000 ) parameter (maxelements =20 000) ! dimensione vettori vari dimension kubo ( 0:mmm,0:mmm ) dimension cluster ( 0:mmm,0:mmm ) dimension icx ( 1:maxelements ) dimension icy ( 1:maxelements ) dimension ielements ( 1:maxelements ) dimension inewx ( 1:maxelements ) dimension inewy ( 1:maxelements ) dimension inewxsur ( 1:maxelements ) dimension inewysur ( 1:maxelements ) dimension isx ( 1:ipoints ) dimension isy ( 1:ipoints ) ifine = 0 do jx = 0 , mmm do jy = 0 , mmm if ( kubo (jx ,jy) ) then ifine = ifine + 1 isx (ifine) = jx isy (ifine) = jy 153 5.3. PERCOLAZIONE CAPITOLO 5. SISTEMI MONTE CARLO Figura 5.5: Cluster di connessione 154 CAPITOLO 5. SISTEMI MONTE CARLO 5.3. PERCOLAZIONE end if end do end do if ( ifine.gt.ipoints) then stop ’aumentare ipoints !’ end if icluster = 0 1015 continue icluster = icluster +1 do jj=1,ifine ix = isx (jj) iy = isy (jj) if (kubo(ix,iy)) then icx (1) = ix icy (1) = iy kubo(ix,iy ) =.false. inewx (1 ) = ix inewy (1 ) = iy go to 102 end if end do icluster = icluster -1 go to 1016 102 continue mmm1 = mmm + 1 number = 1 new = 1 103 continue iadd = 0 cccccccccccccccc caricamento primi vettori di nuovi punti ccccccccccccc do j=1,new do jcasi = 1, 4 if ( jcasi.eq. 1 ) then isux = 0 isuy = 1 elseif ( jcasi.eq. 2 ) then isux = +1 isuy = 0 elseif ( jcasi.eq. 3 ) then 155 5.3. PERCOLAZIONE CAPITOLO 5. SISTEMI MONTE CARLO isux = 0 isuy = -1 elseif ( jcasi.eq. 4 ) then isux = -1 isuy = 0 end if newx = inewx ( j ) + isux newy = inewy ( j ) + isuy if (( newx.eq.-1).or.(newx.eq.mmm1)) then go to 1050 end if if (( newy.eq.-1).or.(newy.eq.mmm1)) then go to 1050 end if if (( isux.eq.0).and.(isuy.eq.0 )) then go to 1050 end if c x boundaries problem if (kubo(newx,newy)) then kubo(newx,newy)=.false. iadd = iadd +1 inewxsur ( iadd ) = newx inewysur ( iadd ) = newy end if 1050 continue end do end do c determinzaione 4 vicini ccccccccccccccc if ( iadd.eq.0 ) then ielements ( icluster) = number cc inseriamo il loop sul calcolo della percolazione cc scanning su y condizionea = .false. condizioneb = .false. do j= 1 , number if (icy(j).eq. 0 ) then condizionea = . true . end if if (icy(j).eq. mmm ) then 156 CAPITOLO 5. SISTEMI MONTE CARLO 5.3. PERCOLAZIONE condizioneb = . true . end if end do condizioney=.false. if ((condizionea).and.(condizioneb)) then condizioney =.true. end if cc scanning su x condizionea = .false. condizioneb = .false. do j= 1 , number if (icx(j).eq. 0 ) then condizionea = . true . end if if (icx(j).eq. mmm ) then condizioneb = . true . end if end do condizionex =.false. if ((condizionea).and.(condizioneb)) then condizionex =.true. if (condizionex.and.condizioney) then si =.true. do jjj = 1 , number iixx = icx ( jjj ) jjyy = icy ( jjj ) cluster ( iixx , jjyy ) =.true. end do end if end if go to 1015 end if do j = 1,iadd number = number + 1 icx (number ) = inewxsur (j) icy (number ) = inewysur (j) end do do j = 1,iadd inewx ( j ) = inewxsur (j) 157 5.4. CATENE DI VORONOI CAPITOLO 5. SISTEMI MONTE CARLO inewy ( j ) = inewysur (j) end do new = iadd go to 103 ccccccccc end great loop cccccccccccccccccccccccccccccccccccccc 1016 continue cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc type *,’clusters veri=’,icluster return end 5.4 Catene di Voronoi Questi diagrammi prendono il nome da un matematico russo che nel 1908 fece un lavoro ( ovviamente analitico ) sui poligoni irregolari che riempiono il piano. Il problema è poi stato ripreso da svariati autori ognuno con in mente una applicazione di diverso tipo: struttura dei cristalli, struttura della cellula, raffreddamento e conseguente frammentazione delle rocce, struttura dell’ universo,etc. Il problema in due dimensioni consiste nel trovare una volta che è dato un insieme di punti, detti nuclei, una partizione dello spazio tale che ogni nucleo abbia un suo dominio e le frontiere, ovverosia le zone equidistanti fra un nucleo e l’ altro, siano marcate. Per riassumere chiamiamo diagrammi di Voronoi il set dei punti tali che le distanze fra i due nuclei più vicini siano uguali. Elenchiamo una serie possibile di disposizioni di nuclei nel piano classificabile in base alla distribuzione di probalità di partenza oppure in base all’ algoritmo generante: 1. generazione random su x ed y, 2. generazione gaussiana polare su r e θ, 3. numeri pseudo-random o di Sobol, 4. autovalori di matrice complessa, 5. punti frattali. 158 CAPITOLO 5. SISTEMI MONTE CARLO 5.4. CATENE DI VORONOI Figura 5.6: Diagramma di Voronoi con nuclei random su x e y 159 5.4. CATENE DI VORONOI CAPITOLO 5. SISTEMI MONTE CARLO Figura 5.7: Diagramma di Voronoi con nuclei gaussiani 160 CAPITOLO 5. SISTEMI MONTE CARLO 5.4. CATENE DI VORONOI Figura 5.8: La testa della margherita 161 5.4. CATENE DI VORONOI CAPITOLO 5. SISTEMI MONTE CARLO Si tratta poi di trovare tramite uno scanning degli N × N punti del lattice quelli equidistanti dai due nuclei più vicini per quanto riguarda i lati e dai tre nuclei più vicini per quanto riguarda i vertici. Riportiamo nelle due figure 5.6 e 5.7 un tipico esempio di tessellazione quando i nuclei sono distribuiti in maniera random su x y ed in maniera gaussiana . Le applicazioni pratiche sono svariate e come esempio riportiamo la struttura logaritmica della testa dei fiori tipo margherita o girasole. Per generare i nuclei usiamo la formula di Vogel: √ (5.3) Φ = n × 137.5 r = c n , dove 1. n è il numero di punti in senso crescente dal centro. Questo e l’ inverso dell’ età dell’ organismo vegetale in questione. 2. Φ è l’ angolo di referenza in gradi del punto n in coordinate polari. 3. r è la distanza fra il centro ed il punto n. Il risultante diagramma di Voronoi viene riportato nella figura 5.8 Per maggiori dettagli sui diagrammi di Voronoi consultare il libro [OBS 92] . L’ implementazione pratica dello scanning avviene attraverso la SUBROUTINE MATRICE. , subroutine matrice (vec,ipunti,side,matrix,nodes,mll,muu,mmm,traspo) implicit real * 8 (a-h,o-z) logical * 1 matrix,yes,nodes,lato1,lato2 parameter (nnnn=1000) dimension matrix (0:mmm,0:mmm ) dimension nodes (0:mmm,0:mmm ) dimension traspo (1:20 ) dimension vec (1:ipunti,1:2) dimension ads0 (1:nnnn) dimension ads (1:nnnn) dimension awork (1:nnnn) dimension index (1:nnnn) dimension indexwork (1:nnnn) dimension nodesx (1:nnnn) dimension nodesy (1:nnnn) 162 CAPITOLO 5. SISTEMI MONTE CARLO 5.4. CATENE DI VORONOI delta = side/mmm delta0 = side/mll rad2 = dsqrt (2.0 D+00) correz = 1. adelta = delta * correz adelta0 = delta0 * correz deltamezzi = delta /2.0 delta0mezzi= delta0/2.0 do jm=0,mmm do jn=0,mmm matrix (jm,jn)=.false. nodes (jm,jn)=.false. end do end do numero = 0 do jy0 =0 , mll -1 do jx0 =0 , mll -1 xx = jx0 * delta0 + delta0mezzi yy = jy0 * delta0 + delta0mezzi do jj =1,ipunti ax = xx - vec(jj,1) ay = yy - vec(jj,2) ads0 (jj) = dsqrt ( ax*ax + ay*ay ) end do ifail =0 call m01caf ( ads0,1,ipunti,’A’,ifail) ! riordino del vettore in ! senso ascendente adiff0 = dabs (ads0(2)- ads0 (1)) if (adiff0.le.( adelta0* rad2)) then do jy =jy0*muu , jy0*muu + muu-1 do jx =jx0*muu , jx0*muu + muu-1 xx = jx * delta + deltamezzi yy = jy * delta + deltamezzi do jj =1,ipunti ax =xx - vec(jj,1) ay =yy - vec(jj,2) ads (jj) = dsqrt ( ax*ax + ay*ay ) end do ifail =0 163 5.4. CATENE DI VORONOI CAPITOLO 5. SISTEMI MONTE CARLO call m01ajf (ads,awork,index,indexwork,ipunti,ipunti,ifail) adiff = dabs (ads(2)- ads (1)) cccccccccccc beginning check on all the square vertex ccccccccccccccccc if (adiff.le.(adelta*rad2)) then x1 = vec(index(1),1) y1 = vec(index(1),2) x2 = vec(index(2),1) y2 = vec(index(2),2) xc = xx yc = yy yes=.false. call retta90 (x1,y1,x2,y2,xc,yc,deltamezzi,yes) if (yes) then numero = numero +1 matrix (jx,jy)=.true. cccccccccc beginning nodes cccccccccccccccccccccccccccccccccccccccc lato1 =.false. lato2 =.false. x1 = vec(index(1),1) y1 = vec(index(1),2) x2 = vec(index(3),1) y2 = vec(index(3),2) xc = xx yc = yy yes=.false. call retta90 (x1,y1,x2,y2,xc,yc,deltamezzi,yes) if (yes) then lato1=.true. end if x1 = vec(index(2),1) y1 = vec(index(2),2) x2 = vec(index(3),1) y2 = vec(index(3),2) xc = xx yc = yy yes=.false. call retta90 (x1,y1,x2,y2,xc,yc,deltamezzi,yes) if (yes) then lato2=.true. 164 CAPITOLO 5. SISTEMI MONTE CARLO 5.4. CATENE DI VORONOI end if if ((lato1).and.(lato2)) then nodes (jx,jy)=.true. endif ccccccccccccccccccccccccc end nodes ccccccccccccccccccccccccccc end if end if end do end do end if end do end do traspo (1) = adelta traspo (2) = numero return end Questa subroutine fa uso della SUBROUTINE RETTA90. subroutine retta90 (x1,y1,x2,y2,xc,yc,deltamezzi,yes) implicit real *8 (a-h,o-z) logical * 1 yes,uno,due yes=.false. uno=.false. due=.false. deltay = y2 -y1 deltax = x2 -x1 am = deltay/deltax 100 continue c determinazione primo coefficiente angolare amprimo = -1.0/am c determinazione secondo coefficiente angolare a 90 gradi ymezzi = (y1+y2)/2.0 xmezzi = (x1+x2)/2.0 165 5.4. CATENE DI VORONOI c c CAPITOLO 5. SISTEMI MONTE CARLO x = xc + deltamezzi y = ymezzi + amprimo * ( x - xmezzi) determinazione prima retta ylower = yc - deltamezzi yupper = yc + deltamezzi if ((y.gt.ylower).and.(y.le.yupper)) uno=.true. end if x = xc - deltamezzi y = ymezzi + amprimo * ( x - xmezzi) determinazione prima retta if ((y.gt.ylower).and.(y.le.yupper)) uno=.true. end if y = yc + deltamezzi x = (y-ymezzi)/amprimo + xmezzi xlower = xc - deltamezzi xupper = xc + deltamezzi if ((x.gt.xlower).and.(x.le.xupper)) due=.true. end if y = yc - deltamezzi x = (y-ymezzi)/amprimo + xmezzi if ((x.gt.xlower).and.(x.le.xupper)) due=.true. end if if ((uno).or.(due)) then yes = .true. end if return end 166 then then then then Appendice A Funzioni intrinseche Riportiamo il nome generico delle funzioni intrinseche attualmente in uso sui compilatori di FORTRAN 77 insieme ad una breve spiegazione del loro significato. ABS (numero) Una funzione che ritorna il valore assoluto dell’ argomento. Il valore assoluto di un numero complesso, (X,Y), è il suo valore reale (X**2 + Y**2)**(1/2). ACOS (numero)Una funzione che ritorna l’ arcocoseno dell’ argomento in radianti. Il valore assoluto dell’ argomento deve essere minore o uguale a 1. ACOSD ( numero reale)Una funzione che ritorna l’ arcocoseno dell’ argomento in gradi. Il valore dell’ argomento deve essere compreso fra 0 (escluso) e 1 (incluso). AIMAG (numero complesso)Una funzione che ritorna la parte immaginaria di un numero complesso. L’ argomento deve essere di tipo COMPLEX*8. Il risultato è di tipo REAL*4. AINT ( numero reale)Una funzione che ritorna l’ intero più grande il cui valore assoluto non supera il valore assoluto dell’ argomento e ha lo stesso segno dell’ argomento. AMAX0 (numero, numero,...)Una funzione che ritorna il maggiore dei valori specificato nella lista degli argomenti. AMIN0 (numero, numero,...) Una funzione che ritorna il minore dei valori specificati nella lista degli argomenti. ANINT ( numero reale) Una funzione che ritorna il valore dell’ intero più vicino al valore dell’ argomento. 167 APPENDICE A. FUNZIONI INTRINSECHE ASIN ( numero reale) Una funzione che ritorna l’ arcoseno dell’ argomento in radianti. Il valore assoluto dell’ argomento deve essere minore o uguale a 1. ASIND ( numero reale) Una funzione che ritorna l’ arcoseno dell’ argomento in gradi. Il valore dell’ argomento deve essere compreso fra 0 (escluso) e 1 (incluso). ATAN ( numero reale) Una funzione che ritorna l’ arcotangente dell’ argomento in radianti. Il valore assoluto dell’ argomento deve essere maggiore di 0. ATAND ( numero reale) Una funzione che ritorna l’ arcotangente dell’ argomento in gradi. Il valore assoluto dell’ argomento deve essere maggiore di 0. ATAN2 ( numero reale, numero reale) Una funzione che ritorna l’ arcotangente del quoziente dei due argomenti in radianti. Se ambedue gli argomenti sono zero, il risultato è indefinito. Se il primo argomento è positivo, il risultato è positivo. Se il primo argomento è negativo, il risultato è negativo. Se il primo argomento è zero, il risultato è zero. Se il secondo argomento è zero, il valore assoluto del’ risultato è pi/2. Il range del risultato è compreso tra -pi e pi. ATAN2D ( numero reale, numero reale) Una funzione che ritorna l’ arcotangente del quoziente dei due argomenti in gradi. Se ambedue gli argomenti sono zero, il risultato è indefinito. Se il primo argomento è positivo, il risultato è positivo. Se il primo argomento è negativo, il risultato è negativo. Se il primo argomento è zero, il risultato è zero. Se il secondo argomento è zero, il valore assoluto del’ risultato è 90. Il range del risultato è compreso tra -180 e 180 gradi. BTEST (intero, posizione) Una funzione che ritorna il valore logico.true. se il bit con l’ intero specificato dalla posizione è settato a 1. I Il bit di ordine basso è posizionato a 0. CHAR (intero) Una funzione che ritorna il carattere associato con il valore ASCII specificato dall’ argomento. L’ argomento deve essere BYTE, LOGICAL*1, LOGICAL*2, LOGICAL*4, INTEGER*2, o INTEGER*4 come tipo di dato. Il risultato deve essere di tipo CHARACTER. Il valore di input deve essere nel range da 0 a 255. CMPLX (numero [,numero]) Una funzione che converte uno o due argomenti nel tipo COMPLEX*8. Se viene specificato un argomento, questo è convertito nella parte reale del valore del complesso e 168 APPENDICE A. FUNZIONI INTRINSECHE la parte immaginaria diventa zero. Se sono specificati due argomenti, il primo è convertito nella parte reale del valore del complesso e il secondo nella parte immaginaria del valore del complesso. I due argomenti che sono specificati devono essere dello stesso tipo. CONJG (numero complesso) Una funzione che ritorna il complesso coniugato dell’ argomento. Se l’ argomento è (X,Y), il suo complesso coniugato è (X,-Y). COS (numero) Una funzione che ritorna il coseno dell’ argomento. L’ argomento deve essere in radianti. COSD (numero) Una funzione che ritorna il coseno dell’ argomento. L’ argomento deve essere in gradi. COSH ( numero reale) Una funzione che ritorna il coseno iperbolico dell’ argomento. DATE (data) Una subroutine che mette la data corrente nel suo argomento. L’ argomento a 9-byte può essere una stringa carattere, una variable, vettore, o un elemento di vettore di ogni tipo. La data è un valore ASCII formattato come segue: gg-mmm-aa. DBLE (numero) Una funzione che converte l’ argomento in un valore REAL*8. DCMPLX (numero [,numero]) Una funzione che converte uno o due argomenti nel tipo COMPLEX*16. Se viene specificato un argomento, questo è convertito nella parte reale del valore del complesso e la parte immaginaria diventa zero. Se sono specificati due argomenti, il primo è convertito nella parte reale del valore del complesso e il secondo argomento nella parte immaginaria del valore del complesso. I due argomenti che sono specificati devono essere dello stesso tipo. DFLOAT (integer) Una funzione che converte l’ argomento in un valore REAL*8. DIM (numero, numero) Una funzione che ritorna il valore del primo argomento meno il minimo (MIN) dei due argomenti. DIMAG (immaginario) Una funzione che ritorna la parte immaginaria di un numero complesso. L’ argomento deve essere di tipo COMPLEX*16. Il risultato è del tipo REAL* 8. DPROD (numeroreal*4, numeroreal*4) Una funzione che ritorna il prodotto di due valori REAL*4 come un valore REAL*8. DREAL (numero complesso) Una funzione che ritorna la parte reale di un numero complesso. L’ argomento deve essere di tipo COMPLEX*16. Il risultato è di tipo REAL*8. 169 APPENDICE A. FUNZIONI INTRINSECHE EXP (esponente) Una funzione che ritorna e**X, dove X è il valore dell’ argomento. FLOAT (integer) Una funzione che converte l’ argomento in un valore REAL*4. IABS (numero) Una funzione che ritorna il valore assoluto di un argomento intero. Il valore assoluto di un numero complesso, (X,Y), è il valore reale (X**2 + Y**2)**(1/2). IAND (intero, intero) Una funzione che produce il LOGICAL degli argomenti su una base del tipo bit per bit. IBCLR (intero, posizione) Una funzione che ritorna il valore del primo argomento con il bit specificato settato a 0. Il bit di ordine basso è in posizione 0. IBITS (intero, posizione di partenza, lunghezza ) Una funzione che ritorna il valore del bit specificato dalla posizione di partenza e dalla posizione finale. Il bit di ordine più basso è in posizione 0. IBSET (intero, posizione) Una funzione che ritorna il valore del primo argomento con il bit specificato settato a 0. Il bit di ordine più basso è in posizione 0. ICHAR (carattere) Una funzione che ritorna il valore ASCII dell’ argomento. L’ argomento deve essere una espressione character di lunghezza uno. Il risultato è un tipo di dato INTEGER*4. IDATE ( mese, giorno, anno ) Una subroutine che ritorna i tre valori rappresentanti la data corrente. Gli argomenti devono essere definiti come interi o vettore di interi. Il mese è rappresentato con il numero del mese (1 -12). Il giorno è rappresentato come il giorno del mese. L’ anno è rappresentato dalle ultime due cifre dell’ anno. IDIM (numero, numero) Una funzione che ritorna il valore del primo argomento meno il minimo (MIN) dei due argomenti. IDINT (numero) Una funzione che ritorna l’ intero più grande il cui valore assoluto non eccede il valore assoluto dell’ argomento e ha lo stesso segno dell’ argomento. L’ argomento deve essere di tipo real * 8. IDNINT ( numero reale) Una funzione che ritorna il valore dell’ intero più vicino al valore dell’ argomento. L’ argomento deve essere di tipo real * 8. IEOR (intero, intero) Una funzione che riporta un OR esclusivo su argomenti di tipo bit per bit. IFIX (real*4) Una funzione che converte un numero reale in un intero 170 APPENDICE A. FUNZIONI INTRINSECHE INDEX (stringa, sub-stringa ) Una funzione che cerca una stringa per la sua prima comparsa di una sottostringa e ritorna la posizione di partenza della sottostringa come un valore INTEGER*4. INT (numero) Una funzione che ritorna il più grande intero il cui valore assoluto non eccede il valore assoluto dell’ argomento e ha lo stesso segno dell’ argomento. La funzione ritorna un valore INTEGER*4 se il commando / I4 è in funzione; altrimenti ritorna un valore INTEGER*2. IOR (intero, intero) Una funzione che produce un OR logico dell’ argomento sulla base di ragionamenti bit per bit. IQINT (numero) Una funzione che ritorna l’ intero più grande il cui valore assoluto non eccede il valore assoluto dell’ argomento ed ha lo stesso segno dell’ argomento. L’ argomento deve essere di tipo real * 16. ISIGN (valore, segno )Una funzione che assegna il segno del secondo argomento al valore assoluto del primo. LEN (carattere)Una funzione che ritorna il numero di caratteri dell’ argomento. L’ argomento deve essere un’ espressione CHARACTER. Il risultato è un valore INTEGER*4. LGE (carattere, carattere )Una funzione che ritorna il valore.true. se la prima stringa carattere è più lunga o uguale alla seconda stringa carattere. Gli argomenti devono essere del tipo CHARACTER mentre il risultato è un valore LOGICAL*4. LGT (carattere, carattere )Una funzione che ritorna il valore.true. se la prima stringa carattere è maggiore della seconda stringa carattere. Gli argomenti devono essere del tipo CHARACTER mentre il risultato è un valore LOGICAL*4. LLE (carattere, carattere )Una funzione che ritorna il valore.true. se la prima stringa carattere è minore o uguale alla seconda stringa carattere. Gli argomenti devono essere del tipo CHARACTER mentre il risultato è un valore LOGICAL*4. LLT (carattere, carattere )Una funzione che ritorna il valore.true. se la prima stringa carattere è minore alla seconda stringa carattere. Gli argomenti devono essere del tipo CHARACTER mentre il risultato è un valore LOGICAL*4. LOG (numero) Una funzione che ritorna il logaritmo naturale (base e) dell’ argomento. L’ argomento deve essere maggiore di zero. 171 APPENDICE A. FUNZIONI INTRINSECHE LOG10 (numero) Una funzione che ritorna il logaritmo comune (base 10 ) dell’ argomento. L’ argomento deve essere maggiore di zero. MAX (numero, numero,...) Una funzione che ritorna il maggiore dei valori specificati nella lista degli argomenti. MIN (numero, numero,...) Una funzione che ritorna il minore dei valori specificati nella lista degli argomenti. MOD (dividendo, divisore) Una funzione che divide il primo argomento per il secondo e ritorna il resto. NINT ( numero reale) Una funzione che ritorna il valore dell’ intero più vicino al valore dell’ argomento. QEXT (numero)Una funzione che converte l’ argomento in un valore REAL*16. QFLOAT (intero) Una funzione che converte un valore intero in un REAL*16. RAN (seme ) Una funzione che ritorna un valore un numero REAL*4 fra 0.0 (incluso) e 1.0 (escluso). L’ argomento deve essere una variabile o elemento di vettore INTEGER*4. Per ottenere i risultati migliori inizializzate con un valore grande e dispari per la prima volta. Per generare sets differenti di valori random inizializzate il seme ogni volta con un valore diverso. REAL (numero) Una funzione che converte l’ argomento in un valore real. SIZEOF ( argomento ) La funzione ritorna il numero di bytes di memoria usata dall’ argomento. SECNDS ( numero reale) Una subroutine che ritorna il numero di secondi da mezzanotte meno il valore dell’ argomento. L’ argomento deve essere di tipo REAL*4. Il valore di ritorno è del tipo REAL*4. Il tempo di ritorno è accurato a 1/100 di secondo. SIGN (valore, segno ) Una funzione che assegna il segno del secondo argomento al valore assoluto del primo. SIN (numero) Una funzione che ritorna il seno dell’ argomento. L’ argomento deve essere in radianti. SIND (numero) Una funzione che ritorna il seno dell’ argomento. L’ argomento deve essere in gradi. SINH (numero) Una funzione che ritorna il seno iperbolico dell’ argomento che deve essere espresso in radianti. SINHD (numero) Una funzione che ritorna il seno iperbolico dell’ argomento che deve essere espresso in gradi. 172 APPENDICE A. FUNZIONI INTRINSECHE SQRT (numero) Una funzione che ritorna la radice quadrata dell’ argomento. Il risultato è il valore principale, con la parte reale maggiore o uguale a zero. Se la parte reale è zero, il risultato è il valore principale, con l’ immaginario maggiore o uguale a zero. TAN ( numero reale) Una funzione che ritorna la tangente dell’ argomento. L’ argomento deve essere in radianti. TAND ( numero reale) Una funzione che ritorna la tangente dell’ argomento. L’ argomento deve essere in gradi. TANH ( numero reale) Una funzione che ritorna la tangente iperbolica dell’ argomento. L’ argomento deve essere espresso in radianti. TANHD ( numero reale) Una funzione che ritorna la tangente iperbolica dell’ argomento. L’ argomento deve essere espresso in gradi. TIME (tempo) Una subroutine che ritorna il tempo attuale in formato ASCII 24-h. L’ argomento deve essere una variabile, vettori, elemento di vettore o sottostringa di 8 bytes. Il tempo è formattato come segue: hh:mm:ss. ZEXT (intero) Una funzione che ritorna il valore dell’ argomento, zero esteso. 173 APPENDICE A. FUNZIONI INTRINSECHE 174 Appendice B Subroutine di interesse comune Riportiamo in questa appendice i listati delle subroutines adoperate più frequentemente nei programmi precedenti. B.1 CLEANTOP Questa subroutine pulisce lo schermo e porta il cursore a sinistra in alto sui terminali. subroutine cleantop implicit real*4 (a-h,o-z) c c c c c c c this program clears the screen , then changes the screen from dark to light print *,char (27),’[2J’ clear the screen print *,char (27),’[0;0H’ bring the cursor at the top left write (6,*)char(27),’[?5h’ change the screen background to light return end 175 B.2. MAXMIN B.2 APPENDICE B. SUBROUTINE DI INTERESSE COMUNE MAXMIN Questa subroutine ritorna il massimo ( XXMAX) e il minimo ( XXMIN ) di un vettore XX di dimensioni IVEC. subroutine maxmin (xx,ivec,xxmax,xxmin) ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c c this subroutine is producing a the max and the minimum of the c c vector xx c ivec :== vector dimension c c c ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc implicit real * 4 (a-h,o-z) dimension xx(1:ivec) xxmax = xx (1) xxmin = xx (1) do j = 1, ivec if (xx(j).gt.xxmax) then xxmax = xx(j) end if if (xx(j).lt.xxmin) then xxmin = xx(j) end if end do return end 176 Appendice C Sistema operativo UNIX Si entra su una macchina UNIX tramite la comunicazione dilogin e Password. Compiuta questa prima operazione comparirà un prompt che dipende dal sistema operativo usato. Se nel file .login inserite il comando set prompt = % comparirà il segno di percentuale ad accompagnarvi nelle vostre avventure. Riportiamo adesso i comandi principali che interessano a noi. C.1 Alcuni comandi UNIX % man nomecomando (C.1) È molto importante per chi non ha tempo o voglia di leggersi i manuali in quanto permette di vedere cosa corrisponde alla voce nomecomando. % man − k stringa (C.2) Serve a cercare una particolare stringa inserita in un comando. La schermata successiva visualizza il comando coinvolto e la posizione contestuale della stringa. % ls (C.3) Questo comando riporta su schermo tutti i files. % ls − l (C.4) Per vedere la loro grandezza ( numero di bytes ) e la data in cui furono creati. 177 C.2. EDITOR APPENDICE C. SISTEMA OPERATIVO UNIX % ls − l − a (C.5) Serve a vedere i file nascosti (quelli che incominciano con punto tipo .netscape , .csrhc, .login etc....). % cat miof ile (C.6) Permette un display del file indicato sul terminale adoperato. % rm miof ile (C.7) Cancella il file indicato; ricordiamo che in questo sistema operativo esiste solo l’ ultima versione del file creato. % mv vecchiof ile nuovof ile (C.8) Cambia il nome del file indicato in quello nuovo. % cp miof ile altrof ile (C.9) Copia il file indicato in uno nuovo. % exit (C.10) Serve a chiudere la sessione interattiva. < Ctrl/c > (C.11) Serve ad interrompere il processo interattivo in corso e ritornare al sistema operativo. C.2 Editor È il mezzo fondamentale per avere accesso ai files nuovi oppure a quelli esistenti e ne abbiamo svariati. Ci limitiamo a quelli più semplici che sono stati anche testati % joe miof ile (C.12) Si può accedere all’ help on line dell’ editor con il comando ( in editing ) < Ctrl + K + H > % pico miof ile (C.13) Questo è l’ editor che adotta la finestra del noto sistema di posta elettronica che risponde al nome di PINE. 178 APPENDICE C. SISTEMA OPERATIVO C.3. COMPILAZIONE+LINK/ESECUZIONE UNIX C.3 Compilazione+link/esecuzione Per compilare ed eseguire un programma, ad esempio miofile.f, si danno i seguenti due comandi: % f 77 − o miof ile.exe miof ile.f (C.14) % ./miof ile.exe (C.15) Che sono in ordine comando per la compilazione + link ed esecuzione. Se invece vogliamo solamente controllare che il programma non contenga eventuali errori di compilazione, diamo il comando % f 77 − g − c miof ile.f C.4 . (C.16) Shell Script Spesso può essere utile abbreviare una intera serie di comandi tramite un solo file dettoscript. Come esempio riportiamo uno script per compilare ed eseguire un programma che chiameremocalcola. calcola #!/bin/sh clear echo Inserire nome del file read nome echo ho inserito echo $nome rm $nome.exe echo la data e l’ ora sono:‘date‘ f77 -o $nome.exe $nome.for ./$nome.exe Volendo adesso eseguire questo file di comandi dovremo prima cambiare le protezioni con il comandochmod u+x calcola e poi il comando ./calcola. Cercate tramite il manuale di capire le varie operazioni compiute da questa sequenza. 179 C.5. LE LIBRERIE C.5 APPENDICE C. SISTEMA OPERATIVO UNIX Le librerie Se volete crearvi una vostra libreria personale dovete prima trasformare i file sorgente in file oggetto e poi collezionarli in un unica libreria. Riportiamo uno script che genera una libreria chiamata mia lib. f77 -c *.f ar rcv libmia lib.a *.o ranlib libmia lib.a rm *.o Controllate sulle pagine del manuale il significato delle varie operazioni. Se avete il file della libreria potete linkare ad essa il programma main con il seguente comando: f77 main.f -L. -lmia lib 180 Appendice D I caratteri ASCII I sistemi collegati con i computers memorizzano i caratteri sotto serie di bits, usualmente lunghi 7 bits oppure 8. Riportiamo di seguito la sequenza dei 128 caratteri ASCII ( American Standard Code for Information Interchange ) in notazione decimale. Ricordiamo che esiste pure la rappresentazione ottale e quella esadecimale. 181 APPENDICE D. I CARATTERI ASCII Tabella D.1: Tabella caratteri ASCII NUL SOH ST X ET X EOT EN Q ACK BEL BS HT LF VT FF CR SO SI 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 DLE DC1 DC2 DC3 DC4 N AK SY N ET B CAN EM SU B ESC FS GS RS US 16 SP 32 0 48 @ 64 P 17 ! 33 1 49 A 65 Q 18 34 2 50 B 66 R 19 # 35 3 51 C 67 S 20 $ 36 4 52 D 68 T 21 % 37 5 53 E 69 U 22 & 38 6 54 F 70 V 23 0 39 7 55 G 71 W 24 ( 40 8 56 H 72 X 25 ) 41 9 57 I 73 Y 26 ∗ 42 : 58 J 74 Z 27 + 43 ; 59 K 75 [ 28 , 44 ¡ 60 L 76 \ 29 − 45 = 61 M 77 ] 30 . 46 > 62 N 78 ˆ 31 47 ? 63 O 79 182 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 ‘ a b c d e f g h i j k l m n o 96 p 97 q 98 r 99 s 100 t 101 u 102 v 103 w 104 x 105 y 106 z 107 { 108 | 109 } 110 ˜ 111 DEL 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 Bibliografia [Ba 88] M.Barnsley,“Fractals everywhere , prima edizione, Academic Press ,Inc. , Boston(1988). [Do 83] R. Doretti,R. Farabone,“Dal FORTRAN IV al FORTRAN 77 , prima edizione, Gruppo Editoriale Jackson , Milano (1983). [El 85] T.M.R. Ellis,“Programmazione strutturata in FORTRAN 77 , prima edizione, Zanichelli , Bologna (1985). [Ol 92] D. Oliver,“Fractal Visions , prima edizione, SAMS PUBLISHING , Carmel (1992). [OBS 92] Okabe,A. ,Boots,B.,Sugihara,K. , “Spatial Tessellations Concepts and Applications of Voronoi Diagrams, prima edizione, John Wiley & Sons , Chichester (1992). [Or 86] A. Orsi Palamara ,“Programmare in FORTRAN 77 , prima edizione, Levrotto e Bella , Torino (1986). [PS88] H.O. Peitgen,S. Saupe,“The Science of Fractal Image , prima edizione, Springer Verlag , Londra (1988). [Pa 83] C. Page,“FORTRAN 77 , prima edizione, Pitman Publishing LTD , Londra (1983). [REC 92] Press W.H.,Teukolsky S.A., Vetterling W.T.,Flannery B.P., “Numerical Recipes in Fortran, seconda edizione, Cambridge University Press, Cambridge (1992). 183 BIBLIOGRAFIA BIBLIOGRAFIA [PL 90] P. Prusinkiewicz, A. Lindenmayer, “The Algorithmic Beauty of Plants, prima edizione, Springer Verlag, New York (1990). [TF 92] Stauffer D., Aharony A., “Introduction to Percolation Theory, seconda edizione, Taylor & Francis , London (1992). [Vi 92] T.vicsek, “Fractal Growth Phenomena, seconda edizione, Word scientific, Singapore (1992). 184 Indice analitico A BACKSPACE istruzione, 41 DIMENSION istruzione, 24 dimensione-vettori, 20 distribuzione esponenziale, 98 gaussiana, 99 Student, 95 DO istruzione, 31 DO-WHILE istruzione, 33 DOUBLE PRECISION variabile, 7 DOUBLE PRECISION istruzione, 5 C E ACCEPT istruzione, 40 aggregazione-ballistica, 142 aggregazione-DLA, 133 algoritmi-Montecarlo, 133 argomenti-subroutine, 20 ASCII-caratteri, 179 assegnazioni, 27 ASSIGN istruzione, 28 B CALL istruzione, 19 caratteri, 2 catene-Voronoi, 156 CHARACTER variabile, 7, 8, 11 CHARACTER istruzione, 5 CLOSE istruzione, 38 colonne , 3 commento, 4 COMMON istruzione, 24 COMPLEX variabile, 7 COMPLEX istruzione, 5 concatenazione, 11 continuazione, 4 CONTINUE istruzione, 33 D DATA istruzione, 27 ELSE istruzione, 30 ELSEIF istruzione, 30 END DO istruzione, 32 ENDFILE istruzione, 41 END istruzione, 5 ENTRY istruzione, 21 EQUIVALENCE istruzione, 25 espressioni, 9 Etichette, 5 EXTERNAL istruzione, 25 F file, 36 fit retta, 105 format /, 44 185 INDICE ANALITICO INDICE ANALITICO Aw, 44 BN, 44 BZ, 44 Dw.d , 43 Ew.d, 43 Fw.d, 42 Gw.d , 43 IW, 42 KP, 44 Lw, 43 nHc1..cn , 43 SP, 44 SS, 44 stringa, 44 Tln, 44 Tn, 44 Trn, 44 FORMAT istruzione, 42 FORTRAN, 1 FUNCTION istruzione, 16 funzione beta incompleta, 93 coefficiente-binomiale, 87 errori, 91 fattoriale, 86 gamma, 88 gamma-incompleta, 88 generatori-interi, 97 generatori-sistema, 95 numeri-random, 95 p-chiquadro, 92 funzione intrinseca, 165 ABS, 165 ACOS, 165 ACOSD, 165 AIMAG, 165 AINT, 165 AMAX0, 165 AMIN0, 165 186 ANINT, 165 ASIN, 166 ASIND, 166 ATAN, 166 ATAN2, 166 ATAN2D, 166 ATAND, 166 BTEST, 166 CHAR, 166 CMPLX, 167 CONJG, 167 COS, 167 COSD, 167 COSH, 167 DATE, 167 DBLE, 167 DCMPLX, 167 DFLOAT, 167 DIM, 167 DIMAG, 167 DPROD, 167 DREAL, 167 EXP, 168 FLOAT, 168 IABS, 168 IAND, 168 IBCLR, 168 IBITS, 168 IBSET, 168 ICHAR, 168 IDATE, 168 IDIM, 168 IDINT, 168 IDNINT, 168 IEOR, 168 IFIX, 168 INDEX, 169 INT, 169 IOR, 169 INDICE ANALITICO IQINT, 169 ISIGN, 169 LEN, 169 LGE, 169 LGT, 169 LLE, 169 LLT, 169 LOG, 169 LOG10, 170 MAX, 170 MIN, 170 MOD, 170 NINT, 170 QEXT, 170 QFLOAT, 170 RAN, 170 REAL, 170 SECNDS, 170 SIGN, 170 SIN, 170 SIND, 170 SINH, 170 SINHD, 170 SIZEOF, 170 SQRT, 171 TAN, 171 TAND, 171 TANH, 171 TANHD, 171 TIME, 171 ZEXT, 171 G globali, 4 GO TO istruzione, 29 I IF istruzione, 30 IMPLICIT istruzione, 22 INDICE ANALITICO IMPLICIT istruzione, 4 INQUIRE istruzione, 39 INTEGER istruzione, 5 INTEGER variabile, 6 INTRINSIC istruzione, 26 L locali, 4 LOGICAL variabile, 7 LOGICAL istruzione, 5 M main, 14 mapping Feigenbaum, 112 Henon, 109 Julia, 119 regolabile, 120 memoria, 6 momenti-campione, 101 asimmetria, 102 curtosi, 102 deviazione-assoluta, 101 deviazione-standard-empirica, 101 valor-medio, 101 varianza-empirica, 101 O OPEN istruzione, 37 P PARAMETER istruzione, 22 parole-chiave, 5 PAUSE istruzione, 34 Percolazione, 148 PRINT istruzione, 40 priorita-istruzioni, 15 PROGRAM, 16 187 INDICE ANALITICO INDICE ANALITICO FAI-PUNTI, 151 FEIGEN, 115 FELCI, 126 FIT, 106 G05DYFZAN, 98 GAMMA, 85 GAMMLN, 85 GAMMP, 89 GAMMQ, 89 GASDEV, 100 GCF, 90 GSER, 90 GX, 132 HENON10, 112 MAKEPIANTA3, 130 MATRICE, 160 MAXMIN, 174 MOMENT, 102 RAN0, 97 RETTA90, 163 SCRIVIDATI, 41 TTTEST, 104 UNO, 118 WO, 134 SUBROUTINE istruzione, 18 PROGRAMMA CAVEN, 60 GAUSS, 74 PARABO, 50 PENDO, 52 RETTA, 47 testc2, 80 testt, 79 R READ istruzione, 39 REAL istruzione, 5 REAL variabile, 6 record, 35 relazioni, 12 relazioni-logiche, 13 RETURN istruzione, 21 REWIND istruzione, 40 S SAVE istruzione, 26 scheda, 3 sottostringhe, 8 STOP istruzione, 34 SUBROUTINE AVEVAR, 105 BA, 142 BETA, 88 BETACF, 94 BETAI, 93 BICO, 87 CLEANTOP, 173 DUETUTTO, 119 ERF, 92 ERFC, 92 EXPDEV, 99 FACTLN, 87 FACTRL, 86 FAI-CLUSTER, 156 T test medie, 103 tipi, 5 TYPE istruzione, 40 U UNIX cp, 176 exit, 176 joe, 176 ls, 175 man, 175 188 INDICE ANALITICO INDICE ANALITICO mv, 176 rm, 176 V vettori, 8 W WRITE istruzione, 39 189