43 using err::LUMIERA_ERROR_LIFECYCLE;
49 double ctxParameter = 1.0;
59 : function<Limited<int, 2,-2, 0>(size_t)>
68 static_assert (not
sizeof(SIG),
"Unable to adapt given functor.");
72 template<
typename RES>
75 template<
typename FUN>
79 return [functor=std::forward<FUN>(fun)]
80 (
size_t hash) -> _FunRet<FUN>
82 return functor(uint(hash/64), uint(hash%64));
88 template<
typename RES>
91 template<
typename FUN>
95 return [functor=std::forward<FUN>(fun)]
96 (
size_t hash) -> _FunRet<FUN>
98 return functor(hash, ctxParameter);
133 verify_adaptMapping();
134 verify_dynamicChange();
144 auto draw =
Draw().probability(0.5);
145 CHECK (draw( 0) == 0);
146 CHECK (draw( 16) == 0);
147 CHECK (draw( 32) == 1);
148 CHECK (draw( 40) == 2);
149 CHECK (draw( 48) == -2);
150 CHECK (draw( 56) == -1);
151 CHECK (draw( 64) == 0);
152 CHECK (draw( 95) == 0);
153 CHECK (draw( 96) == 1);
154 CHECK (draw(127) == -1);
155 CHECK (draw(128) == 0);
156 CHECK (draw(168) == 2);
157 CHECK (draw(256) == 0);
178 CHECK (0 < v1 and v1 <=5);
181 : function<Limited<char, 'Z','A'>(char,uint)>
183 static double defaultSrc (
char b, uint off) {
return fmod ((b-
'A'+off)/
double(
'Z'-
'A'), 1.0); }
187 CHECK (d2(
'A', 2) ==
'D');
188 CHECK (d2(
'M',10) ==
'X');
189 CHECK (d2(
'Y', 0) ==
'Z');
190 CHECK (d2(
'Y',15) ==
'P');
208 auto distribution = [](
Draw const& draw)
210 using Arr = std::array<int,5>;
211 Arr step{-1,-1,-1,-1,-1};
213 for (uint i=0; i<128; ++i)
216 CHECK (-2 <= res and res <= +2);
222 _Fmt line{
"val:%+d (%02d|%5.2f%%)\n"};
224 for (
int idx=0; idx<5; ++idx)
226 report += line % (idx-2) % step[idx] % (100.0*freq[idx]/128);
232 string report{
"+++| --empty-- \n"};
234 CHECK (draw( 0) == 0);
235 CHECK (draw( 32) == 0);
236 CHECK (draw( 96) == 0);
238 report += distribution(draw);
241 "val:-2 (-1| 0.00%)\n" 242 "val:-1 (-1| 0.00%)\n" 243 "val:+0 (00|100.00%)\n" 244 "val:+1 (-1| 0.00%)\n" 245 "val:+2 (-1| 0.00%)\n"_expect);
248 draw.probability(1.0);
249 CHECK (draw( 0) == +1);
250 CHECK (draw( 15) == +1);
251 CHECK (draw( 16) == +2);
252 CHECK (draw( 31) == +2);
253 CHECK (draw( 32) == -2);
254 CHECK (draw( 47) == -2);
255 CHECK (draw( 48) == -1);
256 CHECK (draw( 63) == -1);
257 CHECK (draw( 64) == +1);
258 CHECK (draw( 96) == -2);
260 report =
"+++| p ≔ 1.0 \n";
261 report += distribution(draw);
264 "val:-2 (32|25.00%)\n" 265 "val:-1 (48|25.00%)\n" 266 "val:+0 (-1| 0.00%)\n" 267 "val:+1 (00|25.00%)\n" 268 "val:+2 (16|25.00%)\n"_expect);
271 draw.probability(0.99);
272 CHECK (draw( 0) == 0);
273 CHECK (draw( 1) == +1);
274 CHECK (draw( 16) == +1);
275 CHECK (draw( 17) == +2);
276 CHECK (draw( 32) == +2);
277 CHECK (draw( 33) == -2);
278 CHECK (draw( 48) == -2);
279 CHECK (draw( 49) == -1);
280 CHECK (draw( 63) == -1);
281 CHECK (draw( 64) == 0);
282 CHECK (draw( 65) == +1);
283 CHECK (draw( 80) == +1);
284 CHECK (draw( 82) == +2);
285 CHECK (draw( 97) == -2);
286 CHECK (draw(352) == +2);
287 CHECK (draw(353) == -2);
289 report =
"+++| p ≔ 0.99 \n";
290 report += distribution(draw);
293 "val:-2 (33|25.00%)\n" 294 "val:-1 (49|23.44%)\n" 295 "val:+0 (00| 1.56%)\n" 296 "val:+1 (01|25.00%)\n" 297 "val:+2 (17|25.00%)\n"_expect);
300 draw.probability(0.98);
301 CHECK (draw( 0) == 0);
302 CHECK (draw( 1) == 0);
303 CHECK (draw( 2) == +1);
304 CHECK (draw( 63) == -1);
305 CHECK (draw( 64) == 0);
306 CHECK (draw( 65) == 0);
307 CHECK (draw( 66) == +1);
309 report =
"+++| p ≔ 0.98 \n";
310 report += distribution(draw);
313 "val:-2 (33|25.00%)\n" 314 "val:-1 (49|23.44%)\n" 315 "val:+0 (00| 3.12%)\n" 316 "val:+1 (02|23.44%)\n" 317 "val:+2 (17|25.00%)\n"_expect);
320 draw.probability(0.97);
321 report =
"+++| p ≔ 0.97 \n";
322 report += distribution(draw);
325 "val:-2 (33|25.00%)\n" 326 "val:-1 (49|23.44%)\n" 327 "val:+0 (00| 3.12%)\n" 328 "val:+1 (02|25.00%)\n" 329 "val:+2 (18|23.44%)\n"_expect);
332 draw.probability(0.75);
333 report =
"+++| p ≔ 0.75 \n";
334 report += distribution(draw);
337 "val:-2 (40|18.75%)\n" 338 "val:-1 (52|18.75%)\n" 339 "val:+0 (00|25.00%)\n" 340 "val:+1 (16|18.75%)\n" 341 "val:+2 (28|18.75%)\n"_expect);
344 draw.probability(0.5);
345 report =
"+++| p ≔ 0.50 \n";
346 report += distribution(draw);
349 "val:-2 (48|12.50%)\n" 350 "val:-1 (56|12.50%)\n" 351 "val:+0 (00|50.00%)\n" 352 "val:+1 (32|12.50%)\n" 353 "val:+2 (40|12.50%)\n"_expect);
356 draw.probability(0.2);
357 report =
"+++| p ≔ 0.20 \n";
358 report += distribution(draw);
361 "val:-2 (58| 4.69%)\n" 362 "val:-1 (61| 4.69%)\n" 363 "val:+0 (00|81.25%)\n" 364 "val:+1 (52| 4.69%)\n" 365 "val:+2 (55| 4.69%)\n"_expect);
368 draw.probability(0.1);
369 report =
"+++| p ≔ 0.10 \n";
370 report += distribution(draw);
373 "val:-2 (61| 3.12%)\n" 374 "val:-1 (63| 1.56%)\n" 375 "val:+0 (00|90.62%)\n" 376 "val:+1 (58| 3.12%)\n" 377 "val:+2 (60| 1.56%)\n"_expect);
381 draw.probability(1.0).shuffle(1);
382 CHECK (draw( 6) == +1);
383 CHECK (draw( 6) == +1);
384 CHECK (draw( 6) == +2);
385 CHECK (draw( 6) == +2);
386 CHECK (draw( 6) == +2);
387 CHECK (draw( 6) == -2);
388 CHECK (draw(16) == -1);
389 CHECK (draw(16) == +1);
391 report =
"+++| p ≔ 1.0 +shuffle \n";
392 report += distribution(draw);
394 "+++| p ≔ 1.0 +shuffle \n" 395 "val:-2 (03|25.00%)\n" 396 "val:-1 (04|25.00%)\n" 397 "val:+0 (-1| 0.00%)\n" 398 "val:+1 (00|25.00%)\n" 399 "val:+2 (02|25.00%)\n"_expect);
401 CHECK (draw(16) == +2);
402 CHECK (draw(16) == +2);
403 CHECK (draw(32) == -2);
404 CHECK (draw(32) == -2);
405 CHECK (draw(16) == +2);
406 CHECK (draw(16) == +2);
411 draw.probability(0.5).maxVal(1);
412 CHECK (draw( 0) == 0);
413 CHECK (draw( 16) == 0);
414 CHECK (draw( 31) == 0);
415 CHECK (draw( 32) == +1);
416 CHECK (draw( 42) == +1);
417 CHECK (draw( 43) == -2);
418 CHECK (draw( 53) == -2);
419 CHECK (draw( 54) == -1);
420 CHECK (draw( 63) == -1);
421 CHECK (draw( 64) == 0);
422 CHECK (draw( 95) == 0);
423 CHECK (draw( 96) == +1);
425 report =
"+++| p ≔ 0.50 max ≔ 1 \n";
426 report += distribution(draw);
428 "+++| p ≔ 0.50 max ≔ 1 \n" 429 "val:-2 (43|17.19%)\n" 430 "val:-1 (54|15.62%)\n" 431 "val:+0 (00|50.00%)\n" 432 "val:+1 (32|17.19%)\n" 433 "val:+2 (-1| 0.00%)\n"_expect);
436 draw.probability(1.0).maxVal(1);
437 CHECK (draw( 0) == +1);
438 CHECK (draw( 16) == +1);
439 CHECK (draw( 21) == +1);
440 CHECK (draw( 22) == -2);
441 CHECK (draw( 42) == -2);
442 CHECK (draw( 43) == -1);
443 CHECK (draw( 63) == -1);
444 CHECK (draw( 64) == +1);
445 CHECK (draw( 85) == +1);
446 CHECK (draw( 86) == -2);
447 CHECK (draw( 96) == -2);
449 report =
"+++| p ≔ 1.0 max ≔ 1 \n";
450 report += distribution(draw);
452 "+++| p ≔ 1.0 max ≔ 1 \n" 453 "val:-2 (22|32.81%)\n" 454 "val:-1 (43|32.81%)\n" 455 "val:+0 (-1| 0.00%)\n" 456 "val:+1 (00|34.38%)\n" 457 "val:+2 (-1| 0.00%)\n"_expect);
461 draw.probability(0.5).maxVal(0);
462 CHECK (draw( 0) == 0);
463 CHECK (draw( 31) == 0);
464 CHECK (draw( 32) == -2);
465 CHECK (draw( 47) == -2);
466 CHECK (draw( 48) == -1);
467 CHECK (draw( 63) == -1);
468 CHECK (draw( 64) == 0);
469 CHECK (draw( 95) == 0);
470 CHECK (draw( 96) == -2);
472 report =
"+++| p ≔ 0.50 max ≔ 0 \n";
473 report += distribution(draw);
475 "+++| p ≔ 0.50 max ≔ 0 \n" 476 "val:-2 (32|25.00%)\n" 477 "val:-1 (48|25.00%)\n" 478 "val:+0 (00|50.00%)\n" 479 "val:+1 (-1| 0.00%)\n" 480 "val:+2 (-1| 0.00%)\n"_expect);
483 draw.probability(1.0).maxVal(0);
484 CHECK (draw( 0) == -2);
485 CHECK (draw( 31) == -2);
486 CHECK (draw( 32) == -1);
487 CHECK (draw( 63) == -1);
488 CHECK (draw( 64) == -2);
489 CHECK (draw( 96) == -1);
491 report =
"+++| p ≔ 1.0 max ≔ 0 \n";
492 report += distribution(draw);
494 "+++| p ≔ 1.0 max ≔ 0 \n" 495 "val:-2 (00|50.00%)\n" 496 "val:-1 (32|50.00%)\n" 497 "val:+0 (-1| 0.00%)\n" 498 "val:+1 (-1| 0.00%)\n" 499 "val:+2 (-1| 0.00%)\n"_expect);
503 draw.probability(0.5).maxVal(-1);
504 CHECK (draw( 32) == -2);
505 CHECK (draw( 47) == -2);
506 CHECK (draw( 48) == -1);
507 CHECK (draw( 63) == -1);
508 CHECK (draw( 64) == 0);
509 CHECK (draw( 95) == 0);
510 CHECK (draw( 96) == -2);
512 report =
"+++| p ≔ 0.50 max ≔ -1 \n";
513 report += distribution(draw);
515 "+++| p ≔ 0.50 max ≔ -1 \n" 516 "val:-2 (32|25.00%)\n" 517 "val:-1 (48|25.00%)\n" 518 "val:+0 (00|50.00%)\n" 519 "val:+1 (-1| 0.00%)\n" 520 "val:+2 (-1| 0.00%)\n"_expect);
523 draw.probability(1.0).maxVal(-1);
524 CHECK (draw( 0) == -2);
525 CHECK (draw( 31) == -2);
526 CHECK (draw( 32) == -1);
527 CHECK (draw( 63) == -1);
528 CHECK (draw( 64) == -2);
530 report =
"+++| p ≔ 1.0 max ≔ -1 \n";
531 report += distribution(draw);
533 "+++| p ≔ 1.0 max ≔ -1 \n" 534 "val:-2 (00|50.00%)\n" 535 "val:-1 (32|50.00%)\n" 536 "val:+0 (-1| 0.00%)\n" 537 "val:+1 (-1| 0.00%)\n" 538 "val:+2 (-1| 0.00%)\n"_expect);
542 draw.probability(0.5).maxVal(2).minVal(1);
543 CHECK (draw( 32) == +1);
544 CHECK (draw( 48) == +2);
545 CHECK (draw( 63) == +2);
546 CHECK (draw( 64) == 0);
548 report =
"+++| p ≔ 0.50 min ≔ 1 max ≔ 2 \n";
549 report += distribution(draw);
551 "+++| p ≔ 0.50 min ≔ 1 max ≔ 2 \n" 552 "val:-2 (-1| 0.00%)\n" 553 "val:-1 (-1| 0.00%)\n" 554 "val:+0 (00|50.00%)\n" 555 "val:+1 (32|25.00%)\n" 556 "val:+2 (48|25.00%)\n"_expect);
559 draw.probability(1.0).maxVal(2).minVal(1);
560 CHECK (draw( 0) == +1);
561 CHECK (draw( 32) == +2);
562 CHECK (draw( 63) == +2);
563 CHECK (draw( 64) == +1);
565 report =
"+++| p ≔ 1.0 min ≔ 1 max ≔ 2 \n";
566 report += distribution(draw);
568 "+++| p ≔ 1.0 min ≔ 1 max ≔ 2 \n" 569 "val:-2 (-1| 0.00%)\n" 570 "val:-1 (-1| 0.00%)\n" 571 "val:+0 (-1| 0.00%)\n" 572 "val:+1 (00|50.00%)\n" 573 "val:+2 (32|50.00%)\n"_expect);
577 draw.probability(0.5).maxVal(0);
578 CHECK (draw( 32) == -1);
579 CHECK (draw( 63) == -1);
580 CHECK (draw( 64) == 0);
582 report =
"+++| p ≔ 0.50 max ≔ 0 (-> min ≔ -1) \n";
583 report += distribution(draw);
585 "+++| p ≔ 0.50 max ≔ 0 (-> min ≔ -1) \n" 586 "val:-2 (-1| 0.00%)\n" 587 "val:-1 (32|50.00%)\n" 588 "val:+0 (00|50.00%)\n" 589 "val:+1 (-1| 0.00%)\n" 590 "val:+2 (-1| 0.00%)\n"_expect);
595 report =
"+++| fixedVal(1) \n";
596 report += distribution(draw);
598 "+++| fixedVal(1) \n" 599 "val:-2 (-1| 0.00%)\n" 600 "val:-1 (-1| 0.00%)\n" 601 "val:+0 (-1| 0.00%)\n" 602 "val:+1 (00|100.00%)\n" 603 "val:+2 (-1| 0.00%)\n"_expect);
625 auto d1 =
Draw([](
size_t hash) ->
double {
return hash / 10.0; });
626 CHECK (d1( 0) == +1);
627 CHECK (d1( 1) == +1);
628 CHECK (d1( 2) == +1);
629 CHECK (d1( 3) == +2);
630 CHECK (d1( 4) == +2);
631 CHECK (d1( 5) == -2);
632 CHECK (d1( 6) == -2);
633 CHECK (d1( 7) == -2);
634 CHECK (d1( 8) == -1);
635 CHECK (d1( 9) == -1);
648 CHECK (d1( 6) == +1);
649 CHECK (d1( 7) == +2);
650 CHECK (d1( 8) == -2);
651 CHECK (d1( 9) == -1);
654 d1.minVal(-1).probability(0.7);
659 CHECK (d1( 4) == +1);
660 CHECK (d1( 5) == +1);
661 CHECK (d1( 6) == +2);
662 CHECK (d1( 7) == +2);
663 CHECK (d1( 8) == -1);
664 CHECK (d1( 9) == -1);
670 auto d2 =
Draw([](uint cycle, uint rem){
return double(rem) / ((cycle+1)*5); });
671 CHECK (d2( 0) == +1);
672 CHECK (d2( 1) == +1);
673 CHECK (d2( 2) == +2);
674 CHECK (d2( 3) == -2);
675 CHECK (d2( 4) == -1);
683 CHECK (d2(64) == +1);
684 CHECK (d2(65) == +1);
685 CHECK (d2(66) == +1);
686 CHECK (d2(67) == +2);
687 CHECK (d2(68) == +2);
688 CHECK (d2(69) == -2);
689 CHECK (d2(70) == -2);
690 CHECK (d2(71) == -2);
691 CHECK (d2(72) == -1);
692 CHECK (d2(73) == -1);
698 d2.mapping([](
size_t hash,
double ctx){
return hash / ctx; });
701 CHECK (d2( 0) == +1);
702 CHECK (d2( 1) == +2);
703 CHECK (d2( 2) == -2);
704 CHECK (d2( 3) == -1);
714 CHECK (d2( 0) == +1);
715 CHECK (d2( 1) == +1);
716 CHECK (d2( 2) == +2);
717 CHECK (d2( 3) == +2);
718 CHECK (d2( 4) == -2);
719 CHECK (d2( 5) == -2);
720 CHECK (d2( 6) == -1);
721 CHECK (d2( 7) == -1);
727 d2.maxVal(0).probability(0.5);
732 CHECK (d2( 4) == -2);
733 CHECK (d2( 5) == -2);
734 CHECK (d2( 6) == -1);
735 CHECK (d2( 7) == -1);
754 auto d1 =
Draw([](uint cycle, uint)
756 return Draw().probability((cycle+1)*0.25);
761 CHECK (d1( 16) == 0);
762 CHECK (d1( 24) == 0);
763 CHECK (d1( 32) == 0);
764 CHECK (d1( 40) == 0);
765 CHECK (d1( 48) == 1);
766 CHECK (d1( 56) == -2);
767 CHECK (d1( 63) == -1);
768 CHECK (d1( 64 +0) == 0);
769 CHECK (d1( 64 +8) == 0);
770 CHECK (d1( 64+16) == 0);
771 CHECK (d1( 64+24) == 0);
772 CHECK (d1( 64+32) == 1);
773 CHECK (d1( 64+40) == 2);
774 CHECK (d1( 64+48) == -2);
775 CHECK (d1( 64+56) == -1);
776 CHECK (d1( 64+63) == -1);
777 CHECK (d1(128 +0) == 0);
778 CHECK (d1(128 +8) == 0);
779 CHECK (d1(128 +16) == 1);
780 CHECK (d1(128 +24) == 1);
781 CHECK (d1(128 +32) == 2);
782 CHECK (d1(128 +40) == -2);
783 CHECK (d1(128 +48) == -2);
784 CHECK (d1(128 +56) == -1);
785 CHECK (d1(128 +63) == -1);
786 CHECK (d1(128+64 +0) == 1);
787 CHECK (d1(128+64 +8) == 1);
788 CHECK (d1(128+64+16) == 2);
789 CHECK (d1(128+64+24) == 2);
790 CHECK (d1(128+64+32) == -2);
791 CHECK (d1(128+64+40) == -2);
792 CHECK (d1(128+64+48) == -1);
793 CHECK (d1(128+64+56) == -1);
794 CHECK (d1(128+64+63) == -1);
795 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 ...
Simple 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