!*********************************************************************** ! 線形合同法による乱数 ! わざと質の悪い乱数を作って周期性を見る ! g95 -c lrand.f90 ! Date: 2007/07/15 MODULE lrand INTEGER, PARAMETER :: r0 = 8 !INTEGER, PARAMETER :: A = 3, B = 5, MD = 13 ! 上の例では8→3→1→8→3→……、を繰り返す。 INTEGER, PARAMETER :: A = 9, B = 5, MD = 16 ! 0〜15の範囲で乱数生成 !INTEGER, PARAMETER :: A = 13, B = 5, MD = 24 INTEGER, PARAMETER :: RAND_MAX = 15 !!!! Wikipediaの解説より !! 周期性: 以下の条件が満たされたときに最大周期Mをもつ。 !! 1. BとMが互いに素である。 !! 2. A-1が、Mの持つ全ての素因数で割りきれる。 !! 3. Mが4の倍数である場合は、A-1も4の倍数である。 !! 4. MはXnよりも大きい。 !! A=13、B=5、M=24の組み合わせなどがそれに当たる。 INTEGER r CONTAINS !********************************************************************** ! 初期化 SUBROUTINE l_srand(seed) IMPLICIT NONE INTEGER, INTENT(IN) :: seed r = seed END SUBROUTINE l_srand !********************************************************************** ! 乱数発生 INTEGER FUNCTION l_rand() IMPLICIT NONE r = mod( r * A + B, MD ) l_rand = r END FUNCTION l_rand !********************************************************************** ! 乱数発生、0 〜 r_maxの範囲で、両端を含む REAL*8 FUNCTION l_rand_max(r_max) IMPLICIT NONE REAL*8, INTENT(IN) :: r_max l_rand_max = l_rand() * r_max / RAND_MAX END FUNCTION l_rand_max END MODULE lrand !****************************************************************************** ! テスト用メイン !!PROGRAM main !!USE lrand !!IMPLICIT NONE !! !! INTEGER i !! !! CALL l_srand(8) !! DO i=0, 1000 !! !! print *, i, l_rand() !! print *, i, l_rand_max(100.0d0) !! END DO !! !!END PROGRAM main !**** End of File ************************************************************