34 using err::LUMIERA_ERROR_LIFECYCLE;
40 double ctxParameter = 1.0;
50 : function<Limited<int, 2,-2, 0>(size_t)>
59 static_assert (not
sizeof(SIG),
"Unable to adapt given functor.");
63 template<
typename RES>
66 template<
typename FUN>
70 return [functor=std::forward<FUN>(fun)]
71 (
size_t hash) -> _FunRet<FUN>
73 return functor(uint(hash/64), uint(hash%64));
79 template<
typename RES>
82 template<
typename FUN>
86 return [functor=std::forward<FUN>(fun)]
87 (
size_t hash) -> _FunRet<FUN>
89 return functor(hash, ctxParameter);
124 verify_adaptMapping();
125 verify_dynamicChange();
135 auto draw =
Draw().probability(0.5);
136 CHECK (draw( 0) == 0);
137 CHECK (draw( 16) == 0);
138 CHECK (draw( 32) == 1);
139 CHECK (draw( 40) == 2);
140 CHECK (draw( 48) == -2);
141 CHECK (draw( 56) == -1);
142 CHECK (draw( 64) == 0);
143 CHECK (draw( 95) == 0);
144 CHECK (draw( 96) == 1);
145 CHECK (draw(127) == -1);
146 CHECK (draw(128) == 0);
147 CHECK (draw(168) == 2);
148 CHECK (draw(256) == 0);
169 CHECK (0 < v1 and v1 <=5);
172 : function<Limited<char, 'Z','A'>(char,uint)>
174 static double defaultSrc (
char b, uint off) {
return fmod ((b-
'A'+off)/
double(
'Z'-
'A'), 1.0); }
178 CHECK (d2(
'A', 2) ==
'D');
179 CHECK (d2(
'M',10) ==
'X');
180 CHECK (d2(
'Y', 0) ==
'Z');
181 CHECK (d2(
'Y',15) ==
'P');
199 auto distribution = [](
Draw const& draw)
201 using Arr = std::array<int,5>;
202 Arr step{-1,-1,-1,-1,-1};
204 for (uint i=0; i<128; ++i)
207 CHECK (-2 <= res and res <= +2);
213 _Fmt line{
"val:%+d (%02d|%5.2f%%)\n"};
215 for (
int idx=0; idx<5; ++idx)
217 report += line % (idx-2) % step[idx] % (100.0*freq[idx]/128);
223 string report{
"+++| --empty-- \n"};
225 CHECK (draw( 0) == 0);
226 CHECK (draw( 32) == 0);
227 CHECK (draw( 96) == 0);
229 report += distribution(draw);
232 "val:-2 (-1| 0.00%)\n" 233 "val:-1 (-1| 0.00%)\n" 234 "val:+0 (00|100.00%)\n" 235 "val:+1 (-1| 0.00%)\n" 236 "val:+2 (-1| 0.00%)\n"_expect);
239 draw.probability(1.0);
240 CHECK (draw( 0) == +1);
241 CHECK (draw( 15) == +1);
242 CHECK (draw( 16) == +2);
243 CHECK (draw( 31) == +2);
244 CHECK (draw( 32) == -2);
245 CHECK (draw( 47) == -2);
246 CHECK (draw( 48) == -1);
247 CHECK (draw( 63) == -1);
248 CHECK (draw( 64) == +1);
249 CHECK (draw( 96) == -2);
251 report =
"+++| p ≔ 1.0 \n";
252 report += distribution(draw);
255 "val:-2 (32|25.00%)\n" 256 "val:-1 (48|25.00%)\n" 257 "val:+0 (-1| 0.00%)\n" 258 "val:+1 (00|25.00%)\n" 259 "val:+2 (16|25.00%)\n"_expect);
262 draw.probability(0.99);
263 CHECK (draw( 0) == 0);
264 CHECK (draw( 1) == +1);
265 CHECK (draw( 16) == +1);
266 CHECK (draw( 17) == +2);
267 CHECK (draw( 32) == +2);
268 CHECK (draw( 33) == -2);
269 CHECK (draw( 48) == -2);
270 CHECK (draw( 49) == -1);
271 CHECK (draw( 63) == -1);
272 CHECK (draw( 64) == 0);
273 CHECK (draw( 65) == +1);
274 CHECK (draw( 80) == +1);
275 CHECK (draw( 82) == +2);
276 CHECK (draw( 97) == -2);
277 CHECK (draw(352) == +2);
278 CHECK (draw(353) == -2);
280 report =
"+++| p ≔ 0.99 \n";
281 report += distribution(draw);
284 "val:-2 (33|25.00%)\n" 285 "val:-1 (49|23.44%)\n" 286 "val:+0 (00| 1.56%)\n" 287 "val:+1 (01|25.00%)\n" 288 "val:+2 (17|25.00%)\n"_expect);
291 draw.probability(0.98);
292 CHECK (draw( 0) == 0);
293 CHECK (draw( 1) == 0);
294 CHECK (draw( 2) == +1);
295 CHECK (draw( 63) == -1);
296 CHECK (draw( 64) == 0);
297 CHECK (draw( 65) == 0);
298 CHECK (draw( 66) == +1);
300 report =
"+++| p ≔ 0.98 \n";
301 report += distribution(draw);
304 "val:-2 (33|25.00%)\n" 305 "val:-1 (49|23.44%)\n" 306 "val:+0 (00| 3.12%)\n" 307 "val:+1 (02|23.44%)\n" 308 "val:+2 (17|25.00%)\n"_expect);
311 draw.probability(0.97);
312 report =
"+++| p ≔ 0.97 \n";
313 report += distribution(draw);
316 "val:-2 (33|25.00%)\n" 317 "val:-1 (49|23.44%)\n" 318 "val:+0 (00| 3.12%)\n" 319 "val:+1 (02|25.00%)\n" 320 "val:+2 (18|23.44%)\n"_expect);
323 draw.probability(0.75);
324 report =
"+++| p ≔ 0.75 \n";
325 report += distribution(draw);
328 "val:-2 (40|18.75%)\n" 329 "val:-1 (52|18.75%)\n" 330 "val:+0 (00|25.00%)\n" 331 "val:+1 (16|18.75%)\n" 332 "val:+2 (28|18.75%)\n"_expect);
335 draw.probability(0.5);
336 report =
"+++| p ≔ 0.50 \n";
337 report += distribution(draw);
340 "val:-2 (48|12.50%)\n" 341 "val:-1 (56|12.50%)\n" 342 "val:+0 (00|50.00%)\n" 343 "val:+1 (32|12.50%)\n" 344 "val:+2 (40|12.50%)\n"_expect);
347 draw.probability(0.2);
348 report =
"+++| p ≔ 0.20 \n";
349 report += distribution(draw);
352 "val:-2 (58| 4.69%)\n" 353 "val:-1 (61| 4.69%)\n" 354 "val:+0 (00|81.25%)\n" 355 "val:+1 (52| 4.69%)\n" 356 "val:+2 (55| 4.69%)\n"_expect);
359 draw.probability(0.1);
360 report =
"+++| p ≔ 0.10 \n";
361 report += distribution(draw);
364 "val:-2 (61| 3.12%)\n" 365 "val:-1 (63| 1.56%)\n" 366 "val:+0 (00|90.62%)\n" 367 "val:+1 (58| 3.12%)\n" 368 "val:+2 (60| 1.56%)\n"_expect);
372 draw.probability(1.0).shuffle(1);
373 CHECK (draw( 6) == +1);
374 CHECK (draw( 6) == +1);
375 CHECK (draw( 6) == +2);
376 CHECK (draw( 6) == +2);
377 CHECK (draw( 6) == +2);
378 CHECK (draw( 6) == -2);
379 CHECK (draw(16) == -1);
380 CHECK (draw(16) == +1);
382 report =
"+++| p ≔ 1.0 +shuffle \n";
383 report += distribution(draw);
385 "+++| p ≔ 1.0 +shuffle \n" 386 "val:-2 (03|25.00%)\n" 387 "val:-1 (04|25.00%)\n" 388 "val:+0 (-1| 0.00%)\n" 389 "val:+1 (00|25.00%)\n" 390 "val:+2 (02|25.00%)\n"_expect);
392 CHECK (draw(16) == +2);
393 CHECK (draw(16) == +2);
394 CHECK (draw(32) == -2);
395 CHECK (draw(32) == -2);
396 CHECK (draw(16) == +2);
397 CHECK (draw(16) == +2);
402 draw.probability(0.5).maxVal(1);
403 CHECK (draw( 0) == 0);
404 CHECK (draw( 16) == 0);
405 CHECK (draw( 31) == 0);
406 CHECK (draw( 32) == +1);
407 CHECK (draw( 42) == +1);
408 CHECK (draw( 43) == -2);
409 CHECK (draw( 53) == -2);
410 CHECK (draw( 54) == -1);
411 CHECK (draw( 63) == -1);
412 CHECK (draw( 64) == 0);
413 CHECK (draw( 95) == 0);
414 CHECK (draw( 96) == +1);
416 report =
"+++| p ≔ 0.50 max ≔ 1 \n";
417 report += distribution(draw);
419 "+++| p ≔ 0.50 max ≔ 1 \n" 420 "val:-2 (43|17.19%)\n" 421 "val:-1 (54|15.62%)\n" 422 "val:+0 (00|50.00%)\n" 423 "val:+1 (32|17.19%)\n" 424 "val:+2 (-1| 0.00%)\n"_expect);
427 draw.probability(1.0).maxVal(1);
428 CHECK (draw( 0) == +1);
429 CHECK (draw( 16) == +1);
430 CHECK (draw( 21) == +1);
431 CHECK (draw( 22) == -2);
432 CHECK (draw( 42) == -2);
433 CHECK (draw( 43) == -1);
434 CHECK (draw( 63) == -1);
435 CHECK (draw( 64) == +1);
436 CHECK (draw( 85) == +1);
437 CHECK (draw( 86) == -2);
438 CHECK (draw( 96) == -2);
440 report =
"+++| p ≔ 1.0 max ≔ 1 \n";
441 report += distribution(draw);
443 "+++| p ≔ 1.0 max ≔ 1 \n" 444 "val:-2 (22|32.81%)\n" 445 "val:-1 (43|32.81%)\n" 446 "val:+0 (-1| 0.00%)\n" 447 "val:+1 (00|34.38%)\n" 448 "val:+2 (-1| 0.00%)\n"_expect);
452 draw.probability(0.5).maxVal(0);
453 CHECK (draw( 0) == 0);
454 CHECK (draw( 31) == 0);
455 CHECK (draw( 32) == -2);
456 CHECK (draw( 47) == -2);
457 CHECK (draw( 48) == -1);
458 CHECK (draw( 63) == -1);
459 CHECK (draw( 64) == 0);
460 CHECK (draw( 95) == 0);
461 CHECK (draw( 96) == -2);
463 report =
"+++| p ≔ 0.50 max ≔ 0 \n";
464 report += distribution(draw);
466 "+++| p ≔ 0.50 max ≔ 0 \n" 467 "val:-2 (32|25.00%)\n" 468 "val:-1 (48|25.00%)\n" 469 "val:+0 (00|50.00%)\n" 470 "val:+1 (-1| 0.00%)\n" 471 "val:+2 (-1| 0.00%)\n"_expect);
474 draw.probability(1.0).maxVal(0);
475 CHECK (draw( 0) == -2);
476 CHECK (draw( 31) == -2);
477 CHECK (draw( 32) == -1);
478 CHECK (draw( 63) == -1);
479 CHECK (draw( 64) == -2);
480 CHECK (draw( 96) == -1);
482 report =
"+++| p ≔ 1.0 max ≔ 0 \n";
483 report += distribution(draw);
485 "+++| p ≔ 1.0 max ≔ 0 \n" 486 "val:-2 (00|50.00%)\n" 487 "val:-1 (32|50.00%)\n" 488 "val:+0 (-1| 0.00%)\n" 489 "val:+1 (-1| 0.00%)\n" 490 "val:+2 (-1| 0.00%)\n"_expect);
494 draw.probability(0.5).maxVal(-1);
495 CHECK (draw( 32) == -2);
496 CHECK (draw( 47) == -2);
497 CHECK (draw( 48) == -1);
498 CHECK (draw( 63) == -1);
499 CHECK (draw( 64) == 0);
500 CHECK (draw( 95) == 0);
501 CHECK (draw( 96) == -2);
503 report =
"+++| p ≔ 0.50 max ≔ -1 \n";
504 report += distribution(draw);
506 "+++| p ≔ 0.50 max ≔ -1 \n" 507 "val:-2 (32|25.00%)\n" 508 "val:-1 (48|25.00%)\n" 509 "val:+0 (00|50.00%)\n" 510 "val:+1 (-1| 0.00%)\n" 511 "val:+2 (-1| 0.00%)\n"_expect);
514 draw.probability(1.0).maxVal(-1);
515 CHECK (draw( 0) == -2);
516 CHECK (draw( 31) == -2);
517 CHECK (draw( 32) == -1);
518 CHECK (draw( 63) == -1);
519 CHECK (draw( 64) == -2);
521 report =
"+++| p ≔ 1.0 max ≔ -1 \n";
522 report += distribution(draw);
524 "+++| p ≔ 1.0 max ≔ -1 \n" 525 "val:-2 (00|50.00%)\n" 526 "val:-1 (32|50.00%)\n" 527 "val:+0 (-1| 0.00%)\n" 528 "val:+1 (-1| 0.00%)\n" 529 "val:+2 (-1| 0.00%)\n"_expect);
533 draw.probability(0.5).maxVal(2).minVal(1);
534 CHECK (draw( 32) == +1);
535 CHECK (draw( 48) == +2);
536 CHECK (draw( 63) == +2);
537 CHECK (draw( 64) == 0);
539 report =
"+++| p ≔ 0.50 min ≔ 1 max ≔ 2 \n";
540 report += distribution(draw);
542 "+++| p ≔ 0.50 min ≔ 1 max ≔ 2 \n" 543 "val:-2 (-1| 0.00%)\n" 544 "val:-1 (-1| 0.00%)\n" 545 "val:+0 (00|50.00%)\n" 546 "val:+1 (32|25.00%)\n" 547 "val:+2 (48|25.00%)\n"_expect);
550 draw.probability(1.0).maxVal(2).minVal(1);
551 CHECK (draw( 0) == +1);
552 CHECK (draw( 32) == +2);
553 CHECK (draw( 63) == +2);
554 CHECK (draw( 64) == +1);
556 report =
"+++| p ≔ 1.0 min ≔ 1 max ≔ 2 \n";
557 report += distribution(draw);
559 "+++| p ≔ 1.0 min ≔ 1 max ≔ 2 \n" 560 "val:-2 (-1| 0.00%)\n" 561 "val:-1 (-1| 0.00%)\n" 562 "val:+0 (-1| 0.00%)\n" 563 "val:+1 (00|50.00%)\n" 564 "val:+2 (32|50.00%)\n"_expect);
568 draw.probability(0.5).maxVal(0);
569 CHECK (draw( 32) == -1);
570 CHECK (draw( 63) == -1);
571 CHECK (draw( 64) == 0);
573 report =
"+++| p ≔ 0.50 max ≔ 0 (-> min ≔ -1) \n";
574 report += distribution(draw);
576 "+++| p ≔ 0.50 max ≔ 0 (-> min ≔ -1) \n" 577 "val:-2 (-1| 0.00%)\n" 578 "val:-1 (32|50.00%)\n" 579 "val:+0 (00|50.00%)\n" 580 "val:+1 (-1| 0.00%)\n" 581 "val:+2 (-1| 0.00%)\n"_expect);
586 report =
"+++| fixedVal(1) \n";
587 report += distribution(draw);
589 "+++| fixedVal(1) \n" 590 "val:-2 (-1| 0.00%)\n" 591 "val:-1 (-1| 0.00%)\n" 592 "val:+0 (-1| 0.00%)\n" 593 "val:+1 (00|100.00%)\n" 594 "val:+2 (-1| 0.00%)\n"_expect);
616 auto d1 =
Draw([](
size_t hash) ->
double {
return hash / 10.0; });
617 CHECK (d1( 0) == +1);
618 CHECK (d1( 1) == +1);
619 CHECK (d1( 2) == +1);
620 CHECK (d1( 3) == +2);
621 CHECK (d1( 4) == +2);
622 CHECK (d1( 5) == -2);
623 CHECK (d1( 6) == -2);
624 CHECK (d1( 7) == -2);
625 CHECK (d1( 8) == -1);
626 CHECK (d1( 9) == -1);
639 CHECK (d1( 6) == +1);
640 CHECK (d1( 7) == +2);
641 CHECK (d1( 8) == -2);
642 CHECK (d1( 9) == -1);
645 d1.minVal(-1).probability(0.7);
650 CHECK (d1( 4) == +1);
651 CHECK (d1( 5) == +1);
652 CHECK (d1( 6) == +2);
653 CHECK (d1( 7) == +2);
654 CHECK (d1( 8) == -1);
655 CHECK (d1( 9) == -1);
661 auto d2 =
Draw([](uint cycle, uint rem){
return double(rem) / ((cycle+1)*5); });
662 CHECK (d2( 0) == +1);
663 CHECK (d2( 1) == +1);
664 CHECK (d2( 2) == +2);
665 CHECK (d2( 3) == -2);
666 CHECK (d2( 4) == -1);
674 CHECK (d2(64) == +1);
675 CHECK (d2(65) == +1);
676 CHECK (d2(66) == +1);
677 CHECK (d2(67) == +2);
678 CHECK (d2(68) == +2);
679 CHECK (d2(69) == -2);
680 CHECK (d2(70) == -2);
681 CHECK (d2(71) == -2);
682 CHECK (d2(72) == -1);
683 CHECK (d2(73) == -1);
689 d2.mapping([](
size_t hash,
double ctx){
return hash / ctx; });
692 CHECK (d2( 0) == +1);
693 CHECK (d2( 1) == +2);
694 CHECK (d2( 2) == -2);
695 CHECK (d2( 3) == -1);
705 CHECK (d2( 0) == +1);
706 CHECK (d2( 1) == +1);
707 CHECK (d2( 2) == +2);
708 CHECK (d2( 3) == +2);
709 CHECK (d2( 4) == -2);
710 CHECK (d2( 5) == -2);
711 CHECK (d2( 6) == -1);
712 CHECK (d2( 7) == -1);
718 d2.maxVal(0).probability(0.5);
723 CHECK (d2( 4) == -2);
724 CHECK (d2( 5) == -2);
725 CHECK (d2( 6) == -1);
726 CHECK (d2( 7) == -1);
745 auto d1 =
Draw([](uint cycle, uint)
747 return Draw().probability((cycle+1)*0.25);
752 CHECK (d1( 16) == 0);
753 CHECK (d1( 24) == 0);
754 CHECK (d1( 32) == 0);
755 CHECK (d1( 40) == 0);
756 CHECK (d1( 48) == 1);
757 CHECK (d1( 56) == -2);
758 CHECK (d1( 63) == -1);
759 CHECK (d1( 64 +0) == 0);
760 CHECK (d1( 64 +8) == 0);
761 CHECK (d1( 64+16) == 0);
762 CHECK (d1( 64+24) == 0);
763 CHECK (d1( 64+32) == 1);
764 CHECK (d1( 64+40) == 2);
765 CHECK (d1( 64+48) == -2);
766 CHECK (d1( 64+56) == -1);
767 CHECK (d1( 64+63) == -1);
768 CHECK (d1(128 +0) == 0);
769 CHECK (d1(128 +8) == 0);
770 CHECK (d1(128 +16) == 1);
771 CHECK (d1(128 +24) == 1);
772 CHECK (d1(128 +32) == 2);
773 CHECK (d1(128 +40) == -2);
774 CHECK (d1(128 +48) == -2);
775 CHECK (d1(128 +56) == -1);
776 CHECK (d1(128 +63) == -1);
777 CHECK (d1(128+64 +0) == 1);
778 CHECK (d1(128+64 +8) == 1);
779 CHECK (d1(128+64+16) == 2);
780 CHECK (d1(128+64+24) == 2);
781 CHECK (d1(128+64+32) == -2);
782 CHECK (d1(128+64+40) == -2);
783 CHECK (d1(128+64+48) == -1);
784 CHECK (d1(128+64+56) == -1);
785 CHECK (d1(128+64+63) == -1);
786 CHECK (d1(128+64+64) == 1);
void verify_adaptMapping()
static size_t defaultSrc(size_t hash)
by default use the hash directly as source of randomness
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
A front-end for using printf-style formatting.
Implementation namespace for support and library code.
A component and builder to draw limited parameter values based on some source of randomness (or hash ...
Simplistic test class runner.
void verify_dynamicChange()
A collection of frequently used helper functions to support unit testing.
Build a component to select limited values randomly.
Adaptor to handle further mapping functions.
typename _Fun< FUN >::Ret _FunRet
abbreviation for referring to a function's return type