|
setup diary |
プログラム言語で数値計算をしようとするときに,行列を扱う必要がある場合がある.そのやり方が言語毎に特徴があるので,比較してみた.例として,行列を定義して,固有値を固有ベクトルを求めて,対角化を計算する場合について,やり方を見てみよう.
まず,私が数値計算をするときによく使っているRでは,インストールするだけで,行列を使うことができる.逆行列を求めるコマンドがsolveである点と,行列の掛け算が%*%であることに注意すれば,簡単に使うことができる.
a<-t(matrix(1:4,2,2)) r<-eigen(a) r$values r$vectors solve(r$vectors)%*%a%*%r$vectors
次に,近年人気が出てきたjuliaであるが,これもインストールした時点で行列自体は使えて,さらにLinearAlgebraを組み込むことによって,固有値などの計算をすることができる.
a=[1 2; 3 4] using LinearAlgebra r=eigen(a) r.values r.vectors inv(r.vectors)*a*r.vectors
数値計算の分野でもシェアを広げているpythonでは,numpyを使う必要がある.pipなどでこれをインストールできる.私の場合は,debianでaptitudeからpython3-numpyを入れた.numpyをimportして,linalgを使うと計算ができる.行列の掛け算がnp.dot()で書かないといけないのが面倒だったのだが,新しいversionでは@を使えるようになったようだ.
import numpy as np a=np.array([[1,2],[3,4]]) r=np.linalg.eig(a) r[0] r[1] #np.dot(np.dot(np.linalg.inv(r[1]),a),r[1]) np.linalg.inv(r[1])@a@r[1]
最後にrubyであるが,数値計算は比較的苦手である.行列計算はnarrayを使えば良いのだが,固有値の計算などは困難である.そこで,numo-linalgというものを使ってみた.このインストールは少し手間取ったが,以下のようにしたらdebianにインストールすることができた.
sudo apt install liblapacke libopenblas0 sudo apt install git ruby gcc ruby-dev rake make sudo gem install specific_install sudo gem specific_install https://github.com/ruby-numo/numo-narray.git sudo gem install numo-linalg -- --with-backend=openblas --with-openblas-lib=/usr/lib/x86_64-linux-gnu
すると,numo/linalgをrequireしたら計算できるのだが,いちいちNumoと書くのが面倒なので,それをincludeした.narrayの場合には,NMatrixを定義すると,行列の積は*で書けるのだが,numoの場合には,numo-narrayのdotを使って書かないといけないのが面倒に感じた.
require "numo/linalg" include Numo a=NArray[[1,2],[3,4]] r=Linalg.eig(a) r[0] r[2] Linalg.inv(r[2]).dot(a).dot(r[2])
これらの4つの言語について,インストールのしやすさと,使いやすさを主観でまとめると,下の表のようになった.Rとjuliaはそれなりに使いやすいかな.pythonは行列の積が書きやすくなったことにより,昔よりは書きやすくなった.rubyはインストールが面倒だし,methodをうまく定義して,もっと使いやすくできるポテンシャルを秘めているが,まだまだのように感じる.ニーズが無いのかな.
install | use | |
---|---|---|
R | ◎ | ◎ |
julia | ◎ | ◎ |
python | ○ | △→○ |
ruby | △ | ○ |
数値計算をする場合には,Rを中心にやっていくことになりそうだ.juliaも使うようにすると,Rが苦手な処理を書きやすくなるかも知れない.