2

rng 内で固定シードを使用すると、精度が変化すると結果が再現できなくなります。つまり、テンプレート引数cpp_dec_float<xxx>を変更して次のコードを実行すると、(精度の変更ごとに) 異なる出力が表示されます。

#include <iostream>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <random>
#include <boost/random.hpp>
    
typedef boost::multiprecision::cpp_dec_float<350> mp_backend; // <--- change me
typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> big_float; 
typedef boost::random::independent_bits_engine<boost::mt19937, std::numeric_limits<big_float>::digits, boost::multiprecision::cpp_int> generator;


int main()
{
    std::cout << std::setprecision(std::numeric_limits<big_float>::digits10) << std::showpoint;
    auto ur = boost::random::uniform_real_distribution<big_float>(big_float(0), big_float(1));
    generator gen = generator(42); // fixed seed
    std::cout << ur(gen) << std::endl;
    return 0;
}

合理的だと思います。nしかし、桁数の精度の場合、固定シードが桁数に対して定義されている桁内xと同等の数値を生成するようにするにはどうすればよいですか? 例えばynyn+1

x = 0.213099234     // n = 9
y = 0.2130992347    // n = 10
...
4

2 に答える 2

1

優れた@ user14717の回答に追加して、再現可能な結果を​​得るには、次のことを行う必要があります。

  1. ワイド (出力仮数 + 1 よりも広い) ランダム ビット ジェネレーターを使用します。たとえば、仮数部が 128 ビット以下の MP double が必要な場合は、128 ビット出力を生成するビット ジェネレーターを使用します。内部的には、mersenne twister のような標準的な RNG で単語をつなぎ合わせて、目的の幅を実現することができます。

  2. この128ビットを仮数に変換するuniform_real_distributionを所有しています

  3. 最後に、128 ビット パックの残りのビットを破棄します。

このアプローチを使用すると、同じ実際の出力が得られることが保証されますが、違いは精度だけです。

于 2020-08-18T16:50:51.353 に答える