
----------------------------------------------------------------------------
Il tema conduttore di questa prova è la distribuzione normale (o 'gaussiana')
descritta dalla funzione densità di probabilità ricordata 
nella nota memo_gaussiana.pdf contenuta nella directory doc 

-----------------------------------------------------------------------------
1. Per cominciare, scrivere uno script R che grafichi la funzione
   densità di probabilità e la cumulativa della gaussiana,
   ottenute rispettivamente con le funzioni dnorm() e pnorm(),
   per i seguenti valori:
   - mu=0, sigma=1;
   - mu=0, sigma=2;
   - mu=0, sigma=0.5;
   - mu=2, sigma=1;
   - mu=2, sigma=2;
   - mu=2, sigma=0.5;
   Possibilmente lo script deve produrre due plot nella stessa `pagina',
   quello superiore con la f(x) e quello inferiore con la F(x).
   La scala delle ascisse deve andare, per entrambi i plot,
   da -6 a 8; quella delle ordinate deve essere tale da ottimizzare
   la leggibilità dei plot.
   Si usino infine diverse linee e colori per distinguere
   a occhio le curve tracciate con i diversi parametri
   (se si include anche una legenda, non obbligatoria, ancora meglio).

      [ nome dello script: gaussiane.R ]


2. Scrivere in C le funzioni 'double' dnorm e pnorm, per il calcolo
   di pdf e CDF della normale.
   - La formula della pdf è ricordata in memo_gaussiana.pdf.
     Per il valore di pi greco si usi la costante M_PI dell'header math.h
     (vedi C-mathematical_constant.pdf riportata nella directory doc).
   - Per la valutazione della cumulativa, per la quale non esiste una
     semplice formula, si faccia uso della funzione speciale
     erf() dell'header math.h (vedi C-special_functions.pdf).
     La relazione fra F(x) normale e erf() è data dalla (5)
     della nota memo_gaussiana.pdf.
     
   Scrivere 'quindi' [*] il main() il quale
   - legga i valori x, mu e sigma da riga di comando, con un messaggio
     di errore se essi mancano o se la sigma non è positiva;
   - stampi i tre valori letti;
   - chiami dnorm() e pnorm() e ne stampi i risultati in
     `notazione scientifica'

   [*] L'ordine con il quale scrivere le diverse parti è 'logico',
       ma dal punto di vista pratico conviene cominciare da un main()
       'minimalista' e provarlo, mediante compilazione/esecuzione,
       a mano a mano che si scrivono le funzioni.
       Inoltre nel file del programma va scritto prima il main
       e poi le funzioni (se si fa il contrario si perdono punti),
       separando le funzioni da un commento contenente una sequenza
       di trattini in modo da migliorare la leggibilità dell'insieme.

       [ nome del programma: gaussiana.c ] 
       [ esempio di comando di esecuzione: ./gaussiana 5 3 2 ]


3. Facciamo ora una variante al programma precedente.
   I valori di x, mu e sigma sono nel file parametri_gaussiana.txt,
   ogni riga del quale contiene, nell'ordine i tre valori.
   Il programma legge una riga alla volta, stampa i valori letti
   e calcola, come nel punto precedenti la pdf e la cumulativa.
   Si ricorda che scanf() 'ritorna' il numero di item letto correttamente
   (3 in questo caso), altrimenti significa che è stato raggiundo l'End of File.

       [ file con i parametri: parametri_gaussiana.txt ]
       [ nome del programma: gaussiana_file.c ]
       [ comando di esecuzione: ./gaussiana_file ]


4. Come seconda variante mettiamo nel parametri_gaussiana_prob.txt
   4 valori per riga, ove i primi due sono i limiti dell'intervallo
   entro cui calcolare la probabilità, mentre i secondi due rappresentano,
   come prima, mu e sigma.
   La probabilità va calcolata mediante due chiamate a pnorm(), ricordando
   che la probabilità che una variabile aleatoria assuma il valore
   in un certo intervallo è data dalla differenza delle cumulative
   calcolate agli estremi (chi non ricordasse bene veda memo_gaussiana.pdf).
  
       [ file con i parametri: parametri_gaussiana_prob.txt ]
       [ nome del programma: gaussiana_file_prob.c ]
       [ comando di esecuzione: ./gaussiana_file_prob ]


5. Torniamo ora a R, generando numeri casuali "che seguono una
   distribuzione normale" mediante la funzione rnorm().
   Lo script:
   - definisce i parametri mu=1, sigma=2 e n=1000000
     (non c'è bisogno che lo script chieda i valori);
   - mette nel 'vettore' x gli n valori generati;
   - chiama le funzioni di sistema per calcolare media e deviazione standard
     dei valori generati e stampa i risultati in modo intellegibile.
     (ovviamente non deve assolutamente stampare il milione di numeri generati,
     anche se è buona regola debuggare lo script stampandone un piccolo numero);
   - mostra l'istogramma degli valori generati, scegliendo un numero
     di 'bin' (cellette) dell'istogramma in modo ragionevole.

       [ nome dello script simulazione.R ]


6. Scriviamo infine in C un generatore di numeri gaussiani, tipo rnorm(),
   ma semplificato, nel senso che è abbastanza accurato entro +- 3-4 sigma
   dalla media, mentre è poco affidabile oltre. In particolare, dato l'algoritmo
   usato non può produrre valori oltre +- 6 sigma.
   Tale algoritmo è descritto nell'ultimo punto di memo_gaussiana.pdf.

   Si tratta quindi di scrivere la funzione rnorm12() a cui vengono
   passati il numero di eventi da generate e i parametri mu e sigma.
   Essa esegue n volte la somma di 12 numeri casuali estratti
   uniformemente fra 0 e 1 e dalla somma ottenuta sottrae 6,
   come nella (6) di memo_gaussiana.pdf.
   I numeri così ottenuti seguono approssimativamente una distribuzione normale
   con mu=0 e sigma=1.
   Per ottenere numeri casuali con mu e sigma arbitrari basta
   effettuare la trasformazione lineare (4) di  memo_gaussiana.pdf.
   Il nome della funzione rnorm12() ricorda il trucco usato.

   Ma, a differenza di rnorm() di R, le funzioni di C non possono 'ritornare'
   dei 'vettori' (o, più in generale), quindi bisogna farlo 'in altro modo'
   (la cui conoscenza è uno dei degli argomenti da testare nella prova).

   Per quanto riguarda il main():
   - legge da riga di comando n, mu e sigma ed effettua controlli
     sui valori, incluso quello che n non sia maggiore alla dimensione
     del vettore che dovrà contenere i numeri generati;
   - inizializza il generatore di numeri casuali con il proprio
     numero di matricola, facendo uso della funzione contenuta
     in inizializza_random.c, da inserire nel programma; [*]
   - chiama rnorm12(), dalla quale riceve 'in modo opportuno' il vettore
     contenente gli n numeri casuali gaussiani generati;
   - di questi numeri casuali calcola media e deviazione standard
     [si ricorda che il modo più efficiente per calcolare la deviazione standard
      è quello di calcolare, nello stesso loop usato per calcolare la somma dei
      valori, anche la somma dei loro quadrati: la varianza si calcola quindi
      come 'media dei quadrati meno il quadrato della media', da cui
      si calcola la deviazione standard come semplice radice quadrata
      della varianza];
   - conta il numero di valori compresi fra mu-sigma e mu+sigma
     (attenzione: mu e sigma sono i parametri usati e NON la media
      e la deviazione standard del campione ottenuto.)
   - E ovviamente ci saranno delle stampe per mostrare quanto calcolato.)

     [*] In fase di debug, al fine di controllare che il programma
         stia funzionando conviene inizializzare la random con
         il tempo interno del computer. Solo prima di consegnare
	 usare il nr di matricola, controllando i risultati finali.

     [ nome del programma: generatore_gaussiano.c ]
     [ esempio di comando di esecuzione: ./generatore_gaussiano 1000000 3  2 ]


	   
