In [1]:
srand(1234);

ベクトル(リスト)の処理

ベクトルを作る

In [2]:
x = []  # 何でも入るリスト
Out[2]:
0-element Array{Any,1}
In [3]:
x = Int[]  # Int型のみのリスト
Out[3]:
0-element Array{Int64,1}
In [4]:
x = Vector{Int}()  # Int[]と同じ
Out[4]:
0-element Array{Int64,1}
In [5]:
x = [1,2,3]  # 3要素からなるリスト
Out[5]:
3-element Array{Int64,1}:
 1
 2
 3

すべて同じ値のベクトルを作る

In [6]:
fill(42, 10)
Out[6]:
10-element Array{Int64,1}:
 42
 42
 42
 42
 42
 42
 42
 42
 42
 42
In [7]:
fill("foo", 4)
Out[7]:
4-element Array{String,1}:
 "foo"
 "foo"
 "foo"
 "foo"

ベクトルに要素を追加する

In [8]:
x = [1,2,3]
Out[8]:
3-element Array{Int64,1}:
 1
 2
 3
In [9]:
push!(x, 4) # 右に追加
Out[9]:
4-element Array{Int64,1}:
 1
 2
 3
 4
In [10]:
unshift!(x, 0)  # 左に追加
Out[10]:
5-element Array{Int64,1}:
 0
 1
 2
 3
 4
In [11]:
append!(x, [5,6,7])  # 別のベクトルを追加
Out[11]:
8-element Array{Int64,1}:
 0
 1
 2
 3
 4
 5
 6
 7

ベクトルの要素を削除する

In [12]:
x = [1,2,3,4,5]
Out[12]:
5-element Array{Int64,1}:
 1
 2
 3
 4
 5
In [13]:
pop!(x)  # 右端を削除
Out[13]:
5
In [14]:
x
Out[14]:
4-element Array{Int64,1}:
 1
 2
 3
 4
In [15]:
shift!(x)  # 左端を削除
Out[15]:
1
In [16]:
x
Out[16]:
3-element Array{Int64,1}:
 2
 3
 4
In [17]:
deleteat!(x, 2)  # 特定の場所の要素を削除
Out[17]:
2-element Array{Int64,1}:
 2
 4

ベクトルがソート済みかを判定する

In [18]:
issorted([1,2,3,4])
Out[18]:
true
In [19]:
issorted([1,3,2,4])
Out[19]:
false

ベクトルをソートする

In [20]:
x = [1,5,4,3,7,6,2]
Out[20]:
7-element Array{Int64,1}:
 1
 5
 4
 3
 7
 6
 2
In [21]:
sort(x)  # ベクトルを新しく作る
Out[21]:
7-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
In [22]:
sort(x, rev=true)  # 逆順でソート
Out[22]:
7-element Array{Int64,1}:
 7
 6
 5
 4
 3
 2
 1
In [23]:
sort!(x)  # ベクトルを上書きする
Out[23]:
7-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7

ベクトルの要素を逆順にする

In [24]:
x = [1,2,3,4]
Out[24]:
4-element Array{Int64,1}:
 1
 2
 3
 4
In [25]:
reverse(x)  # ベクトルを新しく作る
Out[25]:
4-element Array{Int64,1}:
 4
 3
 2
 1
In [26]:
x == [1,2,3,4]
Out[26]:
true
In [27]:
reverse!(x)  # ベクトルを上書きする
Out[27]:
4-element Array{Int64,1}:
 4
 3
 2
 1
In [28]:
x == [1,2,3,4]
Out[28]:
false

ベクトルをシャッフルする

In [29]:
x = [1,2,3,4,5,6]
Out[29]:
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
In [30]:
shuffle(x)  # ベクトルを新しく作る
Out[30]:
6-element Array{Int64,1}:
 2
 1
 3
 6
 4
 5
In [31]:
x == [1,2,3,4,5,6]
Out[31]:
true
In [32]:
shuffle!(x)  # ベクトルを上書きする
Out[32]:
6-element Array{Int64,1}:
 6
 1
 5
 2
 3
 4
In [33]:
x == [1,2,3,4,5,6]
Out[33]:
false

ベクトルを結合する

In [34]:
vcat([1,2,3], [4,5,6])  # 縦方向 => ベクトル
Out[34]:
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
In [35]:
hcat([1,2,3], [4,5,6])  # 横方向 => 行列
Out[35]:
3×2 Array{Int64,2}:
 1  4
 2  5
 3  6

辞書

辞書を作る

In [36]:
Dict()  # 何でも入る空の辞書
Out[36]:
Dict{Any,Any} with 0 entries
In [37]:
Dict{String,Int}()  # Stringがキー、Intが値の空の辞書
Out[37]:
Dict{String,Int64} with 0 entries
In [38]:
Dict("one" => 1, "two" => 2)  # 初期値のある辞書
Out[38]:
Dict{String,Int64} with 2 entries:
  "two" => 2
  "one" => 1

辞書があるキーを持つか判定する

In [39]:
haskey(Dict("one" => 1, "two" => 2), "two")
Out[39]:
true
In [40]:
haskey(Dict("one" => 1), "two")
Out[40]:
false

辞書の値を取り出す

In [41]:
d = Dict("one" => 1, "two" => 2)
Out[41]:
Dict{String,Int64} with 2 entries:
  "two" => 2
  "one" => 1
In [42]:
d["one"]
Out[42]:
1
In [43]:
d["three"]  # キーがなければエラー
KeyError: key "three" not found

Stacktrace:
 [1] getindex(::Dict{String,Int64}, ::String) at ./dict.jl:474

デフォルト値を設定して辞書の値を取り出す

In [44]:
d = Dict("one" => 1, "two" => 2)
Out[44]:
Dict{String,Int64} with 2 entries:
  "two" => 2
  "one" => 1
In [45]:
get(d, "one", 0)  # 第三引数がデフォルト値
Out[45]:
1
In [46]:
get(d, "three", 0)
Out[46]:
0

辞書に値を代入する

In [47]:
d = Dict("one" => 1, "two" => 2)
Out[47]:
Dict{String,Int64} with 2 entries:
  "two" => 2
  "one" => 1
In [48]:
d["three"] = 3
Out[48]:
3
In [49]:
d
Out[49]:
Dict{String,Int64} with 3 entries:
  "two"   => 2
  "one"   => 1
  "three" => 3

辞書のキー・値を取り出す

In [50]:
d = Dict("one" => 1, "two" => 2)
Out[50]:
Dict{String,Int64} with 2 entries:
  "two" => 2
  "one" => 1
In [51]:
keys(d)  # イテレータとして取り出す
Out[51]:
Base.KeyIterator for a Dict{String,Int64} with 2 entries. Keys:
  "two"
  "one"
In [52]:
collect(keys(d))  # ベクトルとして取り出す
Out[52]:
2-element Array{String,1}:
 "two"
 "one"
In [53]:
values(d)
Out[53]:
Base.ValueIterator for a Dict{String,Int64} with 2 entries. Values:
  2
  1
In [54]:
collect(values(d))
Out[54]:
2-element Array{Int64,1}:
 2
 1

集合

集合を作る

In [55]:
Set{Int}()  # 空の集合
Out[55]:
Set{Int64}()
In [56]:
Set([1,2,3])  # ベクトルから
Out[56]:
Set([2, 3, 1])
In [57]:
Set(["foo", "bar", "baz"])
Out[57]:
Set(String["bar", "baz", "foo"])

集合にある要素があるか判定する

In [58]:
2 in Set([1,2,3])
Out[58]:
true
In [59]:
4 in Set([1,2,3])
Out[59]:
false
In [60]:
2  Set([1,2,3])  # ∈ は in の別名
Out[60]:
true

集合に要素を追加する

In [61]:
s = Set([1,2,3])
push!(s, 4)
Out[61]:
Set([4, 2, 3, 1])
In [62]:
union!(s, [5, 6])
Out[62]:
Set([4, 2, 3, 5, 6, 1])

和集合・積集合・差集合をとる

In [63]:
s1 = Set([1,2,3])
s2 = Set([2,3,4,5])
Out[63]:
Set([4, 2, 3, 5])
In [64]:
union(s1, s2)  # 和集合
Out[64]:
Set([4, 2, 3, 5, 1])
In [65]:
s1  s2  # \cupは和集合
Out[65]:
Set([4, 2, 3, 5, 1])
In [66]:
intersect(s1, s2)  # 積集合
Out[66]:
Set([2, 3])
In [67]:
s1  s2  # \capは積集合
Out[67]:
Set([2, 3])
In [68]:
setdiff(s1, s2)  # 差集合
Out[68]:
Set([1])

集合の要素をベクトルとして取り出す

In [69]:
s = Set([1,2,3])
collect(s)  # 順番は順不同
Out[69]:
3-element Array{Int64,1}:
 2
 3
 1

文字列処理

文字数をカウントする

In [70]:
length("foo")
Out[70]:
3
In [71]:
length("αβγ")
Out[71]:
3

文字のバイト数を得る

In [72]:
sizeof("foo")
Out[72]:
3
In [73]:
sizeof("αβγ")
Out[73]:
6

文字列をUTF-8のバイト列に変換する

In [74]:
convert(Vector{UInt8}, "foo")
Out[74]:
3-element Array{UInt8,1}:
 0x66
 0x6f
 0x6f
In [75]:
convert(Vector{UInt8}, "αβγ")
Out[75]:
6-element Array{UInt8,1}:
 0xce
 0xb1
 0xce
 0xb2
 0xce
 0xb3
In [76]:
Vector{UInt8}("foo")  # これもOK
Out[76]:
3-element Array{UInt8,1}:
 0x66
 0x6f
 0x6f

UTF-8のバイト列を文字列に変換する

In [77]:
convert(String, [0x66, 0x6f, 0x6f])
Out[77]:
"foo"
In [78]:
convert(String, [0xce, 0xb1, 0xce, 0xb2, 0xce, 0xb3])
Out[78]:
"αβγ"
In [79]:
String([0x66, 0x6f, 0x6f])  # これもOK
Out[79]:
"foo"

特定のパターンを置換する

In [80]:
replace("hello, world", "world", "there")
Out[80]:
"hello, there"
In [81]:
replace("a5b4ra221ca1d856ab86r7a7", r"\d+", "")
Out[81]:
"abracadabra"

文字列を文字の配列に分割する

In [82]:
collect("foo")
Out[82]:
3-element Array{Char,1}:
 'f'
 'o'
 'o'
In [83]:
collect("αβγ")
Out[83]:
3-element Array{Char,1}:
 'α'
 'β'
 'γ'

文字列を連結する

In [84]:
"foo" * "bar"
Out[84]:
"foobar"
In [85]:
string("foo", 123)
Out[85]:
"foo123"
In [86]:
join(["foo", "bar", "baz"], ",")
Out[86]:
"foo,bar,baz"

文字列を分割する

In [87]:
split("foo,bar,baz", ",")
Out[87]:
3-element Array{SubString{String},1}:
 "foo"
 "bar"
 "baz"
In [88]:
split("123 45   567", r"\s+")
Out[88]:
3-element Array{SubString{String},1}:
 "123"
 "45" 
 "567"

特定の幅で左詰め・右詰めする

In [89]:
rpad(123, 5)
Out[89]:
"123  "
In [90]:
lpad(123, 5)
Out[90]:
"  123"
In [91]:
println(" left aligned: ", rpad(123, 5))
println("right aligned: ", lpad(123, 5))
 left aligned: 123  
right aligned:   123
In [92]:
@sprintf("%5d", 123)
Out[92]:
"  123"

末尾の改行を除く

In [93]:
chomp("foo bar\n")
Out[93]:
"foo bar"
In [94]:
chomp("foo bar\r\n")
Out[94]:
"foo bar"

左右の空白を除く

In [95]:
strip(" foo bar ")   # 両側
Out[95]:
"foo bar"
In [96]:
lstrip(" foo bar ")  # 左のみ
Out[96]:
"foo bar "
In [97]:
rstrip(" foo bar ")  # 右のみ
Out[97]:
" foo bar"

大文字・小文字に変換する

In [98]:
uppercase("foo")
Out[98]:
"FOO"
In [99]:
lowercase("FOO")
Out[99]:
"foo"

入出力

ファイルをテキストとして読み込む

In [100]:
readstring("data/julia.md")
Out[100]:
"Juliaは技術計算のための動的言語で、以下の様な機能を備えています。\n\n- 多重ディスパッチ\n- JITコンパイル\n- マクロなどのメタプログラミング\n"
In [101]:
readlines("data/julia.md")  # 改行で分割
Out[101]:
5-element Array{String,1}:
 "Juliaは技術計算のための動的言語で、以下の様な機能を備えています。"
 ""                                   
 "- 多重ディスパッチ"                         
 "- JITコンパイル"                         
 "- マクロなどのメタプログラミング"                  

ファイルを行毎に読み込む

In [102]:
i = 1
for line in eachline("data/julia.md")
    println(i, ": ", line)
    i += 1
end
1: Juliaは技術計算のための動的言語で、以下の様な機能を備えています。
2: 
3: - 多重ディスパッチ
4: - JITコンパイル
5: - マクロなどのメタプログラミング

ファイルをバイナリデータとして読み込む

In [103]:
read("data/julia.md")
Out[103]:
193-element Array{UInt8,1}:
 0x4a
 0x75
 0x6c
 0x69
 0x61
 0xe3
 0x81
 0xaf
 0xe6
 0x8a
 0x80
 0xe8
 0xa1
    ⋮
 0x83
 0xa9
 0xe3
 0x83
 0x9f
 0xe3
 0x83
 0xb3
 0xe3
 0x82
 0xb0
 0x0a

ファイルが存在するかを調べる

In [104]:
isfile("data/julia.md")
Out[104]:
true
In [105]:
isfile("data/python.md")
Out[105]:
false

ファイルサイズを得る

In [106]:
filesize("data/julia.md")  # 単位はバイト
Out[106]:
193

ファイルを開閉する

In [107]:
file = open("data/julia.md")
Out[107]:
IOStream(<file data/julia.md>)
In [108]:
isopen(file)  # ファイルが開いているか判定する
Out[108]:
true
In [109]:
readline(file)  # 1行読み込む
Out[109]:
"Juliaは技術計算のための動的言語で、以下の様な機能を備えています。"
In [110]:
close(file)
In [111]:
isopen(file)
Out[111]:
false

開いているファイルの現在位置を得る

In [112]:
file = open("data/julia.md")
Out[112]:
IOStream(<file data/julia.md>)
In [113]:
position(file)  # 最初の位置は0
Out[113]:
0
In [114]:
sizeof(readline(file))  # 1行(改行含む)を読む
Out[114]:
95
In [115]:
position(file)  # 1行分読み込み位置が進む
Out[115]:
96
In [116]:
eof(file)  # 読み込み位置は末尾か判定
Out[116]:
false
In [117]:
sizeof(read(file))  # 残りすべてを読み込む
Out[117]:
97
In [118]:
eof(file)
Out[118]:
true

開いたファイルを必ず閉じる

In [119]:
# open ... do ... endはdoの中でエラーが起きても必ずファイルを閉じる
open("data/julia.md") do file
    println(readline(file))
    div(1, 0)  # エラー!
end
Juliaは技術計算のための動的言語で、以下の様な機能を備えています。
DivideError: integer division error

Stacktrace:
 [1] open(::##1#2, ::String) at ./iostream.jl:152

gzipの圧縮ファイルを読み込む

In [120]:
using CodecZlib  # https://github.com/bicycle1885/CodecZlib.jl
In [121]:
file = GzipDecompressionStream(open("data/julia.md.gz"))
Out[121]:
TranscodingStreams.TranscodingStream{CodecZlib.GzipDecompression,IOStream}(<state=idle>)
In [122]:
readlines(file)
Out[122]:
5-element Array{String,1}:
 "Juliaは技術計算のための動的言語で、以下の様な機能を備えています。"
 ""                                   
 "- 多重ディスパッチ"                         
 "- JITコンパイル"                         
 "- マクロなどのメタプログラミング"                  
In [123]:
close(file)

テキストをファイルに書き込む

In [124]:
write("data/output.txt", "アブラカダブラ\n")
Out[124]:
22
In [125]:
readstring("data/output.txt")
Out[125]:
"アブラカダブラ\n"
In [126]:
file = open("data/output.txt", "w")
println(file, "寿限無寿限無")
close(file)
In [127]:
readstring("data/output.txt")
Out[127]:
"寿限無寿限無\n"

オブジェクトをファイルにシリアライズする

In [128]:
file = open("data/object.dat", "w")
serialize(file, "テキスト")
serialize(file, 3.14)
serialize(file, [10, 20, 30])
serialize(file, Dict("愛里寿" => "センチュリオン", "ミカ" => "BT-42"))
close(file)
In [129]:
file = open("data/object.dat")
while !eof(file)
    @show deserialize(file)
end
close(file)
deserialize(file) = "テキスト"
deserialize(file) = 3.14
deserialize(file) = [10, 20, 30]
deserialize(file) = Dict("ミカ"=>"BT-42","愛里寿"=>"センチュリオン")

外部コマンド

外部コマンドを実行する

In [130]:
run(`echo "hello"`)
hello

コマンドの出力を読み込む

In [131]:
readstring(`ls data`)
Out[131]:
"julia.md\njulia.md.gz\nobject.dat\noutput.txt\n"
In [132]:
read(`ls data`)
Out[132]:
43-element Array{UInt8,1}:
 0x6a
 0x75
 0x6c
 0x69
 0x61
 0x2e
 0x6d
 0x64
 0x0a
 0x6a
 0x75
 0x6c
 0x69
    ⋮
 0x0a
 0x6f
 0x75
 0x74
 0x70
 0x75
 0x74
 0x2e
 0x74
 0x78
 0x74
 0x0a
In [133]:
pipe, proc = open(`ls data`)  # パイプとプロセス
Out[133]:
(Pipe(RawFD(-1) closed => RawFD(51) open, 0 bytes waiting), Process(`ls data`, ProcessExited(0)))
In [134]:
while !eof(pipe)
    println(readline(pipe))
end
julia.md
julia.md.gz
object.dat
output.txt
In [135]:
proc
Out[135]:
Process(`ls data`, ProcessExited(0))

関数型プログラミング

条件を満たす要素を残す

In [136]:
filter(isodd, [1,2,3,4,5])
Out[136]:
3-element Array{Int64,1}:
 1
 3
 5
In [137]:
filter(x->x>2, [1,2,3,4,5])
Out[137]:
3-element Array{Int64,1}:
 3
 4
 5

条件を満たす要素があるか確認する

In [138]:
any(isodd, [1,2,3,4])
Out[138]:
true
In [139]:
any(isodd, [2,4,6,8])
Out[139]:
false

すべての要素が条件を満たすかを確認する

In [140]:
all(isodd, [1,2,3,4])
Out[140]:
false
In [141]:
all(isodd, [1,3,5,7])
Out[141]:
true

全要素に同じ関数を適用する

In [142]:
map(sin, [0.0, 1.0, 2.0, 3.0])
Out[142]:
4-element Array{Float64,1}:
 0.0     
 0.841471
 0.909297
 0.14112 
In [143]:
sin.([0.0, 1.0, 2.0, 3.0])
Out[143]:
4-element Array{Float64,1}:
 0.0     
 0.841471
 0.909297
 0.14112 

関数を適用して畳み込みをする

In [144]:
foldl(+, 0, [1,2,3])  # 総和の計算
Out[144]:
6
In [145]:
foldl(+, [1,2,3])  # 第二引数は省略可
Out[145]:
6
In [146]:
# 分岐する式の作成
foldr((x, r)->:(if x == $(x); print($(x)); else; $(r); end), :(nothing), [1,2,3])
Out[146]:
:(if x == 1 # In[146], line 2:
        print(1)
    else  # In[146], line 2:
        if x == 2 # In[146], line 2:
            print(2)
        else  # In[146], line 2:
            if x == 3 # In[146], line 2:
                print(3)
            else  # In[146], line 2:
                nothing
            end
        end
    end)

ベンチマーク・プロファイル

関数の実行時間を測定する

In [147]:
sort(randn(100000))  # コンパイルのため測定前に一度実行する
@elapsed sort(randn(100000))  # 単位は秒
Out[147]:
0.008851748
In [148]:
[@elapsed sort(randn(100000)) for _ in 1:10]
Out[148]:
10-element Array{Float64,1}:
 0.00876565
 0.0156572 
 0.00870781
 0.00845791
 0.00924334
 0.0104665 
 0.00999714
 0.0109102 
 0.0105973 
 0.00948196

関数のメモリ割り付けを測定する

In [149]:
sort(randn(100000))  # コンパイルのため測定前に一度実行する
@allocated sort(randn(100000))  # 単位はバイト
Out[149]:
1600240
In [150]:
[@allocated sort(randn(100000)) for _ in 1:10]
Out[150]:
10-element Array{Int64,1}:
 1600240
 1600240
 1600240
 1600240
 1600240
 1600240
 1600240
 1600240
 1600240
 1600240

関数の実行時間とメモリ割り付けを同時に測定する

In [151]:
sort(randn(100000))  # コンパイルのため測定前に一度実行する
@time sort(randn(100000));
  0.008674 seconds (9 allocations: 1.526 MiB)
In [152]:
for _ in 1:10
    @time sort(randn(100000))
end
  0.011001 seconds (5 allocations: 1.526 MiB)
  0.010731 seconds (5 allocations: 1.526 MiB)
  0.010590 seconds (5 allocations: 1.526 MiB)
  0.008951 seconds (5 allocations: 1.526 MiB)
  0.009545 seconds (5 allocations: 1.526 MiB)
  0.008640 seconds (5 allocations: 1.526 MiB)
  0.008199 seconds (5 allocations: 1.526 MiB)
  0.008194 seconds (5 allocations: 1.526 MiB)
  0.009020 seconds (5 allocations: 1.526 MiB)
  0.008863 seconds (5 allocations: 1.526 MiB)
In [153]:
100000 * sizeof(Float64) * 2 / 1024^2  # 100000要素の倍精度浮動小数点数のメモリ割り当て量 (MiB)
Out[153]:
1.52587890625

詳細なベンチマークを行う

In [154]:
using BenchmarkTools  # https://github.com/JuliaCI/BenchmarkTools.jl
In [155]:
@benchmark sort(randn(100000))
Out[155]:
BenchmarkTools.Trial: 
  memory estimate:  1.53 MiB
  allocs estimate:  5
  --------------
  minimum time:     7.214 ms (0.00% GC)
  median time:      8.233 ms (0.00% GC)
  mean time:        8.661 ms (1.33% GC)
  maximum time:     25.404 ms (0.00% GC)
  --------------
  samples:          577
  evals/sample:     1
In [156]:
@benchmark sort(randn(10))
Out[156]:
BenchmarkTools.Trial: 
  memory estimate:  400 bytes
  allocs estimate:  3
  --------------
  minimum time:     421.925 ns (0.00% GC)
  median time:      452.987 ns (0.00% GC)
  mean time:        554.083 ns (3.35% GC)
  maximum time:     19.120 μs (0.00% GC)
  --------------
  samples:          10000
  evals/sample:     199

プロファイルを取る

In [157]:
function bubblesort(x)
    x = copy(x)
    swapped = true
    while swapped
        swapped = false
        for i in 1:endof(x)-1
            if x[i+1] < x[i]
                x[i+1], x[i] = x[i], x[i+1]
                swapped = true
            end
        end
    end
    return x
end
Out[157]:
bubblesort (generic function with 1 method)
In [158]:
bubblesort(randn(10))
Out[158]:
10-element Array{Float64,1}:
 -1.79628 
 -1.73885 
 -0.460956
 -0.450571
 -0.151273
  0.342973
  0.474332
  0.617031
  0.710638
  0.768515
In [159]:
x = randn(10000)
Profile.clear()
@profile bubblesort(x);
In [160]:
Profile.print()
196 ./task.jl:335; (::IJulia.##11#14)()
 1   ...Julia/src/eventloop.jl:5; eventloop(::ZMQ.Socket)
  1 ...v0.6/IJulia/src/msg.jl:87; recv_ipython(::ZMQ.Socket)
   1 ....6/JSON/src/Parser.jl:375; #parse#1(::Type{Dict{String,Any}}...
    1 ....6/JSON/src/Parser.jl:158; parse_value(::JSON.Parser.Memory...
     1 ....6/JSON/src/Parser.jl:201; parse_object(::JSON.Parser.Memor...
 195 ...Julia/src/eventloop.jl:8; eventloop(::ZMQ.Socket)
  195 ...rc/execute_request.jl:160; execute_request(::ZMQ.Socket, ::...
   195 ./loading.jl:515; include_string(::String, ::String)
    195 ./<missing>:?; anonymous
     195 ./profile.jl:23; macro expansion
      53  ./In[157]:6; bubblesort(::Array{Float64,1})
      109 ./In[157]:7; bubblesort(::Array{Float64,1})
      31  ./In[157]:8; bubblesort(::Array{Float64,1})
      2   ./In[157]:9; bubblesort(::Array{Float64,1})

数値の計算

奇数・偶数を判定する

In [161]:
isodd(41)   # 奇数
Out[161]:
true
In [162]:
iseven(42)  # 偶数
Out[162]:
true

素数判定する

In [163]:
using Primes  # https://github.com/JuliaMath/Primes.jl
In [164]:
isprime(42)
Out[164]:
false
In [165]:
isprime(43)
Out[165]:
true

素数列を生成する

In [166]:
using Primes  # https://github.com/JuliaMath/Primes.jl
In [167]:
primes(50)
Out[167]:
15-element Array{Int64,1}:
  2
  3
  5
  7
 11
 13
 17
 19
 23
 29
 31
 37
 41
 43
 47

商を計算する

In [168]:
div(42, 5)
Out[168]:
8
In [169]:
42 / 5  # 整数 / 整数 = 浮動小数点数 になるので注意
Out[169]:
8.4

剰余を計算する

In [170]:
42 % 5
Out[170]:
2
In [171]:
rem(42, 5)  # 上と同じ
Out[171]:
2

絶対値を計算する

In [172]:
abs(-42)
Out[172]:
42
In [173]:
abs(42)
Out[173]:
42

排他的論理和を計算する

In [174]:
xor(42, 35)
Out[174]:
9
In [175]:
42  35  # 上と同じ(\xor)
Out[175]:
9

線形代数

ベクトルの和を計算する

In [176]:
x = [1.0, 2.0, 3.0]
y = [-1.0, 3.0, 0.0]
Out[176]:
3-element Array{Float64,1}:
 -1.0
  3.0
  0.0
In [177]:
x + y
Out[177]:
3-element Array{Float64,1}:
 0.0
 5.0
 3.0
In [178]:
x - y
Out[178]:
3-element Array{Float64,1}:
  2.0
 -1.0
  3.0

ベクトルのスカラー倍を計算する

In [179]:
3.2x
Out[179]:
3-element Array{Float64,1}:
 3.2
 6.4
 9.6

行ベクトルを作る

In [180]:
x'
Out[180]:
1×3 RowVector{Float64,Array{Float64,1}}:
 1.0  2.0  3.0
In [181]:
x''  # 2回でもとに戻る
Out[181]:
3-element Array{Float64,1}:
 1.0
 2.0
 3.0

内積を計算する

In [182]:
dot(x, x)
Out[182]:
14.0
In [183]:
x  x  # 上と同じ (\cdot)
Out[183]:
14.0
In [184]:
x'x
Out[184]:
14.0

直積を計算する

In [185]:
x * x'
Out[185]:
3×3 Array{Float64,2}:
 1.0  2.0  3.0
 2.0  4.0  6.0
 3.0  6.0  9.0

対角行列を作る

In [186]:
diagm([1.0, 2.0, 3.0])  # 通常の行列の型
Out[186]:
3×3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  2.0  0.0
 0.0  0.0  3.0
In [187]:
Diagonal([1.0, 2.0, 3.0])  # 対角行列の型
Out[187]:
3×3 Diagonal{Float64}:
 1.0   ⋅    ⋅ 
  ⋅   2.0   ⋅ 
  ⋅    ⋅   3.0

行列積を計算する

In [188]:
A = randn(3, 3)
B = randn(3, 3)
Out[188]:
3×3 Array{Float64,2}:
  0.726385    1.6588   1.13122 
  1.01566     1.77963  0.710212
 -0.0650975  -1.22412  1.03047 
In [189]:
A * B  # 通常の行列積
Out[189]:
3×3 Array{Float64,2}:
 -1.28874  -3.78644  -1.10194 
 -1.70857  -4.33366  -0.816591
  1.54023   2.93319   1.31487 
In [190]:
At_mul_B(A, B)  # Aを転置して掛ける
Out[190]:
3×3 Array{Float64,2}:
 -2.19284  -5.01086  -2.08284 
 -1.06601  -3.18224   0.516614
  1.47724   2.94792   1.4728  
In [191]:
A'B  # 上と同じ
Out[191]:
3×3 Array{Float64,2}:
 -2.19284  -5.01086  -2.08284 
 -1.06601  -3.18224   0.516614
  1.47724   2.94792   1.4728  
In [192]:
A_mul_Bt(A, B)  # Bを転置して掛ける
Out[192]:
3×3 Array{Float64,2}:
 -0.35104  -1.17308   0.938959
 -1.26934  -2.02604   2.15484 
  2.2404    2.53849  -1.5252  
In [193]:
A * B'  # 上と同じ
Out[193]:
3×3 Array{Float64,2}:
 -0.35104  -1.17308   0.938959
 -1.26934  -2.02604   2.15484 
  2.2404    2.53849  -1.5252  
In [194]:
At_mul_Bt(A, B)  # AもBも転置して掛ける
Out[194]:
3×3 Array{Float64,2}:
 -2.22868   -3.02436    1.7201 
 -0.275315  -0.892186   2.39829
  1.98846    2.34479   -1.18667
In [195]:
A'B'  # 上と同じ
Out[195]:
3×3 Array{Float64,2}:
 -2.22868   -3.02436    1.7201 
 -0.275315  -0.892186   2.39829
  1.98846    2.34479   -1.18667

固有値・固有ベクトルを計算する

In [196]:
X = [5.0 2.0; -2.0 3.0]
Out[196]:
2×2 Array{Float64,2}:
  5.0  2.0
 -2.0  3.0
In [197]:
eigvals(X)
Out[197]:
2-element Array{Complex{Float64},1}:
 4.0+1.73205im
 4.0-1.73205im
In [198]:
eigvecs(X)  # 複素数の固有ベクトル
Out[198]:
2×2 Array{Complex{Float64},2}:
  0.707107+0.0im        0.707107-0.0im     
 -0.353553+0.612372im  -0.353553-0.612372im
In [199]:
eigvals(X'X)  # 固有値はすべて正なので正定値行列
Out[199]:
2-element Array{Float64,1}:
 12.0557
 29.9443
In [200]:
eigvecs(X'X)  # 正定値行列に対しては実数の固有ベクトル
Out[200]:
2×2 Array{Float64,2}:
  0.229753  -0.973249
 -0.973249  -0.229753

線型方程式系を解く

In [201]:
A = [3.0  2.0 -1.0
     2.0 -2.0  4.0
    -1.0  0.5 -1.0]
b = [1.0, -2.0, 0.0]
Out[201]:
3-element Array{Float64,1}:
  1.0
 -2.0
  0.0
In [202]:
x = A \ b  # A x = b の解
Out[202]:
3-element Array{Float64,1}:
  1.0
 -2.0
 -2.0
In [203]:
A * x  b  # 解の確認
Out[203]:
true

統計

一様分布から乱数を得る

In [204]:
rand()
Out[204]:
0.3867181118018075
In [205]:
rand(30)
Out[205]:
30-element Array{Float64,1}:
 0.0233823 
 0.584213  
 0.996262  
 0.0486294 
 0.823912  
 0.00980484
 0.506794  
 0.922409  
 0.846705  
 0.685258  
 0.0148934 
 0.101358  
 0.578418  
 ⋮         
 0.672831  
 0.167329  
 0.826931  
 0.181764  
 0.401678  
 0.1965    
 0.202258  
 0.0961149 
 0.245319  
 0.919989  
 0.549066  
 0.184145  

標準正規分布から乱数を得る

In [206]:
randn()
Out[206]:
0.04586384215519224
In [207]:
randn(30)
Out[207]:
30-element Array{Float64,1}:
 -0.437116 
  0.385278 
 -0.473007 
 -0.371043 
 -0.0256377
  1.2682   
  0.552556 
 -0.0252973
 -1.13349  
  2.46311  
 -0.902314 
  1.19349  
  0.271862 
  ⋮        
 -1.3191   
  0.194445 
  2.25805  
  1.87969  
 -0.176167 
 -0.0395945
  1.24096  
 -1.03593  
 -0.259864 
  1.2209   
  2.11896  
 -0.695827 

様々な分布から乱数を得る

In [208]:
import Distributions  ## https://github.com/JuliaStats/Distributions.jl
In [209]:
g = Distributions.Gamma(1.0, 2.0)  # ガンマ分布
rand(g, 10)
Out[209]:
10-element Array{Float64,1}:
 0.851551 
 1.8048   
 0.0905379
 0.0643867
 0.464794 
 0.792174 
 2.73824  
 0.332647 
 0.565023 
 1.14877  
In [210]:
p = Distributions.Poisson(10)  # ポアソン分布
rand(p, 10)
Out[210]:
10-element Array{Int64,1}:
 10
 12
 13
  8
 12
  7
  7
 12
  4
 11

サンプリングを行う

In [211]:
rand(1:20)  # 1-20の値から1個サンプリング
Out[211]:
8
In [212]:
rand(1:20, 10)  # 1~20の値から10個サンプリング
Out[212]:
10-element Array{Int64,1}:
 10
  8
 17
  7
 17
  3
 10
 18
  7
 10
In [213]:
using StatsBase  # https://github.com/JuliaStats/StatsBase.jl
In [214]:
sample(1:20, 10, replace=false)  # 非復元抽出
Out[214]:
10-element Array{Int64,1}:
  7
 18
 17
  8
 20
 12
 14
  5
  4
 19

平均・分散を計算する

In [215]:
mean(randn(100))
Out[215]:
0.008539475320023372
In [216]:
var(randn(100))
Out[216]:
0.865934027580458

中央値を計算する

In [217]:
median(exp.(randn(100)))
Out[217]:
1.0103736890230341

分位数を計算する

In [218]:
x = exp.(randn(100));
In [219]:
quantile(x, 0.1)
Out[219]:
0.39879867876339664
In [220]:
quantile(x, 0.25)
Out[220]:
0.6779346947809612
In [221]:
for q in linspace(0, 1, 11)
    println(q, ": ", quantile(x, q))
end
0.0: 0.10576604052523694
0.1: 0.39879867876339664
0.2: 0.5585514635406499
0.3: 0.7252001881297099
0.4: 0.9280416777324269
0.5: 1.1110217625293453
0.6: 1.4068712917385797
0.7: 1.7752452712496667
0.8: 2.9288228171021804
0.9: 4.571210350690497
1.0: 15.1433030232737

行列の最大値・最小値を計算する

In [222]:
A = randn(5, 3)
Out[222]:
5×3 Array{Float64,2}:
 -0.80238    0.644167  -0.0853525
  0.823909  -0.350321  -0.969769 
  0.463137   2.23558   -0.64375  
  1.85394    0.886008   1.16761  
 -0.821372   0.468997  -1.69867  
In [223]:
maximum(A)  # 全要素の最大値 (最小値はminimum)
Out[223]:
2.235578644026364
In [224]:
maximum(A, 2)  # 行最大
Out[224]:
5×1 Array{Float64,2}:
 0.644167
 0.823909
 2.23558 
 1.85394 
 0.468997
In [225]:
maximum(A, 1)  # 列最大
Out[225]:
1×3 Array{Float64,2}:
 1.85394  2.23558  1.16761

行列から平均を引く

In [226]:
A = randn(5, 3) + 10
Out[226]:
5×3 Array{Float64,2}:
 10.9184   10.6914    8.21326
 10.2181   10.8977   11.8139 
  9.11668   9.83351  10.3405 
 11.5015    8.74474   9.91524
 11.31     10.1985    8.82895
In [227]:
A .- mean(A, 2)  # 行平均を引く
Out[227]:
5×3 Array{Float64,2}:
  0.977356   0.75038    -1.72774 
 -0.758501  -0.0788276   0.837329
 -0.646876   0.0699516   0.576924
  1.44766   -1.30908    -0.138582
  1.19753    0.0860069  -1.28354 
In [228]:
A .- mean(A, 1)  # 列平均を引く
Out[228]:
5×3 Array{Float64,2}:
  0.305433   0.618205  -1.6091  
 -0.394858   0.824564   1.99153 
 -1.49624   -0.23966    0.51812 
  0.888563  -1.32843    0.092875
  0.697097   0.125321  -0.993418

共分散行列を計算する

In [229]:
X = [3.0 5.8 1.1; 1.0 4.2 0.1]
Out[229]:
2×3 Array{Float64,2}:
 3.0  5.8  1.1
 1.0  4.2  0.1
In [230]:
cov(X, 1)  # 各行がサンプル
Out[230]:
3×3 Array{Float64,2}:
 2.0  1.6   1.0
 1.6  1.28  0.8
 1.0  0.8   0.5
In [231]:
cov(X, 2)  # 各列がサンプル
Out[231]:
2×2 Array{Float64,2}:
 5.59  4.99   
 4.99  4.64333
In [232]:
cor(X, 2)  # ピアソンの相関係数の行列
Out[232]:
2×2 Array{Float64,2}:
 1.0       0.979444
 0.979444  1.0     

最小二乗法を行う

In [233]:
X = randn(20, 4)
b = [-1.0, 1.0, 2.0, 3.0]
Out[233]:
4-element Array{Float64,1}:
 -1.0
  1.0
  2.0
  3.0
In [234]:
y = X * b + randn(20) * 0.1
Out[234]:
20-element Array{Float64,1}:
  1.8996  
  6.01268 
  1.41041 
 -0.542336
 -2.5572  
 -0.450025
  3.60568 
 -3.86358 
 -0.819904
  1.11038 
 -6.1131  
  1.69123 
 -2.1921  
  5.05921 
 -1.56521 
  2.39779 
  3.91339 
  0.451056
 -1.10424 
  4.80995 

正規方程式 $(X'X)\beta = X'y$ の解

In [235]:
(X'X)\X'*y
Out[235]:
4-element Array{Float64,1}:
 -1.02689 
  0.976217
  2.01937 
  2.98385 

また、$X=QR$と分解すると、$X$が最大列階数のとき正規方程式は

\begin{align} (X'X)\beta &= X'y \\ (QR)'(QR)\beta &= (QR)'y \\ R'(Q'Q)R\beta &= R'Q'y \\ R\beta &= Q'y \end{align}

なので次のようにも計算できる

In [236]:
Q, R = qr(X)
R\(Q'y)
Out[236]:
4-element Array{Float64,1}:
 -1.02689 
  0.976217
  2.01937 
  2.98385 

解析

関数の根を計算する

In [237]:
using Roots  # https://github.com/JuliaMath/Roots.jl
In [238]:
fzero(log, 0, 10)
Out[238]:
1.0
In [239]:
fzero(x -> sin(x - 3), 2, 4)
Out[239]:
3.0

データ点を補完する

In [240]:
using Interpolations
In [241]:
f(x) = sin(x) * exp(-x)
Out[241]:
f (generic function with 1 method)
In [242]:
xs = linspace(-3, 3, 8)
itp = interpolate([f(x) for x in xs], BSpline(Cubic(Line())), OnCell())
scl = scale(itp, xs)
g = x->scl[x]
Out[242]:
(::#17) (generic function with 1 method)
In [243]:
f(1)
Out[243]:
0.3095598756531122
In [244]:
g(1)
Out[244]:
0.31573248343343835
In [245]:
using Gadfly
plot(layer([f, g], -3, 3), layer(x=xs, y=f.(xs), Geom.point))
Out[245]:
x -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 -9.0 -8.8 -8.6 -8.4 -8.2 -8.0 -7.8 -7.6 -7.4 -7.2 -7.0 -6.8 -6.6 -6.4 -6.2 -6.0 -5.8 -5.6 -5.4 -5.2 -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4 -3.2 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 -10 -5 0 5 10 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 f1 f2 Color -20.0 -17.5 -15.0 -12.5 -10.0 -7.5 -5.0 -2.5 0.0 2.5 5.0 7.5 10.0 12.5 15.0 -17.5 -17.0 -16.5 -16.0 -15.5 -15.0 -14.5 -14.0 -13.5 -13.0 -12.5 -12.0 -11.5 -11.0 -10.5 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 -20 -10 0 10 20 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 y

1変数関数の微分を計算する

In [246]:
import ForwardDiff  # https://github.com/JuliaDiff/ForwardDiff.jl
In [247]:
f(x) = sin(x) * exp(-x)
f′(x) = ForwardDiff.derivative(f, x)
Out[247]:
f′ (generic function with 1 method)
In [248]:
f(1.0)
Out[248]:
0.3095598756531122
In [249]:
f′(1.0)
Out[249]:
-0.11079376530669924
In [250]:
using Gadfly
plot([f, f′], -3, 3)
Out[250]:
x -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 -9.0 -8.8 -8.6 -8.4 -8.2 -8.0 -7.8 -7.6 -7.4 -7.2 -7.0 -6.8 -6.6 -6.4 -6.2 -6.0 -5.8 -5.6 -5.4 -5.2 -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4 -3.2 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 -10 -5 0 5 10 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 f1 f2 Color -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 -45 -44 -43 -42 -41 -40 -39 -38 -37 -36 -35 -34 -33 -32 -31 -30 -29 -28 -27 -26 -25 -24 -23 -22 -21 -20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 -50 0 50 -46 -44 -42 -40 -38 -36 -34 -32 -30 -28 -26 -24 -22 -20 -18 -16 -14 -12 -10 -8 -6 -4 -2 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 f(x)

多変数関数の勾配を計算する

In [251]:
import ReverseDiff  # https://github.com/JuliaDiff/ReverseDiff.jl
In [252]:
f(x) = 2dot(x, x) + sum(x)
f′(x) = ReverseDiff.gradient(f, x)
Out[252]:
f′ (generic function with 1 method)
In [253]:
f′(zeros(3))
Out[253]:
3-element Array{Float64,1}:
 1.0
 1.0
 1.0
In [254]:
f′(ones(3))
Out[254]:
3-element Array{Float64,1}:
 5.0
 5.0
 5.0

多変数関数の最小化を行う

In [255]:
using Optim  # https://github.com/JuliaNLSolvers/Optim.jl
In [256]:
# 2変数のRosenbrock関数 https://en.wikipedia.org/wiki/Rosenbrock_function
f(x) =  (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2
Out[256]:
f (generic function with 1 method)
In [257]:
optimize(f, zeros(2))
Out[257]:
Results of Optimization Algorithm
 * Algorithm: Nelder-Mead
 * Starting Point: [0.0,0.0]
 * Minimizer: [0.9999710322210338,0.9999438685860869]
 * Minimum: 1.164323e-09
 * Iterations: 74
 * Convergence: true
   *  √(Σ(yᵢ-ȳ)²)/n < 1.0e-08: true
   * Reached Maximum Number of Iterations: false
 * Objective Function Calls: 108
In [258]:
optimize(f, zeros(2), BFGS())
Out[258]:
Results of Optimization Algorithm
 * Algorithm: BFGS
 * Starting Point: [0.0,0.0]
 * Minimizer: [0.9999999926033423,0.9999999852005353]
 * Minimum: 5.471433e-17
 * Iterations: 16
 * Convergence: true
   * |x - x'| < 1.0e-32: false
   * |f(x) - f(x')| / |f(x)| < 1.0e-32: false
   * |g(x)| < 1.0e-08: true
   * f(x) > f(x'): false
   * Reached Maximum Number of Iterations: false
 * Objective Function Calls: 69
 * Gradient Calls: 69