root/lang/cplusplus/boost-supplement/trunk/libs/random/test_discrete_distribution.cpp @ 5902

Revision 5902, 4.7 kB (checked in by mrkn, 5 years ago)

lang/cplusplus/boost-supplement: Boost supplemental library.
lang/cplusplus/boost-supplement (random/discrete_distribution.hpp): discrete distribution implementation.

  • Property svn:keywords set to Id
Line 
1/* test for boost_supplement random/discrete_distribution.hpp
2 *
3 * Copyright (C) 2008 Kenta Murata.
4 * Distributed under the Boost Software License, Version 1.0. (See
5 * accompanying file LICENSE_1_0.txt or copy at
6 * http://www.boost.org/LICENSE_1_0.txt)
7 *
8 * $Id$
9 *
10 */
11
12#define BOOST_TEST_MAIN
13#include <boost/test/unit_test.hpp>
14
15#include <boost_supplement/random/discrete_distribution.hpp>
16
17#include <boost/preprocessor/arithmetic/inc.hpp>
18#include <boost/preprocessor/comparison/not_equal.hpp>
19#include <boost/preprocessor/repetition/for.hpp>
20#include <boost/preprocessor/tuple/elem.hpp>
21                                                                \
22#include <boost/test/floating_point_comparison.hpp>
23#include <boost/tuple/tuple.hpp>
24
25#include <iostream>
26
27template<class Iterator>
28void
29iterator_out(Iterator first, Iterator last)
30{
31  std::cout << *first;
32  while (++first != last) {
33    std::cout << ", " << *first;
34  }
35  std::cout << std::endl;
36}
37
38BOOST_AUTO_TEST_CASE(test_discrete_distribution_from_probability)
39{
40  double const pdf[16] = {
41    0.0 / 36.0, // 0
42    0.0 / 36.0, // 1
43    1.0 / 36.0, // 2
44    2.0 / 36.0, // 3
45    3.0 / 36.0, // 4
46    4.0 / 36.0, // 5
47    5.0 / 36.0, // 6
48    6.0 / 36.0, // 7
49    5.0 / 36.0, // 8
50    4.0 / 36.0, // 9
51    3.0 / 36.0, // 10
52    2.0 / 36.0, // 11
53    1.0 / 36.0, // 12
54    0.0 / 36.0, // 13
55    0.0 / 36.0, // 14
56    0.0 / 36.0  // 15
57  };
58
59  bs::discrete_distribution<> dd(pdf, pdf + 16, true);
60
61  bs::discrete_distribution<>::probability_iterator pi, pi_end;
62  boost::tie(pi, pi_end) = dd.probabilities();
63  iterator_out(pi, pi_end);
64
65  bs::discrete_distribution<>::alias_iterator ai, ai_end;
66  boost::tie(ai, ai_end) = dd.aliases();
67  iterator_out(ai, ai_end);
68
69  double pdf2[16];
70  for (int i = 0; i < 16; ++i) {
71    bs::discrete_distribution<>::probability_iterator p(pi);
72    std::advance(p, i);
73    pdf2[i] = *p;
74
75    for (int j = 0; j < 16; ++j) {
76      if (i == j) continue;
77      bs::discrete_distribution<>::alias_iterator a(ai);
78      std::advance(a, j);
79      if (*a == i) {
80        p = pi;
81        std::advance(p, j);
82        pdf2[i] += 1.0 - *p;
83      }
84    }
85    pdf2[i] /= 16.0;
86  }
87
88#define PRED(r, state)                                  \
89  BOOST_PP_NOT_EQUAL(                                   \
90    BOOST_PP_TUPLE_ELEM(2, 0, state),                   \
91    BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state))      \
92    )
93#define OP(r, state) \
94  (                                                     \
95    BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)),     \
96    BOOST_PP_TUPLE_ELEM(2, 1, state)                    \
97    )
98#define MACRO(r, state)                                         \
99  BOOST_CHECK_CLOSE(pdf2[BOOST_PP_TUPLE_ELEM(2, 0, state)],     \
100                    pdf[BOOST_PP_TUPLE_ELEM(2, 0, state)],      \
101                    1e-9);
102  BOOST_PP_FOR((0, 15), PRED, OP, MACRO);
103#undef MACRO
104#undef OP
105#undef PRED
106}
107
108BOOST_AUTO_TEST_CASE(test_discrete_distribution_from_weight)
109{
110  const double pdf[16] = {
111    0.0, // 0
112    0.0, // 1
113    1.0, // 2
114    2.0, // 3
115    3.0, // 4
116    4.0, // 5
117    5.0, // 6
118    6.0, // 7
119    5.0, // 8
120    4.0, // 9
121    3.0, // 10
122    2.0, // 11
123    1.0, // 12
124    0.0, // 13
125    0.0, // 14
126    0.0  // 15
127  };
128
129  bs::discrete_distribution<> dd(pdf, pdf + 16);
130
131  bs::discrete_distribution<>::probability_iterator pi, pi_end;
132  boost::tie(pi, pi_end) = dd.probabilities();
133  iterator_out(pi, pi_end);
134
135  bs::discrete_distribution<>::alias_iterator ai, ai_end;
136  boost::tie(ai, ai_end) = dd.aliases();
137  iterator_out(ai, ai_end);
138
139  double pdf2[16];
140  for (int i = 0; i < 16; ++i) {
141    bs::discrete_distribution<>::probability_iterator p(pi);
142    std::advance(p, i);
143    pdf2[i] = *p;
144
145    for (int j = 0; j < 16; ++j) {
146      if (i == j) continue;
147      bs::discrete_distribution<>::alias_iterator a(ai);
148      std::advance(a, j);
149      if (*a == i) {
150        p = pi;
151        std::advance(p, j);
152        pdf2[i] += 1.0 - *p;
153      }
154    }
155    pdf2[i] /= 16.0;
156  }
157
158#define PRED(r, state)                                  \
159  BOOST_PP_NOT_EQUAL(                                   \
160    BOOST_PP_TUPLE_ELEM(2, 0, state),                   \
161    BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 1, state))      \
162    )
163#define OP(r, state) \
164  (                                                     \
165    BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(2, 0, state)),     \
166    BOOST_PP_TUPLE_ELEM(2, 1, state)                    \
167    )
168#define MACRO(r, state)                                         \
169  BOOST_CHECK_CLOSE(pdf2[BOOST_PP_TUPLE_ELEM(2, 0, state)],     \
170                    pdf[BOOST_PP_TUPLE_ELEM(2, 0, state)]/36.0, \
171                    1e-9);
172  BOOST_PP_FOR((0, 15), PRED, OP, MACRO);
173#undef MACRO
174#undef OP
175#undef PRED
176}
177
178/*
179 * Local Variables:
180 * coding: utf-8
181 * mode: c++
182 * c-basic-offset: 2
183 * indent-tabs-mode: nil
184 * End:
185 */
Note: See TracBrowser for help on using the browser.