2016-08-15 8 views
1

私は、[0,1]に一様に分布した乱数列$ \ xi_i $をFortranの組み込み関数を使って生成しようとしています。シーケンスは再現可能でなければならないので、シードにシステムクロックを使用するのではなく、インデックス$ i $(シーケンス内の$ \ xi_i $の位置)で乱数ジェネレータをシードします。以下は私のコードです:生成された乱数は、周期性を示します

module rand 

contains 

    function generate_random(iseed) result(xi1) 
    !! 
    implicit none 
    integer, intent(in) :: iseed 

    integer, dimension(:), allocatable :: seed 
    integer :: i, j, n 
    real :: xi1 

    !!-generate a seed first 
    call random_seed(size = n) 
    allocate(seed(n)) 
    seed = iseed * (/(i, i=1,n,1)/) 
    call random_seed(PUT = seed) 
    deallocate(seed) 

    call random_number(xi1) 

    !! 
end function generate_random 

end module rand 

program test 

    use rand 
    implicit none 
    integer :: i, imax 

    imax=100 

    do i=1,imax 
    print *, generate_random(i) 
    enddo 

end program test 

この結果は、$ \ xi_i $は、私ははっきりと$インデックス$に対してプロットされたプロットに示されているが、それは後のすべてのようにランダムではないので、いくつかのパターンがあります。これを改善する、つまり「よりランダムに」する方法

enter image description here

+1

どのコンパイラを使用していますか?シードの使用に関する文書(もしあれば)を読むべきです。推測すると、あなたが提供する種子にはゼロビットがたくさんあり、これはエントロピーには良いものではありません。 – francescalus

+0

私は同意すると、シードとして好きな番号を使うことはできません。 –

答えて

6

私はあなたがrandom_numberへのすべての呼び出しが前に発電機を播種している参照してください。これは明確な虐待であり、あなたはそれをするべきではありません!

発電機をに一度だけ植えてください。再現性がありますが単純すぎるわけではありません。クロックが種として使用されても、一度だけ使用されます。

多くの場合、時間のエントロピーまたは選択した繰り返し可能なシード値を増加させる追加のステップがあります。どのようにlcg()を使用してクロック値のエントロピーを増やすかhttps://gcc.gnu.org/onlinedocs/gcc-4.8.5/gfortran/RANDOM_005fSEED.html#RANDOM_005fSEED

+1

はい、擬似乱数ジェネレータ(PRNG)を1回だけシードしてPRNGを何度も呼び出すと、結果の分布にこれらの相関パターンが存在しません。今私は、PRNGは再帰的に動作するので、PRNGをk回呼び出さずに連続してk番目の番号を見つける方法がないことを認識しています。ありがとう。 –

関連する問題