| 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 | |
|---|
| 27 | template<class Iterator> |
|---|
| 28 | void |
|---|
| 29 | iterator_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 | |
|---|
| 38 | BOOST_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 | |
|---|
| 108 | BOOST_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 | */ |
|---|