# マニュアルページ lcrans.3m

## 名前

         lcrans - 線形合同法による乱数の生成

## 形式

         cc [ flag ... ] file ...  -lsunmath -lm [ library ... ]

              flag にはフラグ、 file にはファイル名、 library には ラ
              イブラリ名を指定します。

         #include <sunmath.h>

         #define LCRAN_MULTIPLIER 16807

         #define LCRAN_MODULUS 2147483647L

         int i_lcran_(void);

         float r_lcran_(void);

         double d_lcran_(void);

         void i_lcrans_(int *x, int *n, int *l, int *u);

         void u_lcrans_(unsigned *x, int *n,  unsigned  *l,  unsigned
         *u);

         void r_lcrans_(float *x, int *n, float *l, float *u);

         void d_lcrans_(double *x, int *n, double *l, double *u);

         void i_get_lcrans_(int *x);

         void i_set_lcrans_(int *x);

         void i_init_lcrans_(void);

## 機能説明

         これらの関数は、整数型、単精度浮動小数点型、倍精度浮動小数点
         型の一様疑似乱数を生成します。

         線形合同法による乱数は、次の式を用いた ..._lcran_()  に よっ
         て、一度に 1 つずつ生成されます。

              lcran_last = (LCRAN_MULTIPLIER * lcran_last) % LCRAN_MODULUS

         i_lcran_() は lcran_last を返し、 r_lcran_()  と  d_lcran_()
         は lcran_last / LCRAN_MODULUS を返します。これにより、乱数は
         次の範囲に含まれます。

    型    |  下位境界                             |  上位境界
          |  名前                               値|  名前                            値

    ______|_______________________________________|____________________________________

    整数  |  I_LCRAN_LB                          1|  I_LCRAN_UB              2147483646

    単精度|  R_LCRAN_LB   4.656612873077392578E-10|  R_LCRAN_UB                       1

    倍精度|  D_LCRAN_LB   4.656612875245796923E-10|  D_LCRAN_UB   0.9999999995343387127

         lcran_last は 1 <= lcran_last <= 2147483646 を満たさなければ
         なりませんが、効率を高めるため、 ..._lcran_() ではその検査を
         行いません。

         線形合同法による乱数は、次の式を用いた ..._lcrans_() に よっ
         て、一度に *n 個生成されます。

               lcran_last = (lcran_multiplier * lcran_last) % LCRAN_MODULUS ;
               return scale * (lcran_last + offset) ;
         ここで、 scale と offset は *l と *u から算出されるため、 算
         出 さ れ た乱数は [*l,*u] 内で一様に分布します。したがって、
         lcran_multiplier を変更すると、 ..._lcrans_() によって生成さ
         れ る乱数も変化しますが、効率を高めるため、 ..._lcrans_() で
         は LCRAN_MULTIPLIER を 16807 に固定して用いています。固定 の
         除数 LCRAN_MODULUS(2147483647L) は、 rand(3C) での欠陥を避け
         るため意図的に 2 の累乗になっていません。関数に入る と き に
         は、 ..._lcrans_() は 1 <= lcran_last <= 2147483646 を満たす
         かどうかを調べ、必要に応じて lcran_last を変更します。

         線形合同法による乱数発生アルゴリズムの状態 (  lcran_last  と
         lcran_multiplier  の  2 つの整数の配列) は、 i_get_lcrans_()
         で取得したり、 i_set_lcrans_() で設定することができます。 初
         期の状態に戻す場合は、 i_init_lcrans_() を使用します。

## 使用例

      間隔 [0,1] 内で 1000 個の倍精度乱数を生成する
              double x[1000] ; int i, n = 1000 ;
              double lb = D_LCRAN_LB, ub = D_LCRAN_UB ;

              for (i=0;i<n;i++) x[i] = d_lcran_();          /* または ... */

              d_lcrans_(x, &n, &lb, &ub) ;                  /* 同じ出力がより効率的に得られる */

      間隔 [-10,+10] 内で 1000 個の整数乱数を生成する
              int x[1000] ; int n = 1000, lb = -10, ub = 10 ;

              i_lcrans_(x, &n, &lb, &ub) ;

## 関連項目

         addrans(3M), drand48(3),  mwcrans(3M),  rand(3C),  rand(3V),
         random(3), shufrans(3M)

         Knuth 著,『準数値算法』( The  Art  of  Computer  Programming
         Volume II ), 渋谷政昭、中川圭介訳, サイエンス社.

         Park and Miller, Random Number  Generators:  Good  Ones  are
         Hard to Find, Communications of the ACM, October 1988.

## 注意事項

         lcrans(3M) と addrans(3M) のどちらを使用すれば処理効率が向上
         するかは、プログラムが乱数生成関数を呼び出す回数によります。
         通常の用途 (50 以上の呼び出しがある場合) では、 lcrans(3M)、
         drand48(3)、  rand(3C)、 rand(3V)、 random(3) に含まれる関数
         よりも、 addrans(3M)、に含まれる関数を ( shufrans(3M) ととも
         に ) 使用する方が処理効率が向上します。また、50 以下の呼び出
         しの場合は、 addrans(3M) よりも lcrans(3M) を使用すること を
         お 勧 めします。 addrans(3M) は最初の呼び出しで、ADDRAN_SIZE
         に定義されている 55 のエレメントテーブルを初期化する た め、
         オーバーヘッドが生じることから、この場合は lcrans(3M) のほう
         が処理効率は向上します。