Soluzioni: Lezione 3

../_images/linea.png

3.1 creazione di un istogramma

  • esercizio01.cpp

/*
c++ -o esercizio01 `root-config --glibs --cflags` esercizio01.cpp
*/

#include "TH1F.h"
#include "TCanvas.h"
#include "TApplication.h"

int main (int argc, char ** argv)
{
  

  TH1F histo ("histo", "prova", 10, 0., 10.) ;
  histo.Fill (9.4) ;
  histo.Fill (2.1) ;
  histo.Fill (123.3) ;
  histo.Fill (0.0004) ;
  histo.Fill (2.9) ;

  TApplication theApp ("theApp", &argc, argv) ;
  TCanvas c1 ;
  histo.Draw () ;
  c1.Print ("histo.png", "png") ;
  theApp.Run () ;

  return 0 ;
}
../_images/linea.png

3.2 creazione di un istogramma con allocazione dinamica di memoria

  • esercizio02.cpp

/*
c++ -o esercizio02 `root-config --glibs --cflags` esercizio02.cpp
*/

#include "TH1F.h"
#include "TCanvas.h"
#include "TApplication.h"

int main (int argc, char ** argv)
{
  

  TH1F * histo = new TH1F ("histo", "prova", 10, 0., 10.) ;
  histo->Fill (9.4) ;
  histo->Fill (2.1) ;
  histo->Fill (123.3) ;
  histo->Fill (0.0004) ;
  histo->Fill (2.9) ;

  TApplication * theApp = new TApplication ("theApp", &argc, argv) ;
  TCanvas * c1 = new TCanvas () ;
  histo->Draw () ;
  c1->Print ("histo.png", "png") ;
  theApp->Run () ;

  delete histo ;
  delete theApp ;
  delete c1 ;
  return 0 ;
}
../_images/linea.png

3.3 lettura di un file di testo

  • esercizio03.cpp

/*
c++ -o esercizio03 esercizio03.cpp
*/

#include <iostream>
#include <fstream>

#include "dynarray.h"

using namespace std ;

int main (int argc, char ** argv)
{

  if (argc < 2)
    {
      cerr << "manca il nome del file da leggere" << endl ;
      exit (1) ;
    }
  ifstream input_file (argv[1]) ;
  dynarray elementi ;
  double input_val = 0. ;
  while (true)
    {
      input_file >> input_val ;
      if (input_file.eof () == true) break ;
      elementi.aggiungi (input_val) ;
    }
  input_file.close () ;

  cout << "letti " << elementi.dim () << " numeri\n" ;

  for (int i = 0 ; i < 10 ; ++i)
    {
      cout << "elemento " << i
           << " : " << elementi.leggi (i) 
           << "\n" ;
    }

  for (int i = 0 ; i < 20 ; i+=2)
    {
      cout << "elemento " << i
           << " : " << elementi.leggi (i) 
           << "\n" ;
    }

  double elem_max = elementi.leggi (0) ;
  double elem_min = elementi.leggi (0) ;

  for (int i = 0 ; i < elementi.dim () ; ++i)
    {
      if (elementi.leggi (i) < elem_min) elem_min = elementi.leggi (i) ;
      if (elementi.leggi (i) > elem_min) elem_max = elementi.leggi (i) ;
    }

  cout << "minimo:  " << elem_min << "\n" ;
  cout << "massimo: " << elem_max << "\n" ;

  return 0 ;
}
  • dynarray.h

#ifndef dynarray_h
#define dynarray_h

class dynarray
{
  public :
    dynarray (int N = 100) : // valore di default 100, nel caso nessun valore venga passato
      m_size (N),
      m_dim (0)
      {
        m_ptr = new double [m_size] ;
      }

    ~dynarray ()
      {
        delete [] m_ptr ;
      }

    int aggiungi (double valore)
      {
        m_ptr[m_dim] = valore ;
        ++m_dim ;
        if (m_dim > m_size)
          {
            double * tempo = m_ptr ;
            m_ptr = new double [m_size * 2] ;
            for (int i = 0 ; i < m_size ; ++i) m_ptr[i] = tempo[i] ;
            m_size *= 2 ;
            delete [] tempo ;
          }
        return m_dim ;
      }
     
    int dim () const 
      { 
        return m_dim ; 
      }

    double leggi (int indice) const
      {
        if (indice >=0 and indice < m_dim) return m_ptr[indice] ;
        return 0. ;
      }

  private :
    double * m_ptr ; // puntatore al primo elemento dell'array
    int m_size ;     // dimensione dello spazion disponibile nell'array
    int m_dim ;      // numero di elementi effettivamente salvati nell'array  

} ;


#endif
../_images/linea.png

3.4 lettura di un file di testo e visualizzazione del contenuto

  • esercizio04.cpp

/*
c++ -o esercizio04 `root-config --glibs --cflags` esercizio04.cpp statistiche.cc
*/

#include <iostream>
#include <fstream>

#include "TH1F.h"
#include "TCanvas.h"
#include "TApplication.h"

#include "statistiche.h"

using namespace std ;

int main (int argc, char ** argv)
{

  if (argc < 2)
    {
      cerr << "manca il numero di eventi da leggere" << endl ;
      exit (1) ;
    }
  ifstream input_file ("../programmi/eventi_gauss.txt") ;
  statistiche campione ;
  double input_val = 0. ;
  int max_N = atoi (argv[1]) ;

  while (true)
    {
      input_file >> input_val ;
      if (input_file.eof () == true) break ;
      campione.aggiungiNumero (input_val) ;
    }
  input_file.close () ;

  cout << "letti " << campione.N () << " numeri\n" ;

  if (max_N > campione.N ()) max_N = campione.N () ;

  double media = campione.media () ;
  double sigma = campione.dev_standard (true) ;

  TH1F histo ("histo", "istogramma", 
              max_N / 10,  // numero di bin
              media - 4 * sigma,   // limite inferiore
              media + 4 * sigma) ; // limite superiore

  for (int i = 0 ; i < max_N ; ++i)
    {
      histo.Fill (campione.elem (i)) ; 
    }

  TApplication theApp ("theApp", &argc, argv) ;
  TCanvas c1 ;
  histo.Draw () ;
  c1.Print ("histo.png", "png") ;
  theApp.Run () ;

  return 0 ;
}
  • statistiche.h

#ifndef statistiche_h
#define statistiche_h

#include <iostream>
#include <cmath>

//----------------- Statistic class -----------------

class statistiche
{
  public:

  statistiche (): dim(10), last_idx(0), arr (new float[dim]), sum (0.), sum_q (0.) {};
  statistiche (int d): dim(d), last_idx(0), arr(dim ? new float[dim] : nullptr), sum (0.), sum_q (0.) {} ;
  ~statistiche () { delete[] arr; } ;

  // aggiunge un numero alle informazioni salvate
  void aggiungiNumero (float val);

 
  // resituisce la media dei numeri aggiunti
  double media () const ;
  // restituisce la varianza dei numeri aggiunti
  // in caso di opzione true, applica la correzione di Bessel
  double varianza_1 (bool corretta = false) const ;
  // restituisce la varianza dei numeri aggiunti
  // in caso di opzione true, applica la correzione di Bessel
  double varianza_2 (bool corretta = false) const ;
  // resituisce la deviazione standard
  // in caso di opzione true, applica la correzione di Bessel
  double dev_standard (bool corretta = false) const ;
  // resituisce la deviazione standard dalla media
  double dev_standard_media (bool corretta = false) const ;
  //restituisce varianza degli scarti quadratici
  double varianza_SQ(bool corretta = false) const;
  //restituisce std dev degli scarti quadratici
  double dev_standard_SQ(bool corretta = false) const;
  //restituisce std dev della media degli scarti quadratici
  double dev_standard_media_SQ(bool corretta = false) const;
  // resituisce il numero dei numeri aggiunti
  double N () const { return last_idx; } ;
  // restituisce un singolo elemento
  double elem (int index) const ; 
  //reset
  void reset() { for(int i = 0; i < last_idx; ++i) arr[i] = 0; last_idx = 0; sum = 0. ; sum_q = 0. ;};

  private:
    int dim;
    int last_idx;
    float* arr;
    double sum ;
    double sum_q ;

   
} ;

#endif
  • statistiche.cc

#include "statistiche.h"

 void statistiche::aggiungiNumero (float val){
     
    if (last_idx >= dim) 
      {
        float * tempo = new float [2*dim] ;
        for (int i = 0 ; i < dim ; ++i) tempo[i] = arr[i] ;
        dim = dim * 2 ;
        delete [] arr ;
        arr = tempo ;
      }
    arr[last_idx] = val; 
    sum += val ;
    sum_q += val * val ;
    ++last_idx;
    return;
 }

double statistiche::media() const{
    /*
        \hat{\mu} = sum(x_i)/N
    */

    return sum/last_idx;
}

double statistiche::varianza_1(bool corretta) const{
    /*
        First variant. Based on the following. 
        Take the numerator of the variance formula:
        sum[(x_i - \mu)^2] = sum((x_i)^2 + (\mu)^2 - 2x_i\mu) = \sum(x_i^2) + N\mu^2 - 2\mu sum(x_i)
        two sums -> x_i and x_i^2. The first one is also useful to compute the mean while the second
        is only instrumental for the variance computation.
    */ 

    if (last_idx < 2) return 0 ;
    double mean = media () ;

    if (corretta) return (sum_q + last_idx * mean * mean - 2 * mean * sum) / (last_idx - 1) ;
    else  return sum_q / last_idx - mean * mean ;
    
}

double statistiche::varianza_2(bool corretta) const{
    /*
        Second variant. Performs two scans of the array -> worse performances.
        First computes the mean then sums (x_i - \mu)^2. Lastly takes the mean
        of the square deviations (with or without Bessel correction).
    */ 

    if (last_idx < 2) return 0 ;
    double mean  = media();
    double sum_q = 0;
    for(int i = 0; i < last_idx; ++i){
        sum_q += pow(arr[i] - mean, 2);
    }

    if (corretta) return sum_q/(last_idx-1);
    else  return sum_q/last_idx;

}

double statistiche::dev_standard (bool corretta) const{
    /*
        dev_std = sqrt(var)
    */ 
    
    return sqrt(varianza_1(corretta)); 
}

double statistiche::dev_standard_media (bool corretta) const{
    /*
        dev_std_media = (dev_std)/sqrt(N)
    */  
    
    return sqrt(varianza_1(corretta)/last_idx); 
}

double statistiche::varianza_SQ(bool corretta) const{
    
    double var = varianza_1(); // mean of the squared deviations var = (x_i - \mu)^2 / N
    double mean = media(); // \mu
    
    if (corretta) return sum_q/(last_idx - 1);
    else return sum_q/last_idx;
    
}

double statistiche::dev_standard_SQ (bool corretta) const{
    /*
        dev_std = sqrt(var)
    */ 
    
    return sqrt(varianza_SQ(corretta)); 
}

double statistiche::dev_standard_media_SQ (bool corretta) const{
    /*
        dev_std_media = sqrt(var)
    */ 
    
    return sqrt(varianza_SQ(corretta)/last_idx);
}

double statistiche::elem (int index) const 
{
    if (index < 0 || index >= last_idx) return 0. ;
    return arr[index];
}     
../_images/linea.png

3.5 lettura di file di testo e visualizzazione simultanea di due istogrammi

  • esercizio01.cpp

/*
c++ -o esercizio01 `root-config --glibs --cflags` esercizio01.cpp
*/

#include "TH1F.h"
#include "TCanvas.h"
#include "TApplication.h"

int main (int argc, char ** argv)
{
  

  TH1F histo ("histo", "prova", 10, 0., 10.) ;
  histo.Fill (9.4) ;
  histo.Fill (2.1) ;
  histo.Fill (123.3) ;
  histo.Fill (0.0004) ;
  histo.Fill (2.9) ;

  TApplication theApp ("theApp", &argc, argv) ;
  TCanvas c1 ;
  histo.Draw () ;
  c1.Print ("histo.png", "png") ;
  theApp.Run () ;

  return 0 ;
}
../_images/linea.png

3.7 Classe statistiche

  • statistiche.h

#ifndef statistiche_h
#define statistiche_h

#include <iostream>
#include <cmath>

//----------------- Statistic class -----------------

class statistiche
{
  public:

  statistiche (): dim(10), last_idx(0), arr (new float[dim]), sum (0.), sum_q (0.) {};
  statistiche (int d): dim(d), last_idx(0), arr(dim ? new float[dim] : nullptr), sum (0.), sum_q (0.) {} ;
  ~statistiche () { delete[] arr; } ;

  // aggiunge un numero alle informazioni salvate
  void aggiungiNumero (float val);

 
  // resituisce la media dei numeri aggiunti
  double media () const ;
  // restituisce la varianza dei numeri aggiunti
  // in caso di opzione true, applica la correzione di Bessel
  double varianza_1 (bool corretta = false) const ;
  // restituisce la varianza dei numeri aggiunti
  // in caso di opzione true, applica la correzione di Bessel
  double varianza_2 (bool corretta = false) const ;
  // resituisce la deviazione standard
  // in caso di opzione true, applica la correzione di Bessel
  double dev_standard (bool corretta = false) const ;
  // resituisce la deviazione standard dalla media
  double dev_standard_media (bool corretta = false) const ;
  //restituisce varianza degli scarti quadratici
  double varianza_SQ(bool corretta = false) const;
  //restituisce std dev degli scarti quadratici
  double dev_standard_SQ(bool corretta = false) const;
  //restituisce std dev della media degli scarti quadratici
  double dev_standard_media_SQ(bool corretta = false) const;
  // resituisce il numero dei numeri aggiunti
  double N () const { return last_idx; } ;
  // restituisce un singolo elemento
  double elem (int index) const ; 
  //reset
  void reset() { for(int i = 0; i < last_idx; ++i) arr[i] = 0; last_idx = 0; sum = 0. ; sum_q = 0. ;};

  private:
    int dim;
    int last_idx;
    float* arr;
    double sum ;
    double sum_q ;

   
} ;

#endif
  • statistiche.cc

#include "statistiche.h"

 void statistiche::aggiungiNumero (float val){
     
    if (last_idx >= dim) 
      {
        float * tempo = new float [2*dim] ;
        for (int i = 0 ; i < dim ; ++i) tempo[i] = arr[i] ;
        dim = dim * 2 ;
        delete [] arr ;
        arr = tempo ;
      }
    arr[last_idx] = val; 
    sum += val ;
    sum_q += val * val ;
    ++last_idx;
    return;
 }

double statistiche::media() const{
    /*
        \hat{\mu} = sum(x_i)/N
    */

    return sum/last_idx;
}

double statistiche::varianza_1(bool corretta) const{
    /*
        First variant. Based on the following. 
        Take the numerator of the variance formula:
        sum[(x_i - \mu)^2] = sum((x_i)^2 + (\mu)^2 - 2x_i\mu) = \sum(x_i^2) + N\mu^2 - 2\mu sum(x_i)
        two sums -> x_i and x_i^2. The first one is also useful to compute the mean while the second
        is only instrumental for the variance computation.
    */ 

    if (last_idx < 2) return 0 ;
    double mean = media () ;

    if (corretta) return (sum_q + last_idx * mean * mean - 2 * mean * sum) / (last_idx - 1) ;
    else  return sum_q / last_idx - mean * mean ;
    
}

double statistiche::varianza_2(bool corretta) const{
    /*
        Second variant. Performs two scans of the array -> worse performances.
        First computes the mean then sums (x_i - \mu)^2. Lastly takes the mean
        of the square deviations (with or without Bessel correction).
    */ 

    if (last_idx < 2) return 0 ;
    double mean  = media();
    double sum_q = 0;
    for(int i = 0; i < last_idx; ++i){
        sum_q += pow(arr[i] - mean, 2);
    }

    if (corretta) return sum_q/(last_idx-1);
    else  return sum_q/last_idx;

}

double statistiche::dev_standard (bool corretta) const{
    /*
        dev_std = sqrt(var)
    */ 
    
    return sqrt(varianza_1(corretta)); 
}

double statistiche::dev_standard_media (bool corretta) const{
    /*
        dev_std_media = (dev_std)/sqrt(N)
    */  
    
    return sqrt(varianza_1(corretta)/last_idx); 
}

double statistiche::varianza_SQ(bool corretta) const{
    
    double var = varianza_1(); // mean of the squared deviations var = (x_i - \mu)^2 / N
    double mean = media(); // \mu
    
    if (corretta) return sum_q/(last_idx - 1);
    else return sum_q/last_idx;
    
}

double statistiche::dev_standard_SQ (bool corretta) const{
    /*
        dev_std = sqrt(var)
    */ 
    
    return sqrt(varianza_SQ(corretta)); 
}

double statistiche::dev_standard_media_SQ (bool corretta) const{
    /*
        dev_std_media = sqrt(var)
    */ 
    
    return sqrt(varianza_SQ(corretta)/last_idx);
}

double statistiche::elem (int index) const 
{
    if (index < 0 || index >= last_idx) return 0. ;
    return arr[index];
}