• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright Pieter Bastiaan Ober 2014.
2 //  Use, modification and distribution are subject to the
3 //  Boost Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <boost/test/unit_test.hpp>
7 #include <boost/test/floating_point_comparison.hpp>
8 #include <boost/mpl/assert.hpp>
9 #include <boost/type_traits/is_same.hpp>
10 #include <boost/accumulators/accumulators.hpp>
11 #include <boost/accumulators/statistics/stats.hpp>
12 #include <sstream>
13 #include <boost/archive/text_oarchive.hpp>
14 #include <boost/archive/text_iarchive.hpp>
15 #include <boost/accumulators/statistics/rolling_variance.hpp>
16 
17 using namespace boost;
18 using namespace unit_test;
19 using namespace accumulators;
20 
21 template<typename T>
assert_is_double(T const &)22 void assert_is_double(T const &)
23 {
24     BOOST_MPL_ASSERT((is_same<T, double>));
25 }
26 
27 /*
28 REFERENCE VALUES PROVIDED BY OCTAVE:
29 
30 x=[1.2 2.3 3.4 4.5 0.4 2.2 7.1 4.0]
31 
32 v1_2 = var(x(1:2))
33 v1_3 = var(x(1:3))
34 v1_4 = var(x(1:4))
35 v2_5 = var(x(2:5))
36 v3_6 = var(x(3:6))
37 v4_7 = var(x(4:7))
38 v5_8 = var(x(5:8))
39 
40 GIVES:
41 
42 v1_2 =  0.605000000000000
43 v1_3 =  1.21000000000000
44 v1_4 =  2.01666666666667
45 v2_5 =  3.05666666666667
46 v3_6 =  3.08250000000000
47 v4_7 =  8.41666666666667
48 v5_8 =  8.16250000000000
49 */
50 
51 ///////////////////////////////////////////////////////////////////////////////
52 // rolling_variance_test_impl
53 // implements a test for window_size = 4
54 
55 size_t window_size = 4;
56 
57 template<typename accumulator_set_type>
rolling_variance_test_impl(accumulator_set_type & acc)58 void rolling_variance_test_impl(accumulator_set_type& acc)
59 {
60     // Window contains x(1), value is zero
61     acc(1.2);
62     BOOST_CHECK_CLOSE(rolling_variance(acc),0.0,1e-10);
63 
64     // Window contains x(1)...x(2)
65     acc(2.3);
66     BOOST_CHECK_CLOSE(rolling_variance(acc),0.605,1e-10);
67 
68     // Window contains x(1)...x(3)
69     acc(3.4);
70     BOOST_CHECK_CLOSE(rolling_variance(acc),1.21,1e-10);
71 
72     // Window contains x(1)...x(4)
73     acc(4.5);
74     BOOST_CHECK_CLOSE(rolling_variance(acc),2.01666666666667,1e-10);
75 
76     // Window contains x(2)...x(5)
77     acc(0.4);
78     BOOST_CHECK_CLOSE(rolling_variance(acc),3.05666666666667,1e-10);
79 
80     // Window contains x(3)...x(6)
81     acc(2.2);
82     BOOST_CHECK_CLOSE(rolling_variance(acc),3.08250000000000,1e-10);
83 
84     // Window contains x(4)...x(7)
85     acc(7.1);
86     BOOST_CHECK_CLOSE(rolling_variance(acc),8.41666666666667,1e-10);
87 
88     // Window contains x(5)...x(8)
89     acc(4.0);
90     BOOST_CHECK_CLOSE(rolling_variance(acc),8.16250000000000,1e-10);
91 
92     assert_is_double(rolling_variance(acc));
93 }
94 
95 ///////////////////////////////////////////////////////////////////////////////
96 // test_rolling_variance
97 //
test_rolling_variance()98 void test_rolling_variance()
99 {
100     // tag::rolling_window::window_size
101     accumulator_set<double, stats<tag::immediate_rolling_variance> >
102         acc_immediate_rolling_variance(tag::immediate_rolling_variance::window_size = window_size);
103 
104     accumulator_set<double, stats<tag::immediate_rolling_variance, tag::rolling_mean> >
105         acc_immediate_rolling_variance2(tag::immediate_rolling_variance::window_size = window_size);
106 
107     accumulator_set<double, stats<tag::rolling_variance(immediate)> >
108         acc_immediate_rolling_variance3(tag::immediate_rolling_variance::window_size = window_size);
109 
110     accumulator_set<double, stats<tag::lazy_rolling_variance> >
111         acc_lazy_rolling_variance(tag::lazy_rolling_variance::window_size = window_size);
112 
113     accumulator_set<double, stats<tag::rolling_variance(lazy)> >
114        acc_lazy_rolling_variance2(tag::immediate_rolling_variance::window_size = window_size);
115 
116     accumulator_set<double, stats<tag::rolling_variance> >
117         acc_default_rolling_variance(tag::rolling_variance::window_size = window_size);
118 
119     //// test the different implementations
120     rolling_variance_test_impl(acc_immediate_rolling_variance);
121     rolling_variance_test_impl(acc_immediate_rolling_variance2);
122     rolling_variance_test_impl(acc_immediate_rolling_variance3);
123     rolling_variance_test_impl(acc_lazy_rolling_variance);
124     rolling_variance_test_impl(acc_lazy_rolling_variance2);
125     rolling_variance_test_impl(acc_default_rolling_variance);
126 
127     //// test that the default implementation is the 'immediate' computation
128     BOOST_REQUIRE(sizeof(acc_lazy_rolling_variance) != sizeof(acc_immediate_rolling_variance));
129     BOOST_CHECK  (sizeof(acc_default_rolling_variance) == sizeof(acc_immediate_rolling_variance));
130 
131     //// test the equivalence of the different ways to indicate a feature
132     BOOST_CHECK  (sizeof(acc_immediate_rolling_variance) == sizeof(acc_immediate_rolling_variance2));
133     BOOST_CHECK  (sizeof(acc_immediate_rolling_variance) == sizeof(acc_immediate_rolling_variance3));
134     BOOST_CHECK  (sizeof(acc_lazy_rolling_variance) == sizeof(acc_lazy_rolling_variance2));
135 }
136 
137 ///////////////////////////////////////////////////////////////////////////////
138 // test_persistency_impl
139 //
140 template<typename accumulator_set_type>
test_persistency_impl(accumulator_set_type & acc)141 void test_persistency_impl(accumulator_set_type& acc)
142 {
143     std::stringstream ss;
144     {
145         acc(1.2);
146         acc(2.3);
147         acc(3.4);
148         acc(4.5);
149         acc(0.4);
150         acc(2.2);
151         acc(7.1);
152         acc(4.0);
153         BOOST_CHECK_CLOSE(rolling_variance(acc),8.16250000000000,1e-10);
154         boost::archive::text_oarchive oa(ss);
155         acc.serialize(oa, 0);
156     }
157     accumulator_set_type other_acc = acc;
158     boost::archive::text_iarchive ia(ss);
159     other_acc.serialize(ia, 0);
160     BOOST_CHECK_CLOSE(rolling_variance(acc),8.16250000000000,1e-10);
161 
162 }
163 
164 ///////////////////////////////////////////////////////////////////////////////
165 // test_persistency
166 //
test_persistency()167 void test_persistency()
168 {
169     // tag::rolling_window::window_size
170     accumulator_set<double, stats<tag::immediate_rolling_variance> >
171         acc_immediate_rolling_variance(tag::immediate_rolling_variance::window_size = window_size);
172 
173     accumulator_set<double, stats<tag::immediate_rolling_variance, tag::rolling_mean> >
174         acc_immediate_rolling_variance2(tag::immediate_rolling_variance::window_size = window_size);
175 
176     accumulator_set<double, stats<tag::rolling_variance(immediate)> >
177         acc_immediate_rolling_variance3(tag::immediate_rolling_variance::window_size = window_size);
178 
179     accumulator_set<double, stats<tag::lazy_rolling_variance> >
180         acc_lazy_rolling_variance(tag::lazy_rolling_variance::window_size = window_size);
181 
182     accumulator_set<double, stats<tag::rolling_variance(lazy)> >
183        acc_lazy_rolling_variance2(tag::immediate_rolling_variance::window_size = window_size);
184 
185     accumulator_set<double, stats<tag::rolling_variance> >
186         acc_default_rolling_variance(tag::rolling_variance::window_size = window_size);
187 
188     //// test the different implementations
189     test_persistency_impl(acc_immediate_rolling_variance);
190     test_persistency_impl(acc_immediate_rolling_variance2);
191     test_persistency_impl(acc_immediate_rolling_variance3);
192     test_persistency_impl(acc_lazy_rolling_variance);
193     test_persistency_impl(acc_lazy_rolling_variance2);
194     test_persistency_impl(acc_default_rolling_variance);
195 }
196 
197 ///////////////////////////////////////////////////////////////////////////////
198 // init_unit_test_suite
199 //
init_unit_test_suite(int argc,char * argv[])200 test_suite* init_unit_test_suite( int argc, char* argv[] )
201 {
202     test_suite *test = BOOST_TEST_SUITE("rolling variance test");
203 
204     test->add(BOOST_TEST_CASE(&test_rolling_variance));
205     test->add(BOOST_TEST_CASE(&test_persistency));
206 
207     return test;
208 }
209