Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use boost accumulators with vectors?

I wanted to use boost accumulators to calculate statistics of a variable that is a vector. Is there a simple way to do this. I think it's not possible to use the dumbest thing:

  using namespace boost::accumulators;
  //stuff...

  accumulator_set<vector<double>, stats<tag::mean> > acc;
  vector<double> some_vetor;
  //stuff 
  some_vector = doStuff();
  acc(some_vector);

maybe this is obvious, but I tried anyway. :P

What I wanted was to have an accumulator that would calculate a vector which is the mean of the components of many vectors. Is there an easy way out?

EDIT:

I don't know if I was thoroughly clear. I don't want this:

 for_each(vec.begin(), vec.end(),acc); 

This would calculate the mean of the entries of a given vector. What I need is different. I have a function that will spit vectors:

 vector<double> doSomething(); 
 // this is a monte carlo simulation;

And I need to run this many times and calculate the vectorial mean of those vectors:

  for(int i = 0; i < numberOfMCSteps; i++){
  vec = doSomething();
  acc(vec);
  }
  cout << mean(acc);

And I want mean(acc) to be a vector itself, whose entry [i] would be the means of the entries [i] of the accumulated vectors.

Theres a hint about this in the docs of Boost, but nothing explicit. And I'm a bit dumb. :P

like image 533
Rafael S. Calsaverini Avatar asked Nov 30 '10 17:11

Rafael S. Calsaverini


People also ask

What is boost accumulator?

Boost. Accumulators is both a library for incremental statistical computation as well as an extensible framework for incremental calculation in general.

What is Accumulators in c++?

An accumulator is a type of register for short-term, intermediate storage of arithmetic and logic data in a computer's central processing unit (CPU).


1 Answers

I've looked into your question a bit, and it seems to me that Boost.Accumulators already provides support for std::vector. Here is what I could find in a section of the user's guide :

Another example where the Numeric Operators Sub-Library is useful is when a type does not define the operator overloads required to use it for some statistical calculations. For instance, std::vector<> does not overload any arithmetic operators, yet it may be useful to use std::vector<> as a sample or variate type. The Numeric Operators Sub-Library defines the necessary operator overloads in the boost::numeric::operators namespace, which is brought into scope by the Accumulators Framework with a using directive.

Indeed, after verification, the file boost/accumulators/numeric/functional/vector.hpp does contain the necessary operators for the 'naive' solution to work.

I believe you should try :

  • Including either
    • boost/accumulators/numeric/functional/vector.hpp before any other accumulators header
    • boost/accumulators/numeric/functional.hpp while defining BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
  • Bringing the operators into scope with a using namespace boost::numeric::operators;.

There's only one last detail left : execution will break at runtime because the initial accumulated value is default-constructed, and an assertion will occur when trying to add a vector of size n to an empty vector. For this, it seems you should initialize the accumulator with (where n is the number of elements in your vector) :

accumulator_set<std::vector<double>, stats<tag::mean> > acc(std::vector<double>(n));

I tried the following code, mean gives me a std::vector of size 2 :

int main()
{
    accumulator_set<std::vector<double>, stats<tag::mean> > acc(std::vector<double>(2));

    const std::vector<double> v1 = boost::assign::list_of(1.)(2.);
    const std::vector<double> v2 = boost::assign::list_of(2.)(3.);
    const std::vector<double> v3 = boost::assign::list_of(3.)(4.);
    acc(v1);
    acc(v2);
    acc(v3);

    const std::vector<double> &meanVector = mean(acc);
}

I believe this is what you wanted ?

like image 132
icecrime Avatar answered Sep 19 '22 23:09

icecrime