2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

numo-linalgをmacで動かしてみた

Last updated at Posted at 2018-12-12

Ruby で数値計算をするのは環境構築がしんどそう.
numo/narrayがいい感じになっているので,linalgを入れようとしたんですが...

load error

2.4.0でrequireしたところででた.

{.example}
/Users/bob/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/numo-linalg-0.1.4/lib/numo/linalg/loader.rb:162:in `load_library': cannot find backend library for Numo::Linalg (RuntimeError)
	from /Users/bob/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/numo-linalg-0.1.4/lib/numo/linalg.rb:3:in `<top (required)>'
	from /Users/bob/.rbenv/versions/2.4.3/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in `require'
	from /Users/bob/.rbenv/versions/2.4.3/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require'
	from /Users/bob/.rbenv/versions/2.4.3/lib/ruby/2.4.0/rubygems/core_ext/kernel_require.rb:39:in `require'
	from plot_100.rb:47:in `<main>'

gem install numo-linalg-autoloader
を試すが

ERROR:  Error installing numo-linalg-autoloader:
	ERROR: Failed to build gem native extension.

です.

少し下に書いてあるpath指定のinstallで成功.
numo-autoloaderってもしかして厄介かも.

  1. autoloaderありで,明示的にrequireするか,
  2. なしで,path指定してinstallするか
    の2択かも.

macへのinstall

blas, lapackのinstall

{.example}
> brew install lapack
==> Downloading https://homebrew.bintray.com/bottles/lapack-3.8.0_1.high_sierra.bottle.tar.gz
######################################################################## 100.0%
==> Pouring lapack-3.8.0_1.high_sierra.bottle.tar.gz
==> Caveats

... 中略

==> Summary
🍺  /usr/local/Cellar/lapack/3.8.0_1: 28 files, 10MB


> brew install openblas
Updating Homebrew...
==> Auto-updated Homebrew!

... 中略

==> Summary
🍺  /usr/local/Cellar/openblas/0.3.4: 21 files, 117.8MB

pathのsetを進められるが,numo-linalgには効かない.

numo-linalgのinstall

gem installするときにpathを指定する必要がある.

{.example}
> gem uninstall numo-linalg
> gem install numo-linalg -- --with-openblas-dir=/usr/local/opt/openblas

https://gist.github.com/sonots/6fadc6cbbb170b9c4a0c9396c91a88e1

ruby sample

最初の一歩.順番が大事みたい.

{.ruby}
require 'numo/narray'
require "numo/linalg/use/openblas"
require 'numo/linalg'

p Numo::Linalg::Loader.libs

m = 10
a = Numo::SFloat.new(m).rand
b = Numo::SFloat.new(m).rand
p a*b


p ma = Numo::NArray[[1, 2, 3 ], [3, 4, 5], [6,7,8]]
p Numo::Linalg.eig(ma)
{.example}
["/usr/local/opt/openblas/lib/libopenblas.dylib"]
Numo::SFloat#shape=[10]
[0.0552492, 0.0212455, 0.241172, 0.201437, 0.401844, 0.586427, 0.344554, ...]
Numo::Int32#shape=[3,3]
[[1, 2, 3], 
 [3, 4, 5], 
 [6, 7, 8]]
[Numo::DComplex#shape=[3]
[14.0664+0i, -1.06637+0i, 3.43928e-17+0i], nil, Numo::DComplex#shape=[3,3]
[[0.265648+0i, 0.744429+0i, 0.408248+0i], 
 [0.491207+0i, 0.190701+0i, -0.816497+0i], 
 [0.829546+0i, -0.63989+0i, 0.408248+0i]]]

narray 配列操作

{.example}
flatten([dim0,dim1,...])
transpose([dim0,dim1,...])
expand_dims(dim)
diagonal(offset, [ax1,ax2])
reshape

narray 配列演算

NArray には以下の演算メソッドがある. '+,-,*,/,%,divmod,**,-@,abs'

narray 統計メソッド

次の統計メソッドが定義されている. sum, prod, mean, stddev, var, rms,
min, min_index, max, max_index, minmax, cumsum, cumprod, sort,
sort_index, median

linalgの関数

Matrix and vector products
: dot, matmul

Decomposition
: lu, lu_fact, lu_inv, lu_solve, ldl, cholesky, cho_fact,
cho_inv, cho_solve, qr, svd, svdvals, orth, null_space

Matrix eigenvalues
: eig, eigh, eigvals, eigvalsh

Norms and other numbers
: norm, cond, det, slogdet, matrix_rank, matrix_power

Solving equations and inverting matrices
: solve, lstsq, inv, pinv

ruby sample II

下の例はnumo/linalgを使って,データフィッティングして
numo/gnuplotでグラフを書かせた例.

{.ruby}
require 'numo/gnuplot'
require 'numo/narray'

pairs = []
File.readlines("data.txt").each do |line|
  vol, _d, _d, _d, _d, ene = line.split(/\s+/)
  pairs << [vol, ene]
end
pairs.sort!{|a,b| a[0].to_f <=> b[0].to_f }
p pairs

x,y=[],[]
pairs.each do |pair|
  x << pair[0].to_f
  y << pair[1].to_f
end

require "numo/narray"

def ff(x,i)
  x**i
end

m = 5
n = 3
av = Numo::DFloat.zeros(m, n)
yy = Numo::DFloat.zeros(m)
n.times do |i|
  m.times do |j|
    av[j,i]=ff(x[j],i)
    yy[j] = y[j]
  end
end

require 'numo/linalg'
p ai = Numo::Linalg.inv(Numo::Linalg.dot(av.transpose,av))
p b = Numo::Linalg.dot(av.transpose,yy)
p vars = Numo::Linalg.dot(ai,b)

eq = ''
vars.each_with_index do |var, i|
  eq << " + " + sprintf("%+6.2f",var) + "*x** #{i} "
end
#p eq = "#{vars[0]} + #{vars[1]}*x + #{vars[2]}*x**2"

Numo.gnuplot do
  set output: 'e_v.gif'
  set term: 'gif'
  set xlabel: 'Volume [%]'
  set ylabel: 'Energy [eV]'
  plot [x, y, w: :lp, pt: 6],
  [eq, w:"lines"]
end

system 'open ./e_v.gif'
{.example}
[["-2.00", "-561.7895200000"], ["-1.00", "-564.1426100000"], ["+0.00", "-565.4727300000"], ["+1.00", "-565.8513000000"], ["+2.00", "-565.3645700000"]]
Numo::DFloat#shape=[3,3]
[[0.485714, -0, -0.142857], 
 [0, 0.1, 0], 
 [-0.142857, 0, 0.0714286]]
Numo::DFloat#shape=[3]
[-2822.62, -8.85879, -5638.61]
Numo::DFloat#shape=[3]
[-565.471, -0.885879, 0.473656]

e_v.gif

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?