Categories: VC/C++

Calcolare Media e Varianza con la Libreria STL

Gli oggetti funzione di STL sono delle classi template con l’operatore “()“, che può essere anche definito inline. Nella libreria ci sono varie funzioni numeriche come accumulate o inner_product o ancora adiacent_difference, ma ne manca una per fare la media degli elementi di un contenitore, vediamo di colmare questa lacuna.

#include <iostream>
#include <vector>
#include <numeric>

using namespace std;

template <class Iterator, class T>
T average(Iterator first, Iterator last, T t0)
{
   return accumulate(first, last, t0) / distance(first, last);
}

int main(int argc, char** args)
{
   int k;

   vector<int> v(7);
   v[0] = 12;
   v[1] = 6;
   v[2] = 4;
   v[3] = 13;
   v[4] = 15;
   v[5] = 5;
   v[6] = 18;

   // Calcolo la media
   cout << "La media del vettore è: "
      << average(v.begin(), v.end(), 0.0)
      << endl;

   cout << endl;    cin >> k;

   return 0;
}

Nel richiamare la funzione ho inserito un valore double ( 0.0 ) perché voglio che ritorni un valore di questo tipo, se ad esempio inseriamo un intero allora avremo il risultato dello stesso tipo e quindi troncato. La nostra funzione average calcola la media  da due iteratori di input forward, con altri tipi farebbe due passate sulla sequenza di valori perché richiamata una volta per accumulate ed una per distance. Per ovviare a questo problema dobbiamo calcolare la media della lista di valori con questo nuovo metodo:

...
int n = 0;
for (; first != last; n++)
{
   t0 += *first;
   ++first;
}

return t0 / n;
...

Ecco la nuova implementazione della funzione average che questa volta potrà funzionare con ogni contenitore di STL.
Vediamo ora qualcosa di più stimolante, il calcolo dello scarto quadratico medio o varianza che in statistica riveste un ruolo molto importante e si calcola con la formula: V(X) = E(X2) – E(X)2, da questa poi è possibile calcolare la radice quadrata ed avere la deviazione standard.

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

template <class Iterator, class T>
T average2(Iterator first, Iterator last, T t0)
{
   int n = 0;
   for (; first != last; n++)
   {
      T temp = *first;
      t0 += (temp * temp);
      ++first;
   }

   return t0 / n;
}

template <class Iterator, class T>
T average(Iterator first, Iterator last, T t0)
{
   int n = 0;
   for (; first != last; n++)
   {
      t0 += *first;
      ++first;
   }

   return t0 / n;
}

int main(int argc, char** args)
{
   int k;

   vector v(7);
   v[0] = 12;
   v[1] = 6;
   v[2] = 4;
   v[3] = 13;
   v[4] = 15;
   v[5] = 5;
   v[6] = 18;

   double m1 = average(v.begin(), v.end(), 0.0);
   m1 *= m1;
   double m2 = average2(v.begin(), v.end(), 0.0);

   // Calcolo la media
   cout << "La varianza del vettore è: " << m2 - m1 << endl;
   cout << "La deviazione standard del vettore é: "
      << sqrt(m2 - m1) << endl;

   cout << endl;    cin >> k;

   return 0;
}

Come potete notare le funzioni sono migliorabili, ma sono anche un buon punto di partenza per crearsi una libreria di statistica utilizzando funzioni generiche basate su STL.

Share
Giampaolo Rossi

Sviluppatore di software gestionale da oltre 28 anni.

Recent Posts

Un Abbonamento per Tutti i Software

Sono arrivato alla convinzione che un abbonamento per tutti i miei software gestionali sia il…

1 anno ago

Software di Magazzino Gratuito

MerciGest è un software per la gestione del magazzino completamente gratuito. Continua a leggere→

1 anno ago

Mettere il PC in Lock Screen

In ufficio può capitare di doversi allontanare dal proprio posto di lavoro, ecco che allora…

3 anni ago

Fare il reset togliendo la corrente

In questo articolo vedremo quando è più o meno utile togliere la corrente ad un…

3 anni ago

Prossimi Aggiornamenti Software

Dopo la pausa invernale dovuta al lavoro che devo fare per sostentarmi, eccomi di nuovo…

3 anni ago

Come Eliminare i Files in Windows

Vediamo come eliminare i files direttamente da Windows senza utilizzare il cestino. Continua a leggere→

4 anni ago