Juliaメモ
頻繁に混同するjuliaとpython (numpy)とfortran
python,numpy | julia | fortran | |
---|---|---|---|
配列の形状 | np.shape | size | |
配列の全要素数 | np.size | length | |
配列の次元 | np.ndim | ndims | |
配列の型の確認 | .dtype | typeof | |
sumやmeanにおける軸の指定 | axis= | dims= | dim= |
配列の最大、最小 | np.max, np.min | maximum, minimum | maxval, minval |
最大、最小の場所 | np.argmax, np.argmin | argmax, argmin | maxloc, minloc |
ゼロ要素の配列 | np.zeros | zeros | |
(最初、最後、間隔) を指定した配列 | np.arange | range(step=) | |
(最初、最後、要素数) を指定した配列 | np.linspace | range(length=) | |
整数の割り算 | A//B | A÷B | A/B |
文字の結合 | A+B | A*B | A//B |
配列の巡回シフト | np.roll | circshift | cshift |
数値→文字 | str | string | write |
ループ強制終了 | break | break | exit |
ループの始めに戻る | continue | continue | cycle |
剰余 | % | % | mod |
論理和、論理積 | or, and | ||, && | or, and |
\((-\pi,\pi]\)を返す逆正接 | np.arctan2(y,x) | atan(y,x) | atan2(y,x) |
手っ取り早く高速化 (経験に基づいて書いている)
プログラムはすべて関数化する
関数の外のプログラムは高速化の恩恵を受けにくいので関数の外でなにか計算するのは避ける。グローバル変数は使わない
関数の外で変数を定義すると、すべての関数でその変数を使うことができる。値を変更しない定数にはconstを付けておく
例外としてconstによって与えられた定数は関数の外側であっても遅くなる影響を受けない。配列を別の関数に渡すときは引数にする
グローバル変数が使えない以上、関数から別の関数へ配列を渡すには関数の引数として渡す。用いる配列 (ベクトルや行列) は全て最初に定義しておき、上書き更新する
JuliaやPythonの特徴として、計算の途中でベクトルや行列を簡単に新規作成することができるという点があるが、高速を目指すのであれば、必要なベクトルや行列は最初に全て定義しておき、それを上書きする形で用いる。in placeの演算が用意されているときは積極的に使う
in place演算とout of place演算ではin-placeの方が速い場合が多い 。in placeの演算が用意されていないときは配列式ではなくforを使う
Pythonではforをなるべく使わず、配列の式は配列のままで書くことが推奨されるが、Juliaは逆にforを使って成分毎に計算したほうが速いケースがよくある。要はある程度fortranを意識して書いたほうが速いということか。
I / O
(Fortranによくある) 空白で区切られたテキストファイルの読み込み
using CSV using DataFrames data = CSV.read("file.txt", delim = " ", ignorerepeated = true)
アスキーデータのフォーマット付き書き出し
実数が5つの例using Printf fmt1 = Printf.Format("%16s" ^ 5 * "\n") fmt2 = Printf.Format("%16.6e" ^ 5) open("value.txt", "w") do file Printf.format(file, fmt1, "π", "ℯ", "√2", "(1 + √5) / 2", "ζ(2)") Printf.format(file, fmt2, π, ℯ, √2, 0.5 * (1 + √5), π ^ 2 / 6) endvalue.txtの中身は
π ℯ √2 (1 + √5) / 2 ζ(2) 3.141593e+00 2.718282e+00 1.414214e+00 1.618034e+00 3.321928e+00
バイナリデータの読み書き
書き出し
using Random # 乱数のために呼び出しているだけなので必要なし
using HDF5
v1 = rand(5)
v2 = rand(6, 3)
h5open("value.bin", "w") do file
write(file, "Vec", v1)
write(file, "Mat", v2)
end
読み込み
using HDF5
v1 = zeros(5)
v2 = zeros(ComplexF64, 6, 3) # 書き出したときは実数だが、読み込むときに複素数の実部として読み込むことも可能
h5open("value.bin", "r") do file
v1 .= read(file, "Vec")
v2 .= read(file, "Mat")
end
すぐに書き込み
flush(file)ですぐに書き込まれる。fileはファイル識別子。標準出力の場合はstdout。