Next: リングバッファ, Previous: キュー, Up: ライブラリモジュール - ユーティリティ [Contents][Index]
data.random
- ランダムデータの生成このモジュールは、特定のデータ型や、特定の値の分布を持つランダムなデータを 生成するジェネレータ、およびそういったジェネレータを作り出すジェネレータ構築器を 提供します。
名前付けの規則:パラメータを受け取り、それにそったジェネレータを返す
手続きにはサフィックス$
がついています (例: integer$
)。
それ自体がジェネレータである手続きにはサフィックスがつきません (例: fixnums
)。
コンビネータ、つまり複数のジェネレータを取ってジェネレータを返す手続きの名前は、
通常前置詞で終わります (例: list-of
)。
このモジュールのジェネレータはすべて一つのグローバルな乱数状態を共有します。 モジュールがロードされた時点で、固定のシードによりこの状態は初期化されます。 次の手続きでグローバルな乱数状態のシードを読み出したり、新たな値に 設定することができます。
{data.random}
引数無しでrandom-data-seed
を呼ぶと、現在の乱数状態を初期化した
シード値が返されます。
ジェネリックなセッターと一緒に使えば、乱数状態をseed-valueをシードとして 再初期化することができます。
ランダムシード値は正確な整数でなければなりません。その下位32ビットが使われます。
; reinitialize the random state with a new random seed.
(set! (random-data-seed) 1)
(random-data-seed) ⇒ 1
註: この手続きはパラメータインタフェース (引数として値を与えるとそれを新たな 値に設定し、以前の値を返す) にはなっていません。本質的に、パラメータとは 相容れないからです (パラメータ参照)。 得られるのは現在の乱数状態の出発点となるシード値であって、 現在の乱数状態そのものではありません。一旦別のシード値に切り替えて、 その後元のシード値に戻した場合、乱数状態は切り替えた時点に戻るのではなく、 あらためて初期化されます。
乱数状態を一時的に切り替えて、その後で切り替えた時点の状態を確実に回復したい場合は、
次に示すwith-random-data-seed
を使ってください。
{data.random}
現在のグローバルな乱数状態を保存し、乱数状態をseedで初期化して
thunkを実行します。thunkから帰ってくるか、
制御がthunkを抜け出した場合、乱数状態はwith-random-data-seed
が
呼び出された時点の状態に戻されます。
デフォルトのランダムシードが固定なのは、何もしなければ再現可能な振る舞いが得られる からです。
以下のジェネレータは特に断りが無い限り、一様分布するデータを生成します。
例の中では、生成された値を具体的に示すために
gauche.generator
モジュールのgenerator->list
を
使っています。ジェネレータを扱うユーティリティについては
ジェネレータを参照してください。
{data.random}
正確な整数のジェネレータを作成します。
integer$
が返すジェネレータは、
start 以上 start + size 未満の整数を一様に発生させます。
integers-between$
はが返すジェネレータは、lower-bound以上、
upper-bound以下の整数を一様に発生させます。
;; サイコロ (define dice (integers$ 6 1)) ;; サイコロを10回振ってみる (generator->list dice 10) ⇒ (6 6 2 4 2 5 5 1 2 2)
{data.random} 固定範囲の一様整数ジェネレータです。 それぞれ、fixnumおよび8/16/32/64ビットの符号つき/符号無し整数を生成します。
(generator->list int8s 10) ⇒ (20 -101 50 -99 -111 -28 -19 -61 39 110)
{data.random}
真偽値(#f
と#t
)を等確率で生成します。
(generator->list booleans 10) ⇒ (#f #f #t #f #f #t #f #f #f #f)
{data.random}
char-setにある文字を一様分布で生成するジェネレータを作ります。
char-setが省略された場合は#[A-Za-z0-9]
が使われます。
(define alphanumeric-chars (chars$)) (generator->list alphanumeric-chars 10) ⇒ (#\f #\m #\3 #\S #\z #\m #\x #\S #\l #\y)
{data.random}
与えられた範囲の実数値を一様に生成するジェネレータを返します。
reals$
の返すジェネレータは、
start 以上 start + size 以下の実数値を生成します。
sizeのデフォルト値は1.0
、startのデフォルト値は0.0
です。
reals-between$
の返すジェネレータは、
lower-bound以上upper-bound以下の実数値を生成します。
(define uniform-100 (reals$ 100)) (generator->list uniform-100 10) ⇒ (81.67965004942268 81.84927577572596 53.02443813660833)
reals$
の返すジェネレータは、integer$
と違って
上限の値を生成し得ることに注意してください。限界値を除外したい場合は、
gfilter
等を使ってその値を棄却します。
(define generate-from-0-below-1 (gfilter (^r (not (= r 1.0))) (reals$ 1.0 0.0)))
{data.random} コレクションcollectionから毎回ランダムにひとつ要素を選んで返すジェネレータを 作成します。
下で説明するsamples-from
と混同しないようにしてください。samples-from
は複数のジェネレータを組み合わせてサンプリングするものです。
(define coin-toss (samples$ '(head tail))) (generator->list coin-toss 5) ⇒ (head tail tail head tail)
{data.random} 与えられたregexpにマッチするランダムな文字列を生成し続けるジェネレータを 作って返します。regexpには条件付きパターン、lookahead/lookbehindアサーションを 含めないでください。
註: 生成される文字列の分布をどうすべきかというのは難しい問題です。 現在の実装は単純に、内部で正規表現からNFAを生成し、複数の選択肢がある場合は 等しい重みでランダムに選択していますが、それが目的(例えばテストデータの生成)に ふさわしいかどうかはまだわかりません。 現在の実装は暫定的なものと考えてください。
{data.random} 期待値mean、標準偏差deviationの正規分布に従って実数値を生成する ジェネレータを作ります。省略時はmeanが0.0、deviationが 1.0になります。
{data.random} 期待値meanの指数分布に従って実数値を生成するジェネレータを作ります。
{data.random}
成功確率p (0 ≦ p ≦ 1) である幾何分布に従って
非負整数値を生成するジェネレータを作ります。
期待値は1/p
、分散は(1-p)/p^2
になります。
{data.random} 期待値Lのポアソン分布に従う非負整数値を生成するジェネレータを作ります。 分散もLになります。
{data.random}
ジェネレータの有限シーケンス (ここではgauche.sequence
がシーケンスとして
扱うもの) を取り、新たなジェネレータを返します。
返されたジェネレータは、値を必要とする度に、
入力となるジェネレータのどれかを等確率で選んで、その入力ジェネレータから値を取ります。
(define g (samples-from (list uint8s (chars$ #[a-z])))) (generator->list g 10) ⇒ (207 107 #\m #\f 199 #\o #\b 57 #\j #\e)
註: 固定した要素の集まりからサンプルするジェネレータを作るには、
上の方で説明したsamples$
を使ってください。
{data.random} 引数は、非負の実数値とジェネレータのペアのリストです。 実数値が「重み」、すなわちペアとなっているジェネレータが選ばれる相対確率を決定します。 重みの総和が1.0である必要はありません。
次の例では、uint8
ジェネレータは文字ジェネレータより4倍頻繁に使われます。
(define g (weighted-samples-from `((4.0 . ,uint8s) (1.0 . ,(chars$))))) (generator->list g 10) ⇒ (195 97 #\j #\W #\5 72 49 143 19 164)
{data.random} ペアを生成するジェネレータを作ります。 各ペアのcarはジェネレータcar-gen、 cdrはジェネレータcdr-genによって生成されます。
(define g (pairs-of int8s booleans)) (generator->list g 10) ⇒ ((113 . #t) (101 . #f) (12 . #t) (68 . #f) (-55 . #f))
{data.random} リストを生成するジェネレータを作ります。 各リストのi番目の要素はi番目の引数のジェネレータによって生成されます。
(define g (tuples-of int8s booleans (char$))) (generator->list g 3) ⇒ ((-43 #f #\8) (53 #f #\1) (-114 #f #\i))
{data.random} シーケンスseqの要素をランダムに並べ替えたシーケンスを生成する ジェネレータを作ります。
seqの型は、ビルダーを持つシーケンスである必要があります (シーケンスフレームワーク参照)。生成されるオブジェクトは seqと同じ型になります。
(generator->list (permutations-of '(1 2 3)) 3) ⇒ ((1 2 3) (2 3 1) (3 2 1)) (generator->list (permutations-of "abc") 3) ⇒ ("cba" "cba" "cab")
{data.random} シーケンスseqからランダムにsize個の要素を取り出して 並べたシーケンスを生成するジェネレータを作ります。
seqの型は、ビルダーを持つシーケンスである必要があります (シーケンスフレームワーク参照)。生成されるオブジェクトは seqと同じ型になります。
(generator->list (combinations-of 2 '(a b c)) 5) ⇒ ((a c) (a b) (a c) (b a) (a c)) (generator->list (combinations-of 2 '#(a b c)) 5) ⇒ (#(a c) #(b c) #(c b) #(b a) #(b c))
以下の手続きは、省略可能なsizer引数を取ります。 sizer引数は非負整数か、非負整数を生成するジェネレータで、 その値(もしくは生成された値)が、最終的に生成されるデータの長さを決定します。
Gaucheの他のほとんどの手続きと違って、sizer引数は省略されない時は
最後の引数よりも前に来ます。これは統一性を損ないますが、
(lists-of 3 booleans)
のように書ける、という誘惑に勝てませんでした。
sizer引数が省略された場合、パラメータdefault-sizer
の値が
使われます。default-sizer
のデフォルトは
(integers-poisson$ 4)
で作られるジェネレータです。
{data.random} それぞれ、リスト、ベクタ、文字列を生成するジェネレータを作ります。 作られるデータの各要素はジェネレータitem-genから取られます。 各データの長さはsizerにより決定されます。
strings-of
の場合はitem-genも省略することができます。
その場合は、(chars$)
で作られるジェネレータが使われます。
(generator->list (lists-of 3 uint8s) 4) ⇒ ((254 46 0) (77 158 46) (1 134 156) (74 5 110)) ;; デフォルトのsizerを使う (generator->list (lists-of uint8s) 4) ⇒ ((93 249) (131 97) (98 206 144 247 241) (126 156 31)) ;; sizerにジェネレータを使う (generator->list (strings-of (integers$ 8) (chars$)) 5) ⇒ ("dTJYVhu" "F" "PXkC" "w" "")
{data.random}
クラスclassのインスタンスであるシーケンスを生成するジェネレータを作ります。
シーケンスの要素はitem-genにより生成されます。
各シーケンスの長さはsizer引数 (省略時はdefault-sizer
の値)
によって決められます。sizerは非負整数か、非負整数を生成するジェネレータです。
classは<sequence>
のサブクラスであり、
ビルダーインタフェースを実装していなければなりません。
(generator->list (sequences-of <u8vector> 4 uint8s) 3) ⇒ (#u8(95 203 243 46) #u8(187 199 153 152) #u8(39 114 39 25))
{data.random}
lists-of
、vectors-of
、strings-of
で
sizer引数が省略された場合に使われるsizerです。
値は、非負整数か、非負整数を生成するジェネレータでなければなりません。
Next: リングバッファ, Previous: キュー, Up: ライブラリモジュール - ユーティリティ [Contents][Index]