2013-02-16 13 views
5

Nel tentativo di essere pigro come possibile ho letto in una matrice comevettore colonna con riga significa - con std :: accumula?

vector< vector<double> > data (rows, vector<double> (columns)); 

e cercare di utilizzare come goodies STL possibile.

Una cosa che devo fare dopo è calcolare i mezzi di riga. Nella programmazione C-stile che sarebbe

vector<double> rowmeans(data.size()); 
for (int i=0; i<data.size(); i++) 
    for (int j=0; j<data[i].size(); j++) 
     rowmeans[i] += data[i][j]/data[i].size(); 

In In C++, how to compute the mean of a vector of integers using a vector view and gsl_stats_mean? si è spiegato che per un vettore di numeri è possibile calcolare un vettore dire in una sola riga senza chiamare l'operatore size() ad ogni passo:

double mean = std::accumulate(stl_v.begin(), stl_v.end(), 0.0)/stl_v.size(); 

È possibile utilizzare questi iteratori su un vettore di vettori? Un modulo intermedio è

vector<double> rowmeans(rows); 
    for (int i=0; i<data.size(); i++) 
     rowmeans[i] = std::accumulate(data[i].begin(), data[i].end(), 0.0)/data[i].size(); 

già 1 riga andata! ma usando le funzioni STL è possibile eliminare anche l'indice [i]? (al livello superiore si tratta solo di raccogliere i mezzi a riga).

risposta

11
std::transform(data.begin(), data.end(), rowmeans.begin(), 
    [](std::vector<double> const& d) { 
     return std::accumulate(d.begin(), d.end(), 0.0)/d.size(); 
    }); 

Anche se, il mio stile personale comporterebbe un lambda o funzione denominata, perché avrei trovato che più auto-documentazione:

auto Mean = [](std::vector<double> const& d) { return std::accumulate(d.begin(), d.end(), 0.0)/d.size(); }; 
std::transform(data.begin(), data.end(), rowmeans.begin(), Mean); 
+0

Questo è quello che vorrei avere pensato. +1 –

+0

+1. Riprendo il commento nella mia risposta :) – eladidan

+0

risposta impressionante +1 :) – M3taSpl0it

1

Utilizzando boost::numeric::ublas però (se si tratta di un'opzione):

matrix<double> m(rows,columns); 
double mean = accumulate(m.data().begin(),m.data().end(),0,std::max<double>)/(rows * columns); 
+0

Grazie! Mi è piaciuta anche quella con for_each pubblicata in precedenza. Solo per la mancanza di contatori di loop –