を使うのに、今一度
で使い方を整理する。
前回
注意
参照文献はかなり古い(2019年)ため、現在のバージョンでは動作しない関数などが多いとの評判がある。そこでそういった齟齬があった場合は随時コメントする。なお筆者の環境は、
アプリケーション | バージョン |
---|---|
である。
0. まえがき
1. データ構造とアルゴリズム
に組み込まれた機能を利用しつつ実用的なカスタムアルゴリズムを実装する方法を紹介する。
1.3 カスタム擬似乱数生成器を実装する
############################## ### カスタム擬似乱数を生成 ### ############################## # Xorshiftを定義してみる using Random mutable struct def_Xorshift <: AbstractRNG state::UInt64 end def_Xorshift() = def_Xorshift(rand(RandomDevice(), UInt64)) Random.seed!(r::def_Xorshift, seed::UInt64 = rand(RandomDevice(), UInt64)) = r.state = seed function xorshift_rand(r::def_Xorshift) state = r.state state ⊻= state << 13 state ⊻= state >> 7 state ⊻= state << 17 r.state = state end const XorshiftSamplers = Union{map(T -> Random.SamplerType{T}, [Bool, UInt32, UInt64, Int64])...} Base.rand(r::def_Xorshift, sampler::XorshiftSamplers) = xorshift_rand(r) % sampler[] Random.rng_native_52(::def_Xorshift) = UInt64 ## using StatsBase r = def_Xorshift(0x0139408dcbbf7a44) # 分布を調べる A = countmap(rand(r, 1:10, 10^8)) println(A) # 実際に生成してみる const X = zeros(Int, 5, 5) foreach(i -> X[rand(r, 1:5), rand(r, 1:5)] += 1, 1:10^7) B = 25 * X / (10^7) println(B)
1.3.1 Juliaでの乱数
における乱数の扱いは以下のとおりで、現在のバージョンでは状態ベクトルを保持し乱数列を生成するのに広く空間を割り当てざるを得ないはデフォルト設定ではなく(標準実装されてはいる。)、の派生形である++を利用している*1。
Random number generation in Julia uses the Xoshiro256++ algorithm by default, with per-Task state. Other RNG types can be plugged in by inheriting the AbstractRNG type; they can then be used to obtain multiple streams of random numbers.
The PRNGs (pseudorandom number generators) exported by the Random package are:
- TaskLocalRNG: a token that represents use of the currently active Task-local stream, deterministically seeded from the parent task, or by RandomDevice (with system randomness) at program start
- Xoshiro: generates a high-quality stream of random numbers with a small state vector and high performance using the Xoshiro256++ algorithm
- RandomDevice: for OS-provided entropy. This may be used for cryptographically secure random numbers (CS(P)RNG).
- MersenneTwister: an alternate high-quality PRNG which was the default in older versions of Julia, and is also quite fast, but requires much more space to store the state vector and generate a random sequence.
1.3.2 実装上の補足
- !:乱数生成器にシードを与える。
- :擬似乱数値を1つだけ生成する。
- __:の処理系に混ん乱数生成器の散布らが生成する乱数値の型を知らせる。
やその派生型の++は、よりも高速という利点がある(他方で、周期が短い、統計的な特性が少し悪いというデメリットも存在する)。
*1:Xoshiroについてはhttps://prng.di.unimi.it/を参照。