Julia は Windows / Mac / Linux、どれでも簡単にインストールできます。2024/9/26 時点では v1.10.5 が最新安定版で、ダウンロードページ の一番上に表示される「Install julia」に従ってインストールを行います。例えば Linux (bash) の場合、一般ユーザ権限で、
$ curl -fsSL https://install.julialang.org | sh
$ . ~/.bash_profile
とするだけでローカル環境にインストールされます。
もちろん、従来通り自分でバイナリを選んでインストールすることも可能です。ダウンロードページ の 「Official Binaries for Manual Download」 から Current stable release(最新安定版)の該当する OS のインストーラを選択します。例えば64ビット版の Windows であれば、「Windows」の「64-bit (installer)」 をダウンロード・実行すれば特に何もすることはありません。
上記の方法でうまくいかない場合はソースインストールを試みてみましょう。例えば Linux の場合、「Source」の「Tarball with dependencies」をダウンロードし、
$ tar xvzf julia-1.8.0-full.tar.gz
$ cd julia-1.8.0
$ make
とすればコンパイルできます。必要に応じて実行バイナリ(julia)へパスを通せば完了です。なお、ソースインストールは一般ユーザでも可能です。
julia
をダブルクリックやコマンドプロンプトから実行すると、対話的にコマンドを実行する REPL (read-eval-print loop) が立ち上がります。
ここで julia の様々なコマンドを入力することで、処理が実行されます。結果は即座に表示されます。
julia> 1 + 2
3
なお、行の末尾にセミコロン(;)を付けると結果は即座に表示されないようになります。また、Jupyter notebook では、最後に処理した行の結果が表示されます。
明示的に表示したい場合は println()
を使います。
julia> println("Hello Julia!")
Hello Julia!
REPL を終了するには exit()
と入力します。
REPL では処理に応じてモードを切り替えます。
julia を立ち上げた直後のモードは julia モードと呼ばれています。これは julia コマンドを受け付けて処理を行うモードであり、プロンプトにはjulia>
と表示されます。julia 以外のモードにおいてバックスペースを入力すると、julia モードへ戻ることができます。
julia モードにおいてクエスチョンマーク(?)を入力するとヘルプモードに入ります。ヘルプモードにおいてキーワードを入力すると、関連するドキュメントが表示されます。
もしくは、クエスチョンマークに続いてコマンド名を入力してもOKです。
julia> ?transpose()
cos(x)
Compute cosine of x, where x is in radians.
See also [cosd], [cospi], [sincos], [cis].
julia モードにおいて右角括弧(])を入力するとパッケージモードに入ります。パッケージをインストールする際に利用します。
julia> ]
(@v1.4) pkg> add PyPlot
セミコロン(;)を入力するとシステムのシェルのコマンドを受け付けるシェルモードに入ります。Windows では機能しないようです。
Julia で1行のコードを複数行に分ける汎用的な記述方法はありません。但し、ある行が完全な式で終了していない場合、次の行へ継続すると解釈されます。例えば、ある行で括弧が閉じていなければ継続行とみなされます。
julia
コマンドにスクリプト名を渡すと、スクリプトを実行できます。
$ julia test.jl
スクリプトの実行が終了すると julia も終了して呼び出し元に戻ります。実行が終了した後も引き続きREPLで julia を使いたい場合は、オプション -i
をつけて実行します。
$ julia -i test.jl
コマンド名に続いて引数を指定すると、julia から配列変数 ARGS によって参照することができます。
$ julia -i test.jl aaa bbb
...
julia> ARGS[1]
aaa
REPL からスクリプトを実行することもできます。この場合は、include()
を利用します。
julia> include("test.jl")
include()
はオーバーヘッドが少ないため、デバッグには重宝します。但し、REPLを立ち上げながら複数回実行すると複数回評価されることになるので注意が必要です。また、引数を与えることはできず、最初に実行した時の引数がそのまま残ります。
ある値を指す(格納する)文字列を変数と言います。多くの他言語では事前の型宣言が必要ですが、Julia では型宣言なしにそのまま利用できます。
代入演算子(=)を利用すると、右辺で指定した値を左辺の変数へ代入できます。
julia> x = 1
1
julia> y = 2.5
2.5
julia> str = "Hello!"
Hello!
値の参照は、単に変数名を指定するだけです。
julia> y
2.5
但し、クオーテーションの中から参照したい場合は、ダラー($)を変数名の前に付けます。
julia> println("y = $y")
y = 2.5
Julia の変数名は大文字・小文字の区別があり、アルファベット(A-Z, a-z)、アンダースコア(_)、又は Unicode の 00A0 以上で開始する必要があります。2文字目以降についてはさらに数値(0-9)、エクスクラメーション(!)、シングルクオーテーション(')、および他の Unicode 文字を利用することが可能です。但し、if や for といった予約語を変数名として利用することはできません。
アンダースコアのみで構成される変数は、代入のみ可能で参照できない、という少し特殊な性質を持っています。これは、例えば以下のようにダミーで変数を受け取りたい時に役に立ちます(アンダースコアは何個でも構いません)。
___, y = size([1 2 3; 4 5 6])
println(y) -> 3
変数名として利用可能な Unicode 文字の詳細については、本家の Allowed Variable Names を参考にしてください。
baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while
Julia本家ドキュメント によると、変数名には以下に従うことがおすすめされています(強制ではありません)。
- 変数の名前は小文字、語の区切りはアンダースコアを利用する(但し、必要がなければアンダースコアは使わない方がよい)。
- 型、モジュールの名前については大文字で始まり、語の区切りは大文字を利用する。
- 関数、マクロの名前は小文字のみを利用し、アンダースコアは利用しない。
- 関数が引数に書き込む場合、関数名の末尾をエクスクラメーション(!)にする。
変数のスコープとは、変数が参照可能なコードの領域です。Julia のスコープは大域(global)スコープと局所(local)スコープに分類されます。
虚数単位を表す変数として、定数 im
が予め定義されています。1 + 2i
を変数 x
に代入する例を示します。
julia> x = 1 + 2im
1 + 2im
複素数を含む演算についても、実数と同様に行うことができます。
複素数から実部、もしくは虚部を実数として取り出すには、関数 real()
、imag()
を利用します。
julia> real(x)
1
julia> imag(x)
2
絶対値は abs()
、複素共役は conj()
、偏角は angle()
によって得ることができます。
julia> angle(x) / 2pi * 360
63.43494882292201
Base パッケージに含まれる主要な関数を紹介します。
関数 | 説明 | 戻り値 |
---|---|---|
round(x) |
x を最も近い整数に丸める |
typeof(x) |
round(T, x) |
(同上) | T |
配列を生成するにはいくつかの方法があります。まずは関数 Array()
を用いた最も基本的な方法を示します。
Array{型}(undef, 次元...)
例えば倍精度実数で 2x3 の2次元配列 a
を作成する場合、
julia> a = Array{Float64}(undef, 2, 3)
と記述します。なお、a
は初期化されないため、格納されている値は不定です。
julia> a
2×3 Matrix{Float64}:
1.40837e-315 9.10338e-316 1.40837e-315
1.00098e-315 1.41457e-315 9.10182e-316
最初から値を埋めたい場合は zeros()
や ones()
、もしくは fill()
を使いましょう。
zeros([型=Float64,] 次元...)
ones([型=Float64,] 次元...)
fill(値, 次元...)
zeros()
は 0 埋め、ones()
は 1 埋め、fill()
は任意の値を埋めます。fill()
については値の型がそのまま配列の型になります。以下は使用例です。
julia> a = zeros(Int32, 2, 3)
julia> b = ones(Float64, 2, 2, 2)
julia> c = fill(1, 10)
値を羅列することで配列を生成することもできます。以下のように大括弧[]の中にコンマ区切りで値を羅列することで、1次元配列(列ベクトル)を生成することができます。要素の値に応じて型が自動的に決定されます。
julia> [1,2,3]
3-element Vector{Int64}:
1
2
3
julia> b=[1.1, 2.2, 3.3]
3-element Vector{Float64}:
1.1
2.2
3.3
julia> println(b)
[1.1, 2.2, 3.3]
julia> eltype(b)
Float64
2次元配列(行列)を作成する場合、行の各要素は空白またはダブルセミコロン(;;)で区切り、縦方向はセミコロン(;)もしくは改行で区切ります。
julia> [1 2 3; 4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> [1 2 3
4 5 6]
2×3 Matrix{Int64}:
1 2 3
4 5 6
以上の応用として、列ベクトルを行方向に並べる形で行列を作成することも可能です。
julia> [[1,4] [2,5] [3,6]]
2×3 Matrix{Int64}:
1 4 7
2 5 8
配列をコピーする場合は copy()
を利用します。
julia> a = copy(b)
なお、=
を用いた代入を用いると、b
を変更すると a
にも反映されてしまいます。これは、Julia の関数が共有渡しで引数を渡していることと関係しています。
配列に対して以下の演算子を利用することができます。演算結果は配列で返ります。単なる乗算のように、配列の各要素に対して演算したい場合はブロードキャストを使いましょう。
- 単項演算子:
演算子 | 名前 | 補足 |
---|---|---|
+ |
単項+ | 特に何もしない |
- |
単項- | 正負を反転 |
- 二項演算子:
演算子 | 名前 | 補足 |
---|---|---|
+ |
加算 | |
- |
減算 | |
* |
内積 | |
/ |
x / y は x * inv(y) と等価 |
|
\ |
x \ y は inv(x) * y と等価 |
|
^ |
べき乗 | x ^ y は x の y 乗 |
- 比較演算子:
演算子 | 名前 | 意味 |
---|---|---|
== |
等価 | |
!= |
非等価 |
vcat()
は与えられた配列を1次元目方向につなげていきます。特に行列(2次元配列)を縦方向に追加していく場合に便利です。
julia> a = [1 2 3 4]
1×4 Matrix{Int64}:
1 2 3 4
julia> b = [10 20 30 40; 100 200 300 400]
2×4 Matrix{Int64}:
10 20 30 40
100 200 300 400
julia> c = vcat(a,b)
3×4 Matrix{Int64}:
1 2 3 4
10 20 30 40
100 200 300 400
行列を横方向に追加したい場合は hcat()
を使いましょう。これは与えられた配列を2次元目方向につなげていきます。
julia> a = [1 2 ; 3 4]
2×2 Matrix{Int64}:
1 2
3 4
julia> b = [10 20 30 40 ; 100 200 300 400]
2×4 Matrix{Int64}:
10 20 30 40
100 200 300 400
julia> c = hcat(a,b)
2×6 Matrix{Int64}:
1 2 10 20 30 40
3 4 100 200 300 400
vcat()
、hcat()
ともに、引数としていくらでも配列を与えることができます。但し、vcat()
であればそれぞれの配列の1次元目、hcat()
であればそれぞれの配列の2次元目を除く各次元の要素数が一致する必要があることに注意が必要です。
以下に配列の結合に関連した関数をまとめておきます。
関数名 | 意味 |
---|---|
vcat(a,...) |
a, ... の縦結合 |
hcat(a,...) |
a, ... の横結合 |
cat(a,...; dims) |
a, ... の汎用的な結合 |
関数名 | 意味 |
---|---|
transpose(a) |
aの転置(aは1-2次元配列) |
adjoin(a) or a' |
aの随伴行列(aは1-2次元配列)。すなわち、aを転置して各要素について複素共役をとって得られる行列。各要素が実数の場合はaの転置と等価 |
文字列はダブルクオーテーション(")、もしくは3連続のダブルクオーテーション(""")で囲みます。
julia> a = "abc"
"abc"
julia> b = """abc"""
"abc"
julia> c = """He said "Yes"."""
"He said \"Yes\"."
このように、ダブルクオーテーションを含む文字列の場合はエスケープ文字(\)を利用してもよいのですが、3連続のダブルクオーテーションで囲むのが便利です。
文字列を参照する場合は通常の変数と同様、変数名をそのまま利用します。ダブルクオーテーションの中で参照したい場合は、ドル記号($)を用いて参照することもできます。
julia> a = "abc"
"abc"
julia> a
"abc"
julia> "a = $a"
"a = ABC"
部分文字列を取り出したい場合は、配列と同様に範囲を指定します。
julia> a = "abc"
"abc"
julia> a[1:2]
"ab"
文字列の結合には string()
、もしくはアスタリスク(*
)を使います。他の言語のように + や // 等を用いないことに注意が必要です。
julia> a = "abc"
"abc"
julia> b = "ABC"
"ABC"
julia> c = string(a, b)
"abcABC"
julia> d = a * b
"abcABC"
別の方法として、ドル記号($)を用いる方法もあります。
julia> e = "$a$b"
"abcABC"
条件に合致した時に実行される構文です。
文法は以下の通りです。
if condition-1
...
elseif condition-2
...
else
...
end
なお、elseif および else ブロックは省略可能です。
break: ループから抜ける
入力した値に対して戻り値を返す仕組みを関数といいます。
関数は function
と end
で囲んで定義します。以下が基本形です。
function func(args...)
...
return ret
end
戻り値は return
で返します。関数の途中に return
がある場合はその後から関数末尾までの処理は実行されません。
以下は2つの引数の和を返す関数の例です。
julia> function add(x, y)
return x + y
end
add (generic function with 1 method)
Julia の関数の面白い特徴として、return
を省略すると最後に評価された式の値が返ります。従って、上の関数は以下のように記述することも可能です。
julia> function add(x, y)
x + y
end
add (generic function with 1 method)
このように一行で記述できるような関数の場合、さらに簡略化した代入形式(assignment form)を利用することもできます。
julia> add(x,y) = x + y
add (generic function with 1 method)
関数を実際に利用する呼び出しは以下のような形で行います。
func(args...)
さきほどの add 関数を利用する例を示します。
julia> add(2, 3)
5
このように、入力した値に対して答えを返すのが関数の役割といえます。
Julia における関数の引数は、共有渡し(pass-by-sharing)で渡されます。大ざっぱには、引数の型の種類に応じて以下のように動作します。
- 数値、文字列など:関数内における変更は関数の呼び出し元に反映されない
- 配列など:関数内における変更は関数の呼び出し元に反映される
具体的な例でみていきましょう。
julia> function addv(x, y)
x = x + y
end
addv (generic function with 1 method)
julia> p=2
addv(p, 5)
p
2
このように、関数内で引数の値を変更しても、呼び出し元には反映されません。
一方、配列を引数として渡すと、関数内での変更が呼び出し元にも反映されます。
julia> function addvarray!(x, y)
x[1] = x[1] + y
x[2] = x[2] + y
x[3] = x[3] + y
end
addvarray! (generic function with 1 method)
julia> a=[1,2,3]
addvarray!(a,3)
a[1]
4
後述の理由により、名前のない関数を定義することがあります。無名関数と呼ばれるこのような関数は、
function (args...)
...
end
のように関数名を省略する、もしくはさらに省略して、
args -> ...
のような文法で定義できます。
無名関数は、関数の引数として関数を渡す場合によく用いられます。以下は、1, 3, -1 それぞれを引数とする無名関数の結果を得る例です。
julia> map(x -> x^2 + 2x - 1, [1, 3, -1])
3-element Vector{Int64}:
2
14
-2
関数の引数として関数を渡す方法は有用ですが、無名関数の定義が長い場合は引数の部分が冗長になってしまいます。このような場合、以下のdoブロック構文で書き換えるとより分かりやすい記述になる場合があります。
func( args-for-func-except-1st-arg ) do args-for-anonymous-func
...
end
たとえば、前述の
map(x -> x^2 + 2x - 1, [1, 3, -1])
は、
map([1, 3, -1]) do x
return x^2 + 2x - 1
end
のような形で書き換えることが可能です。