




























































































Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Documento di fisica computazionale
Tipologia: Sintesi del corso
1 / 137
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!





























































































4 francesco ricci, vincenzo fiorentini
Questo testo è una sintesi di diversi anni di insegnamento di corsi di Fisica Computazionale di base di diverso livello. È diretto a un livello di conoscenza basso: smanettoni e teste d’uovo si adatteranno a ripassare e a far pratica su tecniche di programmazione semplici. Dopo aver visitato in passato territori complicati e remoti (fino ad esempio alle equazioni integrali...), col passare del tempo la tendenza al minimale ha prevalso, ed è stato inevitabile eliminare e semplificare drasticamente. Questo non significa che alcuni argomenti siano sottili e potenzialmente di interesse molto vasto. La scelta del sistema operativo Unix (robusto, usatissimo, flessibile, e alla base di tutti i sistemi operativi commerciali) è obbligatoria. Ne esistono versioni open-source (i vari dialetti di Linux) o proprietarie (MacOSX), facilmente reperibili e ben mantenute. Benchè per i lin- guaggi la scelta sia più difficile, negli ultimi anni il python è emerso come una eccellente alternativa ai classici C e Fortran (anche nelle loro incarnazioni moderne). In particolare, i notebook python offrono una maniera potente per riassumere molto materiale che a stampa sarebbe difficilmente digeribile. Il testo è quindi diviso in capitoli "sdoppiati" in una parte teorica generale e una di programmazione elementare in python; i tutorial relativi a queste ultime sezioni sono disponibili in rete. Vengono anche forniti in rete dei notebook python che riassumono ed elaborano il grosso degli argomenti svolti nel testo, e forniscono una quantità di esempi discussi solo brevemente nel testo. Come noto, un libro non si finisce: lo si abbandona. Se avete inte- resse, suggerite modifiche, aggiunte, tagli. Eviteremo di abbandonarlo del tutto.
1****. A - Introduzione
La descrizione di un sistema o fenomeno fisico tramite simulazione numerica richiede la costruzione di un modello, con tutte le relative semplificazioni e omissioni (che di solito elegantemente chiamiamo approssimazioni), e la sua traduzione in –o descrizione entro lo schema di– un algoritmo di calcolo. Ci sono numerose fonti di errore possibili (la rappresentazione dei numeri, l’accuratezza dei parametri, lo specifico algoritmo scelto) di cui bisogna essere consci. Supponiamo di voler calcolare il periodo di un pendolo. Assumia- mo che la massa sia sospesa a un filo indeformabile e che si possa trascurare la resistenza del mezzo in cui essi si muovono; queste ipotesi possono essere più o meno ragionevoli, o condurre a errori più o meno grandi a seconda dei casi. Assumiamo poi che la lunghezza del filo e la massa del peso siano note esattamente; questo non è vero, ovviamente, essendoci errori inevitabili nella loro misura. Sul peso agisce solamente la forza di gravità, che dipende dalla massa, di cui si è appena detto, e dalla accelerazione di gravità g' 9. 81 m/s^2. Quest’ultima dipende dalla distanza della massa dal centro della Terra e dalle fluttuazioni di densità entro la Terra stessa – tutte cose trascurate assumendola costante. (A rigore, poi, la distanza del peso dal centro della Terra varia durante l’oscillazione del pendolo, e con essa varia g.) Trascurare queste piccole correzioni non causa errori apprezzabili per un piccolo pendolo armonico, ma potrebbe essere sconsigliabile se si studiasse un pendolo anarmonico (quindi con grande elongazione) di grande estensione. Usando la seconda legge della dinamica (equazione di Newton),
m a = F ( 1. 1 )
l’equazione differenziale da cui ottenere l’elongazione angolare istan- tanea del pendolo rispetto alla verticale è
m` d^2 θ dt^2 = −mg sin θ , ( 1. 2 )
fondamenti di fisica computazionale 7
meri in base 2 , essendo tecnologicamente più abbordabile un sistema a due stati, come ad esempio una cella di memoria con o senza magnetizzazione o carica immagazzinata. Con una parola di memoria composta da N oggetti a 2 stati, noti come bit, possiamo rappresentare 2 N^ numeri interi combinando i vari possibili stati di ognuno dei bit. Per esempio, se N= 3 , posso rappresentare 23 = 8 numeri, come mostrato in Tabella 1. 1 , con le tre cifre binarie a rappresentare i coefficienti di 20 , 21 , e 22.
Tabella 1. 1 : Numeri rappresentabili da una parola a 3 bit
0 0 0 → 0 1 0 0 → 20 = 1 0 1 0 → 21 = 2 1 1 0 → 20 + 21 = 3 0 0 1 → 22 = 4 1 0 1 → 20 + 22 = 5 0 1 1 → 21 + 22 = 6 1 1 1 → 20 + 21 + 22 = 7
Convenzionalmente, un numero reale in virgola mobile a preci- sione singola è rappresentato da una parola di memoria. Le parole di memoria dei computer moderni sono rappresentate 32 o 64 bit. Nelle architetture a 32 bit, riservando un bit per il segno, possiamo rappresentare i numeri interi da – 231 a + 231 (circa ± 2 × 109 ). Definito 1 byte= 8 bit, un numero reale in singola precisione occupa 4 byte; uno che ne occupi 8 , di dice a doppia precisione. Ad esempio, la designazione REAL*8 indica i numeri reali in doppia precisione nei compilatori fortran a 32 bit. (Ovviamente se usiamo un architettura a 64 bit, dovremo raddoppiare il tutto, e la nomenclatura cambia.) I numeri a virgola mobile, o floating-point, sono rappresentati come
xfloat = (− 1 )s^ × m × 2 (E−b)^ ( 1. 6 )
I 32 bit vengono suddivisi in 1 per il segno (s= 0 o 1 ), 8 per l’esponente E, e 23 per la mantissa m. Con 8 bit, l’esponente è E∈[ 0 , 255 ]. Sce- gliendo lo shift b= 128 , l’esponenziale cade nell’intervallo [ 2 −^128 , 2127 ]= [ 2. 93 × 10 −^39 , 1. 7 × 1038 ]. Una mantissa a 23 bit permette di rappre- sentare numeri da 0 a circa 8 × 106 , e quindi il massimo e minimo numero rappresentabili stanno tra circa 10 −^40 e 1044. (Con 64 bit, i bit dell’esponente sono 11 , e i numeri rappresentabili sono enormi, all’incirca [ 10 −^320 , 10310 ].) Altra deduzione che deriva da quanto sopra è che un processore che salvi gli indirizzi della memoria in parole a 32 bit potrà accedere al massimo a 232 bit o circa 0. 5 × 109 byte≡ 0. 5 Gb (Giga-byte). L’accesso ormai universale ai processori a 64 bit ha reso possibile la gestione nativa di quantità di memoria pressochè illimitate (circa 2 miliardi di Gigabyte, o 2 Pb, o Petabyte). Con grandi mantisse ed esponenti, non è ovvio a prima vista che la precisione dei numeri e dei risultati di operazioni tra nu- meri sia apprezzabilmente limitata agli effetti pratici. Per capire che questo è effettivamente (almeno potenzialmente) il caso, consi- deriamo un sistema che abbia una mantissa molto ridotta, tale da darci solo 3 cifre decimali, e facciamo la somma 7 .000 10^0 + 1. 000 10 −^2. Aggiustati gli esponenti ( 1 .000 10−^2 = 0 .010 10^0 ) così da po- ter sommare direttamente le mantisse, si ottiene 7 .010 10^0 = 7. 010. Ma consideriamo la somma 7 .000 10^0 + 1 .000 10−^4 : aggiustando gli esponenti, 1 .000 10−^4 diventa 0. 000 ( 1 ) 100 , cioè 0. 000 , essendo la mantissa a tre cifre decimali. La somma è ( 7. 000 + 0. 000 ) 100 = 7. 000. Si definisce precisione di macchina e m il minimo numero rappresen- tabile dalla mantissa; il numero che volevamo sommare a 7. 000 è più piccolo della precisione di macchina del computer fittizio di questo esempio (circa 10 −^3 ), e di fatto non viene sommato. Dun-
8 francesco ricci, vincenzo fiorentini
que, mentre nell’aritmetica l’elemento di identità additiva è lo zero, nell’aritmetica in rappresentazione finita che stiamo considerando l’elemento di identità additiva non è unico, poichè qualunque numero minore della precisione di macchina è equi- valente allo zero. La precisione di macchina è facilmente stimabile come il minimo numero rappresentabile dalla mantissa. Quest’ultima in architettura a 32 bit è tipicamente di 23 bit, e in 64 bit è di 52 , quindi
e m = 2 −^23 ∼ 10 −^7 32 bit, ( 1. 7 ) e m = 2 −^52 ∼ 10 −^16 64 bit. ( 1. 8 )
Più in generale, un numero reale x∗^ in rappresentazione finita è diver- so dal vero numero x. Ad esempio π è diverso dalla sua rappresenta- zione approssimata π ∗= 3. 14159. Possiamo associare a un numero un errore assoluto o relativo. Il primo è eabs=|x − x∗|, e per un numero con n decimali eabs≤ 0 .5 10−n; il secondo è erel=eabs/|x|'eabs/|x∗|. L’errore si propaga, e potenzialmente si amplifica, combinando i nu- meri tramite operazioni. Ad esempio, se i numeri rappresentati sono x∗=x+ex, y∗=y+ey, con e i relativi errori, sommando o sottraendo si ha
x∗^ ± y∗^ = x ± y + ex ± ey
e quindi l’errore sulla somma o differenza è
e = (x∗^ ± y∗) − (x ± y) = ex ± ey.
Poichè |e|=|ex+ey|≤|ex |+|ey| si ottiene che
max{|e|} = |ex | + |ey|,
cioè il massimo errore è la somma dei moduli dei singoli errori. Benchè questo sia il caso peggiore e siano possibili cancellazioni, è chiaro che in generale una somma o sottrazione propaga gli errori dei singoli addendi. Per una moltiplicazione o divisione si mostra facilmente la stessa cosa per gli errori relativi. Un ulteriore errore è quello generato dalle operazione approssi- mate in macchina. In generale, la vera operazione ⊗ è fatta in modo algoritmicamente diverso da quella ⊗∗^ fatta dal computer. La vera operazione con i veri numeri sarebbe rappresentata da x⊗y, e quella approssimata sui numeri approssimati da x∗⊗∗y∗. Si ha che
eabs = |x ⊗ y − x∗^ ⊗∗^ y∗| ( 1. 9 ) = |x ⊗ y − x∗^ ⊗ y∗^ + x∗^ ⊗ y∗^ − x∗^ ⊗∗^ y∗| ≤ |x ⊗ y − x∗^ ⊗ y∗| + |x∗^ ⊗ y∗^ − x∗^ ⊗∗^ y∗|.
Nell’ultima linea si riconoscono l’errore propagato dalla vera opera- zione e quello generato dalla operazione approssimata sui numeri approssimati. Quindi vale come prima il limite superiore dell’errore dato dalla somma dei moduli di errore propagato e generato. Ad esempio, con una mantissa a tre cifre complessive
2.77 × 102 + 7.56 × 102 = [10.36 × 102 ] = 1.04 × 103.
10 francesco ricci, vincenzo fiorentini
valore vero quanto più i rettangolini approssimano la forma della funzione, cioè più sono stretti, cioè più N è grande. Supponiamo quindi che l’errore decresca come una potenza di N, ad esempio
ealgo ' α /N β.
L’errore totale è allora (ricordando, e assumendo che valga, Eq. 1. 10 )
etot ' α N β^
Figura 1. 2 : Errore algoritmico e di round-off.
Come schematizzato in Fig. 1. 2 , in scala log-log a bassi N l’errore algoritmico è grande perchè un campionamento rozzo non fornisce una stima buona dell’integrale; man mano che N cresce, l’errore totale cala, ed è dominato dalla discesa con pendenza – β dell’errore algorit- mico. Raggiunto un certo valore di N, che dipende dal problema e dall’algoritmo, l’errore algoritmico (che cala con N) diventa minore di quello di round-off (che sale con N). L’errore totale ha un minimo. A N abbastanza grandi, il round-off error diventa dominante. Con- cludiamo che c’è un valore ottimale di N che ci fornisce il minimo errore, possiamo valutarlo nel caso di errore algoritmico noto. Ipotizziamo un errore algoritmico ealgo∼ 1 /N^2. L’errore totale è ∼ 1 /N^2 + e m
N. Per trovare il minimo annulliamo la derivata detot dN
e m 2
Riarrangiando,
N (^52) =
e m ; Nmin = (
(^25) ' 1100.
L’errore totale commesso a N=Nmin è
etot =
da cui si vede che l’errore di round-off è il più grande dei due, e fa sì che l’errore totale sia dell’ordine di ben 40 volte la e m. Per dimostrare l’importanza di un buon algoritmo –il quale, cioè, faccia scendere quanto possibile rapidamente l’errore– stimiamo le stesse grandezze per un errore algoritmico dell’ordine di 2 /N^4. Si ha detot dN =^0 =^ −^
e m 2
e quindi N (^92) = 16 e m ; Nmin = ( 16 10 −^7
(^29) ' 67,
e un errore totale minimo
etot = 10 −^7 + 8 10−^7 ∼ 9 10−^7.
La migliore prestazione dell’algoritmo riduce perciò di un fattore 16 il numero delle operazioni e l’errore di un fattore 4. Concludendo, notiamo che l’errore algoritmico può essere espres- so in termini di un parametro grande proporzionale al numero di
fondamenti di fisica computazionale 11
operazioni, ad esempio il numero di divisioni di un intervallo come nel caso precedente, o al contrario in termini di un parametro pic- colo, come ad esempio la dimensione ∆=(b–a)/N dell’intervallino, essenzialmente l’inverso di N. Ambedue questi tipi di parametri sono legati alla scelta fatta per la discretizzazione del problema.
Studiamo ora alcuni modi semplici per calcolare numericamente le derivate. Questo calcolo è potenzialmente rischioso in termini di accuratezza. L’integrazione, che discuteremo più oltre, è una opera- zione di media che tende a sopprimere gli effetti delle fluttuazioni locali della funzione in esame. Al contrario, la derivata misura ed evidenzia –anche drammaticamente– proprietà locali della funzione: la pendenza (derivata prima), la curvatura (derivata seconda) e così via. È difficile da calcolare sostanzialmente perchè, numericamente, è un rapporto tra quantità piccole (si veda la dettagliata discussione su Numerical Recipes, cap. 5 1 ), come è evidente dalla definizione 1
d f dx |x 0 = lim h→ 0
f (x 0 + h) − f (x 0 ) h
come rapporto incrementale destro o in avanti. (Qui assumiamo implicitamente che, come necessario per l’analiticità della derivata, esista anche il rapporto incrementale all’indietro
d f dx |x 0 = lim h→ 0
f (x 0 ) − f (x 0 − h) h
e che i due siano uguali.) Con tutto ciò, la discretizzazione delle derivate è inevitabile e fon- damentale per la discretizzazione delle equazioni differenziali, oltre che più in generale per esprimere una approssimazione alla funzio- ne nelle vicinanze di un punto del dominio (p.es. nell’integrazione numerica). In ogni caso, questo è un punto buono come un altro per familiarizzarci con la discretizzazione e la stima d’errore algoritmico.
Figura 1. 3 : Schema di discretizzazione in 1 D.
Cominciamo con il discretizzare l’intervallo di definizione (o l’in- tervallo locale di nostro interesse) della funzione f (x). Lo dividiamo in N sottointervalli di ampiezza
h = |b^ −^ a| N
e definiamo gli N+ 1 punti (“la griglia”) dove valuteremo la funzione,
xi = a + ih i = 0,... , N ( 1. 17 )
come schematizzato in Fig. 1. 3. La funzione nei punti della griglia è indicata con fi= f (xi). (Ovviamente si può scegliere di lavorare con N punti e quindi N– 1 intervalli. Oppure l’intervallo potrebbe essere aperto a destra o a sinistra o ambedue. Quel che conta è che ogni punto è a distanza h dal punto adiacente.)
fondamenti di fisica computazionale 13
Riarrangiando,
f (^) i′ = fi+ 1 − fi− 1 2 h
Questa formula, detta centered-difference, ha un errore quadratico in h, il che la rende molto più robusta e accurata di quelle forward e backward viste prima (semplicemente perchè se h= 0. 1 , l’errore associato alla derivata nel punto i sarà 0. 1 c per la formula forward, e
fi+ 1 − fi− 1 = 2 fi + h^2 f (^) i′′ + h^4 4! f (^) iIV , ( 1. 26 )
da cui riarrangiando si ottiene una espressione per la derivata seconda,
f (^) i′′ = fi+^1 +^ fi−^1 −^2 fi h^2
con errore quadratico in h. Questa formula è un altro cavallo da tiro nel contesto delle equazioni differenziali. È chiaro che conviene usare le Eq. 1. 25 e 1. 27 con il loro errore quadratico, che permette di usare h non troppo piccoli e di evitare così la divisione tra due numeri troppo piccoli nel calcolo della derivata e la conseguente inaccuratezza.
Analizziamo ora in maggior dettaglio un paio di tecniche per l’inte- grazione numerica. Maggiori dettagli in NR, Cap. 4 2. Parliamo quasi 2 solo di integrazione unidimensionale: l’applicazione delle tecniche che consideriamo a dimensionalità maggiori è possibile, anche se non sempre ovvia, ma diventa rapidamente molto costosa. Accennere- mo più in dettaglio in seguito (Sez. 6. 3 ) ad alcune tecniche tecniche alternative.
Figura 1. 4 : Schema di integrazione trapezoidale.
Consideriamo l’integrale unidimensionale
∫ (^) b a
f (x) dx, ( 1. 28 )
e discretizziamo l’intervallo di integrazione dividendolo come prima in N sottointervalli di ampiezza h = |b − a|/N, e definendo gli N+ 1 punti dove valuteremo la funzione come
xi = a + ih i = 0,... , N. ( 1. 29 )
Le due formule che esamineremo sono quella trapezoidale e quella di Simpson. Questi sono casi particolari della famiglia di formule di Newton-Cotes, che si ottengono approssimando la funzione in ogni intervallino con un polinomio. Trapezi e Simpson si ottengono rispettivamente con una approssimazione lineare e una quadratica. Supponiamo dunque di descrivere la funzione nei dintorni di xi con una retta,
f = fi + f ′^ x = fi + (^ fi+^1 −^ fi) h x, ( 1. 30 )
14 francesco ricci, vincenzo fiorentini
con errore di troncamento o(h^2 ). L’integrale di questa funzione sull’intervallino h tra xi e xi+ 1 è
Ii = ( fi + fi+ 1 )h/2, ( 1. 31 )
come si vede valutando le aree della Fig. 1. 4. L’errore sull’intervallino è ovviamente δ Ii' f *h∼h^3. L’integrale totale è la somma dei singoli integralini:
I = (^) ∑ i
Ii = h 2 [( f 1 + f 2 ) +... ( fN + fN+ 1 )]
h 2 ( f 1 + fN+ 1 ) + h
N ∑ i= 2
fi. ( 1. 32 )
L’errore associato all’integrale complessivo è N volte quello su un intervallino, δ I ' N ∗ h^3 ' 1 h h^3 ' h^2 ' 1 N^2
che decresce come una potenza di N come avevamo ipotizzato nella discussione in Sez. 1. 2. Il caso di Simpson è analogo. Si approssima la funzione come quadratica nell’intervallino,
f = fi + f (^) i′ x + f (^) i′′ x^2 /
e si utilizzano le espressioni delle derivate prima e seconda discretiz- zate ottenute in precedenza. Integrando su un intervallino doppio da −h and h centrato nel punto xi si ha ∫ (^) +h −h
f dx = fi x|+ −hh + ( fi+ 1 + fi− 1 − 2 fi 2 h^2
x^3 3 |+ −hh
= 2 h fi + h 3 (^ fi+i^ +^ fi−^1 −^2 fi) = h 3 (^ fi+i^ +^ fi−^1 +^4 fi),^ (^1.^34 ) dove il termine in f ′^ cade in quanto dispari. Dunque su un intervallino doppio l’integrale è ∫ (^) x 3 x 1
h 3 ( f 1 + 4 f 2 + f 3 ), ( 1. 35 )
ed estendendo la somma a tutti gli intervalli ∫ (^) xN+ 1 x 1
f (x)dx = h 3 ( f 1 + 4 f 2 + 2 f 3 +... ( 1. 36 )
cioè peso 1 per il primo punto, poi pesi alternati 4 e 2 , e di nuovo 1 per l’ultimo. Chiaramente, il numero di punti dev’essere dispa- ri per applicare questa formula. L’errore dell’integrale sull’inter- vallo è δ Ii'h*o(h^4 )=h^5 , perchè i termini dispari (quindi anche quel- lo cubico) non danno contributo su questo intervallino simmetrico. L’errore totale (sugli N intervalli) è perciò, analogamente a prima,
1****. B - Introduzione al Python
In questa sezione vedremo le basi della programmazione in Python, molte delle quali, essendo similari ad altri linguaggi di programma- zione, risulteranno utili in generale. Non è nostra intenzione essere esaustivi, ma soltanto dare una infarinatura delle caratteristiche di base della programmazione e di tutto ciò che ci sarà utile per la imple- mentazione dei codici che useremo per la risolzione dei problemi di fisica. Sarà utile sia a chi è del tutto digiuno di programmazione, sia a chi sa già programmare e vuole imparare il Python. Inoltre alcuni dettagli sui vari aspetti della programmazione verranno ripetuti e ampliati nei successivi capitoli pratici dedicati all’implementazione di problemi. Una costante di questi capitoli sarà la presenza di codici e la loro spiegazione, ma non verrà quasi mai riportato l’output che questi codici restituiscono. Questo per stimolare il lettore a pensare quale sia l’output e confrontarlo con quello reale, provando direttamente sul proprio computer tutti i codici e sperimentando in autonomia. Per chi vuole andare oltre si vedano le referenze sulla programma- zione in generale e sul Python in particolare.
Iniziamo il capitolo con alcune indicazioni su quali sono i software da installare per poter eseguire il codice presentato nelle sezioni pratiche che seguiranno. Presenteremo principalmente due possibili strade da seguire per poter avere un ambiente python adatto all’esecuzione del codice presentato nelle sezioni pratiche: l’installazione di alcuni pacchetti in una distribuzione linux già installata e l’uso di una macchina virtuale linux.
fondamenti di fisica computazionale 19
[GCC 4.8.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> La shell interattiva aspetta dei comandi che una volta inseriti, calcando il tasto invio, verranno eseguiti. Il modo più semplice per provare é fare qualche semplice calcolo: >>> 2 + 2 4 Come si vede la shell legge i comandi che seguono le freccette >>>, esegue l’operazione chiesta e ci risponde con il risultato corretto, senza caratteri ad inizio riga. È ovvio che dovremo inserire dei comandi che Python conosce, altrimenti otterremo un errore: >>> pippo Traceback (most recent call last): File "", line 1, in NameError: name ’pippò is not defined Il comando pippo non è infatti riconosciuto, perché non definito da nessuna parte. Tutto il codice che illustreremo in questa e in tutte le altre sezione del libro, lo si potrà inserire riga per riga direttamente della shell op- pure lo si potrà scrivere in un file di testo, con il vostro editor preferito, ed eseguirlo in un secondo momento. Per eseguire un programma Python, meglio se salvato con estensione .py, dovremo semplicemente digitare nella shell linux python file.py. L’interprete leggerà riga per riga ed eseguirà il vostro programma, dandovi un output o meno a seconda di cosa avete scritto nel codice o un errore se c’é qualcosa che non va. Tutto ciò che viene scritto nella shell o in un file di testo viene interpretato da Python. È utile però inserire nel codice dei commenti per spiegare cosa si sta facendo, sia a se stessi che a terzi che vo- gliono modificare il nostro codice. Per far si che Python non legga i nostri commenti, causando degli errori, possiamo postporre ad essi il carattere #, come nella seguente riga d’esempio: >>> 2+2 #usiamo Python per fare una addizione 4 Il risultato sarà identico al precedente perché l’interprete non terrà in considerazione il commento che segue il cancelletto #. Per concludere citiamo una shell interattiva molto usata: IPython. 2 2 Per avere un idea delle potenziali- tà di IPython si veda http://www. Questa shell interativa avanzata ha numerose funzionalità utili come ipython.org per esempio: un sistema di completamento automatico avanzato, un ampia gestione della storia dei comandi eseguiti, una serie di funzioni aggiuntive come per esempio quelle di aiuto in linea, la possibilità di eseguire un codice contenuto in un file all’interno della shell stessa, anche in modalità di debugging; la possibilità di modificare un codice, mediante un editor, eseguire comandi di sistema e salvarne in una variabile python l’output, e molto altro. Come vedremo, insieme con i pacchetti Numpy e Matplotlib, saremo in grado di ricreare un
20 francesco ricci, vincenzo fiorentini
ambiente di calcolo completo come il famoso Matlab.
Lo strumento principale di un qualunque linguaggio di programma- zione sono le variabili. Queste ci permettono di salvare in memoria dei dati, per esempio numeri, assegnandogli un nome di nostro co- modo. Con esse possiamo compiere delle operazioni di vario tipo e modificarle quando ne abbiamo bisogno. Hanno dunque un significa- to del tutto simile a quello delle variabili in algebra. Vediamo subito come assegnare un valore numerico ad una variabile: x= In questo modo abbiamo detto salva il valore 2 in memoria e chiamalo x. Ora potremo usare la variabile x per esempio per fare operazioni aritmetiche, per esempio: x+x Out: 4 La variabile x può essere perciò letta, usata e anche modificata nel programma ogni volta che ne abbiamo bisogno: x= x+x Out: 4 x= x*x Out: 9 Il nome con cui definiamo una variabile può essere piu lungo di un carattere, può contenere maiuscole e “_”, ma non spazi vuo- ti. È buona norma chiamare le variabili con un nome che sia de- scrittivo del dato che contengono, per esempio g=9.81, oppure accel_gravit=9.81, se vogliamo registrare l’accelerazione di gra- vità. Alcuni nomi non si possono usare per assegnare una variabile perché sono già usati da alcuni comandi del Python, per esempio for. I tipi di dati che vogliamo registrare in una variabile possono essere molteplici. Il modo di assegnare un dato ad una variabile prescinde dal suo tipo, e sarà sempre uguale all’esempio precedente. A differenza di altri linguaggi, Python riconosce il tipo di dato inserito dentro una variabile ed assegna in maniera automatica il tipo corretto alla variabile. I tre tipi di variabile di cui faremo maggiormente uso sono: