「大人の教養・知識・気付き」を伸ばすブログ

一流の大人(ビジネスマン、政治家、リーダー…)として知っておきたい、教養・社会動向を意外なところから取り上げ学ぶことで“気付く力”を伸ばすブログです。現在、コンサルタントの雛になるべく、少しずつ勉強中です(※2024年12月10日改訂)。

MENU

Juliaを使うときのTipsをまとめる(その03/X)

 \mathrm{Julia}を使うのに、今一度

で使い方を整理する。

前回

power-of-awareness.com

注意

 参照文献はかなり古い(2019年)ため、現在のバージョンでは動作しない関数などが多いとの評判がある。そこでそういった齟齬があった場合は随時コメントする。なお筆者の環境は、

アプリケーション バージョン
\mathrm{Julia} 1.8.0
\mathrm{Jupyter} \mathrm{Notebook} 6.5.2

である。

0. まえがき

0.1 パッケージ管理のインストール

コマンド 説明
\mathrm{add} 指定されたパッケージをインストールする。
\mathrm{re} 指定されたパッケージを削除する。
\mathrm{up} [パッケージ名] 指定されたパッケージをアップデートする。
\mathrm{develop} パッケージのレポジトリを完全にローカルにコピーして開発できる状態にする。
\mathrm{up} マニフェストファイルに掛かれたパッケージをアップデートする。
\mathrm{build} パッケージのビルドスクリプトを実行する。
\mathrm{pin} パッケージを現在のバージョンで固定する。
\mathrm{free} \mathrm{pip}\mathrm{develop}でパッケージ管理対象から外したパッケージを再度管理対象に戻す。

1. データ構造とアルゴリズム

 \mathrm{Julia}に組み込まれた機能を利用しつつ実用的なカスタムアルゴリズムを実装する方法を紹介する。

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での乱数

 \mathrm{Julia}における乱数の扱いは以下のとおりで、現在のバージョンでは状態ベクトルを保持し乱数列を生成するのに広く空間を割り当てざるを得ない\mathrm{MersenneTwister}はデフォルト設定ではなく(標準実装されてはいる。)、\mathrm{Xorshift}の派生形である\mathrm{Xoshiro256}++を利用している*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.

docs.julialang.org

1.3.2 実装上の補足
  • \mathrm{Random.seed}!:乱数生成器にシードを与える。
  • \mathrm{rand}擬似乱数値を1つだけ生成する。
  • \mathrm{rng}_\mathrm{native}_\mathrm{52}\mathrm{Julia}の処理系に混ん乱数生成器の散布らが生成する乱数値の型を知らせる。

 \mathrm{Xorshift}やその派生型の\mathrm{Xoshiro256}++は、\mathrm{MersenneTwister}よりも高速という利点がある(他方で、周期が短い、統計的な特性が少し悪いというデメリットも存在する)。

*1:Xoshiroについてはhttps://prng.di.unimi.it/を参照。

プライバシーポリシー お問い合わせ