From 8037520d60d636169c276e01ec07edcf058eca7d Mon Sep 17 00:00:00 2001 From: Quentin Chateau Date: Fri, 21 Dec 2018 01:07:35 +0100 Subject: [PATCH] rolling min and max --- doc/accumulators.qbk | 93 +++++++++++++++++++ .../accumulators/statistics/rolling_max.hpp | 77 +++++++++++++++ .../accumulators/statistics/rolling_min.hpp | 77 +++++++++++++++ test/Jamfile.v2 | 2 + test/rolling_max.cpp | 63 +++++++++++++ test/rolling_min.cpp | 60 ++++++++++++ 6 files changed, 372 insertions(+) create mode 100644 include/boost/accumulators/statistics/rolling_max.hpp create mode 100644 include/boost/accumulators/statistics/rolling_min.hpp create mode 100644 test/rolling_max.cpp create mode 100644 test/rolling_min.cpp diff --git a/doc/accumulators.qbk b/doc/accumulators.qbk index 7e6d1f4..8d07a30 100644 --- a/doc/accumulators.qbk +++ b/doc/accumulators.qbk @@ -2077,6 +2077,99 @@ The rolling count is the current number of elements in the rolling window. [endsect] +[section:rolling_max rolling_max] + +The rolling sum is the sum of the last /N/ samples. + +[variablelist + [[Result Type] [``_sample_type_``]] + [[Depends On] [`sorted_rolling_window`]] + [[Variants] [['none]]] + [[Initialization Parameters] [`tag::rolling_window::window_size`]] + [[Accumulator Parameters] [['none]]] + [[Extractor Parameters] [['none]]] + [[Accumulator Complexity] [O(log N), where N is the window size]] + [[Extractor Complexity] [O(1)]] +] + +[*Header] +[def _ROLLING_MAX_HPP_ [headerref boost/accumulators/statistics/rolling_max.hpp]] + + #include <_ROLLING_MAX_HPP_> + +[*Example] + + accumulator_set > acc(tag::rolling_window::window_size = 3); + + acc(1); + BOOST_CHECK_EQUAL(1, rolling_max(acc)); + + acc(2); + BOOST_CHECK_EQUAL(2, rolling_max(acc)); + + acc(3); + BOOST_CHECK_EQUAL(3, rolling_max(acc)); + + acc(1); + BOOST_CHECK_EQUAL(3, rolling_max(acc)); + + acc(-1); + BOOST_CHECK_EQUAL(1, rolling_max(acc)); + + acc(0); + BOOST_CHECK_EQUAL(1, rolling_max(acc)); + +[*See also] + +* [classref boost::accumulators::impl::rolling_max_impl [^rolling_max_impl]] + +[endsect] + +[section:rolling_min rolling_min] + +The rolling sum is the sum of the last /N/ samples. + +[variablelist + [[Result Type] [``_sample_type_``]] + [[Depends On] [`sorted_rolling_window`]] + [[Variants] [['none]]] + [[Initialization Parameters] [`tag::rolling_window::window_size`]] + [[Accumulator Parameters] [['none]]] + [[Extractor Parameters] [['none]]] + [[Accumulator Complexity] [O(log N), where N is the window size]] + [[Extractor Complexity] [O(1)]] +] + +[*Header] +[def _ROLLING_MIN_HPP_ [headerref boost/accumulators/statistics/rolling_min.hpp]] + + #include <_ROLLING_MIN_HPP_> + +[*Example] + + accumulator_set > acc(tag::rolling_window::window_size = 3); + + acc(1); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(2); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(3); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(4); + BOOST_CHECK_EQUAL(2, rolling_min(acc)); + + acc(-1); + BOOST_CHECK_EQUAL(-1, rolling_min(acc)); + +[*See also] + +* [classref boost::accumulators::impl::rolling_min_impl [^rolling_min_impl]] + +[endsect] + [section:rolling_sum rolling_sum] The rolling sum is the sum of the last /N/ samples. diff --git a/include/boost/accumulators/statistics/rolling_max.hpp b/include/boost/accumulators/statistics/rolling_max.hpp new file mode 100644 index 0000000..f148f0a --- /dev/null +++ b/include/boost/accumulators/statistics/rolling_max.hpp @@ -0,0 +1,77 @@ +/////////////////////////////////////////////////////////////////////////////// +// rolling_max.hpp +// +// Copyright 2018 Quentin Chateau. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_MAX_HPP_QC_20_12_2018 +#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MAX_HPP_QC_20_12_2018 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace accumulators +{ + +namespace impl +{ + /////////////////////////////////////////////////////////////////////////////// + // rolling_max_impl + template + struct rolling_max_impl + : accumulator_base + { + // for boost::result_of + typedef Sample result_type; + + rolling_max_impl(dont_care) + { + } + + template + result_type result(Args const &args) const + { + if (sorted_rolling_window(args).empty()) + { + return numeric::as_min(Sample()); + } + return sorted_rolling_window(args).back(); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// tag::rolling_max +// +namespace tag +{ + struct rolling_max + : depends_on< sorted_rolling_window > + { + /// INTERNAL ONLY + /// + typedef accumulators::impl::rolling_max_impl impl; + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// extract::rolling_max +// +namespace extract +{ + extractor const rolling_max = {}; + + BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_max) +} + +using extract::rolling_max; + +}} // namespace boost::accumulators + +#endif diff --git a/include/boost/accumulators/statistics/rolling_min.hpp b/include/boost/accumulators/statistics/rolling_min.hpp new file mode 100644 index 0000000..2f25a1f --- /dev/null +++ b/include/boost/accumulators/statistics/rolling_min.hpp @@ -0,0 +1,77 @@ +/////////////////////////////////////////////////////////////////////////////// +// rolling_min.hpp +// +// Copyright 2018 Quentin Chateau. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_ACCUMULATORS_STATISTICS_ROLLING_MIN_HPP_QC_20_12_2018 +#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MIN_HPP_QC_20_12_2018 + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace accumulators +{ + +namespace impl +{ + /////////////////////////////////////////////////////////////////////////////// + // rolling_min_impl + template + struct rolling_min_impl + : accumulator_base + { + // for boost::result_of + typedef Sample result_type; + + rolling_min_impl(dont_care) + { + } + + template + result_type result(Args const &args) const + { + if (sorted_rolling_window(args).empty()) + { + return numeric::as_max(Sample()); + } + return sorted_rolling_window(args).front(); + } + }; + +} // namespace impl + +/////////////////////////////////////////////////////////////////////////////// +// tag::rolling_min +// +namespace tag +{ + struct rolling_min + : depends_on< sorted_rolling_window > + { + /// INTERNAL ONLY + /// + typedef accumulators::impl::rolling_min_impl impl; + }; +} + +/////////////////////////////////////////////////////////////////////////////// +// extract::rolling_min +// +namespace extract +{ + extractor const rolling_min = {}; + + BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_min) +} + +using extract::rolling_min; + +}} // namespace boost::accumulators + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index d8cb39e..2b7f84c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -47,7 +47,9 @@ test-suite "accumulators" [ run reference.cpp ] [ run rolling_count.cpp ] [ run rolling_sum.cpp ] + [ run rolling_max.cpp ] [ run rolling_mean.cpp ] + [ run rolling_min.cpp ] [ run skewness.cpp ] [ run sorted_rolling_window.cpp ] [ run sum.cpp ] diff --git a/test/rolling_max.cpp b/test/rolling_max.cpp new file mode 100644 index 0000000..d028816 --- /dev/null +++ b/test/rolling_max.cpp @@ -0,0 +1,63 @@ +// (C) Copyright Eric Niebler 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +using namespace boost; +using namespace unit_test; +using namespace accumulators; +using namespace container; + +typedef accumulator_set > RollingmaxAccumulator; + +/////////////////////////////////////////////////////////////////////////////// +// test_stat +// +void test_stat() +{ + accumulator_set > acc(tag::rolling_window::window_size = 3); + + BOOST_CHECK_EQUAL(numeric::as_min(int()), rolling_max(acc)); + + acc(1); + BOOST_CHECK_EQUAL(1, rolling_max(acc)); + + acc(3); + BOOST_CHECK_EQUAL(3, rolling_max(acc)); + + acc(5); + BOOST_CHECK_EQUAL(5, rolling_max(acc)); + + acc(7); + BOOST_CHECK_EQUAL(7, rolling_max(acc)); + + acc(6); + BOOST_CHECK_EQUAL(7, rolling_max(acc)); + + acc(1); + BOOST_CHECK_EQUAL(7, rolling_max(acc)); + + acc(3); + BOOST_CHECK_EQUAL(6, rolling_max(acc)); + + acc(2); + BOOST_CHECK_EQUAL(3, rolling_max(acc)); +} + +/////////////////////////////////////////////////////////////////////////////// +// init_unit_test_suite +// +test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite *test = BOOST_TEST_SUITE("rolling max test"); + + test->add(BOOST_TEST_CASE(&test_stat)); + + return test; +} diff --git a/test/rolling_min.cpp b/test/rolling_min.cpp new file mode 100644 index 0000000..79ae99e --- /dev/null +++ b/test/rolling_min.cpp @@ -0,0 +1,60 @@ +// (C) Copyright Eric Niebler 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +using namespace boost; +using namespace unit_test; +using namespace accumulators; +using namespace container; + +typedef accumulator_set > RollingMinAccumulator; + +/////////////////////////////////////////////////////////////////////////////// +// test_stat +// +void test_stat() +{ + accumulator_set > acc(tag::rolling_window::window_size = 3); + + BOOST_CHECK_EQUAL(numeric::as_max(int()), rolling_min(acc)); + + acc(1); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(3); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(5); + BOOST_CHECK_EQUAL(1, rolling_min(acc)); + + acc(7); + BOOST_CHECK_EQUAL(3, rolling_min(acc)); + + acc(6); + BOOST_CHECK_EQUAL(5, rolling_min(acc)); + + acc(7); + BOOST_CHECK_EQUAL(6, rolling_min(acc)); + + acc(1); + BOOST_CHECK_EQUAL(1, rolling_min(acc));\ +} + +/////////////////////////////////////////////////////////////////////////////// +// init_unit_test_suite +// +test_suite* init_unit_test_suite( int argc, char* argv[] ) +{ + test_suite *test = BOOST_TEST_SUITE("rolling min test"); + + test->add(BOOST_TEST_CASE(&test_stat)); + + return test; +}