コンテンツにスキップ

数値計算用プログラミング言語 Julia

juliaは、数値計算や計算科学、数値解析を目的として開発された言語です。 数値計算に便利な組み込み型や組み込み関数が用意されています。 文法や使い勝手はPythonに似ていますが、計算速度はPythonより速いとされています。

2012年に公開された若い言語で、ダウンロードやインストールは非常に簡単で、すぐに使い始めることができます。 環境構築方法は、日本語マニュアルなどを参照してください。 本講義では、説明やサンプルプログラムのいくつかをjuliaで示します。

インストール方法

ここでは、Windows搭載パソコン上に準備された、Ubuntu 20.04にLTSのJuliaをインストールする方法を解説します。LTSとはLong-term support releaseのことで、長期にわたってサポートが行われるバージョンのことです。2024-04-01の時点では、以下の通りです。

"Long-term support (LTS) release: v1.6.7 (July 19, 2022)"

macOSの場合もダウンロードするバイナリが"macOS 64bit"になるだけで、それ以外の手順はだいたい一緒です。 詳しくは【入門編】プログラミング言語Juliaの特徴、メリット…|Udemy メディアを参照してください。

  1. 公式ページのDownload Juliaにアクセス

  1. "Generic Linux on x86"の"64-bit"をクリックすると、julia-1.6.7-linux-x86_64.tar.gzがダウンロードされます。

  2. julia-1.6.7-linux-x86_64.tar.gzを以下のコマンドで解凍します。 tar zxfv ./julia-1.6.7-linux-x86_64.tar.gz

  3. 念の為、解凍したディレクトリの中身を確認します。./julia-1.6.7/binディレクトリにjuliaがあればOKです。

    % > ls .
    julia-1.6.7/  julia-1.6.7-linux-x86_64.tar.gz*
    % > ls ./julia-1.6.7
    bin/  etc/  include/  lib/  libexec/  LICENSE.md  share/
    % > ls ./julia-1.6.7/bin
    julia*
    
  4. このバイナリにパスを通すために、バイナリの場所を確認します。この例では、/tmp/julia_dl_test/julia-1.6.7/binディレクトリにあることにします。

    % > ls .
    julia-1.6.7/  julia-1.6.7-linux-x86_64.tar.gz*
    % > cd ./julia-1.6.7/bin
    julia*
    % > pwd
    /tmp/julia_dl_test/julia-1.6.7/bin
    
  5. 以下のexportコマンドでパスを通します。このコマンドは新しいターミナルを起動させたり、PCを再起動させたりすると、もう一度行わなければなりません。毎回パスを通したい場合は、.bashrc.zshrcなどにこのコマンドを追記してください。

    export PATH=$PATH:/tmp/julia_dl_test/julia-1.6.7/bin
    

  6. ちゃんとパスが通ったかwhichコマンドで確認してみましょう。以下の様な表示が返ってくればインストール終了です。

    % > which julia
    /tmp/julia_dl_test/julia-1.6.7/bin/julia
    

  7. 最後にJuliaを起動してみます。ここまでのステップが正しく行われていれば、以下の様なメッセージが見えるはずです。

    % > julia --threads auto
               _
       _       _ _(_)_     |  Documentation: https://docs.julialang.org
      (_)     | (_) (_)    |
       _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
      | | | | | | |/ _` |  |
      | | |_| | | | (_| |  |  Version 1.6.6 (2022-03-28)
     _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
    |__/                   |
    
    julia>
    

  8. Juliaを終了させるには、exit()コマンドを実行します。

    1
    2
    julia> exit()
    % >
    

各ディストリビューションのパッケージ管理ツール(Ubuntuではapt, CentOSではdnf)でもインストールできますが、この方法は推奨されていません。 インストールできるJuliaのバージョンが古いためです。 例えば、Ubuntu 20.04でインストールできるバージョンは、1.4.1+dfsg-1です。

Ubuntu20のaptに登録されたjuliaの情報
% > apt show julia
Package: julia
Version: 1.4.1+dfsg-1
Priority: optional
Section: universe/science
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Julia Team <pkg-julia-devel@lists.alioth.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 6,161 kB
Depends: julia-common (= 1.4.1+dfsg-1), libjulia1 (= 1.4.1+dfsg-1), libc6 (>= 2.4),     libcurl3-gnutls (>= 7.16.2), libdsfmt-19937-1 (>= 2.2.3), libgcc-s1 (>= 3.0),     libgfortran5 (>= 8), libgit2-28 (>= 0.26.0), libgmp10, libllvm8 (>= 1:8~svn298832-1~),     libmbedcrypto3 (>= 2.13), libmbedtls12 (>= 2.13), libmbedx509-0 (>= 2.0), libmpfr6 (>= 3.    1.3), libopenlibm3 (>= 0.4), libpcre2-8-0 (>= 10.22), libquadmath0 (>= 4.6), libssh2-1     (>= 1.0), libunwind8, libutf8proc2 (>= 2.1.1)
Recommends: git, openssl
Suggests: ess (>= 12.09-1~), julia-doc, vim-julia
Breaks: julia-common (<< 0.5.0~)
Replaces: julia-common (<< 0.5.0~)
Homepage: https://julialang.org
Download-Size: 1,230 kB
APT-Sources: http://ftp.riken.jp/Linux/ubuntu focal/universe amd64 Packages
Description: high-performance programming language for technical computing
 Julia is a high-level, high-performance dynamic programming language for
 technical computing, with syntax that is familiar to users of other technical
 computing environments. It provides a sophisticated compiler, distributed
 parallel execution, numerical accuracy, and an extensive mathematical function
 library. The library, mostly written in Julia itself, also integrates mature,
 best-of-breed C and Fortran libraries for linear algebra, random number
 generation, FFTs, and string processing. Julia programs are organized around
 defining functions, and overloading them for different combinations of
 argument types (which can also be user-defined).
 .
 This package provides a complete Julia installation (JIT compiler, standard
 library, text-based user interface).

プログラムの実行方法

簡単なサンプルプログラム

以下に示す簡単なプログラムを実行してみましょう。

  1. Juliaを起動します。

    % > julia
               _
       _       _ _(_)_     |  Documentation: https://docs.julialang.org
      (_)     | (_) (_)    |
       _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
      | | | | | | |/ _` |  |
      | | |_| | | | (_| |  |  Version 1.6.6 (2022-03-28)
     _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
    |__/                   |
    
    julia>
    

  2. julia> 以降をコピペしてみましょう。結果はすぐに返ってきます。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    julia> println("各型の最大値と最小値")
    各型の最大値と最小値
    
    julia> println("$(lpad("Type",7)): [$(lpad("Min value (typemin)",40)),$(lpad("Max value (typemax)",40))]")
       Type: [                     Min value (typemin),                     Max value (typemax)]
    
    julia> for T in [Int8,Int16,Int32,Int64,Int128,UInt8,UInt16,UInt32,UInt64,UInt128]
                      println("$(lpad(T,7)): [$(lpad(typemin(T),40)),$(lpad(typemax(T),40))]")
                  end
       Int8: [                                    -128,                                     127]
      Int16: [                                  -32768,                                   32767]
      Int32: [                             -2147483648,                              2147483647]
      Int64: [                    -9223372036854775808,                     9223372036854775807]
     Int128: [-170141183460469231731687303715884105728, 170141183460469231731687303715884105727]
      UInt8: [                                       0,                                     255]
     UInt16: [                                       0,                                   65535]
     UInt32: [                                       0,                              4294967295]
     UInt64: [                                       0,                    18446744073709551615]
    UInt128: [                                       0, 340282366920938463463374607431768211455]
    

グラフ表示を伴うサンプルプログラム

グラフ表示を行うには、プログラムの実行の前にライブラリのインストールが必要です。 例えば、Plotsというグラフ表示用のライブラリがよく使われますが、これは以下の様にしていインストールします。

  1. 以下のコマンドで、Plotsがインストールできます。Plotsは他のものに置き換えることもできます。実行すると、いろいろダウンロードやコンパイルが行われ、Plotsが使える様になります。

    julia> using Pkg; Pkg.add("Plots")
    Resolving package versions...
    Installed Libffi_jll  v3.2.2+1
    Downloaded artifact: Libffi
      No Changes to `~/.julia/environments/v1.6/Project.toml`
        Updating `~/.julia/environments/v1.6/Manifest.toml`
      [e9f186c6]  Libffi_jll v3.2.2+0  v3.2.2+1
    Precompiling project...
      14 dependencies successfully precompiled in 39 seconds (156 already precompiled)
    julia>
    
  2. Plotsライブラリがインストールできたら、コッホ曲線をコピペして、Enterキーを実行してみましょう。lag.pngという画像ファイルが出来るはずです。


ここでは簡単にJuliaの説明をします。 公式のドキュメントなどは以下の通りです。

使い方

Juliaにはいくつかの実行環境があります。 具体的には、対話型実行環境 REPL、Jupyter Notebook、コマンドライン実行です。 本講義では、REPLでの実行を推奨しています。

対話型実行環境 REPL

REPL (read-eval-print loop) は、Juliaの主となる実行環境で、対話形式でコマンド実行と結果を見ていくものです。

  • 起動:コマンドラインからjuliaでREPLが起動し、Juliaモードに入る
  • 終了:Juliaモードで、exit()Ctrl+dで終了

REPLの5種類のモード

いくつかのモードがありますが、主に使うのはJuliaモードです。 検索モードを使いこなすと作業効率が上がります。 また、シェルモードとパッケージモードはときどき使うでしょう。 ヘルプモードは、ウェブを検索したほうが早い気がします。 なお、各モードからJuliaモードには、行頭でバックスペースを押すと抜けられます。

  1. Juliaモード:プロンプトにJulia式を入力するモード。主にこれを使う。式を入力してenterを押すと、入力した式が評価され、結果が表示される。juliaコマンドで入る。
  2. シェルモード:REPLから下位のシステムを見るためのモード。;で入る。
  3. パッケージ(Pkg)モード:パッケージのロードとアップデートのためのモード。]で入る。
  4. 検索モード:以前の入力の履歴を探すモード。^+Rで入る。
  5. ヘルプモード:関数やライブラリのヘルプが見られるモード。?で入る。

オススメの実行方法

Juliaモードで直接プログラミングと実行を行ったり、コマンドラインでjuliaコマンドにファイル名を繋げて実行するのはあまりオススメではありません。 これはJITコンパイルが効かなくなるためです。 オススメの実行方法は、エディタでコードを書いて、Juliaモードでコードの読み込みと実行する形式です。 具体的な手順は、以下のように、;でシェルモードに入ってディレクトリとファイル名を確認し、Juliaモードに戻ってincludeでそのファイルを実行します。

julia>

shell> pwd
/root

shell> ls
A.png                                    mt19937.png
U.png                                    multiple_agents_simulation.gif
cellular_automaton_wolfram_code.jl       multiple_agents_simulation.jl

julia> include("./cellular_automaton_wolfram_code.jl")

言語仕様

変数など

動的型付け言語なので、変数の宣言は必須ではありません。明示的に型を宣言することもできます。

変数

  • Variables · The Julia Language
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    # Assign the value 10 to the variable x
    julia> x = 10
    10
    
    # Doing math with x's value
    julia> x + 1
    11
    
    # Reassign x's value
    julia> x = 1 + 1
    2
    
    # You can assign values of other types, like strings of text
    julia> x = "Hello World!"
    "Hello World!"
    

配列(ベクトル・行列・テンソル)

  • 1次元配列 = ベクトル、2次元配列 = 行列、多次元配列 = テンソル、と言われることがあります。Juliaは数値計算と密接に関わっているので、これらの用語がよく使われます。
  • Single- and multi-dimensional Arrays · The Julia Language
  • 宣言・代入

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    julia> a = [1,2,3] # an array of 3 integers
    3-element Vector{Int64}:
     1
     2
     3
    
    julia> b = a   # both b and a are names for the same array!
    3-element Vector{Int64}:
     1
     2
     3
    

  • 行列の作り方

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
     julia> zeros(Int8, 2, 3)
    2×3 Matrix{Int8}:
     0  0  0
     0  0  0
    
    julia> zeros(Int8, (2, 3))
    2×3 Matrix{Int8}:
     0  0  0
     0  0  0
    
    julia> zeros((2, 3))
    2×3 Matrix{Float64}:
     0.0  0.0  0.0
     0.0  0.0  0.0
    

その他の型

主な文法

Pythonにかなり似ていますし、ここに例示している以外の記述方法もあります。

分岐処理

反復処理

関数

  • 関数 · The Julia Language

  • 宣言

    1
    2
    3
    4
    julia> function f(x, y)
               x + y
           end
    f (generic function with 1 method)
    

  • 利用

    1
    2
    julia> f(2, 3)
    5
    

  • 複数の戻り値を持つ関数の宣言

    1
    2
    3
    4
    julia> function foo(a,b)
               a+b, a*b
           end
    foo (generic function with 1 method)
    

  • 利用

    1
    2
    julia> foo(2,3)
    (5, 6)
    

特殊な機能

マルチスレッド

マルチスレッド化(並列計算):独立した処理を複数のコアで並列に計算することで、処理全体を短時間で終わらせる技術。Juliaにはこれを簡単に実現する機能が組み込まれている。

Juliaでは、Threads.@threadsを for文に前置すると中身の処理が並列化されます。 @threadsはfor文にしか適用できず、必ずしも並列に実行できるわけではありません。

  • 起動時にオプションをつけて使用するスレッド数を指定し、Threads.nthreads()でスレッド数を確認
% > julia --threads auto
                   _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.6.7 (2022-07-19)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> Threads.nthreads()
24
  • 動いているか確認
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
julia> a = zeros(10)
10-element Vector{Float64}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

julia> @time for i = 1:Threads.nthreads()
                  a[i] = Threads.threadid()
              end
  0.000007 seconds

julia> print(a)
[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]

julia> @time Threads.@threads for i = 1:Threads.nthreads()
                  a[i] = Threads.threadid()
              end
  0.045796 seconds (21.55 k allocations: 1.385 MiB, 97.73% compilation time)

julia> print(a)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]
  • 数列を発生させる例1
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
julia> fib(n) = n  1 ? n : fib(n - 2) + fib(n - 1)
fib (generic function with 1 method)

julia> @time println(fib(40))
102334155
  0.639018 seconds (13.52 k allocations: 837.353 KiB, 4.14% compilation time)

julia> @time for _=1:Threads.nthreads()
               println(fib(40))
       end
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
  2.488928 seconds (32 allocations: 960 bytes)

julia> @time Threads.@threads for _=1:Threads.nthreads()
               println(fib(40))
       end
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
102334155
  1.341190 seconds (21.79 k allocations: 1.273 MiB, 0.00% compilation time)

演習

  1. 以下のコマンドで自分のパソコンのスペックを把握
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
julia> splitdir(homedir())[end]
"root"

julia> Threads.nthreads()
24

julia> Sys.cpu_summary()
Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz:
          speed         user         nice          sys         idle          irq
#1-24  2199 MHz   32243805 s    1975966 s    8584258 s  2373398552 s          0 s

julia> Sys.total_memory() / 2^20 / 1000
128.6924609375

julia> Sys.KERNEL
:Linux

julia> Sys.windows_version()
v"0.0.0"
  1. 「数列を発生させる例」を実行し、Threads.@threadsの有無での計算時間を比較

  1. https://github.com/antimon2/julia_imi_workshop2023_tutorial/tree/main