Laboratorio di Calcolo

Prof. G. D'Agostini

A.A. 18-19


Sommario delle lezioni

  1. Mer 26/09     2. Gio 27/09     3. Mer 03/10     4. Gio 04/10     5. Mer 10/10  
  6. Gio 11/10     7. Mer 17/10     8. Gio 18/10     9. Mer 24/10     10. Gio 25/10  
  11. Mer 31/10     12. Mer 07/11     13. Gio 08/11     14. Mer 14/11     15. Mer 15/11  
  16. Mer 21/11     17. Gio 22/11     18. Mer 28/11     19. Gio 29/11     20. Mer 5/12  
  21. Gio 6/12     22. Mer 12/12     23. Gio 13/12     24. Mer 19/12     25. Gio 20/12  
 
Lezione 1, Mer 26 settembre, 1h
Introduzione al corso
  • Presentazione del corso (molto vaga, a dire il vero).
  • Calcoli e approssimazioni in Fisica. Conticini con carta e penna (e mente!) basati sulla costante solare.
  • Minimalia di Fisica:
    • a = F/m (seconda legge di Newton);
    • Δv = am Δt   (da am = Δv / Δt);
    • Δs = vm Δt   (da vm = Δs / Δt):
    • forza gravitazione fra due 'punti materiali' o fra due sfere 'omogenee' (o almeno con variazione radiale della densità):
      F = ( G M m ) / d2;
    • moto uniformemente accelerato a partire da s=0 a t=0:
      s = ½ a t2
    • Note sulle unità di misura.
  • Introduzione a R come calcolatrice scientifica. Vettore nel senso informatico.
Lavoro suggerito alla prima lezione  
 
 
Lezione 2, Gio 27 settembre, 2h
Intro a html e R (con qualche comando Linux...)
  • Osservare la luna nei prossimi giorni, possibilmente sempre alla stessa ora.
  • Soluzione esercizietto sulla costante solare.
  • Ancora sulla costante solare: potenza emessa dal Sole (a mano con approssimazioni): fare a casa.
  • Illustrazione dei tag del file html
    → chi lo lo avessi fatto si eserciti a modificarlo! (La padronanza di editor è di cruciale importanza per scrivere programmi.)
  • Introduzione a R (continua):
    • Comandi usati in aula (inclusi quelli sbagliati, visto che sbagliando si impara): (lo si scarichi usando il tasto destro e poi lo si apra con un editor)
    • Altri comandi suggeriti per esercitarsi (in caso di problemi si usi l'help, o si cerchi in rete):
    • Primo script R:
      1. salvarlo sul proprio computer mediante tasto destro, etc.;
      2. accertarsi che sia nella directory di lavoro di R;
      3. 'lanciarlo' (da dentro R) con il comando source("primo_script.R")
      4. modificarlo a piacere e rilanciarlo (sulle funzioni sprintf() e cat() torneremo a lezione)
 

 
Lezione 3, Mer 3 ottobre, 1h
Punto situazione ‐ Elementi di programmazione
  • Luna: tenere sotto controllo! Poi un giorno ci faremo qualche conto.
  • Problemini in corso:
    • Energia annuale dal Sole sulla Terra: OK?
    • Diametro angolare e distanza Cupolone: ABC di trigonometria nell'approssimazione di piccoli angoli
      Nota: non andava usato il diametro del Sole, bensì il suo diametro angolare.
    • Continuazione dei problemi della potenza del Sole e della distanza del Cupolone:
      • valutarsi le dimensioni del Sole dalla distanza Terra-Sole e dal diametro angolare (visto dalla Terra — non è una sua proprietà assoluta!);
      • valuare la potenza per unità di supeficie emessa dal Sole.
    • Analisi dei comandi per la rappresentazione grafica di numeri complessi (potenze_numeri_complessi_0.R)
  • R
    • vettori;
    • operatori logici e loro uso nella programmazione;
    • cicli (`loop'), controllati da for() e da while()
    • Primi 'programmini'.
    • Comandi eseguiti in aula: Rhistory_1ott2018.R
    • Esercizi proposti
      • fare variazioni dei comandi proposti;
      • riscrivere i programmi che fanno le somme di elementi di vettori in modo ordinato, su più righe e metterli in uno script da eseguire con source()
      • Fare uno script che trova le soluzioni di una equazione algebrica di secondo grado si provi ad usare if()/else(), non ancora visti a lezione, ma per il cui uso si faccia riferimento all'esempio che segue:
        a=2; b=-1; c=-3   # cambiare questi valori per ottenere i vari casi
        discr = ....      # calcolare il discriminante
        if(discr < 0) {  # se discr è negativo
            sprintf("discriminante <0 : soluzioni complesse coniugate")
            sol1 = ...   # calcolare la prima soluzione complessa
            sol2 = ...   # calcolare la seconda soluzione complessa
        } else {  # altrimenti
            sprintf("discriminante >= 0 : soluzioni reali")
            sol1 = ...   # calcolare la prima soluzione reale
            sol2 = ...   # calcolare la seconda soluzione reale
        }			       
        	   
      • Approssimazioni sin(x)≈x e tan(x)≈x: provare con R, con x=0.1 0.01, 0.001, etc.
      • Trasformare i comandi che graficano le potenze dei numeri complessi' usando un ciclo for() per le 16 possibilità della potenza.
 

 
Lezione 4, Gio 4 ottobre, 2h
Programmazione in R + questioni di Fisica (e di valutazioni di ordini di grandezze)
  • E = m c2   → Continuazione del problema della potenza emessa da Sole:
    • nell'ipotesi che tutta l'energia irraggiata derivi da trasformazione di massa in energia (attraverso fusioni nucleari), calcolare la massa 'bruciata' in un secondo all'interno del Sole.
    • calcolare anche la massa 'bruciata' in un giorno e in un anno.
    (Conti da fare preferibimente a mano, almeno per beccare l'ordine di grandezza — controllare poi con R, evitando invece l'uso delle calcolatrici, in modo da abituarsi ad usare R.)
  • Esprimere la potenza per unità di superficie sul Sole come una funzione che dipenda da
    • costante solare;
    • distanza Terra-Sole;
    • diametro angolare del Sole.
  • Problema dell'ipotetico foglio ripiegato 100 volte (soluzione rapida, con approssimazioni). Riportare il risultato in
    • metri,
    • anni luce
    • parsec
    (il parsec è legato concettualmente a problemi già incontrati: quello del Cupolone e quello della Minerva).
  • Dalle potenze di 2 (e di e) alle potenze di 10.
    • Cambiamento di base
    • “Potenza di 10: potenza di 2 × log10(2)”
      → ≈ "× 0.30"   [→ "× 1/3, - 10%"];
      • 2 ^ 10
      • 10 ^ (10*log10(2)) # 'esatto' (entro le approssimazioni del computer)
      • 10 ^ (10*0.3)         # approssimato (attenzione: si becca l'ordine di grandezza, non molto di più!)
    • “Potenza di 10: potenza di e × log10(e)”
      → ≈ "× 0.43"
      • e <- exp(1); e^10
      • 10 ^ (10*log10(e)) # 'esatto' (entro le approssimazioni del computer)
      • 10 ^ (10*0.43)       # approssimato (attenzione: si becca l'ordine di grandezza, non molto di più!)
  • Programmazione in R  

     
    Lezione 5, Mer 10 ottobre, 1h
    Programmazione in R + questioni di Fisica
    • Stasera non perdere il passaggio della Stazione Orbitale.
    • Controllo problemini sull'energia solare suggeriti nei giorni scorsi.
    • Curiosa interpretazione di c2, alla luce della famosa E = m c2:
      • Energia per unità di massa [0.9×1017 J/kg].
    • Nuovo problema:
      temperatura del Sole a partire dalla potenza per unità di superficie (che ci siamo già ricavata): legge di Stefan-Boltzmann.

      Nota: Si ricorda di fare i conti sia con carta e penna (e/o a mente), per avere rapidamente l'ordine di grandezza, che con la calcolatrice (senza esagerare con le cifre da riportare — due o tre cifre significative vanno in genere bene) o meglio ancora con R (stesso discorso vale per le cifre) al fine di verificare il risultato (e magari imparare che nel conto fatto a mano il risultato è generalmente corretto, benché approssimato, mentre in quello fatto con 'calcolatori' ci si può sbagliare alla grande!, ovvero mancare completamente l'ordine di grandezza).

    • Ripassarsi la fisica dei minimalia ricordati alla prima lezione: li useremo domani!
    • Esempio di sessione di R sotto Windows
      • Creazione directory su cui lavorare (o comunque 'posizionarsi' nella directory dove si intende lavorare, continuando ad esempio la sessione precedente). È raccomandabile di aprire diverse cartelle per diversi 'progetti', sia per tener separati gli script che per riprendere una 'sessione' interrotta.
      • Apertura di R e posizionamento (tramite le opzioni: File, etc. ) nella directory di lavoro.
      • Creazione/modifica/salvataggio di uno script mediante l'editor incluso in R (l'installazione di Linux non ha tale possibilità, e credo nemmeno quella del Mac).
      • Idem con NotePad++ e Emacs (precedentemente installati).
    • R 'da capo' con dettagli sulla sintassi Altro su in particolare le tabelle di verità di 'AND', 'OR' e 'XOR' (att: non corrispondono ai simboli usati in R).
      Vedi anche
     

     
    Lezione 6, Gio 11 ottobre, 2h
    Programmazione in R + questioni di Fisica
    • Per quanto fatto su R:
      • Rhistory_11ott2018.R
      • media.R (solo versione 'finale' — esercitarsi a ripartire da zero, con gli step intermedi.)
      • Curiosità di R scoperta a lezione: la variabile visualizzata con print() nella funzione viene rimandata indietro come se fosse in un return().
        In effetti, print() assegna pure la variabile 'printata', ad esempio
        > a <- print("ciao")
        > a
      • Successione di Fibonacci, per chi non l'ha ancora calcolata:
        • per 'settare' i primi due elementi si può usare, a piacere, uno di questi due comandi:
          > n <- c(1,1)
          > n <- rep(1,2)
        poi basta usare un ciclo for() per gli altri termini.
        (E non dimenticate il problema aperto, inter nos, di calcolare il "milionesimo termine")
    • Questioni di Fisica (si ricorda che questo è un Laboratorio di calcolo e non un Laboratorio di programmazione, né tanto meno un corso accelerato di Informatica).
      • Temperatura (della superficie) del Sole: calcolare sia approssimaticamente che con R, e ovviamente confrontare con Wikipedia.
        (Si ricorda che siamo partiti dalla costante solare: ovviamente è consigliabile double check i risultati lungo la catena di ragionamento, per non propagare errori).
        E la storia non è ancora finita!.
      • Caratteristiche delle lampadine: Watt, lumen e temperatura colore (parametro legato a quanto visto nel punto precedente).
      • Cannone di Newton per spiegare che le mele che cadono e la Luna che gira sono due aspetti dello stesso fenomeno!
      • Moto uniformemente accelerato, con accelerazione a = g (la famosa 9.8 m/s2):
        • Sulle unità di misura di g:
          • 'meglio', nel senso di più immediata interpretazione, (9.8 m/s)/s o addirittura (35 km/h)/s — verificare il valore numerico).
          • Quando poi g entra nella famosa F=mg è meglio ancora 9.8 N/kg, in quanto rappresenta un campo.
        • Se un corpo parte (cade) da fermo, la velocità varierà linearmente con il tempo: v = g t;
        • la velocità media fra t=0 e il genrico t sarà quindi vm = g t / 2;
        • lo spazio percorso in t sarà quindi pari a s = vm t, ottenendo così la famosa s = (1/2) g t2.
      • Fisica dei lanci orizzontali (ignorando resistenza dell'aria e altre forze a parte quella di gravità, pari a mg diretta verso il basso), con esperimento in aula:
        • lo spazio di caduta lungo la verticale dipende solo dal tempo e non dalla velocità iniziale orizzontale;
        • la velocità orizzontale non cambia in quanto non c'è accelerazione orizzontale, in quanto mancano forze con componente orizzontalli (nella nostra approssimazione).
        • Dati dell'esperimento in aula:
          • h = 90 cm;
          • d1 = 96 cm;
          • d2 = 213 cm.
        • Da ricavarsi, per i due casi:
          • tempo impiegato dalla moneta a cadere (ovvero da quando si stacca dal tavolo a quando tocca il pavimento);
          • velocità orizzontale della moneta;
          • componente verticale della velocità 'finale' (un istante prima dell'impatto con il pavimento);
          • modulo della velocità 'finale'.
      • Dall'espressione della forza di gravità di Newton a quella della accelerazione di caduta (con reminder dei diversi concetti di massa gravitazionale e massa gravitazionale):
        • variazione dell'accelerazione di caduta, in particolare gISS della stazione orbitale ISS, nell'ipotesi di orbita circolare all'altezza h = 400 km rispetto alla superficie terrestre:
          • gISS = G MT/(RT + h)2 = G MT / [RT2(1+h/RT)2] = g / (1+h/RT)2
      • Disquisizione su importanti approssimazioni, valide trascurando ε2, quando ε << 1:
        • (1 ± ε)2 ≈ 1 ± 2ε
        • sqrt(1 ± ε) ≈ 1 ± ε/2
        • sqrt(1 - ε2) ≈ 1 - ε2/2,     da cui cos(ε) ≈ 1 - ε2/2
        • 1/(1 ± ε) ≈ 1 ∓ ε
        Provare con R, per epsilon = 10^c(-5:-1), ad esempio si confrontino i risultati dei seguenti comandi:
        • 1/(1 + 10^c(-5:-1))    # esatta
        • (1 - 10^c(-5:-1))        # approssimata
      • Applicazione all'ISS;
        • gISS ≈ g × [1 - 2 (h/RT)]
        Ricavarsi:
        • gISS;
        • il tempo di caduta nel primo secondo della stazione orbitale (e dei suoi occupanti).
      • Dalla Terra alla Luna:
        • ripartendo dalla formula generale, e riscalando opportunamente g con le distanze (proibito usare direttamente G e MT !) su calcoli gL;
        • si calcoli anche lo spazio di caduta della Luna verso la Terra nel primo secondo.
      • Usando il modello di Feynman illustrato a lezione (vedi figura sul sito del corso), si trovi
        • formula che dà la velocità di oggetto in ipotetica orbita circolare radente alla superficie terrestre in funzione di g e RT (di nuovo, proibito usare direttamente G e MT!);
        • la velocità della stazione orbitale ISS e da questa il tempo impiegato a compiere un giro intorno alla Terra.
     

     
    Lezione 7, Mer 17 ottobre, 1h
    Programmazione in R + questioni di Fisica
    • Conticini di riscaldamento (da fare a mente!)
      • 1/0.94 ≈ .... ;
      • (1.03)^2 ≈ .... ;
      • cos(0.1) ≈ .... ;
      • π × 44 × 26 ≈ .... .
    • Soluzione à la Feynman della velocità orbitale. Generalizzazione al moto circolare uniforme.
    • Esempio di successione e serie analizzata con R.
    • Ancora Fibonacci; andamenti esponenziali.
      • Plot della sequenza di Fibonacci su carta semilog (ordinate su scala logaritmica, opzione log='y');
      • Confronto con 2k, ek e 10k.
      • Ansatz: per grandi valori k la successione di Fibonacci ha un andamento α φk, con φ da determinare:
        • 'empiricamente', calcolando il rapporto fra il k-imo termine e il termine k-1 per k 'grande';
        • analiticamente, imponendo la condizione che definisce i termini della successione (si ottiene un'equazione di secondo grado in φ).
      • Rette per due punti, con varianti proposte (vedi problemini di lunedì scorso).

    Materiale di supporto

    Esercizi proposti

    • Valutare φ "di Fibonacci" nei modi descritti sopra;
    • Completare i problemini di lunedì scorso, in particolare l'analisi del lanci delle monete e il tracciamento di rette ottenute cliccando sul plot (funzione locator()).
    • Scrivere una funzione che tracci un cerchio definito dal centro e dal raggio.
    • Migliorare la funzione del cerchio, 'leggendo' due punti sul plot, come visto a lezione (il primo dà il centro; il secondo è a distanza r da esso — si ricorda che un cerchio nel piano è definito da tre punti, ma con questa condizione ne bastano due!).
    • Script con dei comandi per leggere dei parametri direttamente dalla console di R:
      • esempio_readline.R
      • Funzione sample(): provare a ripetere più volte
        • sample(1:6)
        • sample(1:6)[1]
        (il secondo comando può essere usato per giocare a dadi, mentre con sample(1:90)[1:5] si possono fare estrazioni del lotto)
      • Funzione rainbow() per un vettore di codici colore ordinati secondo l'arcobaleno, ad esempio rainbow(7)
        [E, ovviamente, se si 'dà in pasto' il vettore risultante a sample() si possono generare colori 'a caso']
     

     
    Lezione 8, Gio 18 ottobre, 2h
    Questioni di Fisica. Andamenti esponenziali e uso di scale semilog
    • Cifre significative (qualitativamente — per la trattazione quantitativa occorre attendere di conoscere la teoria delle incertezze di misura):
      • cifre significative e cifre decimali sono due cose diverse (queste ultime dipendono dall'unità di misura);
      • regolette pratiche per moltiplicazioni/divisioni e addizioni/sottrazioni.
        Ecco dei comandi R che fanno capire come il risultato è cambiato dall'incertezza dei valori di partenza (qui presa di una unità sull'ultima cifra):
        f1 = 37.2645 + c(-1, 0, +1)*1e-4
        f2 = 2.7 + c(-0.1, 0, +0.1)
        outer(f1, f2)
        outer(f1, f2, '/')
        outer(f1, f2, '+')
        outer(f1, f2, '-')
        (Al centro delle matrici risultanti si ottengono i valori 'centrali', mentre gli altri elementi danno un'idea dei valori possibili, e quindi si capisce quali cifre del risultato siano 'significative' e quali semplicemente 'rumore' che non porta informazioni.)
  • Problemino di crescita e decrescita della borsa valori della stessa percentuale, ad es. oggi aumenta del 5% e domani diminuisce del 5%: non si lo stesso valore ma un po' di meno: (1+ε)(1-ε) = 1-ε2 (ma se la cosa si ripete n giorni alla fine si ottiene ≈ 1 - n ε2... finché non si è annullato il capitale...)
  • 'Divagazioni' su gravità e leggi della meccanica
    • Gravità, moto circolare, accelerazione centripeta, etc. (a partire dalla velocitò orbitale ricavata alla Feynman).
    • Accelerazione della Luna e della ISS scalando opportunamente "g sulla Terra" (e sempre in ipotesi di orbite circolari):
      • caduta nel primo secondo di ISS e astronauti (gli astronauti sulla ISS non sono in assenza di gravità, bensì in assenza di pavimento!);
      • caduta nel primo secondo della Luna verso la Terra.
    • E una volta che si è capito il trucco si può calcolare, da distanza Terra-Sole e dalla velocità orbitale della Terra:
      • l'accelerazione centripeta della Terra della Terra verso il Sole;
      • di quanto cade la Terra verso il Sole nel primo secondo.
    • Dipendenza di velocità, periodo e velocità angolare dalla distanza.
    • Derivazione della terza legge di Keplero per orbite circolari (semplice consequenza dell'esercizio precedente).
    • Introduzione all'analisi dimensionale (dipendenza della velocità orbitale da g e RT nell'ipotesi che essa sia data da una forma monomia dipendente solo da g e da RT).
    • Chiarimenti sul ben noto "terzo principio" (azione-reazione): da non confondere con la risultante nulla di due forze esterne sullo stesso corpo (l'esempio del gessetto sul tavolo aiuta).
    • Commento su cosa rappresenta "R" (o "d") nella formula della forza di gravità fra due corpi:
      • la legge vale per 'punti materiali', ovvero corpi le cui dimensioni sono trascurabili rispetto alle distanze in gioco;
      • essa vale fra punto e sfera, e fra sfera e sfera, se le sfere sono omogenee (o almeno siano omogenee radialmente, evvero possono essere viste come composte da tanti gusci concentrici omogenei, anche se ciascuno con densità diversa dall'altro).
  • Andamenti esponenziali (eα x, 10α x, etc.) vs leggi di potenza (x2, x1/2, etc.) — attenti a non confondere!
  • Ancora sulla linearizzazione di andamenti esponenziali mediante scala della ascisse logaritmica:
    • dipendenza della 'pendenza' dalla base dell'esponente e dal fattore che all'esponente moltiplica la variabile di interesse;
    • differenza fra scala logaritmica e ascissa del valore numerico.
    (Vedi esempi in R in Rhistory_18ott2018.R.)

    Materiale e problemi

    • Rhistory_18ott2018.R
    • dati.R:
      • plottare le y in funzione di x su due plot diversi usando l'opzione log='y';
      • in ciascun caso, avendo ipotizzato un andamento del tipo y = a eb x, si determinino empiricamente a e b;
      • si riportino le due serie di y sulla carta semilog distribuita a lezione (essendo tale carta 'preziosa', ci si scriva sopra a matita leggera per poter cancellare i punti in modo pulito in caso di errori o di dover graficare serie che vanno su diversi ordini di grandezza).
    • Ossatura dello script 'finale' per la risoluzioni di equazioni, comprendente anche l'input da tastiera dei parametri:
    • Ossature degli script che fanno rette e cerchi cliccando (lezione di ieri): (Da completare seguendo i commenti inclusi negli script. Insomma, la programmazione è un conto, ma la geometria la dovete sapere!)
     

     
    Lezione 9, Mer 24 ottobre, 1 h
    Problemi aperti. Introduzione al linguaggio C
     
    • Esercizio di riscaldamento sul calcolo dimensionale: ipotizzando che il periodo di rotazione di un oggetto in orbita circolare dipenda solo dall'accelerazione centripeta dal raggio, e che la legge sia 'monomia', trovare la relazione che lega T ad ac e R, a parte un fattore di proporzionalità.
    • Modi di calcolare il fattoriale; funzioni recursive (vedi problemini del lunedì).
      Calcolo recursivo del fattoriale: fatt_rec.R
    • [I problemi di geometria analitica con locator() son lasciati all'iniziativa personale: chi ha ancora difficoltà può venire a chiedere.]
    • Analisi di dati.R:
      • linearizzazione mediante carta 'semilog';
      • valutazione empirica dei coefficienti dell'andamento esponenziale assumendo una certa base (la base non ha un significato assoluto, a meno che non sia naturale per un dato problema):
        • Usando la base e gli andamenti saranno del tipo y = k em x, ovvero (usando, a scanso di equivoci, il simbolo 'ln' per il logaritmi naturali)
          ln(y) = ln(k) + m x.
        • Quindi due punti determinano univocamente m e ln(k), da cui k.
          Ad esempio, m = [log(y2) - log(y1)] / [x2 - x1] = log(y2/y1)/ (x2 - x1)
          Il resto viene lasciato come esercizio (per chi non l'avesse ancora fatto).
      • Soluzione in R (vedi Rhistory)
       
       
    • Introduzione al linguaggio C e all'uso del compilatore online GDB.
      • Primo programma ("Hello World" — quello che si trova giù bell'e pronto, da complilare , linkare ed eseguire cliccando su Run).
        Raccomandazione: dopo che un programma è stato eseguito senza errori si raccomanda di scaricarselo su apposita directory con nome appropriato. Ad esempio in questo caso
      • Variante italiana (con un po' di aritmetica): Per compilare/linkare/eseguire il programma, cancellare quello che si trova sulla pagina di onlinegdb.com e scriverci a mano il nuovo programma (certo si può anche usare un copia/incolla, ma è altamente sconsigliato, perché bisogna anche acquisire una certa manualità a scrivere i programmi, come chiudere al volo le parentesi aperte, non dimenticare i punti e virgola alla fine di ciascuna istruzione, familiarizzarsi cone le key words, etc.).
      • Esempio di ciclo for:
      • Esempio di calcolo di radice quadrata (notare il nuovo #include!) (Notare i diversi parametri all'interno di printf e cercare di capire cosa succede se si cambiano.)

    Storia odierna di R: Rhistory_24ott.R

    Lavoro raccomandato:

    • Provare il compilatore online con gli esempi sopra riportati — la risposta è spesso lenta, ma sempre meglio che dover andare in laboratorio per solo per esercitarsi sull'ABC del linguaggio C (e la lentezza di risposta del sito dovrebbe essere un incentivo a concentrarsi per non fare errori).
      Nota: ovviamente chi ha un compilatore C installato sul proprio PC/laptop lo può usare al posto di quello online.
      Si scoraggia invece chi non è molto pratico di installarsi compilatori, in quanto ci si può perdere non poco tempo e alla fine non si compensa quelle decine di secondi di attesa della compilazione online.
    • Provare a modificare gli esempi, farne altri, etc. ricordando che sbagliando si impara (in quanto sbaglia solo chi prova a fare qualcosa!).
    • In particolare, si dovrebbe essere in grado di tradurre in C lo script R che risolve l'equazione di secondo grando, ma senza la possibilità di usare variabili complesse e senza grafica.
     

     
    Lezione 10, Gio 25 ottobre, 2 h
    Di R, di C e di Fisica
     
    • Fisica dei lanci, nell'ipotesi di sola forza peso (trascuriamo la resistenza dell'aria): dal caso orizzontale al lancio verticale verso l'alto (la caduta verso il basso è il caso particolare di veocità iniziale nulla):
      • vy in funzione del tempo;
      • come non varia l'accelerazione (e perché) da quando l'oggetto si stacca dalla mano a quando viene ripreso: coloro che pensavano che non fosse costante si ravvedano!.
      Il lancio verso l'alto, fino alla posizione di arresto, può essere visto come un moto 'frenato' (accelerazione di verso opposto alla velocità), da cui il problema che segue.
    • Esercizio di riscaldamento analisi dimensionale: ipotizzando che lo spazio di frenata in un moto uniformemente decelerato dipenda soltanto dalla velocità iniziale e dalla modulo dell'accelerazione, e che la legge sia 'monomia',
      • trovare la relazione che lega s ad |a| e a v0, a parte un fattore di proporzionalità;
      • in particolare dire di quanto varia lo spazio di frenata se v0 raddoppia.
    • Ancora sugli andamenti esponenziali linearizzati quando l'ordinata viene rappresentata in scala logaritmica (opzione log='y').
      • Ovviamente la funzione abline() non ci dà una retta su tale plot, in quanto essa traccia (nella convenzione di R) l'andamento lineare y = a + b x .
      • Scriversi la funzione labline() tale che, dati m e k> dell'andamento esponenziale (vedi lezione precedente), grafichi tale andamento attraverso la funzione points() (la 'l' iniziale sta per log).
        Note:
        • la chiamata a labline() deve essere del tipo labline(k, m, ...) in modo da poter passare a points(), mediante '...', i parametri grafici della retta.
        • per fare la funzione sufficientemente generale, a cui non bisogna fornire il minimo e il massimo della x, conviene prendere questi valori direttamente dal plot mediante par('usr') (provare).
          In pratica, le x da usare in labline() possono essere ottenute, ad esempio, mediante
              x <- seq(par('usr')[1], par('usr')[2], len=100).
    • Ancora sui lanci orizzontali della moneta (lezione 11 ott).
      Lavoro proposto (illustrato in aula):
      1. calcolare l'angolo di impatto sul pavimento dagli ultimi punti della traiettoria;
      2. graficare, sullo stesso plot, vx(t), vy(t) e v(t), ovvero delle componenti della velocità e del suo modulo;
      3. calcolare di nuovo l'angolo di impatto da vx(t) e vy(t) "un istante prima" dell'impatto;
      4. calcolare lo spazio percorso dalla moneta durante il lancio (da non confondere con la distanza fra il punto di partenza e il punto di arrivo!): si può fare in un paio di modi: provare!
    • vettori, matrici e liste in R.
    • Sys.time() per leggere il tempo. Ad esempio.
      • ( t1 = Sys.time() )
      • ( t2 = Sys.time() )
      • ( dt = t2 - t1 )
      • as.numeric(t2 - t1)
      Suggerimento: insieme a opportuno messaggio (con text()) o figura su plot, seguita da una 'pausa di surata aleatoria' [ad es. Sys.sleep( runif(1,1,2) )], queste istruzioni possono essere usate per creare un gioco basato sui tempi di riflesso, lasciato alla fantasia (ad esempio il segnale di VIA può essere dato da un cerchio e si può assegnare un punteggio che dipende dal tempo impiegato a cliccarci sopra e dalla distanza dal centro del punto su cui si è cliccato).

      Storia odierna: Rhistory_25ott.R  

       
    • Riprendiamo C, ricominciando da... dummy.c e guidati da un tutorial di YouTube (ottimo anche per familiarizzarsi con l'inglese tecnico, grazie a pronuncia chiara e sottotitoli)
          → Per una guida al tutorial, con programmini ad hoc, vedi qui.
    • Un altro ottimo tutorial con esempi eseguibili(!) è disponibile presso il sito del compilatore online GDB:
           Learn C Programming
         In particolare:

    Addendum

    • Altro interessante compilatore online basato su gcc (!!).
      Note sull'uso:
      • come nel caso del compilatore online GDB, si raccomanda di riscriversi i programmi a mano, evitando l'uso di copia/incolla — sì, nella programmazione, come si dice, "la pigrizia è una virtù", ma lo è anche saper muovere velocemente le dita (e poco il mouse);
      • per compilare/linkare/eseguire cliccare sul bottoncino Execute;
      • se si prova il programma che fa la radice quadrata mostrato a lezione ('radice_quadrata.c) si riceverà un messaggio di errore, in quanto non è sufficiente l'header <math.h>, ma bisogna anche aggiungere in fondo al comando di gcc l'opzione '-lm' che serve a linkare anche la libreria matematica.
        → nella pagina web del compilatore
        • andare con il mouse su Project e cliccare sull'opzione Compile options;
        • nella finestra che si apre aggiungere al Compilation command l'opzione -lm separata da uno spazio in modo che l'intero comando sia
              gcc -o main *.c -lm
          ['main' è il nome che questa interfaccia a gcc dà all'eseguibile, come si nota nell'execution command; '*.c' sta per qualsiasi file che termina con '.c']
        • cliccare quindi su Update e poi uscire dalla finestrella.
      Infine: se si dovesse pasticciare con i comandi di esecuzione, o con altre opzioni, per resettare tutto andare con il mouse su Project e cliccare sull'opzione New project, rispondere positivamente a 'Leave Project', quindi rientrare.
     

     
    Lezione 11, Mer 31 ottobre, 1 h
    Soluzione numerica di problemi fisici e matematica
     
    • Molla (con dimostrazione in aula):
      • la forza di richiamo aumenta con lo spostamento dal punto di equilibrio F = -k\,x, essendo x=0 il punto di equilbrio;
      • se teniamo l'oggetto sospeso fermo nella posizione xM (ove 'M' sta per allungamento massimo) e lo lasciamo all'istante t=0
        • la sola forza sarà F=-k xM, la quale causerà una accelerazione F/m = -(k/m) xM;
        • l'accelerazione provocherà una variazione di velocità e uno spostamento;
        • nella nuova posizione avremo una forza di valore diverso a quella iniziale (minore in modulo), la quale provocherà una diversa variazione di velocità (minore in modulo) e un diverso spostamento;
        • la cosa andrebbere avanti virtualmente all' 'infinito' se non ci fossero forze di attrito che alla fine arrestano il moto.
      • Vedremo in seguito come risolvere 'numericamente' il problema, per ora osserviamo empiricamente che (cosa ben nota) si hanno oscillazioni e che la durata di ciascuna oscillazione aumenta all'aumentare della massa sospesa.
      • Dipendenza del periodo di oscillazione T da m e k con argomenti dimensionali:
        • il periodo ha le dimensioni di un tempo: dim T = T (si usa anche [T] = [T], ove il 'T' a sinistra sta per periodo e quello a destra sta per la grandezza tempo.
        • la costante k ha dimensione legate a quelle delle forza e della lunghezza: dim k = dim F / dim x (con 'L' che sta per lunghezza), ove le dimensioni della forza si ricava dalla seconda legge di Newton: dim F = dim m × dim a, ovvero dim F = M L T -2; ne segue che dim k = L T-2.
        • quindi l'equazione dimensionale di interesse è T = (L T -2)α (M)β, da cui si ottengono α e β e quindi la dipendenza del periodo dalla massa e dalla costante elastica k della molla.
        Un modo equiivalente e che per qualcuno potrà risultare più intuitivo è di usare, invece delle dimensioni, le unità di misura del Sistema Internazionale (SI).
        • U[F] = N;   U[m] = kg;   U[T]= s;   etc.
        • Abbiamo quindi che U[k] = U[F] / U[x] = N / m = kg m/s2 / m = kg s-2.
        • L'equazione dimensionale di interesse diventa quindi
                U[T] = (U(k))α (U(m))β,  ovvero
                s = (kg s-2)α kg β .
      • Esercizio proposto: mostrare con argomenti dimensionali che il periodo non può dipendere da g (nella nostra ipotesi di forma funzionale monomia — di questo risultato daremo anche una motivazione dettagliata).
    • Illustrazione degli scheletri dei numerici proposti lunedì su come calcolare con un programma in C la lunghezza percorsa da un oggetto lungo la traiettoria.
    • Calcolo dell'area di un triangolo e di un semicerchio sommando le aree delle 'striscioline'.
      Per il primo caso si dà l'evoluzione del programma a mano a mano che viene scritto (si raccomanda ancora una volta di non scrivere l'intero programma e poi provare a compilarlo, bensì di compilarlo ed eseguirlo a mano a mano che lo si scrive, con stampe di controllo da commentare successivamente e toglierle eventualmente quando ci si è convinti che tutto funziona):   Nota: in questo programma la cosa più macchinosa è la funzione che, dato un valore dell'ascissa, dà un valore dell'ordinata della 'funzione triangolare' (ovviamente poteva esser fatta anche in altri modi, questa è volutamente didascalica).
       
      Del secondo, in cui la funzione è molto più semplice, si dà solo l'ossatura Note su quest'ultimo programma:
      • il numero di intervalli viene chiesto dal programma stesso mediante la funzione scanf():
        • il motivo per cui l'argomento ha '&' davanti al nome della variabile verrà spiegato a lezione; per ora si noti come, contrariamente alle altre funzioni viste finora, &N non viene passato a scanf(), bensì viene restituito dalla funzione.
        • nel caso si abbiano problemi con i compilatori online a far accettare dal programma il numero di punti si assegni un valore ad N all'interno del programma.
      • Si noti come, contrariamente a R, il C non ha π predefinito. Nel programma viene usato il trucco di valutarlo mediante una funzione trigonometrica inversa.
      • È infine molto interessante la stima numerica di π ottenuta dalla stima numerica dell'area.
     

    Lezione 12, Mer 7 novembre, 1 h
    Valutazione numerica e a 'campionamento' di pi greco. Vettori in C, e argomenti correlati
     
    • Esercizi di riscaldamento
      • a mente e al volo: log2256
      • a mente e al volo: ordine di grandezza del 10000-imo termine della successione di Fibonacci
        (si ricorda che, espresso in R, log10( (1+sqrt(5))/2 ) = 0.2089876 — che c'entra? c'entra, c'entra...)
    • Problemini del lunedì risolti con considerazioni dimensionali (periodo del pendolo e velocità massima di oscillazione della molla).
    • Area e arco di un quarto di cerchio in R, con valutazione numerica di pi greco.
    • Area e 'lunghezza di linea' di una funzione (continua) qualsiasi .
      • modificare lo script precedente cambianfo fun()
    • Ancora sull'arco di cerchio: valutazione dell'area e consequente stima pi greco mediante campionamento.
    • Estensione a una funzione continua continua 'qualsiasi' definita in un intervallo finito (pensarci su),
      in particolare provare a stimare per campionamento l'area sotto
    • Implementazioni in C degli algoritmi precedenti:
     
    Lezione 13, Gio 8 novembre, 2 h
    Dettagli sul linguaggio C. Plot e carte 'log-log'.
    • Problemino di riscaldamento (su cui meditare — ci ritorneremo):
      1. trovare l'espressione della forza F(r) (dovuta alla sola forza di gravità della Terra) che agisce su un corpo in un ipotetico pozzo che passa per il centro della Terra, ovve r è la distanza dal centro della Terra;
      2. (facile continuazione) trovare l'espressione dell'accelerazione a(r).
      (Nota: si cerchi di esprimere i risultati in una forma semplice che eviti l'uso diretto di G e di MT.)
    • Problema 'ricreativo' per l'intervallo: esercizio su analisi dimensionale moti planetari con orbite circolari.
    • Riprendiamo gli esempi sui vettori (“array unidimensionali”) illustrati velocemente la lezione scorsa.
      • primo esempio, con sola dichiarazione o dichiarazione e assegnazione:
            vettori_01.c
      • il contenuto iniziale degli elementi di un vettore non è zero: dipende da dove l'eseguibile è caricato nella RAM del computer:
            vettori_02.c
        (sui diversi modi con i quali gli elementi vengono 'stampati' torneremo poi.)
      • C permette di 'sconfinare' dallo spazione dichiarato per vettore, con effetti non desiderati:
            vettori_03.c
      • In questo esempio si mostra come sconfinando da un vettore si va a scrivere in un altro (sola lettura)
            vettori_04.c
      • Caso più serio di confinamento con scrittura!
            vettori_05.c
      • Caso di sconfinamento ESAGERATO che fa 'crash-are' il programma:
            vettori_06.c
        Messaggio di errore:
        *** stack smashing detected ***: terminated
        Aborted (core dumped)
        [Nota: lo stesso succede se si sconfina da v[4] anche di poco (vedi vettori_05a.c, variante di vettori_05.c)]
    • Osservazione sulla lunghezza dei vettori:
          vettori_07.c
    • Osservazione sulla dipendenza dell'eseguibile dalla dimensione di un vettore.
      Sorgente (→ modificare 'n=100;' e ricompilare):
          vettori_08.c Ecco cosa si ottiene con ls -l vettori_08* in alcuni casi
      • n=100:
        -rwxr-xr-x 1 giulio giulio 8360 Nov  7 20:41 vettori_08
        -rw-r--r-- 1 giulio giulio  507 Nov  7 20:41 vettori_08.c 
        	    
      • n=1000000:
        -rwxr-xr-x 1 giulio giulio 8360 Nov  7 20:57 vettori_08
        -rw-r--r-- 1 giulio giulio  511 Nov  7 20:57 vettori_08.c	      
        	    
        → cambia solo il sorgente a causa dei 4 caratteri aggiunti!
    • Cambia invece lo spazio che l'eseguibile occupa nella RAM mentre è in esecuzione.
      Sorgente, con istruzioni all'interno (→ modificare 'n=100;', ricompilare e rieseguire):
          vettori_09.c
      • n=100: 132 kB;
      • n=1000: 132 kB;
      • n=10000: 132 kB;
      • n=100000: 404 kB;
      • n=1000000: 3916 kB;
      • n=2000000: 7828 kB.
    • A proposito di int e unsigned (e variabili di tipo char):
    • Ma una variabile char può contenere anche... un carattere, su cui si possono fare addirittura delle operazioni: Ed ecco un programa per ottenere il codice ASCII di un carattere (da programiz.com):  
    • Ancora sui vettori vettori:
      • Come passare un vettore a una funzione (la quale fa la media e i valori sono voti casuali):
            media_voti.c
      Ed ecco un esempio per capire il significato di #define (non solo un valore numerico!):  
    • Approssimazione di sin(x) ≈ x e plot 'log-log'
      • Rhistory_8nov2018.R
      • Esercizi proposti
        1. monstrare, in analogia con quanto visto per le scale logaritmiche sull'ordinata, che i plot con scale 'log-log' (o 'doppiolog') linearizzano andamenti esponenziali.
        2. Con riferimento al plot di y = x - sin(x) in funzione di x (vedi Rhistory), ricavarsi empiricamente la legge di potenza che lega x e y.
        3. Con riferimento al plot di y = (x - sin(x)) / sin(x) in funzione di x (vedi Rhistory), ricavarsi empiricamente la legge di potenza che lega x e y.
        4. Dati i seguenti vettori x e y, dire se i loro valori sono legati da una legge esponenziale o di legge di potenza e ricavarsi i coefficienti.
          1. x=c(0.100, 5.08, 10.1, 15.0, 20.0), y=c(9.51, 0.79, 0.068, 0.0055, 0.00045);
          2. x=c(0.100, 5.08, 10.1, 15.0, 20.0), y=c(0.158, 1.13, 1.59, 1.94, 2.24);
          3. x=c(0.100, 5.08, 10.1, 15.0, 20.0), y=c(15.8, 2.22, 1.57, 1.29, 1.12).
        5. In analogia alla funzione labline() fatta per graficare 'rette' su plot in scala 'semilog', crearsi l'analoga funzione llabline() per i plot con scale log-log.
    • Ecco, per finire, il programma di pi greco ottenuto per campionamento nel quale la sequenza del generatore di numeri casuali viene inizializzata usando il tempo macchina nel computer (come fatto nel programma delle medie dei voti)
     
    Lezione 14, Mer 14 novembre, 1 h
    Linguaggio C e algoritmi (+ questioni di Fisica e Matematica)  
     

       
    • Alcuni plot 'curiosi' per chi ha fatto il programma in R sulla molla con smorzamento.
      Dopo aver fatto il plot, eseguire il comando
      • plot(t, abs(x), log='y')
      → a parte i dettagli complicati, concentrarsi sull'andamento dei massimi locali in funzione del tempo.
      Provare anche ad eseguire
      • n=200;   plot(t[1:n], k*x[1:n]^2/2 + m*v[1:n]^2/2, ylim=c(0, 0.07), ty='l')
      eventualmente cambiando n (oltre che i parametri della simulazione che probabilmente vorranno un nuovo range di ylim).
      In particolare, è interessante osservare come cambia il plot per beta → 0.
       
    • Sulla linearizzazione nei plot log-log di x-sin(x), tan(x)-x e di cos(x)-(1-x2/2): la 'magia' consiste nel fatto che il primo termine trascurato nell'approssimazione è una potenza di x con un coefficiente moltiplicativo (vedi ad esempio qui). Essi sono, nei tre casi,
      • x3/6;
      • x3/3;
      • x4/24,
      come è possibile 'verificare' empiricamente (entro i limiti delle approssimazioni numeriche) dai risultati dalle analisi grafiche degli andamenti sui plot con scale log-log.
       
    • Operazioni bit a bit:
        Prima di cominciare, ecco un programma per far capire che in C '&' e '&&' non sono la stessa cosa, così come '|' e '||':
            attenzione_AND_OR.c
      • Ed ecco una carrellata di esempi delle possibili operazioni su bit
            bits_ops.c
      (Per ricordarsi cosa fa lo XOR si vedano gli appunti della lezione del 10 ottobre, con dettagli su Rhistory_10ott2018.R )
    • Tornando al programma che calcola la media, vediamo cosa succede se non viene passata, come argomento della chiamata, la lunghezza del vettore:
    • Variabile statica all'interno di una funzione:
    • Introduzione ai puntatori
      • Nelle 'normali' chiamate a funzioni, se si modifica un argomento, non si ha nessun effetto sulla variabile nella function che l'ha invocata:
      • Ma questa operazione è fattibile se, invece di passare alla funzione il valore se ne passa il puntatore: [E adesso finalmente si capisce il ruolo dell'argomento di scanf()]
      • Come esercizio più divertente, usiamo i puntatori in una function che scambia il contenuto di due variabili Variante che mostra anche i due puntatori, sia nel main che nella funzione swap(): ... seguita da un virtuosismo per scambiare il contenuto di a e b passando alla funzione solo a: (solo per finalità didascalica, ma astenersi da fare cose del genere nei programmi!!)
      (*) Esempio non illustrato a lezione, la cui comprensione è lasciata come esercizio.
          Per capire cosa succede, bisogna analizzare, dal sorgente e dalle 'stampe',
      • il tipo di variabili in gioco;
      • le locazioni di memoria delle due variabili;
      • le operazioni effettuate all'interno di questa versione di swap().
      Attenzione: il funzionamento o meno di questo pericoloso 'virtuosismo' dipende da come le due variabili sono allocate nella memoria dal compilatore:
      • si guardino le locazioni di memoria stampate;
      • se la locazione di 'b' è inferiore a quella di 'a', vuol dire che sono state allocate in ordine inverso: in questo caso si modifichi la frunzione swap() o, brutalmente, le si invii 'b'.
    • Primo esempio di pipe sotto Linux:
      • echo 3 7 | ./test_swap_puntatori
      Per cominciare a capire il concetto (su cui ovviamente torneremo) eseguire i seguenti comandi (ovviamente i numeri 'passati' possono essere diversi, purché siano 2)
      • echo 3 7
      • echo 3 7 | ./test_swap_puntatori > risultato.txt
      • ls -ltr
      • cat risultato.txt
    • Altri esempi di uso di pipe
      • echo 3 7 | wc
      • echo 3 7 | ./test_swap_puntatori | wc
        (I tre numeri che si ottengono sono, nell'ordine: numero di righe, numero di parole e numero di caratteri.
      • echo 3 7 | ./test_swap_puntatori | wc > risultato_wc.txt
      • cat risultato_wc.txt
      • echo 3 7 | ./test_swap_puntatori | wc -l
      • echo 3 7 | ./test_swap_puntatori | wc -w
      • echo 3 7 | ./test_swap_puntatori | wc -c
      • echo 3 7 | ./test_swap_puntatori | wc -c -w
      • echo 3 7 | ./test_swap_puntatori | wc -cw
      • echo 3 7 | ./test_swap_puntatori | wc -wc
      • cat ./test_swap_puntatori.c | wc
      • wc ./test_swap_puntatori.c
      Per l'uso di wc si usi il comando
      • man wc
     
    Lezione 15, Gio 15 novembre, 1 h
    Linguaggio C e algoritmi (+ hit/miss)  
     
    • Estensione del calcolo di aree per campionamento (vedi qui):
           campionamento su un quadrato → campionamento su un rettangolo (del quale l'area è facilmente calcolabile)
      • la base del rettangolo è ovvio (fra xmin e xmax);
      • l'altezza del rettangolo è in principio arbitraria, purché sia maggiore del massimo della funzione fra xmin e xmax (ma, come si capisce bene, ci si perde in efficienza).
      [L'algoritmo ha il nome di hit or miss (colpito, 'sotto' la funzione, o mancato, 'sopra') Esempio (script lasciato per esercizio)  
       
      → implementazione in C lasciata come esercizio (a parte la parte grafica).
       
    • Alcuni dettagli sui puntatori:
      • puntatori_0.c
        [Notare, nei tre casi, la differenza numerica fra puntatori a variabili definite in successione (variabili short int, variabili int, variabili float e variabili double)]
      • Uso non corretto dei puntatori (errore tipico):
            puntatori_1.c
        → Segmentation fault (core dumped)
      • Va prima definita la variabile a cui puntare
             puntatori_2.c
        → Ok
      • Curiosa aritmetica dei puntatori: se, ad esempio, il puntatore pA vale 0x7ffdc3d53720, pA+1 non vale 0x7ffdc3d53721 !!
             aritmetica_puntatori.c
        [questa peculiarità era già stata usata nella 'roccambolesca'
        funzione swap() di test_swap_puntatori_a.c]
       
    • Vettori in argomenti di funzione: come modificarli dall'interno della funzione chiamata.
      • Invece è possibile modificare gli elementi di un vettore 'passato' come argomento (in realtà non si passa il vettore ma solo il puntatore e l'informazione che si tratta di un vettore, mentre, come abbiamo già visto, la lunghezza deve essere passata separatamente)
      • Esempio per mostrare come, dall'interno della funzione chiamata si può accedere agli elementi del vettore usando il suo nome come fosse un puntatore:
            vettore-puntatore.c
      • Ma l'uso del nome della funzione come fosse un puntatore è più generale, come mostrato nell'esempio seguente:
            vettore-puntatore_1.c
      • Come esempio di modifica degli elementi di un vettore dalla funzione chiamata scriviamo una function che inverte gli elementi di un vettore: Nota In questo algoritmo si 'spreca' molto spazio per il vettore temporaneo.
        Possibili soluzioni:
        • Usare una semplice variabile di appoggio:
          1. mettere l'ultimo elemento nella variabile di appoggio;
          2. far 'slittare' ('shift) di una posizione tutti gli elementi dal primo al penultimo (in modo da portarli, nell'ordine, dalla seconda all'ultima posizione);
          3. mettere il valore della variabile di appoggio nella prima posizione;
          4. ripetere dal punto 1. a 3., però questa volta partendo dal secondo elemento; etc. etc.
          (Tecnicamente si fa uso di due cicli for 'annidati', uno che gestisce l'elemento iniziale, l'altro che gestisce gli shift).
                 → Fare come esercizio
          [Per controllare che l'algoritmo funzioni si raccomanda di cominciare con un vettore di soli tre elementi, con valori tali da non poter essere confusi con gli indici.]
        • Allocare spazio temporaneo: → malloc() (forse ne parleremo)
       
    • Divide et impera, ovvero dividere il codice in pezzi.
      • Prima di affrontare l'argomento, rivediamo il programma dei numeri random del quale era stata data random_ossatura.c
        • Se si hanno molte funzioni (o se sono lunghe) conviene scriverle dopo il main. Ma in questo caso vanno dichiarati prima di main() i loro prototype: (Provare a vedere cosa succede se si commentano le dichiarazioni.)
      • Quando si hanno molte funzioni è conveniente raggrupparle in una 'libreria' personale, da compilare una volta per tutte (mediante apposito parametro di gcc che produce il 'codice oggetto') e da linkare in seguito. In questo caso, hanno definiti degli header personali da includere nel 'programma' che chiama la libreia personale.
        Ecco come dividiamo random_a.c in un file con le funzioni, un file con il main e l'header:
       
    • Ancora sui vettori: Problemi di ricerca di minimo e di massimo fra gli elementi di un vettore.
      • Come prototipo di strategia generale, ecco un esempio in R
      • Il divertimento è di scrivere delle funzioni in C, lasciate come esercizio. In particolare, scrivere
        • function vMin() che 'ritorna' il valore minimo;
        • function vMax() che 'ritorna' il valore massimo;
        • function indMin() che 'ritorna' l'indice del valore minimo;
        • function indMax() che 'ritorna' l'indice del valore massimo;
        • function findMin() che 'ritorna' sia il valore minimo che l'indice del vettore;
        • function findMax() che 'ritorna' sia il valore massimo che l'indice del vettore;
        Note: le funzioni devono trattare valori float; negli ultimi due casi ovviamente serve l'uso di almeno un puntatore; scrivere tutte le funzioni in un file minimax.c da compilare separatamente dal programma che le 'testa', come visto sopra (e, ovviamente, serve anche il file di header).

    Puntatori a ... puntatori

    Come esercizio provare ad andare a un livello superiore, ovvero puntatore→puntatore→puntatore→variabile ...  

    Intervento speciale di Francesco Safai Tehrani

    • Glossario dei termini legati ai puntatori:
    • Primo esempio di uso di puntatori, uso di indirizzi e dereferenze per accedere ai valori puntati ed eventualmente modificarli:
    • Nel caso degli array ('vettori'), possiamo semplificare le operazioni ricordando che il nome dell'array stesso è un puntatore al primo elemento dell'array (vedi sopra vettore-puntatore.c e vettore-puntatore_1.c). Per accedere agli elementi successivi, possiamo usare l'usuale notazione con le parentesi quadre o l'aritmetica dei puntatori, dereferenziando il puntatore incrementato di i per accedere all'i-esimo elemento:
    • Il tipo void viene utilizzato per indicare una funzione che non ritorna valori, ma è anche un modo per accedere ad un blocco di memoria in maniera non allineata (vedi il glossario per la definizione di allineamento).
      Trasformando un puntatore in un puntatore a void*, possiamo vedere i singoli byte che costituiscono, ad esempio, un intero, o nel caso di questo programma, un array di interi:
    • Per capire meglio come interagire con un programma in C, prendiamo degli argomenti dalla linea di comando del programma e stampiamoli, andando anche a studiarne la struttura interna. Vediamo subito come le stringhe in C siano semplicemente sequenze di char terminate da uno 0 (non il carattere zero, ma il numero zero!): (ci ritornerete a lezione).
    • Infine, per vedere in dettaglio la correlazione tra tipo del puntatore ed accesso alla memoria, definiamo un blocco di memoria tramite un array di tipo void*, che contiene otto byte, con valori crescenti da uno ad otto. A questo punto cambiamo il tipo del puntatore, tramite un cast, da void* a short*, int* e long*, ed accediamo al contenuto dell'array in questo modo, scoprendo che il C “cattura” ogni volta un numero diverso di byte, a seconda del sizeof del tipo del puntatore: (vedi anche, sopra, aritmetica_puntatori.c).
     
    Lezione 16, Mer 21 novembre, 1 h
    Ancora dettagli del C. Matrici in R  
     
    • Introduzione ai problemi di ordinamento ('sorting'): provare a scrivere una function in C che implementi l'algoritmo escogitato (suggerimento: scrivere prima la function in R e poi cercare di 'tradurla' in C).
    • Pozzo per il centro della Terra (lezione scorsa):
      • gusci sferici di densità omogenea non esercitano alcuna forza su un oggetto al suo interno (mentre per oggetti all'esterno "si comportano come sfere");
      • quindi, siccome conta solo la forza dovuta alla sfera di raggio r, F(r) ∝ - M(r)/r2 ∝ - r;
      • ricordando inoltre che F(r=RT) = -m g, il gioco è fatto... (il resto è lasciato come esercizio).
      • infine, una volta capito da quali variabili "facilmente memorizzzabili" dipende il moto, ricavarsi, mediante analisi dimensionale, la dipendenza del periodo da esse.
      Problemino su cui cominciare a pensare: analogia fra moto di un oggetto sospeso a una molla e quello di moto lasciato cadere nell'ipotetico pozzo (ovviamente senza resistenza dell'aria, etc.).
       
    • Ancora dettagli del linguaggio C (anche alla luce dell'intervento speciale di F. Safai Tehrani)
      • main(int argc, char** argv) (vedi sopra arrays.c)
        Permette al programma di ricevere dei parametri quando è lanciato, senza dover starli ad inserire su richiesta (ad esempio mediante scanf). Quindi il modo di usare arrays.c è mediante comandi del tipo
           ./arrays 4
        Ecco alcuni esempi sull'uso di 'argc' e 'argv':
        • uso_argc-argv1.c mostra come argv è un vettore ('array') di puntatori, il cui numero è dato da argc.
          Ciascun elemento del vettore punta all'inizio di un vettore di caratteri: si provi ad eseguire uso_argc-argv1 come indicato all'inizio del sorgente o con varianti.
        • Nel programma precedente il secondo argomento del main è stato scritto come char* argv[]. Ecco la versione in cui è stato scritto come char** argv
             uso_argc-argv2.c
          → si accede alle stesse informazioni, ma usando la sintassi dei puntatori.
        • In questo esempio si analizzano i singoli caratteri di ciascuna stringa argv[i], la quale è terminata con uno zero (vedi ulteriori commenti nel sorgente)
             uso_argc-argv3.c
        • Ed ecco una piccola applicazione per visualizzare il codice ascii di un carattere dato nella 'riga di comando' (e se non viene dato, esso viene richiesto e letto tramite scanf):
             ascii_code.c
        • Infine, ecco come convertire le stringhe dei parametri in intero (come fatto in arrays.c di Safai) e in float:
             uso_argc-argv4.c
          (si fa uso delle funzioni atoi() e atof() per le quali è richiesto l'header stdlib.h)
      • Strings: in C non esistono variabili di tipo string:
          → una stringa è semplicemente un vettore di caratteri, terminato con uno zero (ovvero tutti i bit del byte devono essere uguali a zero, da non confondere con il carattere '0', per i cui valore numerico si può far uso di ascii_code.c).
        • Cominciamo con un esempio in cui la string è definita con il suo contenuto:
             strings_1.c
          (si noti lo zero per terminare);
        • La dichiarazione con assegnazione somiglia a quella di un vettore. E in effetti si possono assegnare i singoli caratteri come fosse un vettore:
             strings_2.c
          (attenzione agli apicetti singoli!)
        • E, ovviamente, si può usare direttamente il nome come un normale vettore, invece di usare il puntatore
             strings_3.c
        • Ecco come troncare il nome mettendo la terminazione della string (numero '0' o sequenza speciale '\0') da qualche parte dentro il nome
             strings_4.c
        • E se si toglie lo zero si ottengono risultati imprevedibili, i quali cambiano ogni volta che si esegue il programma:
             strings_5.c
          (e per fortuna che qualche zero c'è sempre!)
        Esercizio scrivere la function
        • int lunghezza(char s[])
        che 'ritorni' la lunghezza della string (escluso lo zero di terminazione, inclusi eventuali spazi)

       
    • Operazioni con matrici in R
      • Rhistory_21nov2018.R
      • Altro file di comandi autoesplicativi o con commenti (mancano solo quelli per mostrare di volta in volta i risultati) sull'accesso agli elementi di una matrice, su come inizializzarla, su come cambiarne le dimensioni (a parità di contenuto), sull'ordine con cui i valori sono messi in memoria, etc:
      Problemini:
      • scrivere una function che calcoli la trasposta di una matrice (R permette di 'ritornare' anche una matrice, come fosse un vettore o un valore qualsiasi);
      • scrivere una function che calcoli il prodotto di due matrici (in questo caso, come si capirà scrivendo l'algoritmo, è conveniente inizializzare la matrice 'vuota' che contiene il risultato con degli zeri invece che con dei NA).
     
    Lezione 17, Gio 22 novembre, 1 h
    Matrici in R e in C (+ oscillatori armonici)  
     
    • Analogia fra moto dell'oggetto sospeso a una molla e quella dell'oggetto lasciato cadere nell'ipotetico pozzo per il centro della Terra:
      • ax = - (k/m) x
      • ar = - (g/RT) r
      Esercizio sulle derivate (legato a questo tipo di problemi):
      • calcolare la derivata prima e seconda rispetto al tempo di x(t) = X cos(ω t + φ) dove X, ω e φ sono opportune costanti (delle quali X ha le dimensioni dello spazio e ω dell'inverso del tempo.

       
    • Matrici in R  
      Rhistory_22nov2018.R
       
      Esercizio in due passi:
      • 'automatizzare' Gauss_elim_steps.R in modo che possa gestire una matrice di grandezza arbitraria, purché non abbia candidati pivot negativi;
      • risolvere il problema dei candidati pivot negativi con opportuna mossa di Gauss.

       
    • Matrici in C — introduzione Fare esercizi a piacere per implementare operazioni su matrici in C (per ora all'interno del main).
     
    Lezione 18, Mer 28 novembre, 1 h
    Ancora questioni di C (+ varie in sospeso)  
     
    • Derivate di funzioni sinusoidali rispetto al tempo (vedi Galleria etc.) e loro importanza in Fisica:
      • ω ('pulsazione') deve essere dimensionale in quanto gli argomenti delle funzioni trigonometriche (così come di log, exp, etc.) adimensionali: deve avere quindi dimensione inversa a quella del tempo;
      • riscrivendo opportunamente le funzioni trigonometriche mediante le 'famose' formule (tipicamente dimenticate, ma per fortuna c'è uil web...) si trova che
            l'effetto della derivata rispetto al tempo è di moltiplicare per ω e anticipare la fase di π/2
        (indipendentemente dal fatto che si tratti si seno o coseno!)

     
  • Soluzione empirico/euristica dell'oscillazione smorzata con forza di attrito '-β v', alla luce della soluzione numerica ottenuta (vedi qui e qui):
    • dall'andamento dei massimi locali se vede come l'alpiezza di oscillazione 'decada' in modo esponenziale nel tempo;
    • poi c'è un termine oscillatorio che si riduce a una semplice sinusoide in assenza di smorzamento;
    • una possibile soluzione è quindi del tipo di quella riportata nel primo problema di lunedi 26;
    • si tratta solo di ricavarsi X0 e φ dalle condizioni iniziali (mentre τ e ω dipendono dalla dinamica del sistema, e quindi dai parametri fisici m, k e β):
      • x(t=0) = X0   (lo spostamento inizialmente dal punto di equilibrio era al suo massimo);
      • x'(t=0) = 0   (l'oggetto sospeso era inizialmente a riposo — dicordiamo che dx/dt, limite di Δx/Δt per Δt → 0, rappresenta la velocità istantanea).

     
  • Memento sulle linearizzazioni:
    • un andamento lineare appare (banalmente) lineare plottando y in funzione di x;
    • un andamento esponenziale è linearizzato facendo uso di scala logaritmica sulle 'y' ('carta semilog');
    • una legge di potenza è linearizzata facendo uso di scala logaritmica su entrambi gli assi ('carta doppio log', o 'log-log').
    Una volta capito il tipo di andamento, i coefficienti vanno ricavati a partire dal rapporto incrementale fra le variabili che linearizzano l'andamento stesso. Quindi, ad esempio in una legge di potenza y = a*xb:
    • log(y) = log(a) + b*log(x)
      b = (log(y2) - log(y1)) / (log(x2) - log(x1));
    • a si ricava quindi a partire da un punto qualsiasi, in quanto yi = a*xib.

     
  • switch() in C, incontrato in uno dei problemi del lunedì
    (Esiste anche in R, con diversa sintassi — fuori programma.)
     
  • Un primo esempio, mooolto 'ingenuo', di ordinamento:
       sorting_0.c
    gli elementi di un vettore vengono rimossi nell'ordine e messi in un altro vettore (sì, non sarà il massimo dell'efficienza e della velocità, ma è la prima cosa che potrebbe venire in mente).
     
    Problema connesso: inserimento ordinato
    → provare (si ricorda che prima di cominciare a scrivere il codice bisogna farsi uno schema delle operazioni da effettuare: un algoritmo è una questione logica; la sua implementazione in un linguaggio di computer è una questione tecnica).
     
  • Metodo di eliminazione di Gauss: ecco come passare da una matrice max 4x4 a una matrice quadrata qualsiasi, con vincoli 'prudenziali' sugli elementi nulli: Esercizi
    • scrivere una function che gestisca bene i candidati pivot nulli mediante swap di righe;
    • scrivere una function che ruoti gli elementi di una matrice quadrata di 180 gradi
      (è una curiosa operazione, prettamente tecnica, che non ha niente a che vedere con rotazioni di vettori nello spazio, ma ci tornerà utile).

     
  • Matrici in C
    • Dopo aver visto come stampare gli elementi del prodotto di due matrici, ecco come costruire la matrice prodotto:
         matrici_2.c
      → la cosa importante è preparare la matrice 'vuota', della quale dobbiamo già conoscere le dimensioni.
    • Un punto delicato è come passare una matrice a una funzione. difatti bisogna passare sia il puntatore all'inizio della matrice (operazione spesso trasparente, in quanto, come nei vettori, è il nome stesso) che le dimensioni. Ecco come fare in una function che stampa la matrice (con valori interi per semplicità):
         matrici_3.c
    • Le dimensioni di una matrice non sono qualcosa di assoluto, ma 'convenzionale'. Ecco un esempio che mostra come sia possibile passare a una function le dimensioni scambiate
         matrici_4.c
      (ma questi sono esercizi accademici, tanto per capire come funziona internamente C, di nessun interesse pratico).
      Si noti inoltre, da questi esempi come, contrariamente a R e altri linguaggi, in C gli elementi della matrice sono ordinati per riga!
    • L'esempio che segue è invece più interessante (e talvolta anche utile), in quanto si mostra come passare alla function direttamente il puntatore alla matrice e, soprattutto, come usarlo per accedere agli elementi della matrice:
         matrici_5.c
    • Un comodo uso del puntatore è per assegnare lo stesso valore (tipicamente 0) a tutti gli elementi di una matrice:
         matrici_6.c
    • Ecco inoltre un esempio 'perverso', nel quale passiamo la matrice come fosse un vettore e ne stampiamo i valori nell'ordine con cui sono immagazzinati in memoria (ovvero per riga):
         matrici_7.c
      (Si noti come il compilatore gcc si accorga della stranezza e dia un segnale di avvertimento, ma esegue ubbidiente la compilazione e il programma funzione pure).

     
      Nota: i sorgenti matrici_6.c e matrici_7.c non sono stati illustrati a lezione, ma dovrebbero essere comprensibili dai commenti e alla luce degli esempi precedenti.
     
    Esercizi
    • Per semplicità questi esempi usano matrici di interi. Scriversi le equivalenti funzioni per float e/o double.
    • Scrivere la funzione per calcolare il prodotto di matrici, data la seguente ossatura (e ricordando che il calcolo nel main è in matrici_2.c):
         matrici_prod_ossatura.c
    • Scrivere la versione C della function R elim.Gauss.dnz() di Gauss_elim_dnz.R
    • Scrivere una function in C che scambi due righe di una matrice (si immagina facilmente a cosa servirà) secondo il seguente prototype
         void RowsSwap(int nr, int nc, int A[nr][nc], int r1, int r2)

     
    Lezione 19, Gio 29 novembre, 1 h
    C: algoritmi e strings (etc.)  
     
    • Nota storica, in occasione del quarto di luna, su un importante 'tentativo' storico di una misura di distanza mediante triangolazione: distanza Terra-Sole (Aristarco di Samo).
      ['tentativo' in quanto era una misura molto difficile, basata su un angolo che è π/2 - ε, ma comunque interessante per la metodologia e dal risultato culturalmente strepitoso, seppur la distanza Terra Sole venne clamorosamente sottostimata (ma implicava pur sempre un Sole gigantesco rispetto alla Terra, e ovviamente alla Luna)]
       
    • Inserimento ordinato proposto nella lezione precedente:
       
    • Strings (seguito)
      • Come far uso dello zero finale per calcolarsi la lunghezza di una string (function lunghezza() proposta la settimana scorsa):
           strings_6.c
      • Proviamo a concatenare due string:
           concatena.c
        Si noti come per il risultato deve essere allocato un vettore di lunghezza sufficiente!
      • Come 'scrivere' su una string mediante sprintf()
        • in R lo abbiamo incontrato per scrivere in modo formattato mediante il comando cat( sprintf() ): la funzione 'ritorna' la string;
        • il C non può 'ritornare' una string (che in realtà è un vettore di caratteri!): il puntatore alla string va quindi posto come primo argomento di sprintf().
          Ecco un esempio:
             esempio_sprintf.c
      • Ed ecco come trasformare tutte le lettere in maiuscole (uno dei problemini del lunedì):
           test_toUpper.c
        (Nota come non bisogna imparare i codici ASCII, in quanto si possono effettuare operazioni logiche e aritmetiche con i caratteri, come già visto a suo tempo: → char_04.c)
         
      • Concludiano (per ora) l'argomento con un programma che è quasi un riepilogo generale sul tema, incluso un ripasso dell'uso di argv[]:
           to_upper.c
           to_upper_dbg.c (versione con stampe di debug, per capire meglio)
        da eseguire con comandi del tipo
           ./to_upper andiamo tutti al mare
         
        (output di “./to_upper_dbg andiamo tutti al mare”: to_upper_dbg_output.txt)
        Esercizi
        1. in analogia alla funzione toUpper() scrivere la funzione toLower();
        2. scrivere le funzioni isletter(), isdigit(), islower(), isupper(), isspace() e isnewline(), che hanno come parametro un carattere e danno in uscita un intero che sia 1 o 0 a seconda che il carattere sia rispettivamente, una lettera, una cifra, una lettera minuscola, una lettera maiuscole, uno spazio o un accapo ('\n');
        3. modificare quindi to_upper.c, da chiamare change_case.c in modo tale che il primo argomento sia 'u' o 'l' a seconda che si voglia trasformare tutto in maiusculo o in minuscolo. Ad esempio
             ./change_case u andiamo tutti al mare → tutto maiuscolo;
             ./change_case l NON mi piacciono le MAIUSCOLE → tutto minuscolo;

       
     
    Lezione 20, Mer 5 dicembre, 1 h
    Dettagli su C e problema generale delle soluzioni numeriche di equazioni del moto  
     
    Domani cominciamo alle 9:00
    • Note sui problemi di lunedì:
      • calcolatrice.c (minimalista) con le sole 4 operazioni aritmetica: si noti l'uso del case quando vogliamo fare la stessa cosa con due opzioni diverse;
      • inoltre, l'uso del puntatore è dovuto al fatto che argv[2] è una `zero terminated string', ovvero un vettore di charatteri lungo almeno 2 (il simbolo dell'operatore e lo zero di terminazione), mentre a noi ci fa più comodo avere l'operatore in una singola variabile di tipo carattere.
        (In alternativa si sarebbe potuto definire il solo puntatore 'p = argv[2]' ed accedere all'operatore con '*p' ovunque compare 'op').
        [Attenzione: la scrittura 'p = argv[2]', fuori dal contesto, potrebbe indurre a errore in quanto, ripetiamo, argv[2] è una string!]

       
    • Variante del sorting 'ingenuo' proposta lunedì: (niente di speciale, a parte il trucco per riusare indMin anche quando lo spazio della ricerca del minimo si accorcia).
       
    • E, a proposito di 'trucchi', è da notare come il for() si può usare anche in modo più 'complicato' del solito “for (i=0; i<n; i++)”, in quanto i punti e virgola separano l'inizializzazione, la condizione per continuare i loop e cosa fare alla fine di ciascun loop.
      Ecco un esempio (nel quale sono mostrate anche altre peculiarità/'curiosità' del linguaggio)
          uso_for.c
       
    • Soluzione numerica del problema dei lanci (a suo tempo avevamo lavorato sulla soluzione analitica che si trova in tutti i manuali di Fisica).
      Il vantaggio della soluzione numerica è che possiamo affrontare anche casi non risolvibili analiticamente (ad esempio forze dipendenti in modo complicato da tempo, posizione e velocità), usando solo i minimalia di Fisica usati più volti.
      • Il passaggio da un problema tipo quello della molla a quello dei lanci è che il moto è almeno bidimensionale (ma poi ci si possono mettere 'effetti' di vario tipo e due dimensioni non sono più sufficienti — si pensi all'effetto nel gioco del calcio, o a forze magnetiche, perpendicalari al piano formato dai vettori velocità e campo magnetico). Ovviamente cominciamo dal caso bidimensionale.
      • L'idea di base è (in questi casi semplici) è che ciascuna coordinata si evolve per conto suo, avendo il tempo in comune. Ne segue che, estendendo i ragionamenti fatti per la soluzione numerica della molla, avremo per ogni istante ti:
        • x(ti), vx(ti), Fx(ti) e ax(ti) = Fx(ti) / m;
        • y(ti), vy(ti), Fy(ti) e ay(ti) = Fy(ti) / m.
      • Saremo quindi in grado di calcolare tutte le grandezze di interesse, come la gittata, lo spazio percorso, etc.
      • E ovviamente potremo pure graficare in qualche modo le soluzioni numeriche delle equazioni orarie, ovvero x(t) e y(t), e la traiettoria, ovvero y(x).
      • Cominciamo a pensare
        • a implementare direttamente in C la soluzione numerica del moto:
               lancio_2D_ossatura.c
        • a come graficare i risultati in R (ove eventualmente effettuare anche altre analisi di interesse).

         
      Lezione 21, Gio 6 dicembre, 1 h
      Scrittura su file e ... ritorno a R (con applicazione alla soluzione numerica dei lanci)  
       
    • Soluzione numerica del problema dei lanci:
       
    • Scrittura su file
      • Un modo 'brutale' per scrivere su file è quelli di inviare l'output su file mediante '>' (attenzione: se si esegue più volte il file viene sovrascritto!). Ad esempio, riprendendo il programma dei lanci
           ./lancio_2D 10 45 0.05 > lancio.out
        si noti come '>' non venga passato ad argv[], in quanto viene trattato dalla shell (il programma di Linux che gestisce i comandi dati da terminale) come un suo carattere speciale (ricordate la gestione di '*' in calcolatrice.c?)
         
        Per accedere al contenuto del file possiamo usare
        • cat, seguito dal nome del file, per inviare il contenuto sul terminale;
        • more, seguito dal nome del file, è comodo per file con molte righe, in quanto ci mostra una schermata alla volta (si va avanti con 'Enter', si esce con 'q');
        • less, seguito dal nome del file, è simile a more, ma dà anche la possibilità di tornare indietro mediante la freccia in alto (e si può andare avanti sia con Enter che con la freccia in basso);
        • head, seguito dal nome del file, mostra le prime righe del file (la 'testa');
        • tail mostra invece la coda
          (e se si vogliono vedere più righe del default basta aggiungere il parametro - n, con n il numero di righe da mostrare).
        — Ovviamente si può anche usare un editor di testo, come Emacs, ma se gli si vuol dare solo un'occhiata non vale la pena, anche perché è un processo più lento.
        — Si ricorda inoltre che per avere informazioni generali sul file, senza accedere al contenuto, si possono usare wc e ls.
         
      • Un modo più 'furbo' per scrivere su file è
        • di inviare sul file solo quello che ci intessa, continuando a inviare le 'normali stampe' su terminale, come si vedrà dagli esempi che seguono.
        • scrivere le informazioni di interesse in modo opportunamente formattato in modo che siano facilmente rileggibili:
          space separated values (attenzione: a lezione era stato erroneamente detto 'csv', ovvero 'comma separated values', uno standard largamente più utilizzato) (*).
      • Possiamo poi rileggere il file da R e proseguire con la parte grafica (ed eventuali altre analisi)
        → sessione R: Rhistory_6dic2018.R (contiene anche alcuni comandi relativi al file di lanci)
        Novità su fronte R:
        • La lettura del file mediante read.table() a cui abbiamo banalmente assegnato il nome 'dati'.
        • Internamente i dati vengono immagazzinati in un data frame, un 'oggetto' che non è una semplice matrice, in quanto le varie colonne colonne possono contenere oggetti di tipo diverso, anche se nel nostro caso i valori sono tutti numerici, come si evince dal comando
              str(dati).
        • Le colonne hanno anche dei nomi:
          • se essi compaiono nella prima riga del file (separati da spazi), chiamata header, come succede eseguendo l'esempio riportato sopra (vedi il primo fprintf()) verranno usati questi ('t', 'x' e 'v', nel nostro caso);
          • se invece il file è privo di header, R assegna i nomi standard V1, V2, etc.
        • Le colonne possono utilizzate come fossero dei vettori, usando la sintassi nomeDataFrame$nomeColonna[], ad esempio nel notro caso
          • dati$V1[], dati$V3[], dati$V3[];
          • dati$t[], dati$x[], dati$v[]
          a seconda che i nomi delle colonne erano quelli default o quelli trovati nell'header.

       
    • Esempio del problema dei lanci con scrittura su file:
      • lancio_2D_file.c
        → da studiare bene
        • contiene anche un paio di nuove 'direttive' di precompilazione (#ifdef e #endif): → a differenza di un normale if, le istruzioni racchiuse fra #ifdef e #endif vengono passate al compilatore solo se HEADER (nel nostro caso) è stato definito;
        • il nome del file su cui scrivere viene generato automaticamente dai parametri del lancio e della discretizzazione;
        • è stato 'dimenticato' il comando fclose(fp) per chiudere il file (vedi invece esempio precedente), cosa da evitare, anche se in un programmino del genere non è grave in quanto il file viene chiuso automaticamente da Linux quando il programma termina.
      • ./lancio_2D_file 10 45 0.05
        lancio_10_45_0.05.txt

       
    • Lettura file da R con grafica e analisi:
      • carica_file.R
        oltre alla lettura del file mediante read.table() viene mostrato come estrarre informazioni generali sul data frame di interesse e come fare un 'plot riassuntivo' (oltre a un trucchetto per non dover ridare il nome del file)
      • analizza_lancio.R
        → si noti l'uso di vettori, eventualmente giocando in maniera opportuna con gli indici, per evitare l'uso di cicli for(), tipico degli script R.
        In questo script è stato fatto uso del parametro mfrow() visualizzare più plot nella stessa 'finestra grafica': in particolare abbiamo usato mfrow(3,1) per avere una 'matrice' di plot di 3 righe e 1 colonna.
        → si noti inoltre come lo script non esegue soltanto plot, ma effettua anche analisi complementari a partire dai dati a disposizione.
      • parametri_lancio.R
        → la manipolazione di string per estrarre i parametri di interesse non è da ritenersi basilare ai fini del corso, ma è utile ricordarsi che tali cose sono possibili e cercare su internet come farle qualora dovessero servire;
        →importante invece la posibilità di 'ritornare' più valori (anche di vario tipo, seppur questa possibilità non è usata in questa function) all'interno di una list, concetto su quale torneremo.


      (*) Per capire la differenza, ecco le versioni csv di lancio_2D_file.c, di carica_file.R e del file scritto/letto: (e ovviamente in analizza_lancio.R va sostituito il 'source()' al fine di chiamare lo script carica_csv.R invece di carica_file.R)
     
    Lezione 22, Mer 12 dicembre, 1 h
    Varie su C e su R
     
    • Problemino di riscaldamento:
      • caduta in aria o altro mezzo: velocità asintotica nei casi in cui la forza di resistenza del mezzo sia proporzionale alla velocità o al suo quadrato:
        (→ accelerazione nulla).

    • Qualche commento sulla 'prova' d'esame:
      • niente di speciale dal punto di vista tecnico (→ vedere le soluzioni);
      • abituarsi a lavorare con le Reference Card, specialmente quella del linguaggio C;
      • osservazioni sui modi ci calcolare il prodotto scalare (a proposito dell'addendum al quesito su 'Giove visto dalla Terra').

    • Osservazioni (tecniche) sui programmi dei lanci in 2D
      • In lancio_2D_file.c era stato dimenticato close(fp): in genere non fa niente, se doveva stare verso la fine del programma, ma meglio abituarsi metterlo sempre.
      • Differenza fra #ifdef .... #endif e il normale if() {} :
        le 'direttive' preceduti da cancelletto agiscono a livello di precompilazione, quindi se la condizione è falsa le istruzioni relative a quelle righe saranno assenti nell'eseguibile, che diventa quindi più conciso e veloce.
      • per dettagli sui csv (comma separated values) chi è interessato veda Wiki (si parla anche degli space separated values e varianti).
      • R è in grado di leggere entrambi i tipi mediante read.csv() e read.table().
        I dati del file vengono memorizzati internamente in forma di data frame: in carica_file.R, carica_csv.R e analizza_lancio.R abbiamo visto come accedere ai suoi valori.
      • Cenno ai data frame con trucchi fuori programma. L'importante è il minimo per poter accedere alle informazioni di interesse fisico.
      • list di R (incontrata in parametri_lancio.R per 'ritornare' vari valori da una funzione — ma in quel caso potevamo anche usare un vettore, essendo le variabili dello stesso tipo)
        • a differenza di vettori e matrici (o array di dimensioni superiori), possono contenere variabili di tipo diverso;
        • gli elementi possono essere anche vettori e matrici;
        • gli elementi possono avere anche dei nomi, come visto in parametri_lancio.R;
        • si accede all'elemento della list in un modo simile a quanto visto per i data frame.
        Esempi: esempi_list.R
       
    • Ancora qualcosa sulle string
      • Il format di printf(), sprintf() e fprintf() è una string. Vediamo come sia possibile crearla dinamicamente per cambiare format all'occorrenza:
      • Le operazioni 'a mano' su caratteri e string hanno un intento didattico. Per scrivere i programmi cominciare ad usare le funzioni standard di C (vedi Reference Card).
    • Cenni a bc (arbitrary precision calculator).
      Per invocarlo, sotto Linux ('-l' per la libreria matematica):
          bc -l
      Esempi di comandi, da eseguire uno alla volta con copia/incolla: (uscire con quit)
       
    • Di nuovo sui lanci in 2D, ma tenendo conto della resistenza dell'aria
      (niente di complicato se si sono capiti bene il programma precedente, che però non teneva conto della resistenza dell'aria, e, soprattutto, la soluzione numerica del problema della molla, in quanto avevamo una forza non costante)
     
    Lezione 23, Gio 13 dicembre, 1 h
    Stutture in C. Istogrammi e altre rappresentazioni grafiche di dati in R
     
    • Problema dei lanci in aria
      • provare l'algoritmo 'di Feynman' nel quale si calcola la velocità a dt/2 ("ε/2" nel suo libro);
      • per l'inizio si può cominciare con una velocità fittizia a -dt/2

    • Stutture, direttamente con un esempio, per cominciare a capire di cosa si tratta Segue esempio di array nella struttura e suo uso passaggio a una funzione (con ripasso sulla random e un po' di ginnastica mentale su un for 'criptico' ) E per concludere, ecco pure il passaggio a funzione mediante puntatore Si noti, in questo caso, '->' al posto di '.', per accedere agli 'elementi' della struttura.
      (segue...)
       
    • Visualizzazione dati in R (appena un assaggio):

      Problemi
    • Esercitarsi all'uso di sample(), table(), hist(), barplot() e pie() inventandosi qualcosa (o cercando dati su internet).
    • Trasformare irunif() e frunif() (vedi lezione del 15 novembre) in function che ritornino un vettore di n random.
      I prototype saranno quindi qualcosa tipo
      • void Nirunif(int N, int v[N], int min, int max)
      • void Nfrunif(int N, float v[N], float min, float max)
    • Scrivere le funzioni in C dai prototype
      • void sampleI(int n, int v[n])
      • void sampleF(int n, float v[n])
      per 'mescolare' a caso gli n elementi di v[]
    • Per capire la differenza fra il passaggio di una struttura a funzione normalmente o tramite puntatore, si scriva un programma nel quale l'assegnazione (random o come si preferisce) dei voti a studenti[] sia effettuata all'interno di un'apposita funzione.
     
    Lezione 24, Mer 19 dicembre, 1 h
    Varie su C, R, bc e algoritmi. In particolare I/O
     
    • Esercizio di riscaldamento: un curioso tacchino (da non confondere con il tacchino induttivista):
      • mangia in continuazione;
      • tanto mangia tanto ingrassa;
      • la sua voracità è proporzionale al suo peso;
      • per t=0 pesa 1 kg e la sua voracità è pari a 10 g/h.
      Trovare
      • come aumenta la sua massa in funzione del tempo;
      • in particolare dopo quanto tempo raddoppia.
      [Soluzione]
       
    • Generatori di numeri casuali (quasi) arbitrari ottenuti generando punti uniformemente all'interno di un rettangolo la cui base corrisponde al dominio della funzione e la cui altezza deve superare il massimo della funzione in quell'intervallo (vedi problemi dell'ultimo lunedì).
      → Algoritmo semplice ma con immaginabili problemi di efficienza.
      → Non funziona per funzioni di probabilità il cui dominio è infinito.
      [È noto in letteratura come algoritmo hit/miss (beccato/mancato), in quanto si accettano i punti sotto la curva f(x) e si scartano gli altri. Si basa sull'osservazione che la probabilità che un punto sia accettato è proporzionale a f(x), come si intuisce facilmente.]
       
    • Osservazioni sul random walk associato all'esito del lanci di una moneta, ovvero avanti e indietro con la stessa probabilità, nel seguito saranno 1 e 0 (0 → Testa → avanti; 1 → Croce → indietro)
      • Il processo elementare che associa a 1 la probabilità p e a 0 la probabilità (1-p) è chiamato processo di Bernoulli;
      • il caso di Croce/Testa (→ 0/1) rappresenta il caso particolare con p=1/2;
      • c'è una corrispondenza uno a uno fra il numero di '1' usciti in una sequenza di n tentativi e la posizione finale in un random walk di n passi associati a tali esiti;
      • nel caso di p=1/2 tutte le sequenze (ad esempio 0000000000, 0100000000, 0011111000, ... 1111111111, per n=10) hanno la stessa probabilità, semplicemente perché i tentativi sono indipendenti e le possibilità alternative 0/1 a ogni tentativo sono equiprobabili (nel senso che non c'è nessun motivo razionale per attendersi più facilmente un esito anziché l'altro);
      • il motivo per cui è più probabile osservare un numero di 1 pari a circa 5=n/2 è un fatto puramente combinatorio: c'è una sola sequenza con 10 zeri e nessun 1 e idem per 10 uni e nessuno 0; ce ne sono invece 10 con un solo 1 e 9 zeri, e idem per un solo 0 e 9 uni; ci saranno poi 45 sequenze che hanno 2 zeri e 8 uni ovvero pari al di scelte di 2 elementi su un campione di 10; e così via, 3 scelte su 10, 4 scelte su 10, etc.
      • in R la funzione che ci calcola il numero di scelte di k oggetti fra n si chiama choose(), ad esempio
            choose(10, 1)
            choose(10, 2)
            choose(10, 3)
        mentre la funzione che ci calcola la probabilità di avere k successi su n estrazioni, in ciascuna delle quali l'esito di interesse ha probabilità p è dbinom() da 'distribuzione binomiale', la quale prende il nome dal coefficiente binomiale, che non è altro che 'choose()'.
        Abbiamo quindi, ad esempio
            dbinom(0:10, 10, 0.5)
            barplot (dbinom(0:10, 10, 0.5), names=0:10 )
            n = 10; barplot (dbinom(0:n, n, 0.2), names=0:n )
            n = 20; barplot (dbinom(0:n, n, 0.7), names=0:n )
      • Se esiste la funzione dbinom() esisterà anche rbinom() per estrarre numeri random che seguono tale distribuzione.
        Quindi possiamo ottere barplot simili a quelli ottenuti con i random walk mediante
            barplot( table( rbinom(10000, 10, 0.5) ), col='cyan')
            barplot( table( rbinom(10000, 10, 0.5) * 2 - 10), col='cyan')
      (Questo excursus sulla distribuzione binomiale è da considerarsi a beneficio degli interessati e fuori dal programma di esame a meno che eventuali quesiti su questi temi non siano corredati da una traccia con informazioni esaurienti.)
       
    • Piccola nota su bc (fuori programma, ma può essere utile agli interessati — ad esempio i comandi di sistema possono essere invocati da R, come vedremo per fare le gif animate), anche per richiamare il concetto di pipe e soprattutto per introdurre alcune importanti questioni di I/O sia in R che in C (in programma).
      • Ricordiamo:
            echo ciao a tutti | wc
        da non confondere con
            echo ciao a tutti > wc
        che scrive su file.
        (Per altri esempi si veda lezione 14)
      • Attenzione a non confondere '|' con '>':
            echo 3 8 | ./test_swap   OK
            echo 3 8 > ./test_swap   NO! (sovrascrive il file!)
      • E ora bc:
            echo "4*a(1)" | bc -l   (gli apicetti, singoli o doppi, sono importanti)
            echo "scale=100; 4*a(1)" | bc -l
            echo "scale=100; 4*a(1)" | BC_LINE_LENGTH=0 bc -l
            echo "scale=1000; 4*a(1)" | BC_LINE_LENGTH=0 bc -l > pi1000.txt
        (Poi cosa farci con tutte queste cifre di π è altra storia...)

    • Se volessimo rileggerlo con R:
    • Ovviamente, soffrendo un po' lo si può fare anche in C, a parte la grafica.
      [I programmi, oltre ad essere ripassi su cose già viste, hanno delle novità, come fscanf(), un 'curioso' format di lettura per leggere un intero file, e altro.]
      • analizza_pi_1.c (solo lettura e visualizzazione di quanto letto)
      • analizza_pi_1a.c (con statistica delle cifre di π — praticamente indistinguibili da quelle proveniente da un generatore di numeri casuali).

    • Dopo l'esercizio sulla profondità del pozzo ottenuta con metodo iterativo, ecco un paio di importanti algoritmi iterativi (implementati in R per procedere più lesti e per usufruire della grafica).
      • Algoritmo di Newton per trovare gli zeri di una funzione, qui applicato alla valutazione numerica della radice quadrata:
            newton.R
            Plot
        Problemino: Trovare la formula di iterazione per ottenere, nel caso della radice quadrata con il metodo di Newton, i valori di x nei vari passi (ovviamente è gia nello script R relativo e bisogna solo metterla in bella forma).
       
      Lezione 25, Gio 20 dicembre, 2 h
      Varie su C, R, algoritmi e Fisica (e ancora I/O in C)
       
      • Esercizio di riscaldamento (facile, ma nel quale l'intuizione può essere fallace)
        • velocità media nel caso due tratti di strada uguali vengano percorsi con velocità diverse.
        (L'intento era di far tornare alla memoria i concetti di media aritmetica, geometrica e armonica. In particolare, una famosa relazione fra le prime due sarà usata nella derivazione del metodo iterativo 'dei babilonesi' del calcolo della radice quadrata.)
         
      • Soluzione del sasso nel pozzo:
            pozzo.c
        [Si ricorda che abbiamo lasciato in sospeso la domanda di quale problema è soluzione la soluzione spuria?]
         
      • Algoritmo dei babilonesi (sic dicunt!) per il calcolo della radice quadrata con la base teorica messa nel commento al sorgente.
      • Chi ha svolto il problema suggerito ieri sull'algoritmo di Newton riconoscerà nella regola di aggiornamento di x 'dei babilonesi' la stessa regola 'di Newton' (ma in quest'ultima non c'è la condizione che la x di partenza debba essere maggiore di sqrt(N), anche se, come abbiamo visto, partendo x minore si perde solo un po' di tempo nelle prime mosse).
         
      • Ricerca del minimo (locale) di una funzione mediante l'algoritmo di 'scivolamento lungo la pendenza' (*) ('gradient descent'):
            minimizzazione.R
            Plot
        Esercizi proposti:
        1. provare a modificare alpha per vedere come cambia il processo di minimiazazione;
        2. provare con altre funzioni, calcolando la derivata direttamente con R (vedi nel seguito);
        3. riscrivere l'algoritmo in C (ovviamente senza grafica);
        4. nei problemi fisici y e x hanno delle dimensioni (e spesso sull'ascissa c'è il tempo e sull'ordinata la grandezza fisica da esso dipendente): quali sono in questo caso le dimensioni di alpha e qual'è quindi il suo significato fisico/matematico?

        [(*) Nome inventato, inutile cercarlo su internet]
         
      • Altre modalità di I/O in C (avevamo cominciato con il problema della lettura di π a 1000 cifre decimali da file).
        • Altra possibilità di lettura: un carattere alla volta mediante fgetc() — e visto che abbiamo un carattere alla volta lo inviamo allo schermo ('lo stampiamo') as is mediante putchar():
            Per finire con il file di π a 1000 cifre, ecco, dulcis in fundo un'ultima possibilità che nel caso di una file composto da una sola string è senz'altro la più semplice, facendo uso di fgets() e fputs() (gli altri erano pur sempre utili esercizi...)
          E, se esistono fget() e putchar(), esisteranno pure (vedi Reference Card) fputc() e getchar(), di cui ecco egli esempi:
          • Usiamo fputc(), in abbinamento a fgetc(), per fare un semplice programma per copiare un file su un altro:
                copia_file.c
          • Usiamo getchar() per leggere da tastiera molte righe di testo e putc() per scrivere su file:
                prova_getchar2file1.c
          • Variante nella quale la scrittura su file del vettore contenente il testo viene fatta in un solo colpo mediante fputs()
                prova_getchar2file2.c

           
        • Scrittura e rilettura di file binari mediante fwrite() fread().
          (Un file binario è illegibile con text editor, ma in genere più compatto; per essere riletto bisogna sapere come è stato scritto)
        [Per altre modalità di I/O si veda sulla Reference Card o su internet. Una volta capite queste non dovrebbe essere complicato far uso di altre.]
         
      • A proposito di sizeof():
        • numero di bytes per i diversi tipi di variabili: vedi Lezione 13 sulle lunghezze dei vettori;
        • sul range dei vari tipi (dettagli su Reference Card)
              info_limiti_variabili.c
        • Infine (assolutamente fuori programma!) per chi fosse interessato alla rappresentazione a bit di integer, unsigned e float:
              bit_analyser.c
          (Nota: dovrebbe funzionare con Linux/gcc: assume che, come i vettori sono immagazzinati nella memoria del computer in ordine crescenti di valori, così pure i byte di una variabile sono memorizzati dal meno significativo al più significativo; quindi quando li leggiamo uno dietro l'altro in ordine crescente di puntatore li dobbiamo scrivere da destra verso sinistra. Chi ottiene risultati strani sul proprio computer è invitato a segnalarlo, specificando sistema operativo e compilatore.)

         
      • Crivello di Eratostene per la determinazione dei numeri primi
        • Figura esplicativa
        • eratostene.c (N max prefissato nel sorgente; risultati visualizzati)
        • eratostene_file.c (N max da riga di comando; risultati su file)
        • eratostene_file_mall.c (come il precedente, ma allocazione dinamica della memoria al fine di superare i limite sulla lunghezza dei vettori imposti dal compilatore: il numero di primi che si riescono a trovare con questo antico dipende così solo dalla dimensione della RAM del computer e da quanto si è disposti ad aspettare).

         
      • Problemi gravitazionali di due corpi e tre corpi Provare a cambiare i parametri per vedere cosa succede e, nel caso dei tre corpi, fare la simulazione anche in 3D, plottando una proiezione alla volta. Nel caso dei due corpi si osservi la transizione a orbite ellittiche variando opportunamente la velocità del satellite.
        Dal punto di vista tecnico si notino:
        • la funzione ifelse();
        • le variabili xlim e ylim definite per comodità all'inizio e passate agli 'omonimi' argomenti della funzione plot() ['xlim=xlim' e 'ylim=ylim' non son o inutili tautologie!];
        • il trucco per plottare solo una frazione dei punti (controllata da 'iplot') sia per non affollare troppo il plot che per aumentare la velocità di esecuzione (plottare punti sullo schermo prende tempo);

         
      • Gif animate
        • potenza_numeri_complessi_animazione.R
          Note:
          • la conversione è effettuata mediante convert di Imagemagick;
          • nello script 'convert' è chiamato al volo mediante la funzione system(), che esegue il comando di Linux passato come string;
          • i file temporanei .png sono scritto su tmp/ e vanno cancellati alla file con "rm -f tmp/*");
          • per chi non ha Linux: Imagimagick esiste anche per altri sistemi operativi, ed esisteranno altri programmi che fanno la stessa cosa, basta aver capito la 'filosofia' sottostante.

         
      • Tombola A parte l'aspetto giocherelloso — ma esisteranno app fatte molto meglio e più divertenti — lo script è stato 'postato' come un invito a dare un occhiata al codice, anche se non è il massimo di eleganza, efficienza e comprensione.
        Nota tecnica
        • L'assegnazione "<<-" agisce su una variabile che è nell'ambiente di lavoro della sessione di R: peculiarità del linguaggio da usare con cautela in quanto può essere pericoloso!

        E per chi vuole esercitarsi con il linguaggio C:
         
      • Derivate con R
        • Calcolare numericamente derivate mediante rapporti incrementali con incrementi 'sufficientemente piccoli' (senza esagerare, a meno di non avere funzioni che variano i valori 'ad alta frequenza') è una operazione semplice che viene lasciata come esercizio personale;
        • La cosa interessante è che R permette di calcolare le derivate anche analiticamente, e il risultato può essere usato in calcoli e plot, come mostrato negli esempi dello script: espressions_etc.R

         
      • Equazioni differenziali
        Anche se, volutamente, il nome non era mai stato evocato a lezione, abbiamo trattato equazioni differenzali sia in modo analitico che numerico. Infatti in molti casi avevamo delle relazioni fra derivate e grandezze fisiche e il problema era quello di valutare come la grandezza fisica cambiava con il tempo ('variabile indipendente'), date particolari condizioni iniziali.
        In particolare, scrivendo le derivate prime e seconde rispetto al tempo della generica x come x'' e x'' abbiamo incontrato
        1. x''(t) = k;   x'(0),   x(0)    →   x(t);
        2. x''(t) = - ω2 * x(t);   x'(0),   x(0)    →   x(t);
        3. x''(t) = - ω2 * x(t) - β/m * x'(t);   x'(0),   x(0)    →   x(t);
        4. x''(t) = k - η/m * |x'(t)| * x';     x'(0),   x(0)    →   x(t);
        5. x'(t) = α * x(t);   x'(0),   x(0)    →   x(t);
        6. x1''(t)   =   f1( x1(t), x2(t), y1(t), y2(t) ),
          y1''(t)   =   f2( x1(t), x2(t), y1(t), y2(t) ),
          x2''(t)   =   f3( x1(t), x2(t), y1(t), y2(t) ),
          y2''(t)   =   f4( x1(t), x2(t), y1(t), y2(t) );
          x'1 (0), x1 (0) , y'1 (0), y1 (0) , x'2 (0), x2 (0) , y'2 (0), y2 (0)
             →    x1(t), y1(t), x2(t), y2(t).
        7. analogo con 'tre coppie di coordinate' →    x1(t), y1(t), x2(t), y2(t), x3(t), y3(t)
          (prevedendo estensione a 'tre terne di coordinate')

        A quali problemi si riferiscono?


  • Torna alla pagina del corso