Julianへの道①

また関係のないことに手を伸ばしてしまう。。

japan.techrepublic.com

「C」言語のスピードと「Python」の使いやすさ、「Ruby」の動的型付け、「MatLab」の強力な数学的能力、「R」言語の優れた統計機能の融合を目指した

謳い文句がかっこいい。。

インストール

バイナリを公式からダウンロード。

https://julialang.org/downloads/

解凍して

$ tar -xf julia-1.0.0-linux-x86_64.tar.gz

シンボリックリンクをパスの通ってる場所に張る

$ ln -s /home/kimoton/src/julia-1.0.0/bin/julia /home/kimoton/bin/
$ julia
              _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.0 (2018-08-08)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia>

ひゃーかっちょいぃーー。

チュートリアルをやってみる。

高速でマスターできるとか何とか。
Julia高速チュートリアル

やっていきながらできる限りPythonと比較してみる。
レッツじゅりあ!

変数名

pythonは、使えないutf-8文字がいくつかあった。
Python 3 の変数名に使える文字たち

>>> ⊿ = 0.01
  File "<stdin>", line 1
    ⊿ = 0.01
    ^
SyntaxError: invalid character in identifier

julia

julia> ⊿ = 0.01
0.01

julia> ⊿
0.01

Juliaだと、変数名に恐らくすべてのutf-8が使用可能。
つまり日本語もギリシア文字も使い放題です。

π

python ではわざわざmathモジュールをimport してしかもpiとか書く。
わかりづらい。

>>> import math
>>> math.pi
3.141592653589793
>>> type(math.pi)
<class 'float'>

julia

julia> π
π = 3.1415926535897...
julia> typeof(π)
Irrational{:π}

そのままかける。
そう。juliaなら。
Irrational型とかいう特殊な型がある。

配列

インデックスの始まり

pythonだと0始まり。

>>> xs
[1, 2, 3, 4, 5, 6]
>>> xs[0]
1

julia

julia> xs = [1,2,3,4,5,6]
julia> xs[1]
1

juliaは1から。

末端のインデックス

配列末端のアクセスにはendが使える。

pythonだと-1で示せる末端のインデックス

>>> xs = [1,2,3,4,5,6]
>>> xs[-1]
6

julia

julia> xs = [1,2,3,4,5,6]
6-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6

julia> xs[end-1]
5

Juliaでは、end で示す。

直観的~

配列の切り出し

python

>>> for i in range(0,51,10):
...   print(i)
...
0
10
20
30
40
50

julia

julia> for i in 0:10:50
           println(i)
       end
0
10
20
30
40
50

juliaではpythonと違って、start:step:stopの順で指定するらしい。 まぁどっちでもいい。

切り出した配列の取得

python

>>> list(range(0, 101, 10))
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

julia

julia> collect(0:10:100)
11-element Array{Int64,1}:
   0
  10
  20
  30
  40
  50
  60
  70
  80
  90
 100

juliaだとcollect関数を使う。よいね。

辞書型

python

>>> {"foo":1, "bar":2}
{'foo': 1, 'bar': 2}

julia

julia> x = Dict("foo" => 1, "bar" => 2)
Dict{String,Int64} with 2 entries:
  "bar" => 2
  "foo" => 1

julia> x["foo"]
1

うん。わかりやすい。

関数

python

import math
def dist(p, q):
    dx = p[0]- q[0]
    dy = p[1] - q[1]
    return math.sqrt(dx**2 + dy**2)

julia

function dist(p, q)
    dx = p[1] - q[1]
    dy = p[2] - q[2]
    sqrt((dx)^2 + (dy)^2)
end

Juliaでは返り値を明示しない場合、最後に評価された式が返り値になる。 ^で階乗を表す辺りさすがJulia。

引数を取る関数

python

def ktop(xs, k=3, rev=False):
    return sorted(xs, reverse=rev)[0:k]

julia

function ktop(xs; k=3, rev=false)
    sort(xs, rev=rev)[1:k]
end

; k=3,のように、;を使って記述する。 これはpythonのままでよかった。

可変長引数

python

def pathlength(p, q, *args):
    len = dist(p, q)
    for r in args:
        len += dist(q, r)
        q = r
    return len

julia

function pathlength(p, q, args...)
    len = dist(p, q)
    for r in args
        len += dist(q, r)
        q = r
    end
    return len
end

ほぼ*argsargs...になっただけ。

1行関数

python

>>> ktop = lambda x, k=3: sorted(x)[0:k]
>>> ktop(xs)
[1, 2, 3]

julia

julia> ktop(xs, k=3) = sort(xs)[1:k]
ktop (generic function with 2 methods)
julia> ktop(xs)
3-element Array{Int64,1}:
 1
 2
 3

juliaは関数定義の代入ができる。

Julia 関数独特の定義

quicksort!のように、関数名の最後に!をつける.引数のデータを変えてしまう関数は最後に!をつける (push!, sort!)

データ型にsensitiveなJuliaでは入力と出力のデータ型が異なる場合、それを明示的に関数名で示すのが慣習になっているらしい。

型定義

pythonだとDataClass

import dataclasses

@dataclasses.dataclass
class Person:
    name: str
    age: int

@dataclasses.dataclass(frozen=True)
class Loation:
    name: float
    age: float

julia

mutable struct Person
    name::String
    age::Int
end

struct Location
    x::Float64
    y::Float64
end

Juliaでも同じ感じ。juliaは同じFloat型でも6つくらいあるので選択する。

とりあえずここまで。

面白いJulia かっこいいjulia
次回も引き続きチュートリアルを進めたいと思います。