Juliaの基礎

Author
Affiliation

柳本和春

神戸大学

Published

October 1, 2025

Modified

October 27, 2025

なぜJuliaを使うのか

数値計算におけるプログラミング言語の壁

数値計算をする上でプログラミング言語の選択はとても重要です. 経済学でよく使われるプログラミング言語は速度の意味で概ね以下のような関係があります.

\[ \text{C/C++, Fortran, Julia} \gg \text{Python, Matlab} > \text{R} \]

おおむね, C/C++, Fortran, Juliaは10-100倍ほどPython, Matlab, Rより速く計算が可能です. なおベクトル化というテクニックやPythonのNumbaを用いることで, Python, Matlab, Rでも同様の速度も出すことが可能ですが, C/C++, Fortran, Juliaなどの言語とはそもそも質的に異なるという事実は頭に入れておいた方が良いでしょう.

Juliaの特徴

JuliaはC並の速さとPython, Matlab, Rの使いやすさを目指して開発された比較的新しい言語です (Bezanson et al. 2012). 私自身, 高速化のためにはある程度の前提知識が必要なものの, C/C++, Fortranよりもデバックが容易であるため, 数値計算においてはJuliaを使っています.

また, 無料かつオープンソースであるため, アカデミアを離れたとしても使い続けることができます.

環境構築

Julia

Juliaupを用いたインストールを推奨します.

Windows

パワーシェルを開き, 以下のコマンドを実行します.

winget install julia -s msstore

Mac, Linux

ターミナルを開き, 以下のコマンドを実行します.

curl -sSL https://julialang.org/juliaup | bash

なお, インストール後はパワーシェル/ターミナルで以下のコマンドを実行することで最新版のJuliaにアップデートすることができます.

juliaup update

関数, forループ, if文

関数

function f(K, L; α)
    return K^α * L^(1 - α)
end

f(0.3, 0.7, α=0.5)
  • functionendで囲まれた部分が関数の定義です.
  • 引数は()内に,で区切って列挙します.
  • 引数のうち, ; 以降はキーワード引数と呼ばれ, 呼び出す際に引数名を用いる必要があります.
function f(K, L, A=1.0; α)
    return A * K^α * L^(1 - α)
end

f(0.3, 0.7, α=1/3) # or equivalently, f(0.3, 0.7, 1.0, α = 1/3)
  • 引数にデフォルトの値を持たせることができます.
  • デフォルトの値をもつ引数は, デフォルトを持たない引数の後に配置する必要があります.

一行関数

f(x, y) = 2x + y^2 + x * y
f(1.0, 2.0)
  • function-endを省略し, =によって関数を定義することができます.
  • なお, 変数の前の数値の*は省略可能です.

forループ

for i in 1:5
    println(i)
end
1
2
3
4
5
  • for-endで囲まれた部分がforループです.
  • inの後にイテレータを指定します.
for i in 1:5
    for j in 1:3
        println((i, j))
    end
end

# Or equivalently
for i in 1:5, j in 1:3
    println((i, j))
end
  • 2次元のforループを行う場合は, for-endをネストするか,で区切って複数のイテレータを指定します.

if文

function f(x)
    if x > 0
        return "Positive"
    elseif x < 0
        return "Negative"
    else
        return "Zero"
    end
end
  • if-endで囲まれた部分がif文です.
  • elseifelseを用いて条件分岐を行います.

文字列と文字

String と Character

Pythonやその他のプログラミング言語と異なり, Juliaでは文字列 (String) と文字 (Character) が厳密に区別されています.

  • 文字列はダブルクォーテーション " で囲みます.
  • 文字 (1文字のみ) はシングルクォーテーション ' で囲みます.
typeof('a')
Char
typeof("a")
String

そのため, 以下のようなコードで直感的でない結果が得られることがあります.

"abcd"[3] == "c"
false
"abcd"[3] == 'c'
true

Unicode文字

  • JuliaではUnicode文字を変数名として使用することができます (e.g., α, ÷, σ², x₁).
  • Unicode文字は\ + 文字列 + <tab>で入力することができます. (e.g., \alpha + <tab>α が入力できます.)
  • 使用できるUnicode文字の一覧.

そのため, CRRA効用関数とその導関数を以下のようにUnicode文字を用いて簡単に書くことができます.

\[ \begin{aligned} u(c, \sigma) &= \begin{cases} \log c & \text{ if } \sigma = 1 \\ \frac{c^{1 - \sigma}}{1 - \sigma} & \text{ if } \sigma \ne 1 \end{cases}\\ u'(c, \sigma) &= c^{-\sigma} \end{aligned} \]

u(c, σ) = σ == 1.0 ? log(c) : c^(1 - σ) / (1 - σ)
u′(c, σ) = c^(-σ)
  • 導関数 u′ の上付き文字は \prime + <tab> で入力できます.
  • 三項演算子 ? : を用いることで, if-else文を簡潔に書くことができます. つまり上のコードは以下と等価です.
function u(c, σ)
    if σ == 1.0
        return log(c)
    else
        return c^(1 - σ) / (1 - σ)
    end
end

文字列の内挿

age = 26
years_stay = 6
f(years, age) = 100years ÷ (age) # ÷ returns the quotient

s = "I came here $years_stay years ago, when I was $(age - years_stay).\nSo I spent $(f(years_stay, age)) % of my life in Madrid."
println(s)
I came here 6 years ago, when I was 20.
So I spent 23 % of my life in Madrid.
  • $ + 変数名 で変数を文字列内に埋め込むことができます.
  • $(式) で式を文字列内に埋め込むことができます.

データ構造

タプル

animals = ("bird", "cow", "fish")
animals[1]
"bird"
pars ==1.0, β=2.0, γ=4.0)
pars.β
2.0
  • タプルは()で囲まれた要素の集まりです.
  • タプルの要素は[]を用いてアクセスできます.
  • 名前付きタプルは=を用いて要素に名前をつけることができます.
  • 名前付きタプルの要素は.を用いてアクセスできます.
function tuple_sum(pars)
    (; α, γ) = pars
    return α + γ
end

tuple_sum(pars)
5.0
  • 名前付きタプルの要素は(; )を用いて, 各要素に展開することができます

ベクトル, 行列 (Array)

[1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3
[1 2 3]
1×3 Matrix{Int64}:
 1  2  3
[1; 2; 3]
3-element Vector{Int64}:
 1
 2
 3
  • ベクトルは[]で囲まれた,区切りの要素の集まりです.
  • 空白区切りの場合は行列 (この場合は横ベクトル)として扱われます.
  • ; 区切りは行列の中での改行を表します. 結果的にこの場合は縦ベクトルとして扱われます.
[1 2; 3 4]
2×2 Matrix{Int64}:
 1  2
 3  4
A = [1 2
    3 4]
2×2 Matrix{Int64}:
 1  2
 3  4
  • 行列は;区切りの行ベクトルを[]で囲むことで作成できます.
  • なお;の代わりに改行を入れることもできます.

レンジ

0:0.1:1
0.0:0.1:1.0
  • start:step:stop でレンジを作成できます.
  • start から stop まで step ずつ増加する数列を生成します.
  • ステップが省略された場合はデフォルトで1になります.
range(0, length=11, stop=1)
0.0:0.1:1.0
  • range(start, length = n, stop = end)n 個の start から end までの数列を生成できます.
Noteレンジとベクトルの違い

Juliaにおけるレンジはベクトルではなく, イテレータです. データとしては, レンジはベクトルではなく, レンジの始点, 終点, ステップの情報を持っているだけです. そのため, 生成の際のメモリは節約できる一方, ベクトルの様に要素を参照しようとすると計算コストがかかります.

r = 0:0.1:1
typeof(r)
StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}
typeof(collect(r))
Vector{Float64} (alias for Array{Float64, 1})

collect() 関数を用いることで, レンジをベクトルに変換することができます.

特殊記法

内包表記

[2^i for i in 1:5]
5-element Vector{Int64}:
  2
  4
  8
 16
 32
[i + j for i in 1:3, j in 1:3]
3×3 Matrix{Int64}:
 2  3  4
 3  4  5
 4  5  6
  • 内包表記は[ ]の中でforループを用いてベクトルや行列を生成する方法です.
  • 1次元の場合はforループを1つ, 2次元の場合はforループを,で区切って2つ用います.

ドット記法

f(x) = x^2
f.([1, 2, 3])
3-element Vector{Int64}:
 1
 4
 9
  • 定数に対して定義された関数をベクトルや行列に適用する際には, .を関数名の後につけることで各要素に適用することができます.
[1, 2, 3] .* [4, 5, 6]
3-element Vector{Int64}:
  4
 10
 18
[1, 2, 3] * [4, 5, 6] # Error
[1, 2, 3]' * [4, 5, 6]
32
  • .* は要素ごとの積を計算します.
  • * は行列の積を計算します. この例では縦ベクトルと縦ベクトルの積は定義できないため, エラーが発生します.
  • 内積を計算する場合は, 'を用いて転置を行った後に行列の積を計算します.

Plots.jlの使い方

using Plots

Plots.jlは, Juliaで図を描画するためのパッケージです. そのバックエンドとして以下の様なパッケージを統一的な文法で扱うことができます.

  • GR: デフォルト
  • Plotly: JavaScriptを利用したインタラクティブなプロット
  • PyPlot: Pythonのmatplotlibを利用
  • PGFPlotsX: LaTeXのpgfplotsを利用

この授業では基本的にGRを使用します. また, Plots.jl以外のパッケージとして, 近年はMakieも人気を集めています.

数列のプロット

以下の様なフィボナッチ数列をプロットしてみましょう.

\[ F_n = \begin{cases} 1 & n = 1, 2 \\ F_{n-1} + F_{n-2} & n = 3, 4, \dots \end{cases} \]

N = 20
fibs = zeros(Int, N)
fibs[1], fibs[2] = 1, 1
for i = 3:N
    fibs[i] = fibs[i-1] + fibs[i-2]
end

scatter(1:N, fibs, title="Fibonacci Sequences", legends=false)
  • scatter: 散布図を描画します.

関数のプロット

\[ B_n = \begin{cases} \frac{1}{n} & n \text{ odd} \\ 1 - \frac{1}{n} & n \text{ even} \end{cases} \]

f(n) = isodd(n) ? 1 / n : 1 - 1 / n
scatter(1:40, f, legends=false)
  • 描画関数 (e.g, scatter) の第2引数に関数を指定することで, 第一引数の値に対する関数の値をプロットできます

プロットの重ね合わせ

using LaTeXStrings

f₁(x) = x^2
f₂(x) = x
f₃(x) = log(x)

xs = 0:0.01:1
plot(xs, f₁, label=L"f_1(x) = x^2", legend=:bottomright)
plot!(xs, f₂, label=L"f_2(x) = x")
plot!(xs, f₃, label=L"f_3(x) = \log \,x")
  • plot: 折れ線グラフを描画します.
  • !を付けることで, 既存のプロットに追加描画します.
  • scatterを追加する場合は, scatter!を使用します.
  • 数式をグラフに表示するためには, LaTeXStringsパッケージを使用し, L"..."で囲みます.

レイアウト

f(x, y) = (x  y) ? (x + y) / (x - y) : one(x)
xs = range(-1.0, 1.0, length=100)
ys = copy(xs)
p1 = contour(xs, ys, f)
p2 = surface(xs, ys, f)
plot(p1, p2, layout=(1, 2))
  • contour: 等高線プロットを描画します.
  • layout=(1, 2): レイアウトを指定します. この場合, 1行2列のプロットを描画します.
  • より複雑なレイアウトはドキュメントを参照してください.

Julia での表の作り方

using SummaryTables

レポートや論文を書く際に, Juliaのコードを実行した結果を表として出力したい場合, SummaryTables.jlを用いることができます. 最も簡単な方法は simple_table() 関数を用いることですが, より複雑な票を作成することも可能です. また, 出力形式としては, HTML, LaTeX, DOCX, Typst などがサポートされています.

data = (
    id=1:5,
    name=["Alice", "Bob", "Charlie", "David", "Eve"],
    age=[34, 29, 42, 37, 25],
    score=[88, 92, 75, 80, 95]
)

simple_table(data)
Table 1: An example of SummaryTables.jl
id name age score
1 Alice 34 88
2 Bob 29 92
3 Charlie 42 75
4 David 37 80
5 Eve 25 95

References

Bezanson, Jeff, Stefan Karpinski, Viral B. Shah, and Alan Edelman. 2012. “Why We Created Julia.” https://julialang.org/blog/2012/02/why-we-created-julia/.