1// Copyright (C) Eric Niebler 2008.
2// Copyright (C) Pieter Bastiaan Ober 2014.
3// Use, modification and distribution are subject to the
4// Boost Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#include <boost/test/unit_test.hpp>
8#include <boost/test/tools/floating_point_comparison.hpp>
9#include <boost/mpl/assert.hpp>
10#include <boost/type_traits/is_same.hpp>
11#include <boost/accumulators/accumulators.hpp>
12#include <boost/accumulators/statistics/stats.hpp>
13#include <boost/accumulators/statistics/rolling_mean.hpp>
14#include <sstream>
15#include <boost/archive/text_oarchive.hpp>
16#include <boost/archive/text_iarchive.hpp>
17
18using namespace boost;
19using namespace unit_test;
20using namespace accumulators;
21
22template<typename T>
23void assert_is_double(T const &)
24{
25 BOOST_MPL_ASSERT((is_same<T, double>));
26}
27
28// test_rolling_mean_test_impl
29// implements a test for window_size = 5
30size_t window_size = 5;
31
32template<typename accumulator_set_type>
33void
34test_rolling_mean_test_impl(accumulator_set_type& acc)
35{
36 acc(1);
37 BOOST_CHECK_CLOSE(1., rolling_mean(acc), 1e-5);
38
39 acc(2);
40 BOOST_CHECK_CLOSE(1.5, rolling_mean(acc), 1e-5);
41
42 acc(3);
43 BOOST_CHECK_CLOSE(2., rolling_mean(acc), 1e-5);
44
45 acc(4);
46 BOOST_CHECK_CLOSE(2.5, rolling_mean(acc), 1e-5);
47
48 acc(5);
49 BOOST_CHECK_CLOSE(3., rolling_mean(acc), 1e-5);
50
51 acc(6);
52 BOOST_CHECK_CLOSE(4., rolling_mean(acc), 1e-5);
53
54 acc(7);
55 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
56
57 assert_is_double(rolling_mean(acc));
58}
59
60template<typename accumulator_set_type>
61void
62test_rolling_mean_unsigned_test_impl(accumulator_set_type& acc)
63{
64 acc(7U);
65 BOOST_CHECK_CLOSE(7., rolling_mean(acc), 1e-5);
66
67 acc(6U);
68 BOOST_CHECK_CLOSE(6.5, rolling_mean(acc), 1e-5);
69
70 acc(5U);
71 BOOST_CHECK_CLOSE(6., rolling_mean(acc), 1e-5);
72
73 acc(4U);
74 BOOST_CHECK_CLOSE(5.5, rolling_mean(acc), 1e-5);
75
76 acc(3U);
77 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
78
79 acc(2U);
80 BOOST_CHECK_CLOSE(4., rolling_mean(acc), 1e-5);
81
82 acc(1U);
83 BOOST_CHECK_CLOSE(3., rolling_mean(acc), 1e-5);
84
85 assert_is_double(rolling_mean(acc));
86}
87
88///////////////////////////////////////////////////////////////////////////////
89// test_persistency_impl
90//
91template<typename accumulator_set_type>
92void test_persistency_impl(accumulator_set_type& acc)
93{
94 std::stringstream ss;
95 {
96 acc(1);
97 acc(2);
98 acc(3);
99 acc(4);
100 acc(5);
101 acc(6);
102 acc(7);
103 BOOST_CHECK_CLOSE(5., rolling_mean(acc), 1e-5);
104 boost::archive::text_oarchive oa(ss);
105 acc.serialize(oa, 0);
106 }
107 // initialize from acc to make sure all values are passed
108 accumulator_set_type other_acc = acc;
109 // accumulate more, to make sure that deserialization set the right value
110 // and not the copy ctor
111 other_acc(100);
112 other_acc(100);
113 other_acc(100);
114 other_acc(100);
115 other_acc(100);
116 boost::archive::text_iarchive ia(ss);
117 other_acc.serialize(ia, 0);
118 BOOST_CHECK_CLOSE(5., rolling_mean(other_acc), 1e-5);
119}
120
121///////////////////////////////////////////////////////////////////////////////
122// test_rolling_mean
123void test_rolling_mean()
124{
125 accumulator_set<int,stats<tag::immediate_rolling_mean> >
126 acc_immediate_rolling_mean(tag::immediate_rolling_mean::window_size = window_size),
127 acc_immediate_rolling_mean2(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
128
129 accumulator_set<int,stats<tag::rolling_mean(immediate)> >
130 acc_immediate_rolling_mean3(tag::immediate_rolling_mean::window_size = window_size);
131
132 accumulator_set<int,stats<tag::lazy_rolling_mean> >
133 acc_lazy_rolling_mean(tag::lazy_rolling_mean::window_size = window_size),
134 acc_lazy_rolling_mean2(tag::lazy_rolling_mean::window_size = window_size, sample = 0);
135
136 accumulator_set<int,stats<tag::rolling_mean(lazy)> >
137 acc_lazy_rolling_mean3(tag::lazy_rolling_mean::window_size = window_size);
138
139 accumulator_set<int,stats<tag::rolling_mean> >
140 acc_default_rolling_mean(tag::rolling_mean::window_size = window_size),
141 acc_default_rolling_mean2(tag::rolling_mean::window_size = window_size, sample = 0);
142
143 //// test the different implementations
144 test_rolling_mean_test_impl(acc&: acc_lazy_rolling_mean);
145 test_rolling_mean_test_impl(acc&: acc_default_rolling_mean);
146 test_rolling_mean_test_impl(acc&: acc_immediate_rolling_mean);
147
148 test_rolling_mean_test_impl(acc&: acc_lazy_rolling_mean2);
149 test_rolling_mean_test_impl(acc&: acc_default_rolling_mean2);
150 test_rolling_mean_test_impl(acc&: acc_immediate_rolling_mean2);
151
152 test_rolling_mean_test_impl(acc&: acc_lazy_rolling_mean3);
153 test_rolling_mean_test_impl(acc&: acc_immediate_rolling_mean3);
154
155 //// test that the default implementation is the 'immediate' computation
156 BOOST_REQUIRE(sizeof(acc_lazy_rolling_mean) != sizeof(acc_immediate_rolling_mean));
157 BOOST_CHECK (sizeof(acc_default_rolling_mean) == sizeof(acc_immediate_rolling_mean));
158
159 //// test the equivalence of the different ways to indicate a feature
160 BOOST_CHECK (sizeof(acc_lazy_rolling_mean) == sizeof(acc_lazy_rolling_mean2));
161 BOOST_CHECK (sizeof(acc_lazy_rolling_mean) == sizeof(acc_lazy_rolling_mean3));
162 BOOST_CHECK (sizeof(acc_immediate_rolling_mean) == sizeof(acc_immediate_rolling_mean2));
163 BOOST_CHECK (sizeof(acc_immediate_rolling_mean) == sizeof(acc_immediate_rolling_mean3));
164
165 //// test unsigned int with both implementations
166 accumulator_set<unsigned int,stats<tag::immediate_rolling_mean> >
167 acc_immediate_rolling_mean4(tag::immediate_rolling_mean::window_size = window_size),
168 acc_immediate_rolling_mean5(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
169
170 test_rolling_mean_unsigned_test_impl(acc&: acc_immediate_rolling_mean4);
171 test_rolling_mean_unsigned_test_impl(acc&: acc_immediate_rolling_mean5);
172}
173
174///////////////////////////////////////////////////////////////////////////////
175// test_persistency
176void test_persistency()
177{
178 accumulator_set<int,stats<tag::immediate_rolling_mean> >
179 acc_immediate_rolling_mean(tag::immediate_rolling_mean::window_size = window_size),
180 acc_immediate_rolling_mean2(tag::immediate_rolling_mean::window_size = window_size, sample = 0);
181
182 accumulator_set<int,stats<tag::rolling_mean(immediate)> >
183 acc_immediate_rolling_mean3(tag::immediate_rolling_mean::window_size = window_size);
184
185 accumulator_set<int,stats<tag::lazy_rolling_mean> >
186 acc_lazy_rolling_mean(tag::lazy_rolling_mean::window_size = window_size),
187 acc_lazy_rolling_mean2(tag::lazy_rolling_mean::window_size = window_size, sample = 0);
188
189 accumulator_set<int,stats<tag::rolling_mean(lazy)> >
190 acc_lazy_rolling_mean3(tag::lazy_rolling_mean::window_size = window_size);
191
192 accumulator_set<int,stats<tag::rolling_mean> >
193 acc_default_rolling_mean(tag::rolling_mean::window_size = window_size),
194 acc_default_rolling_mean2(tag::rolling_mean::window_size = window_size, sample = 0);
195
196 //// test the different implementations
197 test_persistency_impl(acc&: acc_lazy_rolling_mean);
198 test_persistency_impl(acc&: acc_default_rolling_mean);
199 test_persistency_impl(acc&: acc_immediate_rolling_mean);
200
201 test_persistency_impl(acc&: acc_lazy_rolling_mean2);
202 test_persistency_impl(acc&: acc_default_rolling_mean2);
203 test_persistency_impl(acc&: acc_immediate_rolling_mean2);
204
205 test_persistency_impl(acc&: acc_lazy_rolling_mean3);
206 test_persistency_impl(acc&: acc_immediate_rolling_mean3);
207}
208///////////////////////////////////////////////////////////////////////////////
209// init_unit_test_suite
210//
211test_suite* init_unit_test_suite( int argc, char* argv[] )
212{
213 test_suite *test = BOOST_TEST_SUITE("rolling mean test");
214
215 test->add(BOOST_TEST_CASE(&test_rolling_mean));
216 test->add(BOOST_TEST_CASE(&test_persistency));
217
218 return test;
219}
220

source code of boost/libs/accumulators/test/rolling_mean.cpp