Esempi: Appendice 4

../_images/linea.png

A4.0 generazione di coppie di punti secondo una legge funzionale y = g(x), con dispersione gaussiana lungo y

  • main_00.cpp

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

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>

#include "generazione.h"

using namespace std ;

// retta con termine noto non nullo
double g (double x)
  {
     return 3.14 + 2 * x ;
  }


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


int main (int argc, char ** argv)
  {
    if (argc < 3)
      {
        cout << "usage: " << argv[0] << " sigma_y nomefile.txt [Npoints = 5]" << endl ;
        exit (1) ;
      }
    double sigma = fabs (atof (argv[1])) ;

    ofstream output_file ;
    output_file.open (argv[2]) ;

    int Npoints = 5 ; 
    if (argc > 3) Npoints = atoi (argv[3]) ;
    for (int i = 0 ; i < Npoints ; ++i)
      {
        double epsilon = rand_TAC_gaus (sigma) ; 
        output_file << i << " " << g (i) + epsilon << "\n" ;
      }

    output_file.close () ;

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

A4.1 determinazione dei parametri di una funzione lineare y = a + bx con il metodo dei minimi quadrati

  • main_01.cpp

/*
c++ -o main_01 algebra_2.cc main_01.cpp
*/

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>

#include "algebra_2.h"

using namespace std ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


int main (int argc, char ** argv)
  {
    if (argc < 3)
      {
        cout << "usage: " << argv[0] << " sigma_y nomefile.txt" << endl ;
        exit (1) ;
      }

    // lettura del file di input
    // -------------------------

    double sigma = atof (argv[1]) ;
    ifstream input_file ;
    input_file.open (argv[2]) ;
    vector<double> asse_x ;
    vector<double> asse_y ;
    while (true) 
      {
        double dummy_x = 0. ; 
        double dummy_y = 0. ; 
        input_file >> dummy_x ;
        input_file >> dummy_y ;
        if (input_file.eof () == true) break ;
        asse_x.push_back (dummy_x) ;
        asse_y.push_back (dummy_y) ;
      } 
    input_file.close () ;

    int N_points = asse_x.size () ; 

    // creazione delle matrici del metodo dei minimi quadrati
    // -------------------------

    matrice H (N_points, 2) ;
    for (int i_point = 0 ; i_point < N_points ; ++i_point)
      {
        H.setCoord (i_point, 0, 1) ;
        H.setCoord (i_point, 1, asse_x.at (i_point)) ;
      }
    vettore y (asse_y) ;

    // ipotesi: incertezza costante su tutti i valori
    matrice V (N_points) ;
    for (int i_point = 0 ; i_point < N_points ; ++i_point) 
      V.setCoord (i_point, i_point, sigma * sigma) ;

    // calcolo dei parametri di interesse
    // -------------------------

    matrice V_inv = V.inversa () ;
    //Metzger, cap. 8.5.2, eq. 8.116
    matrice theta_v = (H.trasposta () * V_inv * H).inversa () ;
    //Metzger, cap. 8.5.2, eq. 8.112
    vettore theta = (theta_v * (H.trasposta () * V_inv)) * y ;
    cout << "parametri risultanti dai mimimi quadrati: \n" ;
    theta.stampa () ;
    cout << "matrice di covarianza dei parametri risultanti dai mimimi quadrati: \n" ;
    theta_v.stampa () ;
    cout << "termine noto: " << theta.at (0) << " +- " << sqrt (theta_v.at (0, 0)) << endl ;
    cout << "pendenza:     " << theta.at (1) << " +- " << sqrt (theta_v.at (1, 1)) << endl ;

    return 0 ;
  }
  • algebra_2.h

#ifndef algebra_2_h
#define algebra_2_h

#include <cmath>
#include <vector>

class matrice ;

class vettore 
{
  public:
    vettore (int N) ;
    vettore (const std::vector<double> & v) ;
    vettore (const vettore & orig) ;
    vettore & operator = (const vettore & orig) ;
    ~vettore () ;

    void    setCoord (int i, double val) ;
    double  norm () const ;
    int     N () const ;
    double  at (int i) const ;
    void    stampa () const ;
    double  operator[] (int i) const ;
    vettore operator+ (const vettore & v) const ;
    vettore operator- (const vettore & v) const ;
    vettore operator* (double val) const ;
    double  dot (const vettore & v) const ;

  private:
    double * m_elementi ;
    int m_N ;
} ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


class matrice
{
  public:
    matrice (int R) ;
    matrice (int R, int C) ;
    matrice (const matrice & orig) ;
    matrice & operator= (const matrice & orig) ;
    ~matrice () ;

    void    setCoord (int i, int j, double val) ;
    double  at (int i, int j) const ;
    void    stampa () const ;
    bool    quadrata () const ;
    int     rango () const ;
    int     N_righe () const ;
    int     N_colonne () const ;
    bool    simmetrica () const ;
    void    dimensioni () const ;
    matrice minore (int r, int c) const ;
    matrice inversa () const ;
    matrice trasposta () const ;
    double  determinante () const ;
    void    operator*= (double val) ;

  private:
    int index (int i, int j) const ;
    int m_R ;
    int m_C ;
    double * m_elementi ;
} ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


vettore operator* (const matrice & M, const vettore & v) ;
matrice operator* (const matrice & M1, const matrice & M2) ;
matrice operator+ (const matrice & M1, const matrice & M2) ;

#endif
  • algebra_2.cc

#include "algebra_2.h"

#include <iostream>

using namespace std ;

vettore::vettore (int N) : 
  m_N (N),
  m_elementi (new double[N])
  {
    for (int i = 0 ; i < m_N ; ++i) m_elementi[i] = 0. ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore::vettore (const std::vector<double> & v) :
  m_N (v.size ()),
  m_elementi (new double[v.size ()])
  {
    for (int i = 0 ; i < m_N ; ++i) m_elementi[i] = v.at (i) ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore::vettore (const vettore & orig) : 
  m_N (orig.m_N),
  m_elementi (new double[orig.m_N])
  {
    for (int i = 0 ; i < m_N ; ++i) m_elementi[i] = orig.m_elementi[i] ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore & vettore::operator = (const vettore & orig)
  {
    m_N = orig.m_N ;
    m_elementi = new double[m_N] ;
    for (int i = 0 ; i < m_N ; ++i) m_elementi[i] = orig.m_elementi[i] ;
    return *this ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore::~vettore () { delete [] m_elementi ; } 

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void vettore::setCoord (int i, double val)
  {
    if (i < 0 || i > m_N-1) return ;
    m_elementi[i] = val ;
    return ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double vettore::norm () const
  {
    double sum = m_elementi[0] * m_elementi[0] ; 
    for (int i = 1 ; i < m_N ; ++i) sum += m_elementi[i] * m_elementi[i] ;
    return sqrt (sum) ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

int vettore::N () const {return m_N ;}

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double vettore::at (int i) const
  {
    if (i < 0 || i > m_N-1) return 0. ;
    return m_elementi[i] ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void vettore::stampa () const
  {
    for (int i = 0 ; i < m_N ; ++i)
      cout << this->at (i) << "\t" ;
    cout << "\n" ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double vettore::operator[] (int i) const
  {
    return m_elementi[i] ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore vettore::operator+ (const vettore & v) const 
  {
    vettore result (*this) ;
    for (int i = 0 ; i < m_N ; ++i) 
      result.setCoord (i, result.at (i) + v.at (i)) ;
    return result ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore vettore::operator- (const vettore & v) const 
  {
    vettore result (*this) ;
    for (int i = 0 ; i < m_N ; ++i) 
      result.setCoord (i, result.at (i) - v.at (i)) ;
    return result ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

vettore vettore::operator* (double val) const 
  {
    vettore result (*this) ;
    for (int i = 0 ; i < m_N ; ++i) 
      result.setCoord (i, result.at (i) * val) ;
    return result ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double vettore::dot (const vettore & v) const
  {
    if (m_N != v.N ())
      {
        cerr << "prodotto scalare fra vettori di dimensione diversa" << endl ;
        exit (1) ;
      }
    double result = 0 ;
    for (int i = 0 ; i < m_N ; ++i) result += this->at (i) * v.at (i) ; 
    return result ;
  }

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

matrice::matrice (int R) :
  m_R (R),
  m_C (R),
  m_elementi (new double [R * R]) 
  {
    for (int i = 0 ; i < m_R ; ++i) 
      for (int j = 0 ; j < m_C ; ++j) 
        this->setCoord (i, j, 0.) ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice::matrice (int R, int C) :
  m_R (R),
  m_C (C),
  m_elementi (new double [R * C]) 
  {
    for (int i = 0 ; i < m_R ; ++i) 
      for (int j = 0 ; j < m_C ; ++j) 
        this->setCoord (i, j, 0.) ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice::matrice (const matrice & orig) :
  m_R (orig.m_R),
  m_C (orig.m_C),
  m_elementi (new double [orig.m_R * orig.m_C]) 
  {
    for (int i = 0 ; i < m_R ; ++i) 
      for (int j = 0 ; j < m_C ; ++j) 
        this->setCoord (i, j, orig.at (i,j)) ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice & matrice::operator= (const matrice & orig)
  {
    m_R = orig.m_R ;
    m_C = orig.m_C ;
    m_elementi = new double [orig.m_R * orig.m_C] ;
    for (int i = 0 ; i < m_R ; ++i) 
      for (int j = 0 ; j < m_C ; ++j) 
        this->setCoord (i, j, orig.at (i,j)) ;
    return *this ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice::~matrice () { delete [] m_elementi ; } 

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

int matrice::index (int i, int j) const 
  {
    int index = j + i * m_C ;
    if (index < 0 || index >= m_R * m_C) 
      {
        cerr << "indici matrice fuori intervallo" << endl ;
        exit (1) ;
      }  
    return index ; 
  } 

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void matrice::setCoord (int i, int j, double val)
  {
    m_elementi[index (i, j)] = val ;
    return ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double matrice::at (int i, int j) const
  {
    return m_elementi[index (i, j)] ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void matrice::stampa () const
  {
    for (int i = 0 ; i < m_R ; ++i)
      {
        for (int j = 0 ; j < m_C ; ++j)
          cout << this->at (i, j) << "\t" ;
        cout << "\n" ;
      }
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

bool matrice::quadrata () const {return (m_R == m_C) ;} 

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

// per matrici quadrate
int matrice::rango () const {return m_R ;}

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

// per matrici quadrate
int matrice::N_righe () const {return m_R ;}

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

// per matrici quadrate
int matrice::N_colonne () const {return m_C ;}

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

bool matrice::simmetrica () const
  {
    if (!this->quadrata ()) return false ;
    for (int i = 0 ; i < m_R ; ++i)
      for (int j = i+1 ; j < m_R ; ++j)
        if (fabs (this->at (i,j) - this->at (j,i)) > 0.00001) return false ;
    return true ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void matrice::dimensioni () const { cout << m_R << " x " << m_C << endl ; } 

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

// produce la sottomatrice in cui mancano riga r e colonna c
matrice matrice::minore (int r, int c) const
  {
    matrice M_out (m_R-1, m_C-1) ;
    int i_new = 0 ; 
    for (int i = 0 ; i < m_R ; ++i)
      {
        if (i == r) continue ;
        int j_new = 0 ;
        for (int j = 0 ; j < m_C ; ++j)
          {
            if (j == c) continue ;
            M_out.setCoord (i_new, j_new, this->at (i,j)) ;
            ++j_new ;
          }
        ++i_new ;
      }
    return M_out ;  
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice matrice::inversa () const
  {
    double invdet = this->determinante () ;
    matrice M_out (m_C, m_R) ;
    if (invdet < 0.000001) return M_out ;
    invdet = 1. / invdet ;
    for (int i = 0 ; i < m_R ; ++i)
      {
        for (int j = 0 ; j < m_C ; ++j)
          {
            M_out.setCoord (
               j, i,  // trasposta
               this->minore (i,j).determinante () * pow (-1, i+j+2) // complemento algebrico
               * invdet  // divisione per il determinante
            ) ;
          }
      }
    return M_out ;
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

matrice matrice::trasposta () const
  {
    matrice M_out (m_C, m_R) ;
    for (int i = 0 ; i < m_R ; ++i)
      for (int j = 0 ; j < m_C ; ++j)
        M_out.setCoord (j, i, this->at (i,j)) ;
    return M_out ;  
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

double matrice::determinante () const
  {
    if (!this->quadrata ()) return 0. ;
    if (this->rango () == 1) return this->at (0,0) ;
    double det = 0. ;
    for (int i = 0 ; i < m_R ; ++i)
      {
        det += this->at (0,i) * pow (-1, i + 2) * this->minore (0,i).determinante () ;
      }
    return det ; 
  }

// .... .... .... .... .... .... .... .... .... .... .... .... .... ....

void matrice::operator*= (double val)
  {
    for (int i = 0 ; i < m_R * m_C ; ++i)
      {
        m_elementi[i] *= val ;
      }
    return ; 
  }

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

vettore operator* (const matrice & M, const vettore & v)
  {
    if (M.N_colonne () != v.N ())
      {
        cerr << "prodotto fra matrice e vettore con dimensioni non compatibili" << endl ;
        exit (1) ;
      }
  
    vettore w (M.N_righe ()) ;
  
    for (int i = 0 ; i < M.N_righe () ; ++i)
      {
        double res = 0 ;
        for (int j = 0 ; j < M.N_colonne () ; ++j) res += M.at (i,j) * v.at (j) ;
        w.setCoord (i, res) ;
      }
    return w ;
  }

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

matrice operator* (const matrice & M1, const matrice & M2)
  {
    if (M1.N_colonne () != M2.N_righe ())
      {
        cerr << "prodotto fra matrici con dimensioni non compatibili" << endl ;
        exit (1) ;
      }
  
    matrice M_out (M1.N_righe (), M2.N_colonne ()) ;
  
    for (int i = 0 ; i < M1.N_righe () ; ++i)
      for (int k = 0 ; k < M2.N_colonne () ; ++k)
        {
          double res = 0 ;
          for (int j = 0 ; j < M1.N_colonne () ; ++j) res += M1.at (i,j) * M2.at (j,k) ;
          M_out.setCoord (i, k, res) ;
        }
    return M_out ;
  }

// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----

matrice operator+ (const matrice & M1, const matrice & M2)
  {
    if (M1.N_colonne () != M2.N_colonne () ||
        M1.N_righe () != M2.N_righe ())
      {
        cerr << "somma fra matrici con dimensioni non compatibili" << endl ;
        exit (1) ;
      }
  
    matrice M_out (M1.N_righe (), M1.N_colonne ()) ;
  
    for (int i = 0 ; i < M1.N_righe () ; ++i)
      for (int k = 0 ; k < M1.N_colonne () ; ++k)
        {
          M_out.setCoord (i, k, M1.at (i,k) + M2.at (i,k)) ;
        }
    return M_out ;
  }
  • generazione.h

#ifndef generazione_h
#define generazione_h


// media sempre zero
// non normalizzata, cosi' il massimo in zero vale sempre 1
double fgaus (double x, double sigma) 
  {
    return exp (-0.5 * x * x / (sigma * sigma)) ; 
  }


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


double rand_range (double min, double max)
  {
    return min + (max - min) * rand () / static_cast<double> (RAND_MAX) ;
  } 


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


double rand_TAC_gaus (double sigma)
  {
    double x = 0. ;
    double y = 0. ; 
    do {
      x = rand_range (-5 * sigma, 5 * sigma) ;
      y = rand_range (0, 1.) ;
    } while (y > fgaus (x, sigma)) ;
    return x ; 
  }


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


double rand_TAC_uniform (double sigma)
  {
//    sqrt (3) = 1.7320508076
    return rand_range (-1.7320508076 * sigma, 1.7320508076 * sigma) ; 
  }

#endif
../_images/linea.png

A4.2 studio del risultato del fit con toy experiment

  • main_02.cpp

/*
c++ -o main_02 `root-config --glibs --cflags` algebra_2.cc main_02.cpp
*/

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>

#include "TH1F.h"
#include "TH2F.h"
#include "TCanvas.h"

#include "algebra_2.h"
#include "generazione.h"

// retta con termine noto non nullo
double g (double x)
  {
     return 3.14 + 2 * x ;
  }


using namespace std ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


int main (int argc, char ** argv)
  {
    if (argc < 4)
      {
        cout << "usage: " << argv[0] << " sigma_y N_points Ntoys" << endl ;
        exit (1) ;
      }

    double sigma  = atof (argv[1]) ;
    int N_points  = atoi (argv[2]) ;
    int N_toys    = atoi (argv[3]) ;

    // istogrammi per il disegno dei risultati del fit
    TH1F h_a ("h_a", "termine noto", 
              100, 3.14 * (1. - 1. * sigma), 3.14 * (1. + 1. * sigma) ) ;
    TH1F h_b ("h_b", "coefficiente angolare", 
              100, 2. * (1. - 1. * sigma), 2. * (1. + 1. * sigma) ) ;

    TH2F h_ab ("h_ab", "parametri", 
              50, 3.14 * (1. - 1. * sigma), 3.14 * (1. + 1. * sigma),
              50, 2. * (1. - 1. * sigma), 2. * (1. + 1. * sigma) ) ;
    h_ab.GetXaxis ()->SetTitle ("termine noto") ;
    h_ab.GetYaxis ()->SetTitle ("coefficiente angolare") ;
    h_ab.SetStats (0) ;

    // contatori per la determinazione dell'intervallo di copertura
    int cont_a  = 0 ;
    int cont_b  = 0 ;

    // generazione dei toy experiment e calcolo del fit per ciascuno di essi
    // ----------------------------------------

    //loop over toys
    for (int i_toy = 0 ; i_toy < N_toys ; ++i_toy)
      {
        vector<double> asse_x ;
        vector<double> asse_y ;

        // generare il sample
        // --------------------

        for (int i_point = 0 ; i_point < N_points ; ++i_point)
          {
            double epsilon = rand_TAC_gaus (sigma) ; 
            asse_x.push_back (i_point) ;
            asse_y.push_back (g (i_point) + epsilon) ;
          }

        // trovare i parametri
        // --------------------

        matrice H (N_points, 2) ;
        for (int i = 0 ; i < N_points ; ++i)
          {
            H.setCoord (i, 0, 1) ;
            H.setCoord (i, 1, asse_x.at (i)) ;
          }
        vettore y (asse_y) ;
        matrice V (N_points) ;
        for (int i = 0 ; i < N_points ; ++i) V.setCoord (i, i, sigma * sigma) ;
    
        matrice V_inv = V.inversa () ;
        matrice theta_v = (H.trasposta () * V_inv * H).inversa () ;
        vettore theta = (theta_v * (H.trasposta () * V_inv)) * y ;

        // riempire istogrammi e contatori
        // --------------------

        h_a.Fill (theta.at (0)) ;
        h_b.Fill (theta.at (1)) ;
        h_ab.Fill (theta.at (0), theta.at (1)) ;

        if (fabs (theta.at (0) - 3.14) < sqrt (theta_v.at (0,0))) ++cont_a ;
        if (fabs (theta.at (1) - 2.  ) < sqrt (theta_v.at (1,1))) ++cont_b ;

      } //loop over toys

    cout << "copertura parametro a: " << static_cast<double> (cont_a) / N_toys << endl ;
    cout << "copertura parametro b: " << static_cast<double> (cont_b) / N_toys << endl ;

    TCanvas c1 ("c1", "", 800, 800) ;
    c1.SetRightMargin (0.15) ;
    h_a.SetFillColor (kOrange + 1) ;
    h_a.SetLineColor (kGray + 1) ;
    h_a.Draw ("hist") ;
    c1.Print ("parametro_a.png", "png") ;
 
    h_b.Draw ("hist") ;
    h_b.SetFillColor (kOrange + 1) ;
    h_b.SetLineColor (kGray + 1) ;
    c1.Print ("parametro_b.png", "png") ;

    h_ab.Draw ("colz") ;
    c1.Print ("parametri_2D.png", "png") ;

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

A4.3 determinazione della varianza degli scarti delle singole misure y<sub>i</sub>

  • main_03.cpp

/*
c++ -o main_03 `root-config --glibs --cflags` algebra_2.cc main_03.cpp
*/

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>

#include "TH1F.h"
#include "TCanvas.h"
#include "TH2F.h"
#include "TFile.h"

#include "algebra_2.h"
#include "generazione.h"

// retta con termine noto non nullo
double g (double x)
  {
     return 3.14 + 2 * x ;
  }

using namespace std ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


int main (int argc, char ** argv)
  {
    if (argc < 4)
      {
        cout << "usage: " << argv[0] << " sigma_y N_points Ntoys" << endl ;
        exit (1) ;
      }

    double sigma  = atof (argv[1]) ;
    int N_points  = atoi (argv[2]) ;
    int N_toys    = atoi (argv[3]) ;

    // istogrammi per il disegno dei risultati del fit

    TH1F h_scarti ("h_scarti", "scarti", 200, 0., 5 * N_points) ;
    TH1F h_varianza ("h_varianza", "varianza calcolata", 50, 0., 10 * sigma) ;
    TH1F h_sigma ("h_sigma", "sigma calcolata", 50, 0., 3 * sigma) ;

    // generazione dei toy experiment e calcolo del fit per ciascuno di essi
    // ----------------------------------------

    //loop over toys
    for (int i_toy = 0 ; i_toy < N_toys ; ++i_toy)
      {
        vector<double> asse_x ;
        vector<double> asse_y ;

        // generare il sample
        // --------------------

        for (int i_point = 0 ; i_point < N_points ; ++i_point)
          {
            double epsilon = rand_TAC_gaus (sigma) ; 
            asse_x.push_back (i_point) ;
            asse_y.push_back (g (i_point) + epsilon) ;
          }

        // trovare i parametri
        // --------------------

        matrice H (N_points, 2) ;
        for (int i_point = 0 ; i_point < N_points ; ++i_point)
          {
            H.setCoord (i_point, 0, 1) ;
            H.setCoord (i_point, 1, asse_x.at (i_point)) ;
          }
        vettore y (asse_y) ;
        matrice V (N_points) ;
        for (int i_point = 0 ; i_point < N_points ; ++i_point) 
          V.setCoord (i_point, i_point, 1.) ;
    
        matrice V_inv = V.inversa () ;
        matrice theta_v = (H.trasposta () * V_inv * H).inversa () ;
        vettore theta = (theta_v * (H.trasposta () * V_inv)) * y ;

        // calcolo la somma degli scarti quadratici normalizzati per l'incertezza
        double Q2min = (y - H * theta).dot (V_inv * (y - H * theta)) ;
        h_scarti.Fill (Q2min) ;

        double varianza = Q2min / (N_points - 2) ;
        h_varianza.Fill (varianza) ;
        h_sigma.Fill (sigma) ;

      } //loop over toys

    cout << "sigma = "
         << sqrt (h_scarti.GetMean () / (N_points - 2))
         << endl ;
         
    TCanvas c1 ("c1", "", 800, 800) ;
    c1.SetRightMargin (0.15) ;
    h_scarti.Draw ("hist") ;
    c1.Print ("scarti.png", "png") ;
 
    TFile f_out ("main_04.root", "recreate") ;
    h_scarti.Write () ;
    h_sigma.Write () ;
    h_varianza.Write () ;
    f_out.Close () ;

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

A4.4 confronto della distribuzione di Q<sup>2</sup><sub>min</sub> con la forma &Chi;<sup>2</sup>(x, N-k) con scarti non gaussiani

  • main_04.cpp

/*
c++ -o main_04 `root-config --glibs --cflags` algebra_2.cc main_04.cpp
*/

#include <cstdlib>
#include <iostream>
#include <cmath>
#include <fstream>
#include <vector>

#include "TH1F.h"
#include "TCanvas.h"
#include "TH2F.h"
#include "TFile.h"

#include "algebra_2.h"
#include "generazione.h"

// retta con termine noto non nullo
double g (double x)
  {
     return 3.14 + 2 * x ;
  }

using namespace std ;


// ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----


int main (int argc, char ** argv)
  {
    if (argc < 4)
      {
        cout << "usage: " << argv[0] << " sigma_y N_points Ntoys" << endl ;
        exit (1) ;
      }

    double sigma  = atof (argv[1]) ;
    int N_points  = atoi (argv[2]) ;
    int N_toys    = atoi (argv[3]) ;

    // istogrammi per il disegno dei risultati del fit

    TH1F h_scarti ("h_scarti", "scarti", 200, 0., 5 * N_points) ;
    TH1F h_varianza ("h_varianza", "varianza calcolata", 50, 0., 10 * sigma) ;
    TH1F h_sigma ("h_sigma", "sigma calcolata", 50, 0., 3 * sigma) ;

    // generazione dei toy experiment e calcolo del fit per ciascuno di essi
    // ----------------------------------------

    //loop over toys
    for (int i_toy = 0 ; i_toy < N_toys ; ++i_toy)
      {
        vector<double> asse_x ;
        vector<double> asse_y ;

        // generare il sample
        // --------------------

        for (int i_point = 0 ; i_point < N_points ; ++i_point)
          {
            double epsilon = rand_TAC_uniform (sigma) ; 
            asse_x.push_back (i_point) ;
            asse_y.push_back (g (i_point) + epsilon) ;
          }

        // trovare i parametri
        // --------------------

        matrice H (N_points, 2) ;
        for (int i_point = 0 ; i_point < N_points ; ++i_point)
          {
            H.setCoord (i_point, 0, 1) ;
            H.setCoord (i_point, 1, asse_x.at (i_point)) ;
          }
        vettore y (asse_y) ;
        matrice V (N_points) ;
        for (int i_point = 0 ; i_point < N_points ; ++i_point) 
          V.setCoord (i_point, i_point, sigma * sigma) ;
    
        matrice V_inv = V.inversa () ;
        matrice theta_v = (H.trasposta () * V_inv * H).inversa () ;
        vettore theta = (theta_v * (H.trasposta () * V_inv)) * y ;

        // calcolo la somma degli scarti quadratici normalizzati per l'incertezza
        double Q2min = (y - H * theta).dot (V_inv * (y - H * theta)) ;
        h_scarti.Fill (Q2min) ;

        double varianza = Q2min / (N_points - 2) ;
        h_varianza.Fill (varianza) ;
        h_sigma.Fill (sigma) ;

      } //loop over toys

    cout << "sigma = "
         << sqrt (h_scarti.GetMean () / (N_points - 2))
         << endl ;
         
    TCanvas c1 ("c1", "", 800, 800) ;
    c1.SetRightMargin (0.15) ;
    h_scarti.Draw ("hist") ;
    c1.Print ("scarti.png", "png") ;
 
    return 0 ;
  }
../_images/linea.png ../_images/linea.png