venerdì, novembre 24, 2006

l'istogramma implementato

ecco una possibile implementazione di istogramma.cc

#include "istogramma.h"
#include <cmath>
#include <iostream>


istogramma::istogramma () :
m_somma (0.) ,
m_sommaSq (0.) ,
m_entries (0) ,
m_binsNumber (0) ,
m_bins (0) ,
m_minimum (0) ,
m_maximum (0) ,
m_invStep (0)
{}


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


istogramma::istogramma (const double & minimo,
const double & massimo,
const int & bins) :
m_somma (0.) ,
m_sommaSq (0.) ,
m_entries (0) ,
m_binsNumber (bins) ,
m_bins (new int[m_binsNumber]) ,
m_minimum (minimo) ,
m_maximum (massimo) ,
m_invStep (m_binsNumber/(m_maximum - m_minimum))
{
// TODO: controlli
// azzero gli elementi dell'istogramma
for (int i=0; i<m_binsNumber; ++i)
{
m_bins[i] = 0 ;
}
}


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


istogramma::istogramma (const istogramma & original) :
m_somma (original.m_somma) ,
m_sommaSq (original.m_sommaSq) ,
m_entries (original.m_entries) ,
m_binsNumber (original.m_binsNumber) ,
m_bins (new int[m_binsNumber]) ,
m_minimum (original.m_minimum) ,
m_maximum (original.m_maximum) ,
m_invStep (m_binsNumber/(m_maximum - m_minimum))
{
for (int i=0; i<m_binsNumber; ++i)
{
m_bins[i] = original.m_bins[i] ;
}
}


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


istogramma::~istogramma ()
{
delete [] m_bins ;
}


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


istogramma & istogramma::operator= (istogramma const & original)
{
if (m_binsNumber) delete [] m_bins ;
m_somma = original.m_somma ;
m_sommaSq = original.m_sommaSq ;
m_entries = original.m_entries ;
m_binsNumber = original.m_binsNumber ;
m_bins = new int[m_binsNumber] ;
m_minimum = original.m_minimum ;
m_maximum = original.m_maximum ;
m_invStep = m_binsNumber/(m_maximum - m_minimum) ;

for (int i=0; i<m_binsNumber; ++i)
{
m_bins[i] = original.m_bins[i] ;
}
return *this ;
}


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


int
istogramma::fill (const double & value)
{
m_somma += value ;
m_sommaSq += value * value ;
++m_entries ;
int bin = static_cast<int> (floor ((value-m_minimum) * m_invStep)) ;
++m_bins[bin] ;
return m_bins[bin] ;
}


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


double
istogramma::getMean () const
{
if (m_entries) return m_somma / m_entries ;
else return 0 ;
}


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


double
istogramma::getSigma () const
{
if (m_entries) return sqrt ((m_sommaSq - m_somma*m_somma/m_entries)/m_entries) ;
else return -1 ;
}


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


int
istogramma::getEntries () const
{
return m_entries ;
}


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


void
istogramma::print (int altezza, int larghezza) const
{
int maxIsto = getMaxValue () ;

// disegno le singole barre:
std::cout << " +---------------------->\n" ;
// loop sugli elementi dell'istogramma
for (int i=0; i<m_binsNumber; ++i)
{
int numeroSimboli = m_bins[i] * altezza / maxIsto ;
std::cout << " | " ;
for (int j=0; j<numeroSimboli; ++j) std::cout << "#" ;
for (int j=numeroSimboli; j<altezza+2; ++j) std::cout << " " ;
std::cout << "m_bins[" << i << "] : " << m_bins[i] ;
std::cout << "\n" ;
} // chiuso loop sugli elementi dell'istogramma
std::cout << " |\n\\/\n\n" ;
std::cout << "media = " << getMean () << "\n" ;
std::cout << "sigma = " << getSigma () << "\n" ;
return ;
}


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


void
istogramma::printOr (int altezza, int larghezza) const
{
int maxIsto = getMaxValue () ;
// istogramma "re-binnato" per farne il plot in orizzontale
int * localBins ;

// se larghezza e' maggiore del numero di bin,
// cerca di plottare l'istogramma rispettando le proporzioni
// allargandolo il piu' possibile
if (larghezza/m_binsNumber)
{
int volte = larghezza/m_binsNumber ;
localBins = new int[m_binsNumber*volte] ;
for (int i=0 ; i<m_binsNumber ; ++i)
for (int j=0 ; j<volte; ++j)
localBins[i*volte+j] = m_bins[i] ;
larghezza = volte * m_binsNumber ;
}
else
{
int volte = m_binsNumber/larghezza ;
localBins = new int[m_binsNumber/(volte+1)+1] ;
for (int i=0 ; i<m_binsNumber/(volte+1)+1 ; ++i) localBins[i] = 0 ;
for (int i=0 ; i<m_binsNumber ; ++i)
localBins[i/(volte+1)] += m_bins[i] ;
larghezza = m_binsNumber/(volte+1)+1 ;
maxIsto *= (volte+1) ;
}

std::cout << "\n/\\\n|\n" ;
// loop sulle righe
for (int i=0 ; i<altezza; ++i)
{
std::cout << "| " ;
// loop sui caratteri della riga
for (int j=0 ; j<larghezza; ++j)
{
int numeroSimboli = localBins[j] * altezza / maxIsto ;
if (altezza-i <= numeroSimboli) std::cout << "#" ;
else std::cout << " " ;
} // chiuso loop sui caratteri della riga
std::cout << "\n" ;
} // chiuso loop sulle righe
std::cout << "+-" ;
for (int j=0 ; j<larghezza+1; ++j) std::cout << "-" ;
std::cout << ">\n" ;
delete [] localBins ;
std::cout << "media = " << getMean () << "\n" ;
std::cout << "sigma = " << getSigma () << "\n" ;
return ;
}


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


int
istogramma::getMaxValue () const
{
// cerco il massimo dell'istogramma:
int maxIsto = 0 ;
// loop sugli elementi dell'istogramma
for (int i=0; i<m_binsNumber; ++i)
{
if (maxIsto < m_bins[i]) maxIsto = m_bins[i] ;
} // chiuso loop sugli elementi dell'istogramma
return maxIsto ;
}

Nessun commento: