eval.pass.cpp revision 14fe08bcb729f076d889de4e38955051bc041923
1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// REQUIRES: long_tests 11 12// <random> 13 14// template<class RealType = double> 15// class piecewise_linear_distribution 16 17// template<class _URNG> result_type operator()(_URNG& g); 18 19#include <iostream> 20 21#include <random> 22#include <algorithm> 23#include <vector> 24#include <iterator> 25#include <numeric> 26#include <cassert> 27#include <limits> 28 29template <class T> 30inline 31T 32sqr(T x) 33{ 34 return x*x; 35} 36 37double 38f(double x, double a, double m, double b, double c) 39{ 40 return a + m*(sqr(x) - sqr(b))/2 + c*(x-b); 41} 42 43void 44test1() 45{ 46 typedef std::piecewise_linear_distribution<> D; 47 typedef D::param_type P; 48 typedef std::mt19937_64 G; 49 G g; 50 double b[] = {10, 14, 16, 17}; 51 double p[] = {0, 1, 1, 0}; 52 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 53 D d(b, b+Np+1, p); 54 const int N = 1000000; 55 std::vector<D::result_type> u; 56 for (int i = 0; i < N; ++i) 57 { 58 D::result_type v = d(g); 59 assert(d.min() <= v && v < d.max()); 60 u.push_back(v); 61 } 62 std::sort(u.begin(), u.end()); 63 int kp = -1; 64 double a = std::numeric_limits<double>::quiet_NaN(); 65 double m = std::numeric_limits<double>::quiet_NaN(); 66 double bk = std::numeric_limits<double>::quiet_NaN(); 67 double c = std::numeric_limits<double>::quiet_NaN(); 68 std::vector<double> areas(Np); 69 double S = 0; 70 for (int i = 0; i < areas.size(); ++i) 71 { 72 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 73 S += areas[i]; 74 } 75 for (int i = 0; i < areas.size(); ++i) 76 areas[i] /= S; 77 for (int i = 0; i < Np+1; ++i) 78 p[i] /= S; 79 for (int i = 0; i < N; ++i) 80 { 81 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 82 if (k != kp) 83 { 84 a = 0; 85 for (int j = 0; j < k; ++j) 86 a += areas[j]; 87 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 88 bk = b[k]; 89 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 90 kp = k; 91 } 92 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 93 } 94} 95 96void 97test2() 98{ 99 typedef std::piecewise_linear_distribution<> D; 100 typedef D::param_type P; 101 typedef std::mt19937_64 G; 102 G g; 103 double b[] = {10, 14, 16, 17}; 104 double p[] = {0, 0, 1, 0}; 105 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 106 D d(b, b+Np+1, p); 107 const int N = 1000000; 108 std::vector<D::result_type> u; 109 for (int i = 0; i < N; ++i) 110 { 111 D::result_type v = d(g); 112 assert(d.min() <= v && v < d.max()); 113 u.push_back(v); 114 } 115 std::sort(u.begin(), u.end()); 116 int kp = -1; 117 double a = std::numeric_limits<double>::quiet_NaN(); 118 double m = std::numeric_limits<double>::quiet_NaN(); 119 double bk = std::numeric_limits<double>::quiet_NaN(); 120 double c = std::numeric_limits<double>::quiet_NaN(); 121 std::vector<double> areas(Np); 122 double S = 0; 123 for (int i = 0; i < areas.size(); ++i) 124 { 125 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 126 S += areas[i]; 127 } 128 for (int i = 0; i < areas.size(); ++i) 129 areas[i] /= S; 130 for (int i = 0; i < Np+1; ++i) 131 p[i] /= S; 132 for (int i = 0; i < N; ++i) 133 { 134 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 135 if (k != kp) 136 { 137 a = 0; 138 for (int j = 0; j < k; ++j) 139 a += areas[j]; 140 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 141 bk = b[k]; 142 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 143 kp = k; 144 } 145 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 146 } 147} 148 149void 150test3() 151{ 152 typedef std::piecewise_linear_distribution<> D; 153 typedef D::param_type P; 154 typedef std::mt19937_64 G; 155 G g; 156 double b[] = {10, 14, 16, 17}; 157 double p[] = {1, 0, 0, 0}; 158 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 159 D d(b, b+Np+1, p); 160 const int N = 1000000; 161 std::vector<D::result_type> u; 162 for (int i = 0; i < N; ++i) 163 { 164 D::result_type v = d(g); 165 assert(d.min() <= v && v < d.max()); 166 u.push_back(v); 167 } 168 std::sort(u.begin(), u.end()); 169 int kp = -1; 170 double a = std::numeric_limits<double>::quiet_NaN(); 171 double m = std::numeric_limits<double>::quiet_NaN(); 172 double bk = std::numeric_limits<double>::quiet_NaN(); 173 double c = std::numeric_limits<double>::quiet_NaN(); 174 std::vector<double> areas(Np); 175 double S = 0; 176 for (int i = 0; i < areas.size(); ++i) 177 { 178 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 179 S += areas[i]; 180 } 181 for (int i = 0; i < areas.size(); ++i) 182 areas[i] /= S; 183 for (int i = 0; i < Np+1; ++i) 184 p[i] /= S; 185 for (int i = 0; i < N; ++i) 186 { 187 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 188 if (k != kp) 189 { 190 a = 0; 191 for (int j = 0; j < k; ++j) 192 a += areas[j]; 193 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 194 bk = b[k]; 195 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 196 kp = k; 197 } 198 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 199 } 200} 201 202void 203test4() 204{ 205 typedef std::piecewise_linear_distribution<> D; 206 typedef D::param_type P; 207 typedef std::mt19937_64 G; 208 G g; 209 double b[] = {10, 14, 16}; 210 double p[] = {0, 1, 0}; 211 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 212 D d(b, b+Np+1, p); 213 const int N = 1000000; 214 std::vector<D::result_type> u; 215 for (int i = 0; i < N; ++i) 216 { 217 D::result_type v = d(g); 218 assert(d.min() <= v && v < d.max()); 219 u.push_back(v); 220 } 221 std::sort(u.begin(), u.end()); 222 int kp = -1; 223 double a = std::numeric_limits<double>::quiet_NaN(); 224 double m = std::numeric_limits<double>::quiet_NaN(); 225 double bk = std::numeric_limits<double>::quiet_NaN(); 226 double c = std::numeric_limits<double>::quiet_NaN(); 227 std::vector<double> areas(Np); 228 double S = 0; 229 for (int i = 0; i < areas.size(); ++i) 230 { 231 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 232 S += areas[i]; 233 } 234 for (int i = 0; i < areas.size(); ++i) 235 areas[i] /= S; 236 for (int i = 0; i < Np+1; ++i) 237 p[i] /= S; 238 for (int i = 0; i < N; ++i) 239 { 240 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 241 if (k != kp) 242 { 243 a = 0; 244 for (int j = 0; j < k; ++j) 245 a += areas[j]; 246 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 247 bk = b[k]; 248 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 249 kp = k; 250 } 251 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 252 } 253} 254 255void 256test5() 257{ 258 typedef std::piecewise_linear_distribution<> D; 259 typedef D::param_type P; 260 typedef std::mt19937_64 G; 261 G g; 262 double b[] = {10, 14}; 263 double p[] = {1, 1}; 264 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 265 D d(b, b+Np+1, p); 266 const int N = 1000000; 267 std::vector<D::result_type> u; 268 for (int i = 0; i < N; ++i) 269 { 270 D::result_type v = d(g); 271 assert(d.min() <= v && v < d.max()); 272 u.push_back(v); 273 } 274 std::sort(u.begin(), u.end()); 275 int kp = -1; 276 double a = std::numeric_limits<double>::quiet_NaN(); 277 double m = std::numeric_limits<double>::quiet_NaN(); 278 double bk = std::numeric_limits<double>::quiet_NaN(); 279 double c = std::numeric_limits<double>::quiet_NaN(); 280 std::vector<double> areas(Np); 281 double S = 0; 282 for (int i = 0; i < areas.size(); ++i) 283 { 284 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 285 S += areas[i]; 286 } 287 for (int i = 0; i < areas.size(); ++i) 288 areas[i] /= S; 289 for (int i = 0; i < Np+1; ++i) 290 p[i] /= S; 291 for (int i = 0; i < N; ++i) 292 { 293 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 294 if (k != kp) 295 { 296 a = 0; 297 for (int j = 0; j < k; ++j) 298 a += areas[j]; 299 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 300 bk = b[k]; 301 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 302 kp = k; 303 } 304 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 305 } 306} 307 308void 309test6() 310{ 311 typedef std::piecewise_linear_distribution<> D; 312 typedef D::param_type P; 313 typedef std::mt19937_64 G; 314 G g; 315 double b[] = {10, 14, 16, 17}; 316 double p[] = {25, 62.5, 12.5, 0}; 317 const size_t Np = sizeof(p) / sizeof(p[0]) - 1; 318 D d(b, b+Np+1, p); 319 const int N = 1000000; 320 std::vector<D::result_type> u; 321 for (int i = 0; i < N; ++i) 322 { 323 D::result_type v = d(g); 324 assert(d.min() <= v && v < d.max()); 325 u.push_back(v); 326 } 327 std::sort(u.begin(), u.end()); 328 int kp = -1; 329 double a = std::numeric_limits<double>::quiet_NaN(); 330 double m = std::numeric_limits<double>::quiet_NaN(); 331 double bk = std::numeric_limits<double>::quiet_NaN(); 332 double c = std::numeric_limits<double>::quiet_NaN(); 333 std::vector<double> areas(Np); 334 double S = 0; 335 for (int i = 0; i < areas.size(); ++i) 336 { 337 areas[i] = (p[i]+p[i+1])*(b[i+1]-b[i])/2; 338 S += areas[i]; 339 } 340 for (int i = 0; i < areas.size(); ++i) 341 areas[i] /= S; 342 for (int i = 0; i < Np+1; ++i) 343 p[i] /= S; 344 for (int i = 0; i < N; ++i) 345 { 346 int k = std::lower_bound(b, b+Np+1, u[i]) - b - 1; 347 if (k != kp) 348 { 349 a = 0; 350 for (int j = 0; j < k; ++j) 351 a += areas[j]; 352 m = (p[k+1] - p[k]) / (b[k+1] - b[k]); 353 bk = b[k]; 354 c = (b[k+1]*p[k] - b[k]*p[k+1]) / (b[k+1] - b[k]); 355 kp = k; 356 } 357 assert(std::abs(f(u[i], a, m, bk, c) - double(i)/N) < .001); 358 } 359} 360 361int main() 362{ 363 test1(); 364 test2(); 365 test3(); 366 test4(); 367 test5(); 368 test6(); 369} 370