Julia
XorShift

Xorshift のJuliaでの実装 (32ビット版だけ)

本日は

XorshiftのJulia版をやってみましょう.
前々からJuliaをやろうと思いながら重い腰を動かすのに時間がかかります.
グーグル先生にお尋ねしながらJuliaを書いていきました.
もう書き方の方針がわかっているので基本的な文法を抑えるだけで記述できてしまいます.

実装例

手元の環境はMacのSierra,Juliaはv0.5.1です.

function xorshift32(seed=UInt32(2463534242))
    y = seed
    inner=function counter() 
        y = y $ (y << 13) 
        y = y $ (y >> 17)
        y = y $ (y << 5)
        return y
    end
    return inner
end

function uniform(generator,b=0.0,e=1.0)
    inner=function inner()
        value=b+generator()/typemax(UInt32)/(e-b)
        return value
    end
    return inner
end

function main()
    xor32=xorshift32()
    uniform01=uniform(xorshift32())
    N=10000000
    count=0
    for i = 1:N
        x=uniform01()
        y=uniform01()
        if x*x+y*y<1.0
            count+=1
        end
    end
    println("Pi=",4.0*count/N)
end

main()

良いJuliaの練習になりました. 

$でXORだそうです. (追記:Juliaのバージョンが0.5.1の場合です. コメント欄にも指摘されていますように将来的には使えなくなるようです.)

 結構素直にかけます. Fortranを書いているんだと念じるとendの存在が自然に感じますが,Pythonに戻ると必要なのかこの子は・・・と感じるこの頃です. uniform 関数の中で引数がデフォルトだと自明な割り算 /(e-b) を行うことになりますが,デフォルトでしか用いない場合はこの割り算はしないほうが速度パフォーマンスが上がります. 

追記(パフォーマンス 2017/12/3)

上記の実装では私のMacBook12inchでは10秒ほどかかってしまいます.
遅い.遅すぎる. Pythonに比べると速いのは間違い無いのですが・・・・.
と悶々していた時

@antimon2 さんの記事
Julia Advent Calendar 2017 3日目 Julia で Closure のパフォーマンスを気にしてみる

にてパフォーマンスを改善するヒントを提示してくださいました.
最終的にはCでの実装に匹敵するスピードを出してくれたのでとても勉強になりました.