Hello Ys world ?

技術的なことや何か役立つこと、日々の活動を記録する

Juliaの基本的な構文や関数についてまとめてみた

最近Juliaを触りまじめました。Pythonを触り始め、それから少し経ってJuliaを使い始めたため、インデントが構文規則になっている言語は未だに慣れないです。

※ 2018.09.27 数学定数について追記

はじめに

Juliaについての基本的な構文(コンソール出力、演算、if-else文、関数など)や簡単な数学の演算関数についてなど、入門的なプログラムを淡々と貼り付けておく。貼り付けるプログラムはGitHub Gistにも投稿しておく。

gist.github.com

環境

環境は以下の通りである。

環境
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などのように elseifelse 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キーを押すことで入力することができる。

また、カタラン定数、オイラー・マスケローニ定数、黄金比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で使えるようにする記事を参考に貼っておく。

ysss.hateblo.jp

ysss.hateblo.jp