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).
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+ .
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.
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);
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With