JuliaTokyo #2 導入セッション

2014年9月27日開催

Juliaとは?

技術計算のための新しいプログラミング言語です。

c.f. Juliaのこれまでとこれから // SpeakersDeck

JuliaTokyo とは?

プログラミング言語「Julia」の集いです。まだまだ利用者の少ないJuliaについて、様々な知見を共有することを目的としています。

JuliaTokyo #2 アンケート

JuliaTokyo #2 では、参加者の方々へ利用言語についてのアンケートを行いました。以下が結果です;

総回答者数 81名 (複数回答可)

  50 Python
  36 R
  25 Java
  20 Ruby
  20 C++
  19 その他
  18 Excel
  15 C
  14 Julia
   6 Visual Basic
   6 Perl
   6 Matlab / Octave
   5 Scala
   2 Fortran
   2 Clojure
   1 F#

環境構築

この導入セッションでは、IJuliaのnotebookを使って説明を行います。IJuliaは、iPythonをJuliaで利用するためのパッケージです。

IJulia(iPython)の他にも

といった環境で利用できます。

Vim、Emacs、Sublime Text、Textmate、Notepad++、Kateといったエディタには、Juliaの編集モードが用意されています

Julia本体のインストール

公式サイトで、安定版および開発版(Nightly builds)のバイナリが、Windows、Mac OS X、Ubuntu向けに用意されています。

Max OS XのhomebrewやDebianのaptといったパッケージ管理システムに登録されている場合もありますが、バージョンが最新安定版より古い可能性もあるので注意が必要です。

このチュートリアル実施時の最新安定版は、2014年8月に公開された v0.3 です。以前のバージョンと一部互換性のない部分もありますので、ご注意ください。

バイナリを実行すると、標準REPLが起動します。

$ julia # Juliaを起動
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "help()" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.3.0 (2014-08-20 20:43 UTC)
 _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
|__/                   |  x86_64-apple-darwin13.3.0

julia>

IJuliaのインストール

まず、iPythonをインストールする必要があります。色々なPythonのライブラリをまとめてインストールしてくれるAnacondaを使うと便利です。

次に、JuliaのREPLから

Pkg.add("IJulia")

とすると、IJuliaをインストールできます。

エラーの場合は

Pkg.update("IJulia")

Pkg.build("IJulia")

を試してみてください。

IJuliaがインストールされると、シェルから

$ ipython notebook --profile julia

と実行するか、JuliaのREPLから

julia> using IJulia
julia> notebook()

とすることでIJulia notebookを起動できます。

ちなみにこれからは、iPythonからPython部分を除いたものがJupyterというプロジェクトになるので、Juliaもこちらを使うことになります。


基礎文法

簡単な計算

In [1]:
1 + 1
Out[1]:
2
In [2]:
+(1, 1)
Out[2]:
2
In [3]:
methods(+)
Out[3]:
125 methods for generic function +:
In [4]:
1 + 2 * 3
Out[4]:
7
In [5]:
typeof(1) # 型を調べる
Out[5]:
Int64
In [6]:
typeof(1.0)
Out[6]:
Float64
In [7]:
1 / 3 # 除算の結果は必ず浮動小数点数
Out[7]:
0.3333333333333333
In [8]:
3 \ 1 # 右辺を左辺が割る除算
Out[8]:
0.3333333333333333
In [9]:
1 // 3 # 有理数
Out[9]:
1//3
In [10]:
typeof(1 // 3)
Out[10]:
Rational{Int64} (constructor with 1 method)
In [11]:
names(1 // 3) # 型の構造を調べる
Out[11]:
2-element Array{Symbol,1}:
 :num
 :den
In [12]:
(1 + 2im) * (2 - 3im) # 複素数
Out[12]:
8 + 1im
In [13]:
typeof(1 + 2im)
Out[13]:
Complex{Int64} (constructor with 1 method)
In [14]:
names(1 + 2im)
Out[14]:
2-element Array{Symbol,1}:
 :re
 :im
In [15]:
sqrt(-1 + 0im)
Out[15]:
0.0 + 1.0im
In [16]:
2 ^ 8 # べき乗
Out[16]:
256
In [17]:
0.314e1 # 科学技術表記
Out[17]:
3.14
In [18]:
1_000_000 # アンダースコアによる数値の区切りが可能
Out[18]:
1000000
In [19]:
e # あらかじめ定義されている数値
Out[19]:
e = 2.7182818284590...
In [20]:
π
Out[20]:
π = 3.1415926535897...
In [21]:
golden
Out[21]:
φ = 1.6180339887498...
In [22]:
typeof(golden)
Out[22]:
MathConst{:φ} (constructor with 1 method)
In [23]:
pi
Out[23]:
π = 3.1415926535897...

ちなみにタブキーで補完が行えるが、これはLaTex記法の変換にも使える。

> \pi TAB
In [ ]:
\pi

変数

In [25]:
x = 10
Out[25]:
10
In [26]:
 = 10
Out[26]:
10
In [27]:
pi = 3
Out[27]:
3
Warning: imported binding for pi overwritten in module Main
In [28]:
pi
Out[28]:
3
In [29]:
2pi # *を省略できる
Out[29]:
6
In [30]:
2x^2 + 4x + 1 # シンプルに多項式を記述できる
Out[30]:
241

スタイル規則

  • 変数名は小文字。アンダースコアの使用は推奨されない
  • 型の名前は、大文字で始まるキャメルケース
  • 関数やマクロの名前はアンダースコアなしの小文字
  • 破壊的な関数には、名前の最後に!をつける

c.f.

文字列、辞書

In [31]:
str1 = "This is a string."
Out[31]:
"This is a string."
In [32]:
typeof(str1)
Out[32]:
ASCIIString (constructor with 2 methods)
In [33]:
str2 = "これは文字列です。"
Out[33]:
"これは文字列です。"
In [34]:
str2[1]
Out[34]:
'こ'
In [35]:
typeof(str2)
Out[35]:
UTF8String (constructor with 2 methods)
In [36]:
str3 = "\u2200 x \u2203 y s.t. f(y) > x"
Out[36]:
"∀ x ∃ y s.t. f(y) > x"
In [37]:
str4 = "1 + 1 = $(1 + 1)" # インターポレーション
Out[37]:
"1 + 1 = 2"
In [38]:
print("Hello World!")
Hello World!
In [39]:
println("Hello Julia!")
Hello Julia!
In [40]:
dict = ["one"=> 1, "two"=> 2, "three"=> 3]
Out[40]:
Dict{ASCIIString,Int64} with 3 entries:
  "two"   => 2
  "one"   => 1
  "three" => 3
In [41]:
dict = ["one"=> 1, "two"=> 2, "three"=> 3.0]
Out[41]:
Dict{ASCIIString,Any} with 3 entries:
  "two"   => 2
  "one"   => 1
  "three" => 3.0
In [42]:
dict["one"]
Out[42]:
1

配列など

In [43]:
x = [1, 2, 3] # Int64
Out[43]:
3-element Array{Int64,1}:
 1
 2
 3
In [44]:
x[1] # Indexは1から始まる
Out[44]:
1
In [45]:
x[0]
BoundsError()
while loading In[45], in expression starting on line 1

 in getindex at /opt/homebrew-cask/Caskroom/julia/0.3.0/Julia-0.3.0.app/Contents/Resources/julia/lib/julia/sys.dylib (repeats 2 times)
In [46]:
x[2:3]
Out[46]:
2-element Array{Int64,1}:
 2
 3
In [47]:
x[end]
Out[47]:
3
In [48]:
[1, 2, "Hello"] # Any
Out[48]:
3-element Array{Any,1}:
 1       
 2       
  "Hello"
In [49]:
[1 2 3] # 1x3
Out[49]:
1x3 Array{Int64,2}:
 1  2  3
In [50]:
matrix = [1 4 7; 2 5 8; 3 6 9]
Out[50]:
3x3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9
In [51]:
matrix[1,3]
Out[51]:
7
In [52]:
[1 2 3] * [1,2,3]
Out[52]:
1-element Array{Int64,1}:
 14

制御構文

In [53]:
# if /else

x = 1

if x == 1
    println("One!")
elseif x == 2
    println("Two!")
else
    println("Not One or Two!")
end
One!
In [54]:
# for

for i = 1:5
    println(i)
end
1
2
3
4
5
In [55]:
for str in ["foo","bar","baz"]
    println(str)
end
foo
bar
baz
In [56]:
for i = 1:2, j = 3:4
    println((i, j))
end
(1,3)
(1,4)
(2,3)
(2,4)

関数

In [57]:
square(x) = x * x
Out[57]:
square (generic function with 1 method)
In [58]:
square(3)
Out[58]:
9
In [59]:
f = (x) -> 2x^2 + 4x + 1
Out[59]:
(anonymous function)
In [60]:
f(2)
Out[60]:
17
In [1]:
# FizzBuzz

function fizzbuzz(x::Int64) # 引数の型を指定している
  println("This is Int64 fizzbuzz")
  for i = 1:x
      if (i % 3 == 0) && (i % 5 == 0)
          println("FizzBuzz")
      elseif i % 3 == 0
          println("Fizz")
      elseif i % 5 == 0
          println("Buzz")
      else
          println(i)
      end
  end
end
Out[1]:
fizzbuzz (generic function with 1 method)
In [5]:
# 同じ名前で違う引数型の関数
function fizzbuzz(x::Float64)
    println("This is Float64 fizzbuzz")
  for i = 1:x
      if (i % 3 == 0) && (i % 5 == 0)
          println("FizzBuzz")
      elseif i % 3 == 0
          println("Fizz")
      elseif i % 5 == 0
          println("Buzz")
      else
          println(i)
      end
  end
end
Out[5]:
fizzbuzz (generic function with 2 methods)
In [6]:
function fizzbuzz(x)
    println("$(x) is neither Int or Float.")
end
Out[6]:
fizzbuzz (generic function with 3 methods)
In [7]:
fizzbuzz(10)
This is Int64 fizzbuzz
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
In [9]:
fizzbuzz(10.0)
This is Float64 fizzbuzz
1.0
2.0
Fizz
4.0
Buzz
Fizz
7.0
8.0
Fizz
Buzz
In [11]:
fizzbuzz(10 + 10im)
10 + 10im is neither Int or Float.
In [12]:
fizzbuzz("String")
String is neither Int or Float.

パフォーマンス

発展的な話題

Appendix

Julia Logo