GSLLの導入(Roswell)

Posted on May 5, 2021

既にあるgsllを入れる(quicklisp) - Nosの日記(2012)の二番煎じな内容。

以下はUbuntu20.04(WSL2)でRoswellが入ってるものとしての説明。 処理系はSBCL。

GSLLとは

数値計算のライブラリGNU Scientific Library (GSL)をCommon Lispから使えるようにしたもの。 GNU Scientific Library for Lisp、略してGSLL。 公式サイトはGNU Scientific Library for Lisp。 もともとのGSLはGSL - GNU Scientific Library

基本的に公式を読めば解決。公式を読もう。

GSLLの導入の前に

公式にある通り、まずは

sudo apt install libgsl0-dev libffi-dev

で必要なパッケージをインストールする(libgsl0-devで実際にインストールされるのはlibgsl-devと表示された)。

GSLLの導入

必要なパッケージは上のコマンドでインストールされたはずなので、Roswell環境下のQuicklispが使える状態で

(ql:quickload :gsll)

を実行することでGSLLが使えるようになる。

ユニットテスト

上述のWebサイトを真似てユニットテストを実行してみると

; SLIME 2.24

CL-USER> (ql:quickload :lisp-unit)
To load "lisp-unit":
  Load 1 ASDF system:
    lisp-unit
; Loading "lisp-unit"

(:LISP-UNIT)

CL-USER> (ql:quickload :gsll)
To load "gsll":
  Load 1 ASDF system:
    gsll
; Loading "gsll"
..................
(:GSLL)

CL-USER> (in-package :gsll)
#<PACKAGE "GSLL">

GSL> (lisp-unit:run-tests)
Unit Test Summary
 | 3994 assertions total
 | 3902 passed
 | 92 failed
 | 4 execution errors
 | 0 missing tests

#<TEST-RESULTS-DB Total(3994) Passed(3902) Failed(92) Errors(4)>

という結果になった。

GSLLの初歩的な使い方

それほど使いこなせているわけではないので、初歩的な使い方のみ述べる。 GSLLは基本的にdouble-float用のパッケージなので

(setq *read-default-float-format* 'double-float)

で特に指定していない時の浮動小数点数をdouble-floatにしておく。

GSLのドキュメント(英語であればGSL - GNU Scientific Libraryの半ばに、日本語訳はGSL 1.15 リファレンス・マニュアル 日本語訳)が充実しているので、基本的にはここで必要なものを調べて、対応するCommon lispでの名前を

(gsl-lookup "gsl_sf_zeta_e")
ZETA
T

のように検索する。

あとは普通にdescribeを使って

GSL> (describe 'zeta)
GSLL:ZETA
  [symbol]

ZETA names a generic function:
  Lambda-list: (X)
  Derived type: (FUNCTION (T) *)
  Documentation:
    The Riemann zeta function zeta(n).
  Method-combination: STANDARD
  Methods:
    (ZETA (FLOAT))
      Documentation:
        The Riemann zeta function zeta(s) for arbitrary s, s ne 1.
    (ZETA (INTEGER))
      Documentation:
        The Riemann zeta function zeta(n) for integer n, n ne 1.
  Source file: /home/shimo/.roswell/lisp/quicklisp/dists/quicklisp/software/gsll-quicklisp-eeeda841-git/special-functions/zeta.lisp
; No value

のようにある程度の使い方の確認が出来る。

半無限区間の積分、例えばガウス積分は

GSL> (setq *read-default-float-format* 'double-float)
DOUBLE-FLOAT

GSL> *default-absolute-error*
1.0e-5

GSL> (* 2 (integration-qagiu (lambda (x) (exp (* -1.0 x x))) 0.0))
1.7724538509067373

GSL> (sqrt pi)
1.7724538509055159

GSL> (setq  *default-absolute-error* 1.0e-8)
1.0e-8

GSL> (* 2 (integration-qagiu (lambda (x) (exp (* -1.0 x x))) 0.0))
1.7724538509055159

のように実行できる。

行列演算の扱いの導入については上述のgsllを入れる(quicklisp) - Nosの日記に載っている。

GSL> (setq grid:*default-grid-type* 'grid:foreign-array)
GRID:FOREIGN-ARRAY

GSL> (matrix-product #m(1 2 ^ 3 4) #m(5 6 ^ 7 8))
#m((19.000000000000000d0 22.000000000000000d0)
(43.000000000000000d0 50.000000000000000d0))