1 #ifndef MTTOOLBOX_ALGORITHM_EQUIDISTRIBUTION_HPP
2 #define MTTOOLBOX_ALGORITHM_EQUIDISTRIBUTION_HPP
35 #if __cplusplus >= 201103L
38 #if defined(__clang__)
39 #if __has_include(<tr1/memory>)
40 #define MTTOOLBOX_USE_TR1
44 #endif // __has_indlude
46 #define MTTOOLBOX_USE_TR1
49 #endif // cplusplus version
56 #if defined(MTTOOLBOX_USE_TR1)
57 using std::tr1::shared_ptr;
59 using std::shared_ptr;
87 template<
typename U,
typename V = U>
117 shared_ptr<ECGenerator> r(generator.clone());
149 shared_ptr<ECGenerator> r(generator.clone());
154 next = getOne<U>() << (bit_size<U>() - bit_pos - 1);
156 cout <<
"DEBUG:" << dec << bit_pos <<
":"
157 << hex <<
next << endl;
237 template<
typename U,
typename V = U>
298 bit_len = bit_length;
300 basis =
new linear_vec * [size];
306 for (
int i = 0; i < bit_len; i++) {
307 basis[i] =
new linear_vec(rand, i);
309 basis[bit_len] =
new linear_vec(rand);
322 for (
int i = 0; i < size; i++) {
331 int get_equidist_main(
int bit_len);
332 void adjust(
int new_len);
398 template<
typename U,
typename V>
399 void AlgorithmEquidistribution<U, V>::adjust(
int new_len) {
403 U mask = ~tmp << (bit_size<U>() - new_len);
404 for (
int i = 0; i < size; i++) {
405 basis[i]->next = basis[i]->next & mask;
406 if (
isZero(basis[i]->next)) {
407 basis[i]->next_state(new_len);
421 template<
typename U,
typename V>
425 cout <<
"debug ====" << endl;
426 cout <<
"count = " << dec << count << endl;
427 cout <<
"zero = " << zero << endl;
428 cout <<
"next = " << hex << next << endl;
429 cout <<
"debug ====" << endl;
432 template<
typename U,
typename V>
469 template<
typename U,
typename V>
475 veq[bit_len - 1] = get_equidist_main(bit_len);
477 for (
int i = 0; i < size; i++) {
478 basis[i]->debug_print();
481 sum += stateBitSize / bit_len - veq[bit_len - 1];
483 for (; bit_len >= 1; bit_len--) {
485 veq[bit_len - 1] = get_equidist_main(bit_len);
486 sum += stateBitSize / bit_len - veq[bit_len - 1];
523 template<
typename U,
typename V>
527 int veq = get_equidist_main(bit_len);
530 for (; bit_len >= 1; bit_len--) {
532 sum += stateBitSize / bit_len - get_equidist_main(bit_len);
549 template<
typename U,
typename V>
554 rand->add(*src.
rand);
575 template<
typename U,
typename V>
583 next = rand->generate(bit_len);
587 if (zero_count > rand->bitSize() * 2) {
589 if (rand->isZero()) {
594 next = rand->generate(bit_len);
615 template<
typename U,
typename V>
623 pivot_index =
calc_1pos(basis[bit_len]->next);
624 while (!basis[bit_len]->zero) {
626 if (pivot_index == -1) {
627 cout <<
"pivot_index = " << dec << pivot_index << endl;
628 cout <<
"zero = " << basis[bit_len]->zero << endl;
629 cout <<
"next = " << hex << basis[bit_len]->next << endl;
630 throw new std::logic_error(
"pivot error 0");
632 if (pivot_index >= bit_len) {
633 cout <<
"pivot_index = " << dec << pivot_index << endl;
634 cout <<
"bit_len = " << bit_len << endl;
635 cout <<
"next = " << hex << basis[bit_len]->next << endl;
636 throw new std::logic_error(
"pivot error 0.1");
638 if (pivot_index !=
calc_1pos(basis[pivot_index]->next)) {
639 cerr <<
"pivot error 1" << endl;
640 cerr <<
"pivot_index:" << dec << pivot_index << endl;
641 cerr <<
"calc_1pos:" << dec
642 <<
calc_1pos(basis[pivot_index]->next) << endl;
643 cerr <<
"next:" << hex << basis[pivot_index]->next << endl;
644 throw new std::logic_error(
"pivot error 1");
649 if (basis[bit_len]->count > basis[pivot_index]->count) {
650 swap(basis[bit_len], basis[pivot_index]);
653 cout <<
"before add bit_len next = " << hex
654 << basis[bit_len]->next <<
" count = " << dec
655 << basis[bit_len]->count << endl;
656 cout <<
"before add pivot next = " << hex
657 << basis[pivot_index]->next <<
" count = " << dec
658 << basis[pivot_index]->count << endl;
660 basis[bit_len]->add(*basis[pivot_index]);
662 cout <<
"after add bit_len next = " << hex
663 << basis[bit_len]->next <<
" count = " << dec
664 << basis[bit_len]->count << endl;
668 if (
isZero(basis[bit_len]->next)) {
669 basis[bit_len]->next_state(bit_len);
670 pivot_index =
calc_1pos(basis[bit_len]->next);
672 cout <<
"zero" << endl;
673 cout <<
"pivot_index = " << dec << pivot_index << endl;
674 if (pivot_index >= bit_len) {
675 cout <<
"pivot_index = " << dec << pivot_index << endl;
676 cout <<
"bit_len = " << bit_len << endl;
677 cout <<
"next = " << hex << basis[bit_len]->next << endl;
678 throw new std::logic_error(
"pivot error 1.1");
680 if (basis[bit_len]->zero) {
681 cout <<
"loop exit condition" << endl;
682 }
else if (pivot_index == -1) {
683 cerr <<
"pivot error 1.1" << endl;
684 throw new std::logic_error(
"pivot error 1.2");
691 old_pivot = pivot_index;
692 pivot_index =
calc_1pos(basis[bit_len]->next);
693 if (pivot_index >= bit_len) {
694 cout <<
"pivot_index = " << dec << pivot_index << endl;
695 cout <<
"bit_len = " << bit_len << endl;
696 cout <<
"next = " << hex << basis[bit_len]->next << endl;
697 throw new std::logic_error(
"pivot error 2");
699 if (old_pivot <= pivot_index) {
700 cerr <<
"pivot error 2" << endl;
701 cerr <<
"old_pivot = " << dec << old_pivot << endl;
702 cerr <<
"pivot_index = " << dec << pivot_index << endl;
703 throw new std::logic_error(
"pivot error 2.1");
709 int min_count = basis[0]->count;
710 for (
int i = 1; i < bit_len; i++) {
711 if (min_count > basis[i]->count) {
712 min_count = basis[i]->count;
716 cout <<
"min_count = " << min_count << endl;
717 cout <<
"stateBitSize = " << stateBitSize << endl;
718 cout <<
"bit_len = " << bit_len << endl;
719 cout <<
"theoretical bound " << (stateBitSize / bit_len) << endl;
721 if (min_count > stateBitSize / bit_len) {
722 cerr << basis[0]->rand->getParamString() << endl;
723 for(
int i = 0; i < size; i++) {
724 basis[i]->debug_print();
726 cerr <<
"min_count = " << min_count << endl;
727 cerr <<
"stateBitSize = " << stateBitSize << endl;
728 cerr <<
"bit_len = " << bit_len << endl;
729 cerr <<
"over theoretical bound " << (stateBitSize / bit_len)
731 throw new std::logic_error(
"over theoretical bound");
736 #if defined(MTTOOLBOX_USE_TR1)
737 #undef MTTOOLBOX_USE_TR1
739 #endif // MTTOOLBOX_ALGORITHM_EQUIDISTRIBUTION_HPP
このクラスはGF(2)線形疑似乱数生成器の均等分布次元を計算するためのクラスである。