std::tr1::array<double, 10> alpha;
  std::iota(alpha.begin(), alpha.end(), 0);
  using namespace boost::accumulators;
  size_t const SIZE = 1000000;  
  accumulator_set<double, stats<tag::mean, tag::lazy_variance > > acc;
  std::for_each(alpha.begin(), alpha.end(), [&](double const VALUE){ acc(VALUE);});

How could I clear the contents of the acc if I want to evaluate a new mean and variance?
Thank you very much.

Recommended Answers

All 11 Replies

drop would make the feature stop active again
but what I need is something it could recalculate the data

std::tr1::array<T, N> alpha;
  std::iota(alpha.begin(), alpha.end(), 0);
  using namespace boost::accumulators;
  accumulator_set<T, stats<droppable<tag::mean> > > acc;
  std::for_each(alpha.begin(), alpha.end(), [&](T const VALUE){ acc(VALUE);});
  std::cout<<"mean = "<<mean(acc)<<"\n"; //ok, the answer is 3.5
  acc.template drop<tag::mean>();
  std::iota(alpha.begin(), alpha.end(), 10);
  std::for_each(alpha.begin(), alpha.end(), [&](T const VALUE){ acc(VALUE);});
//oops,the answer is 3.5 again, but the answer I want is 13.5
  std::cout<<"mean = "<<mean(acc)<<"\n";

Thank you

> oops,the answer is 3.5 again, but the answer I want is 13.5

The simplest way would be to use a new accumulator_set<> for the fresh calculations.

If you want to reuse the same accumulator_set<> from scratch, just reinitialize it.

#include <iostream>
#include <new>
#include <boost/utility.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>

template< typename DEFAULT_INITIALIZABLE >
inline void clear( DEFAULT_INITIALIZABLE& object )
{
    object.DEFAULT_INITIALIZABLE::~DEFAULT_INITIALIZABLE() ;
    ::new ( boost::addressof(object) ) DEFAULT_INITIALIZABLE() ;
}

int main()
{
    using namespace boost::accumulators ;

    accumulator_set< double, features< tag::count, tag::sum, tag::mean > > ac ;
    ac(123) ; ac(456) ; ac(789) ; ac(1234) ;
    std::cout << sum(ac) << '/' << count(ac) << " == " << mean(ac) << '\n' ;

    clear(ac) ;
    ac(1) ; ac(22) ; ac(333) ;
    std::cout << sum(ac) << '/' << count(ac) << " == " << mean(ac) << '\n' ;
}

Thanks a lot
There are something I don't know
Is accumulator_set using dynamic memory?

> Is accumulator_set using dynamic memory?

It shouldn't matter either way, should it?

> Because not every statistical data could be computed without saving the input values

Boost.Accumulators is a library for incremental statistical computation.

Incremental computation means that the statistic is updated each time new data arrives. Incremental computation of statistics use algorithms that are quite different from static computation algorithms.

For an example, see: http://www.johndcook.com/standard_deviation.html

For incremental computation of statistics like median, which would otherwise require the entire data set, estimators are used. http://www.boost.org/doc/libs/1_46_1/doc/html/accumulators/user_s_guide.html#accumulators.user_s_guide.the_statistical_accumulators_library.median

Thanks, I would check for it

ps : I can't understand how to extend accumulator or features
looks like it is much more complicated than stl
I haven't seen any calculations of those features
what should I know before I try to extend it?
Should I know some metaprogramming language or the other's part of the boost?

> what should I know before I try to extend it?
> Should I know some metaprogramming language or the other's part of the boost?

You need to read up on the accumulator framework and concepts.
You also need to have a basic knowledge of the Boost.Parameter library.
For anything not very trivial, it would help if you understand Boost.MPL Lambda Expressions and Boost.MPL Metafunctions/Metafunction Classes.

The basics are straight forward as illustrated here: http://www.boost.org/doc/libs/1_46_0/doc/html/accumulators/user_s_guide.html#accumulators.user_s_guide.the_accumulators_framework.extending_the_accumulators_framework.defining_a_new_accumulator

1. Define your new accumulator (ideally in boost::accumulators::impl). It must derive from accumulator_base
2. In boost::accumulators::tag, define a tag for it. Your tag must inherit from depends_on<>.
3. In boost::accumulators::extract define an extractor for it. And hoist the extractor to the boost::accumulators namespace.


Here is a trivial example that accumulates the average of the last decimal digit of (integral) sample values:

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/assert.hpp>
#include <iostream>

namespace boost
{
    namespace accumulators
    {
        namespace impl
        {
            template< typename T > struct average_last_digit : accumulator_base
            {
                BOOST_MPL_ASSERT( ( is_integral<T> ) ) ;

                typedef typename boost::common_type< T, double >::type result_type ;

                template< typename ARGS >  average_last_digit( const ARGS& args )
                  : sum_of_last_digits( args[ sample | T() ] ) {}

                template< typename ARGS > void operator () ( const ARGS& args )
                { sum_of_last_digits += args[sample] % 10 ; 

                template< typename ARGS > result_type result( const ARGS& args ) const
                { return sum_of_last_digits / count( args[accumulator] ) ; }

                private: result_type sum_of_last_digits ;
            };
        }

        namespace tag
        {
            struct average_last_digit : depends_on<count>
            { typedef ::boost::accumulators::impl::average_last_digit< mpl::_1 > impl ; } ;
        }

        namespace extract
        { const extractor< tag::average_last_digit > average_last_digit = {} ; }

        using extract::average_last_digit ;
    }
}

int main()
{
    using namespace boost::accumulators ;

    accumulator_set< int, features< tag::average_last_digit > > ac ;
    ac(1007) ; ac(25) ; ac(33) ; ac(1230) ; ac(1) ;
    std::cout << average_last_digit(ac) << '\n' ;
}

Thanks a lot, there are still a long way to go
The more I study about programming, I finf out that to become a competent programmer
I have to know many things, and looks like I would never end up learning

> The more I study about programming, I finf out that to become a competent programmer
> I have to know many things, and looks like I would never end up learning

Yes. It is a journey that never ends.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.