void make_temper_bit(TemperingCalculatable<U>& rand,
                      U mask,
                      int param_pos,
                      U pattern) {
     rand.setTemperingPattern(mask, pattern, param_pos);
     rand.setUpTempering();
 }
 /**
  *\japanese
  * テンパリングパラメータをひとつ探索する。
  *
  * vビット精度均等分布次元をk(v)とする。vにおけるk(v)の理論的上限と
  * 実際のk(v)の差をd(v)とする。vを変化させたd(v)の和をΔで表す。
  *<ol>
  * <li>v_bit から max_v_bit までのすべてのビットパターンを生成し</li>
  * <li>すべてのビットパターンについてk(v),d(v)をそれぞれ計算し</li>
  * <li>v-bit から max_v_bitまでのd(v)の和(Δ)の最も小さかったビッ
  * トパターンを選択する。</li>
  * <li>同じΔであればハミングウェイトの大きいビットパターンを選択する</li>
  *</ol>
  * なお、このメソッドは再帰する。
  *
  * @param rand GF(2)疑似乱数生成器
  * @param v_bit テンパリングパラメータを探索するビット範囲
  * @param param_pos 何番目のテンパリングパラメータを探索しているか
  * @param max_v_bit このビットで探索をやめる
  * @param verbose true なら探索過程の情報を出力する
  * @return delta このテンパリングパラメータの設定結果によるΔ
  *\endjapanese
  *
  *\english
  * Search a tempering parameter.
  *
  * Search the best tempering parameter. Here, k(v) means dimension
  * of equi-distribution with v-bit accuracy, d(v) means the difference
  * between k(v) and the theoretical upper bound at v. &Delta; means
  * sum of d(v) for some vs.
  *<ol>
  * <li>Generates all bit patterns from v_bit to max_v_bit,</li>
  * <li>Calculates k(v) and d(v) for all bit patterns,</li>
  * <li>Select the bit pattern which gives the least &Delta;
  * for v = 1 to max_v_bit.</li>
  * <li>Select the bit pattern whose hamming weight is the largest for
  * the bit patterns whose &Delta;s are same.</li>
  *</ol>
  * This method calls itself recursively.
  *
  * @param rand GF(2)-linear pseudo random number generator
  * @param v_bit start position bit of searching tempering parameter
  * @param param_pos index of tempering parameter
  * @param max_v_bit end position bit of searching tempering parameter
  * @param verbose if true, output redundant message.
  * @return delta &Delta; for v = 1 to max_v_bit for the
  * selected bit pattern.
  *\endenglish
  */
 int search_best_temper(TemperingCalculatable<U>& rand, int v_bit,
                        int param_pos, int max_v_bit, bool verbose) {
     using namespace std;
     int bitSize = rand.bitSize();
     int delta;
     int min_delta = bitSize * bit_len;
     U min_pattern = 0;
     int size = max_v_bit - v_bit;
     U pattern;
     U mask = make_mask(v_bit, size);
     int length = bit_size<U>() / 4;
     for (int i = (1 << size) -1; i >= 0; i--) {
         if (lsb) {
             pattern = static_cast<U>(i) << v_bit;
         } else {
             pattern = static_cast<U>(i) << (bit_len - v_bit - size);
         }
         make_temper_bit(rand, mask, param_pos, pattern);
         delta = get_equidist(rand, bit_len);
         if (delta < min_delta) {
             if (verbose) {
                 cout << "pattern change " << hex << min_pattern
                      << ":" << pattern << endl;
             }
             min_delta = delta;
             min_pattern = pattern;
         } else if (delta == min_delta) {
             if (count_bit(min_pattern) < count_bit(pattern)) {
                 if (verbose) {
                     cout << "pattern change " << hex << min_pattern
                          << ":" << pattern << endl;
                 }
                 min_pattern = pattern;
             }
         }
     }
     make_temper_bit(rand, mask, param_pos, min_pattern);
     if (verbose) {
         cout << dec << min_delta << ":"
              << hex << setw(length) << min_pattern << ":"
              << hex << setw(length) << mask << endl;
     }
     return min_delta;
 }
        /**
         * 状態遷移パラメータとテンパリングパラメータを探索する。
         *
         * @param lg テンパリングパラメータ計算可能な疑似乱数生成器
         * @param st1 テンパリングパラメータ探索アルゴリズム
         * @param st2 テンパリングパラメータ探索アルゴリズム(LSB)
         * @param verbose 余分な情報を出力するフラグ
         * @param os 出力ストリーム
         * @param no_lsb LSBからのテンパリングをしない
         * @return 原始多項式を発見した
         */
        bool search(TemperingCalculatable<T>& lg,
                    AlgorithmTempering<T>& st1,
                    AlgorithmTempering<T>& st2,
                    bool verbose = false,
                    std::ostream& os = std::cout,
                    bool no_lsb = false) {
            using namespace NTL;
            using namespace std;
            using namespace std::tr1;

            out = &os;
            int veq[bit_size<T>()];
            AlgorithmRecursionSearch<T> search(lg, *baseGenerator);
            int mexp = lg.bitSize();
            bool found = false;
            for (int i = 0;; i++) {
                if (search.start(1000 * mexp)) {
                    found = true;
                    break;
                }
                if (verbose) {
                    *out << "not found in " << (i + 1) * 10000 << endl;
                }
            }
            if (!found) {
                return false;
            }
            if (verbose) {
                time_t t = time(NULL);
                *out << "irreducible parameter is found at " << ctime(&t);
            }
            if (verbose) {
                *out << "count = " << search.getCount() << endl;
                *out << lg.getParamString() << endl;
            }
            poly = search.getMinPoly();
            weight = NTL::weight(poly);
            if (verbose) {
                AlgorithmEquidistribution<T> sb(lg, bit_size<T>());
                //print_binary(*out, poly);
                int delta = sb.get_all_equidist(veq);
                print_kv(veq, mexp, bit_size<T>());
                *out << "delta = " << dec << delta << endl;
            }
            if (! no_lsb) {
                st2(lg, verbose);
                if (verbose) {
                    if (st2.isLSBTempering()) {
                        lg.setReverseOutput();
                    }
                    AlgorithmEquidistribution<T> sc(lg, bit_size<T>());
                    delta = sc.get_all_equidist(veq);
                    lg.resetReverseOutput();
                    time_t t = time(NULL);
                    *out << "lsb tempering parameters are found at "
                         << ctime(&t) << endl;
                    print_kv(veq, mexp, bit_size<T>());
                    *out << "lsb delta = " << dec << delta << endl;
                }
            }
            st1(lg, verbose);
            AlgorithmEquidistribution<T> sc(lg, bit_size<T>());
            delta = sc.get_all_equidist(veq);
            if (verbose) {
                time_t t = time(NULL);
                *out << "tempering parameters are found at " << ctime(&t)
                     << endl;
                *out << lg.getParamString() << endl;
                print_kv(veq, mexp, bit_size<T>());
                *out << "delta = " << dec << delta << endl;
            }
            return true;
        }