分からんこと多すぎ

何故か就職できたので技術磨く。一人前の多重線形代数使いを目指しつつ、機械学習、データマイニングをやる

RユーザのためのJulia入門(行列編)

Julia(プログラミング言語)が、高速で取っ付き易い言語との噂だったので、Deep押し過ぎのNIPSで折れた心を癒やすために、遊んでみる。

なお、本当にRしか書けない底辺コーダーなので、言語の仕様とかは他のページを見てください。

この記事は、とりあえずJuliaの配列操作が知りたい人向けの、公式文書の抜粋みたいなものです。

書いてる途中で発見したのですが、↓を読むのが一番早いと思います。

Multi-dimensional Arrays — Julia Language 0.3.0-dev documentation

Juliaとは

The Julia Language

高速で、簡単に学べて、数学っぽい書き方ができる言語。

公式いわく、Cの半分くらいの早さらしいです。

設計理念的な話は↓

なぜ僕らはJuliaを作ったか - 丸井綜研

きちんと勉強したい人は↓

Julia Documentation — Julia Language 0.3.0-dev documentation

基本的な話

拡張子.jlでファイルを作ってコンパイル&実行できるようですが、今回はお試しなので対話的に書きます。

コメントアウトは"#"、代入は"="

julia> #コメントアウトは"#"

julia> x = 2
2

プリントはこんな感じ

julia> print("x is equal to ", 2)
x is equal to 2

積には3通りの書き方がある。

julia> (x + 1) * x
6

julia> (x + 1)x
6

julia> *(x,x+1,x+2)
24

後ろに(x+1)みたいに書くのはダメ。

julia> (x + 1)(x + 1)
ERROR: type: apply: expected Function, got Int64

"*"記号がない場合、かけるもの同士の間にスペースを入れるのはダメ。

julia> 2 (x + 1)
ERROR: syntax: extra token "(" after end of expression

"ans"で前回の演算の答えが呼べる。ただしエラーは除く。

julia> ans
24

関数は以下のように書く。

function multi(x::Int,y)
    x*y
end
julia> multi(3,4)
12

xはInt型で宣言しているので、Float型は計算できない。
Vector型やMatrix型があって便利。

julia> typeof(1.1)
Float64

julia> multi(1.1,2)
ERROR: no method multi(Float64,Int64)

julia> multi(1,2.1)
2.1

for文とif文はこんな感じ。
複数返り値は","で区切れば良い。タプルで帰ってくる。

function foo(n)
  x = 0
  for i = 1:n
    if x < 5
      x = x + 1
    else
      x = x + 2
      return(x, 10)
    end
  end
  x
end

julia> foo(5)
5

julia> foo(15)
(7,10)

配列の操作

RユーザがPythonを投げ出す最大の理由は、配列の操作が煩雑なことだと思う。

なので、今回は配列の操作の話をする。

ベクトルは[]で作る。

julia> a = [1:3]
3-element Array{Int64,1}:
 1
 2
 3

要素番号で配列の中身が呼べる。

julia> a[2]
2

julia> a[[3,1,1,2,3]]
5-element Array{Int64,1}:
 3
 1
 1
 2
 3

true,falseでも配列の中身が呼べる。

julia> a[[true,false,true]]
2-element Array{Int64,1}:
 1
 3

行列積は"*"、転置はtranspose()

julia> A = a * transpose(a)
3x3 Array{Int64,2}:
 1  2  3
 2  4  6
 3  6  9

julia> transpose(a) * a
1-element Array{Int64,1}:
 14

行列の生成はこんな感じ

#単位行列
julia> x = eye(2,3)
2x3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  1.0  0.0

#乱数
julia> x = rand(2,3)
2x3 Array{Float64,2}:
 0.440441  0.608175  0.123271
 0.636391  0.30175   0.560413

#変形
julia> x = reshape(1:12, 3, 4)
3x4 Array{Int64,2}:
 1  4  7  10
 2  5  8  11
 3  6  9  12

行列の中身の呼び出しは、完全にR。

Pythonテンソル操作して泣きそうになったので、この仕様は神だと思った。

julia> A
3x3 Array{Int64,2}:
 1  2  3
 2  4  6
 3  6  9

#左上から数えて五番目の要素を取り出す
julia> A[5]
4

#行列の二行二列の要素を取り出す
julia> A[2,2]
4

#行列の第二要素を二回取り出す
julia> A[[2,2]]
2-element Array{Int64,1}:
 2
 2

#1,2行かつ2,3列の要素を取り出す
julia> A[[1,2],[2,3]]
2x2 Array{Int64,2}:
 2  3
 4  6

#要素番号を指定して、関数で呼び出すこともできる
julia> getindex(A,[1,5])
2-element Array{Int64,1}:
 1
 4

代入も可

julia> A[1:2,2:3] = -1
-1

julia> A
3x3 Array{Int64,2}:
 1  -1  -1
 2  -1  -1
 3   6   9

要素ごとの積も取れる。

julia> A .* A
3x3 Array{Int64,2}:
 1   1   1
 4   1   1
 9  36  81

テンソル(R的にはArray)も作れます。

julia> x = reshape(1:12, 3, 2, 2)
3x2x2 Array{Int64,3}:
[:, :, 1] =
 1  4
 2  5
 3  6

[:, :, 2] =
 7  10
 8  11
 9  12

スパース型を標準装備。

julia> I = [1, 4, 3, 5]; J = [4, 7, 18, 9]; V = [1, 2, -5, 3];

julia> S = sparse(I,J,V)
5x18 sparse matrix with 4 Int64 nonzeros:
	[1 ,  4]  =  1
	[4 ,  7]  =  2
	[5 ,  9]  =  3
	[3 , 18]  =  -5

exitで終了できます。

exit()

以上でとりあえず行列まわりは大丈夫だと思います。

誰かがわかりやすいwikiを作ってくれますように。