Juliaの基本的な構文や関数についてまとめてみた
最近Juliaを触りまじめました。Pythonを触り始め、それから少し経ってJuliaを使い始めたため、インデントが構文規則になっている言語は未だに慣れないです。
※ 2018.09.27 数学定数について追記
はじめに
Juliaについての基本的な構文(コンソール出力、演算、if-else文、関数など)や簡単な数学の演算関数についてなど、入門的なプログラムを淡々と貼り付けておく。貼り付けるプログラムはGitHub Gistにも投稿しておく。
環境
環境は以下の通りである。
環境 | |
---|---|
OS | Windows10 Pro 64bit version 1709 |
Julia | Version1.0.0 Windows 64bit |
LLVM | libLLVM-6.0.0 (ORCJIT, skylake) |
Juliaの実行環境は1.0.0であり、記事中のプログラムは1.0.0より前のバージョン、1.0.0以降のバージョンでの動作は保証しない。
基本的な使い方
Juliaのプログラムは、先頭に #
をつけた1行をコメントアウトすることができる。また、初めを #=
終わりを =#
で囲んだ範囲すべてをコメントアウトすることもできる。
文字出力
Juliaは動的型付けを行うため、出力時にC言語などのように数値型や文字列型などを意識しなくてよい。
文字列と変数、文字列と数値など、出力するものが少ない場合カンマで区切る方法がラクでいい。複数出力や文字列の途中に変数を出力する場合は文字列中に $
で変数を指定する方法がいい。
print("a") # 改行なし出力 println("b") # 改行付き出力 println("\n") # \nは改行文字を表す # 文字列 str = "ABC_def_0123456789_HelloWorld!" println(str) # 大文字小文字変換 println(uppercase(str)) # すべて大文字に変換 println(lowercase(str)) # すべて小文字に変換 # 出力 文字列結合 println("str : [", str, "]") println("str : [" * str * "]") # 出力 文字列内に変数埋め込み println("str : [$str]") # Juliaは配列番号は1から println(str[1]) # 文字列strの1番目 A println(str[1:6]) # 文字列strの1~6の範囲 ABC_de println(str[end-15:end]) # 文字列strの最後から15引いた位置から最後まで 6789_HelloWorld! # 文字列と数値表示 x = 10 println(x) println("x = ", x) println("x = " * string(x)) # 数値を文字列に変換 println("x = $x") println("x + 20 = $(x + 20)") # 文字列内で計算し表示 # 数文字列を数値に変換 str_num = "100" int_num = parse(Int, str_num) # Int型に変換 println(int_num + 200) # Cのprintfのような表示マクロ using Printf # ライブラリ読み込み @printf("pi = %.5f\n", pi) # JuliaではUTF-8エンコードではUnicode文字をサポート println("αβγ", "\u03B1", "\u03B2", "\u03B3") # αβγ ユニバーサル文字名でも可能
計算
Juliaでは、掛け算をする際の *
を省略することができる場合がある。また、一般的な四則演算の他に、虚数に im
を用いて複素数計算をすることもできる。
省略時の注意点
可否 | 左側 | 右側 | 計算例 | 理由 |
---|---|---|---|---|
○ | 数字 | 変数 | 2x | - |
○ | 数字 | ( ) | 2(x + 1) | - |
○ | ( ) | 変数 | (1 + 2)x | - |
× | 数字 | 数字 | 23 | 普通の数字 |
× | 変数 | 数字 | x2 | 変数名 |
× | 変数 | 変数 | xy | 変数名 |
× | 変数 | ( ) | x(1 + 2) | 関数xの引数に1+2 |
× | ( ) | 数字 | (x + 1)2 | 構文エラー |
× | ( ) | ( ) | (x + 1)(y + 2) | 構文エラー |
x = 2 y = 3 println("x = $x, y = $y") # 変数を含む計算 (*の省略) println("2x+1 = ", 2x+1) println("(x+2)x = ", (x+2)x) # xを括弧の前にするのは不可 x(x+2) # 表記が関数と混在するため # 除算 println("4/3 = ", 4/3) # 結果は実数 1.3333333... println("div(4, 3) = ", div(4, 3)) # 結果は整数 1 println("2\\3 = ", 2\3) # 3/2 と同等 # 余り println("8%3 = ", 8%3) # rem(8,3) と同等 # 累乗 println("2^10 = ", 2^10) println() # 複素数 i1 = 2 + 4im i2 = 4 - 3im println("i1 + i2 = ", i1 + i2) # 小数表記 println(.018) # 0.018 println(3.29e-2) # 0.0329 println(8.19e3) # 8190.0 println() # 各要素に演算を適用 # Juliaでは、一部を除くほとんどの演算子は関数である。 # そのため(1, 2, 3)などのタプルに対して演算を適用することができる println(+(1, 2, 3, 4, 5)) # 1+2+3+4+5 println(*(+(1, 1, 2), +(2,3))) # (1+1+2)*(2+3) # 値入れ替え(スワップ) println("x, y = ", x, ", ", y) x,y = y,x println("x, y = ", x, ", ", y)
if-else
&&
を省略して数学的な書き方で評価できるのは直感的にわかりやすいし、無駄が少なくていい。CやJavaなどのように elseif
を else if
で書くとエラーになる。if文は end
の付け忘れに注意。三項演算子と同じように書くことができるifelse関数がある。
x = 2 y = 5 # プログラムでの一般的なの書き方 println(0<x && x<3) # true println(0<x && x<1) # false # 数学的な書き方(`&&` の省略) println(0<x<3) # true println(0<x<1) # false println(0<x<3<y) #true # 複数変数を含めての評価も可能 if 0 < x println("x is greater than 0") elseif x < 0 println("x is less than 0") else println("x is 0") end # ifelse関数 println(ifelse(0<x<3, "x is 0<x<3", "x is not 0<x<3")) # 三項演算 println(0<x<3 ? "x is 0<x<3" : "x is not 0<x<3")
関数
Juliaの関数の定義方法は比較的柔軟に行える。関数内のreturn文で即時に値が返されないので注意する。多重ディスパッチが行えるため、引数の型によって処理を柔軟に実装することができる。
# 一般的な記法の関数定義 function f1(a) return a + 1 end println("f1 : ", f1(3)) # 括弧をつけない関数f1は、関数オブジェクトとして、他の値と同じように受け渡しが可能 g = f1 println("g : ", g(3)) # return文は省略可能 # return文の省略をした場合、最後に行った演算や変数、数値、文字列などが返される function f2(a, b) a+=2 b+=3 a+b # a+bを返す end println("f2 : ", f2(1,1)) # 以下のようなif-elseなどの条件分岐でも同様に省略ができる # ただし、return文を付け、返り値であることを示したほうがよい function f2_1(a,b) if a == b "同じ" else "違う" end end println("f2_1 : ", f2_1(1, 1)) # 関数に計算の式を代入(上と同様に最後に行った演算や変数、数値、文字列などが返される) f3(a, b) = (a + b) / 2 println("f3 : ", f3(2, 4)) # 計算結果を複数返す function f4(a, b) return1 = a + b return2 = a - b return1, return2 end c1, c2 = f4(10, 2) println("f4 : c1 = $c1 c2 = $c2") # 多重ディスパッチ # 引数の値の型によって実装の異なる関数 function f5(a::Int) println(" a[Int] = $a") end function f5(a::Float64) println(" a[Float64] = $a") end function f5(a::Int, b::Int) println(" a[Int] = $a, b[Int] = $b") end function f5(a, b) println(" a = $a, b = $b") end println("f5 : ") f5(2) # a[Int] = 2 f5(2.0) # a[Float64] = 2.0 f5(2, 3) # a[Int] = 2, b[Int] = 3 f5(2, 2.0) # a = 2, b = 2.0
ループ
ループ範囲を 1:5
のように直感的にわかりやすく記述することができる。記述は 初期値 : 終了値
または初期値 : 増分 : 終了値
となる。また、配列などを用いてのループも行える。
for i in 1:5 # i = 1:5と同等 1~5の範囲 print("$i ") end println() for i in 5:-1:1 # 5~1の範囲で-1ずつ変化 print("$i ") end println() # 配列を用いた繰り返し a1 = [1, 2, 4, 8, 16] for i in a1 print("$i ") end println() while !isempty(a1) print("$(pop!(a1)) ") end println() a2 = ["One", "Two", "Three", "Four"] for i in 1:length(a2) print("$i : $(a2[i]) ") # 配列の番号は1から end println() for (i, a) in enumerate(a2) print("$i : $a ") end println()
数学
JuliaはUnicode文字をサポートしているため、より数式や変数を数学的に記述することができる。また、Pythonでの三角関数 math.sin()
や円周率 math.pi
のように math.
を付ける必要がなく、数学的に記述し関数を呼び出すことができる。
# JuliaではUTF-8エンコードではUnicode文字をサポート # 対話モード(インタプリタ)でバックスラッシュ(円マーク)に続けて記号名称を入力しTabキーを押すことで変換可能 # 円周率の値は pi でも π でも利用可能 println("pi = $(pi), π = $(π))") # π は \pi で変換可能 # 数学でよく使う演算 println("|-10| = ", abs(-10)) # 絶対値 println("√9 = ", sqrt(9)) # 平方根 println("∛9 = ", cbrt(64)) # 立方根 println("辺が1, √3の直角三角形の斜辺 = ", hypot(1, sqrt(3))) # 斜辺を求める println("round(2.67) = ", round(2.67)) # 四捨五入 println("floor(1.23) = ", floor(1.23)) # 床関数 println("ceil(4.56) = ", ceil(4.56)) # 天井関数 println("trunc(-2.89) = ", trunc(-2.89)) # 切り落とし関数 0へ丸める println("gcd(169, 13) = ", gcd(169, 39)) # 最大因数 println("lcm(12, 15) = ", lcm(12, 15)) # 最小公倍数 println("e = ", ℯ) # 自然対数の底(ネイピア数) exp(1)と同じ \eulerで変換可能 println("e^2 = ", exp(2)) # 対数 println("log[e](10) = ", log(10)) # 自然対数 底eの対数 : ln(10) println("log[10](100) = ", log10(100)) # 常用対数 底10の対数 : log(100) println("log[2](16) = ", log2(16)) # 二進対数 底2の対数 : lg(16) # 三角関数もそのまま呼び出し可能 α = sin(π/6) # \alpha β = cos(π/6) # \beta γ = tan(π/6) # \gamma println("sin(π) = $α, cos(π) = $β, tan(π) = $γ") println("1/2 = $(1/2), (√3)/2 = $(sqrt(3)/2), 1/(√3) = $(1/sqrt(3))") # 0.5, 0.866, 0.577 # 度数法(Deg)、弧度法(Rad)変換 println(deg2rad(180)) println(rad2deg(pi))
数学定数
一部のUnicode文字に数学定数が割当られている。以下のURLを参照。
The Julia Language - Numbers https://docs.julialang.org/en/stable/base/numbers/#Base.MathConstants.pi
円周率と自然対数の底eはバックスラッシュ(円マーク)\
に続けて記号名称を入力し、Tabキーを押すことで入力することができる。
- 円周率 π :
\pi
- 自然対数の底 e :
\euler
また、カタラン定数、オイラー・マスケローニ定数、黄金比は Base.MathConstants.
を付けることでも呼び出すことができる。
- カタラン定数 :
Base.MathConstants.catalan
- オイラー・マスケローニ定数 :
Base.MathConstants.eulergamma
またはBase.MathConstants.γ
- 黄金比 :
Base.MathConstants.golden
またはBase.MathConstants.φ
※ 上記の記号の呼び出し γ : \gamma
、φ : \varphi
行列
行列の記述方法も直感的で、積や転置、逆行列などの演算を行うことができる。
m1 = [1 2 3] # 横行列 m2 = [1; 2; 3] # 縦行列 [1, 2, 3]と同等 println("m1 = ", m1) println("m2 = ", m2) # 2×2の行列 m3 = [ 2 3; 4 5; ] m4 = [ 1 2; 2 2; ] println("m3 = ", m3) println("m4 = ", m4) println("2*m3 = ", 2m3) # 転置 println("m3の転置 : ",m3') # 逆行列 m5 = inv(m3) println("m3の逆行列 : ", m5) # 行列の演算 println("m3-m4 = ", m3-m4) println("行列の積 m3*m4 = ", m3*m4) println("行列の各要素同士の積 : ", m3.*m4) # 連立一次方程式 #= x - 2y + 3z = 1 3x + y - 5z = -4 -2x + 6y - 9z = -2 =# A = [1 -2 3; 3 1 -5; -2 6 -9] b = [1; -4; -2] x, y, z = A\b # 実行結果は[1.0, 3.0, 2.0]となり行列の各要素を変数x, y, zに代入する println("x = $x, y = $y, z = $z")
参考
■ Julia 1.0 Documentation https://docs.julialang.org/en/v1/
Juliaの環境構築の記事とJupyterLabで使えるようにする記事を参考に貼っておく。