Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

column vector with row means -- with std::accumulate?

In an effort to be as lazy as possible I read in a matrix as

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

and try to use as many STL goodies as I can.

One thing I need to do next is to compute the row means. In C-style programming that would be

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? it is explained that for a vector of numbers you can compute a vector mean in one line without calling the size() operator at every step:

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

Is it possible to use these iterators over a vector of vectors? An intermediate form is

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();

already 1 line gone! but using STL functions is it possible to get rid of the [i] index as well? (on the top level it's just a matter of collecting the row means).

like image 541
alle_meije Avatar asked Feb 16 '13 22:02

alle_meije


People also ask

How does std :: accumulate work?

In other terms, this means that std::accumulate takes a collection of elements and returns only one value. If you don't specify anything, std::accumulate does the sum of all the elements in the range that it takes. This sum being done with operator+ .

How do I find the row and column of a vector in C++?

size() give you the row number, and on the other side myVector[0]. size() or myVector[n]. size() any valid range of row "n" give you the column number of that particular row. If columns and rows no are the same, then just one check can solve your problem.


2 Answers

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

Although, my personal style would involve a named lambda or function, because I would find that more self-documenting:

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);
like image 200
Benjamin Lindley Avatar answered Sep 22 '22 16:09

Benjamin Lindley


Using boost::numeric::ublas however (if it's an option):

matrix<double> m(rows,columns);
double mean = accumulate(m.data().begin(),m.data().end(),0,std::max<double>) / (rows * columns);
like image 24
eladidan Avatar answered Sep 25 '22 16:09

eladidan