このページについて

このページに関する質問やコメントはお気軽に以下のメールアドレスまで. mail

リンクは御自由にどうぞ

powered by FreeBSD

重要なお知らせ

サイト閉鎖のお知らせ (2012-02-26)

恩師,三橋教授のご厚意により博士課程修了後も維持されてきた当サイトでありますが, この度,三橋教授のご退官により, 時期は未定でありますが来年度中に閉鎖される見通しとなりました. したがいまして,このページの情報を必要とされる方は各自それぞれで必要なページの保存等を行うことをお奨めいたします. 圧縮ファイル形式での提供を希望される方は著者までメールでご連絡下さい. 可能な限り対応させていただきます.

なお,ダウンロードツール類を使用してのバックアップ取得は堅くお断りいたします. この種のツールを利用した場合,ネットワークブロックに対するアクセス規制が行われる恐れがあります.

更新履歴と目次

更新履歴

2009-08-28

Windows版のサンプルコードを更新しました.

2008-10-09

Visual C++を利用する場合のライブラリの構築方法の記述を追加しました.

2008-01-18

サンプルコードを更新.

  • ヘッダファイルrandlib.hの呼び出しの誤りを修正しました
2007-12-16

サンプルコードを更新.

  • サンプルコードをRANDLIB V1.3に更新しました
  • ranlib.hrandlib.hに変更されました
  • 旧版はサンプルコード (V1.1)に置いておきます
2007-12-15

サンプルコードを更新.

  • 乱数源を文字列から初期化するようにしました
  • サンプルコードがFreeBSDの環境に依存しないようにしました
  • サンプルコードのライブラリの構築を自動化しました
2006-01-05

サンプルコードを更新.

  • バイナリをstripするようMakefileを修正しました
  • 乱数源の初期化をモジュールにまとめました
  • 二次元正規乱数の発生のサンプルを追加しました

目次

はじめに

RANDLIBはTexas大学,M. D. Anderson 癌センターのBarry W. Brown,James Lovato両氏によって実装されたC言語による擬似乱数発生ライブラリです. ここでの擬似乱数とはある値の次の値が完全に決定論的な数列を指すこととします, また,擬似乱数は疑似乱数と書くこともあるようですが,ここでは擬似乱数で統一します. C言語からこのRANDLIBを利用することで,一様乱数や正規乱数を簡単に得ることができます. RANDLIBを用いることで以下の分布に従う乱数が生成できます.

工学的な応用で多用されるガウス雑音は一様分布を何らかの手段で正規分布に変換して発生させます. 例えば,乱数間に相関のある多次元正規分布を得るには, Box-Muller法などを用いて得た複数の標準正規乱数を共分散行列のCholesky分解で変換する必要がありますが, RANDLIBを用いることでこうした手間を省くことができます. また,RANDLIBはFortran版がoctaveの乱数生成ルーチン であるrand()randn()に, C言語版の一部がPHPの統計関数群に使用されています.

RANDLIBは三橋研のFreeBSDの標準インストールパッケージには含まれていませんが, RANDLIBはC言語の標準ライブラリのみに依存するため,配布ファイル単独でコンパイルできます. 最新のサンプルコードはライブラリの構築を自動化してあるため, 利用中の計算機にRANDLIBがインストールされていなくとも問題ありません.

参考文献

参考文献をあげておきます.ドキュメントによれば,RANDLIBは [1]に基づく実装です, また基礎理論を知るためには [2]は非常に良い文献です.

  1. Pierre L’Ecuyer and Serge Côté. Implementing a Random Number Package with Splitting Facilities. ACM Transactions on Mathematical Software, Vol. 17, No. 1, pp. 98-111, March 1991.
  2. William H. Press, Saul A. Teukolsky, William T. Vetterling, and Brian P. Flannery. NUMERICAL RECIPES in C. 技術評論社, 1993. 丹慶勝市,奥村晴彦,佐藤俊郎,小林誠訳.

ACM TransactionsはACM transactions on Mathematical Software から検索できます.2005年9月現在,webからFull-text(pdf)が利用できます. この文献で提案される乱数源の周期はおよそ,23*1018であるとのことです.

ライブラリの構築

ソースコードの入手からライブラリの構築までを解説します.

ソースコードの入手

最新版のサンプルコードはライブラリの構築を自動化してあります. したがって,本節は何らかの理由でライブラリを手動で構築する際の参考にしてください.

まず,公式サイトから, ソースコードRANDLIB_V90.tar.gz)をダウンロードしてください.

ソースコードのコンパイル

ダウンロードしたソースコードはディレクトリrandlibcに展開してあるとします.

% cd randlibc
% gcc -O2 -c ./source/randlib.c/src/linpack.c
% gcc -O2 -c ./source/randlib.c/src/com.c
% gcc -O2 -c ./source/randlib.c/src/randlib.c
% ar cr librandlibc.a linpack.o com.o randlib.o
% ranlib librandlibc.a

この作業でrandlibcディレクトリにライブラリlibrandlibc.aが作成されます. arコマンドによりアーカイブが作成され,ranlibコマンドによりアーカイブ内のファイルや関数の一覧表をアーカイブに埋め込みます. それぞれのコマンドの詳細はarranlibのマニュアルページを参照して下さい.

RANDLIBの利用に必要なのはlibrandlibc.aと配布ファイル中の ./source/randlib.c/src/にあるrandlib.hです.

関数の仕様

RANDLIBは一様乱数をもとにして種々の分布に従う乱数系列を生成します. RANDLIBでユーザーから利用可能な関数を以下の表にまとめます. ここで,日本語の解説のない関数を利用する場合は, RANDLIBの配布ファイル中の./source/randlib.c/doc/ の英語ドキュメントを参照してください.

RANDLIBの関数
関数名内容
advnst乱数源の状態を2kだけ進めます
genbetベータ分布にしたがう乱数を発生させます
genchiカイ二乗分布にしたがう乱数を発生させます
genexp指数分布にしたがう乱数を発生させます
genfF分布にしたがう乱数を発生させます
gengamガンマ分布にしたがう乱数を発生させます
genmn多次元正規分布に従う乱数を発生させます
genmulGENerate MULtinomial random deviate
gennchGenerate random value of Noncentral CHIsquare variable
gennfGENerate random deviate from the Noncentral F distribution
gennor一次元正規分布に従う乱数を発生させます
genprm任意の長さの整数配列をランダム置換します
genunf任意の実数区間の一様乱数を発生させます
getsdGET SeeD
gscgnGet/Set GeNerator
ignbinGENerate BINomial random deviate
ignnbnGENerate Negative BiNomial random deviate
ignlgiGeNerate LarGe Integer
ignpoiポアソン分布にしたがう乱数を発生させます
ignuin任意の整数区間の一様乱数を発生させます
initgnINIT-ialize current G-e-N-erator
mltmodReturns (A*S) MOD M
phrtsd任意のフレーズから乱数源の初期化のための整数の組を生成します
ranfRANDom number generator as a Function
setall全ての乱数源を初期化します
setantSET ANTithetic
setgmn多次元正規分布のパラメターを設定します
setsdSET S-ee-D of current generator
sexpoSranderd EXPOnantial distribution
sgammaSranderd GAMMA distribution
snormSranderd NORmal distribution

advnst

処理の内容

乱数源の状態を2kだけ進めます.

宣言

void advnst(long k);

引数

long k
乱数源の状態を進めるための整数を指定します.

状態がkではなく2kだけ進められる事に注意してください.

genbet

処理の内容

次の確率密度関数を有する(第1種)ベータ分布に従う乱数を発生させます. Beta Distribution ただし,B はベータ関数です.引数で指定可能なパラメターは a と b です.

宣言

float genbet(float aa, float bb);

引数

float aa
ベータ分布のパラメター a を指定します.
float bb
ベータ分布のパラメター b を指定します.

戻り値

指定したパラメターのベータ分布に従う乱数が返されます.

genchi

処理の内容

次の確率密度関数を有するカイ二乗分布に従う乱数を発生させます. Chi-Square Distribution ただし,G はガンマ関数です.引数で指定可能なパラメターは k です.

宣言

float genchi(float df);

引数

float df
カイ二乗分布の自由度 k を指定します.

戻り値

指定した自由度のカイ二乗分布に従う乱数が返されます.

genexp

処理の内容

次の確率密度関数を有する指数分布に従う乱数を発生させます. Exponential Distribution 引数で指定可能なパラメターは期待値Expectation of the Exponential Distributionです.

宣言

float genexp(float av);

引数

float av
指数分布の期待値Expectation of the Exponential Distributionを指定します.

lambda でななく,その逆数である期待値を指定することに注意してください.

戻り値

指定した期待値の指数分布に従う乱数が返されます.

genf

処理の内容

次の確率密度関数を有するF分布にしたがう乱数を発生させます. F Distribution F分布は二つのカイ二乗分布にしたがう乱数の比で定義されます. 引数で指定可能なパラメターはこのカイ二乗分布の自由度です.

宣言

float genf(float dfn, float dfd);

引数

float dfn (degree of freedom - numerator)
分子のカイ二乗分布の自由度 dn を指定します.
float dfd (degree of freedom - denominator)
分母のカイ二乗分布の自由度 ddを指定します.

戻り値

指定したパラメターのF分布に従う乱数が返されます.

gengam

処理の内容

次の確率密度関数を有するガンマ分布に従う乱数を発生させます. Gamma Distribution ただし,G はガンマ関数です.引数で指定可能なパラメターはスケールパラメターの逆数 Inverse shape parameter of the Gamma Distribution と形状パラメターです.

宣言

float gengam(float a,float r);

引数

float a
ガンマ分布のスケールパラメターの逆数Inverse shape parameter of the Gamma Distributionを指定します.
float r
ガンマ分布の形状パラメター k を指定します.

戻り値

指定したパラメターのガンマ分布に従う乱数が返されます.

genmn

処理の内容

多次元正規分布に従う乱数を発生させます.

宣言

void genmn(float *parm,float *x,float *work);

引数

float *parm
多次元正規分布のパラメターを指定します.
float *x
正常終了時に多次元正規分布に従う乱数が格納される領域へのポインタを指定します.
float *work
多次元正規分布と同じ長さの作業領域へのポインタを指定します.

多次元正規分布のパラメターは関数setgmnで設定します.

gennor

処理の内容

一次元正規分布に従う乱数を発生させます.

宣言

float gennor(float av,float sd);

引数

float av
正規分布の平均を指定します.
float sd
正規分布の標準偏差を指定します.

戻り値

指定した平均と標準偏差の正規分布に従う乱数が返されます.

genprm

処理の内容

任意の長さの整数配列をランダム置換します.

宣言

void genprm(long *iarray,int larray);

引数

long *iarray
ランダム置換する配列へのポインタを指定します.
int larray
置換する配列の長さを指定します.

genunf

処理の内容

任意の実数区間[low, high]の一様乱数を発生させます.

宣言

float genunf(float low,float high);

引数

float low
一様分布の上限値を指定します.
float high
一様分布の下限値を指定します.

戻り値

指定した上限と下限の間の一様分布に従う乱数が返されます.

上限値は下限値よりも大きくなければなりません.

ignpoi

処理の内容

次の確率密度関数を有するポアソン分布に従う乱数を発生させます. Poisson Distribution 引数で指定可能なパラメターはポアソン分布の平均値 mu です,

宣言

long ignpoi(float mu);

引数

float mu
ポアソン分布の平均値 mu を指定します.

戻り値

指定した平均値のポアソン分布に従う乱数が返されます.

ignuin

処理の内容

任意の整数区間[low, high]の一様乱数を発生させます.

宣言

long ignuin(long low,long high);

引数

long low
一様分布の上限値を指定します.
long high
一様分布の下限値を指定します.

戻り値

指定した上限と下限の間の一様分布に従う乱数が返されます.

上限値は下限値よりも大きくなければなりません.

phrtsd

処理の内容

ヌル文字で終わる任意のフレーズから乱数源の初期化のための整数の組を生成します.

宣言

void phrtsd(char* phrase, long* seed1, long* seed2);

引数

char *phrase
整数の組を生成するためのフレーズへのポインタを指定します.
long *seed1, *seed2
正常終了時に乱数源の初期化に利用可能な整数が格納される領域へのポインタ指定します.

setgmn

処理の内容

関数genmnで利用する多次元正規分布のパラメターを設定します.

宣言

void setgmn(float *meanv, float *covm, long p, float *parm);

引数

float *meanv
多次元正規分布の平均ベクタを指定します.
float *covm
多次元正規分布の共分散行列を指定します.
long p
多次元正規分布の次元を指定します.
float *parm
正常終了時に多次元正規分布のパラメターが格納される領域へのポインタを指定します.

共分散行列は正定値対称行列を列優先で与える必要があります. また,正常終了時に*covmの領域の内容が破壊される事に注意してください.

setall

処理の内容

全ての乱数源を初期化します.

宣言

void setall(long iseed1,long iseed2);

引数

long iseed1, iseed2
乱数源を初期化するための整数を指定します.

初期化のための整数は互いに異なるものとし, また,その値は230を越えない正の数とします. 良く分からない場合は関数phrtsdにランダムな文字列を与えて作った数値を利用してください.

サンプルコード

サンプルコードの利用

サンプルコードとしてsample_randlib.tbzを置いておきます. 適当なところで展開するとMakefileと以下のソースコードが展開されます.

gauss2d.cは二次元正規乱数の発生の,permutation.cは整数配列のランダム置換の,test_randlib.cは一様分布,正規分布,指数分布に従う乱数の生成のサンプルコードです.init_randlib.cは乱数源の初期化の手続きをまとめたものです. randlib_config.h内のDEV_RANDOM_INITマクロを設定することで, /dev/urandomデバイスから取得した値で乱数源を初期化できます. /dev/urandomが存在しない場合はTIME_INIT マクロを設定することで乱数源を現在時刻から生成した数値列で初期化するように設定できますが, 初期化のためのフレーズが数字に偏ることによる問題が発生する恐れがあります. 初期設定では,これらのオプションは設定されておらず, 何らかのフレーズの入力によって乱数源を初期化します. また,初期化の手続きはあくまで実装例である事に注意してください. 必要があれば利用者側で調整した方が良いと思われます.

サンプルコードの利用 (Windows)

まず,Visual C++を用意してください. 2010年現在無償で入手できる Visual C++2008 Express Editionでもかまいません. 続いて,sample_randlib_win32.zipを適当な場所で展開すると, sample_randlib_win32フォルダが作られますから, ここに公式サイト からダウンロードできるソースコード(RANDLIB_V90.tar.gz)を展開してください. 後はVCProjフォルダ内のソリューションをビルドしてください. サンプルコードの実行ファイルと以下のライブラリが構築されます. 利用するランタイムは上からそれぞれ/MT/MTd/MD/MDd, 呼び出し規約は全て__cdeclです. なお, Windows では乱数源の初期化にCryptGenRandom関数を利用します.

RANDLIBの利用に必要なのはこれらのライブラリと配布ファイル中の ./source/randlib.c/src/にあるrandlib.hです. サンプルコードは既定ではダイナミックリンクライブラリを利用するように設定してあります. スタティックリンクライブラリを利用する場合はプロジェクトの依存関係とコンパイラのコード生成オプションを適切に設定してください.

おわりに

本マニュアルは不完全です,改訂を歓迎します.