はじめに
RubyはPythonに比べると数値計算に関するライブラリが少ないです。(正確には、ライブラリは存在していても、作成日が古いものが多いです。)既存のライブラリでは、numo-gslがオススメです。これはGSL(Gnu Scientific Library)をNumo::NArrayと一緒に使えるようにするものです。
GSLはCで書かれていますが、一般に数値解析ではC++のライブラリが充実しています。R言語も、多くの処理はC++で実装されています。RubyからもC++の資産を活用できないでしょうか?
今回は統計的仮説検定ができるライブラリがRubyではほとんどない1ので、ALGLIBのC++バインディングの作成してみました。
GitHub: ruby-alglib (作りかけ)
バインディグ作成と心の損益分岐点
個人の感想になりますが、私の場合は、だいたいバインディングのプロトタイプを作成する時間が数時間〜1日程度でおさまると、精神的な採算がとれます。(これは人によって違うと思います)
バインディングを作成すると、APIを観察することになり学習効果が見込めます。また成果物はRubyのGemという形ではっきりと残ります。それを加味すると、半日〜1日以内にプロトタイプを作ることができれば、「それはPythonやRを使った方がはやい」という心の意見に対して、Gem作成が許容されると思います。
今回ALGLIBのバインディングを作ってみて、Rubyバインディングを作りやすい特徴がそろっていると感じたので、その理由をまとめます。
ALGLIBとは
ALGLIBは、クロスプラットフォームおよびオープンソースな数値解析・データ処理ライブラリ。
ALGLIBは1999年にから長期間にわたって地道な開発が続けられており、年に1~3回程度、アップデートされている。(Wikipedia)
Riceとは
RubyからC++の呼び出しは、Riceを利用しました。
ALGLIBのバインディングを作るのが簡単な理由
ALGLIBのバインディングを作成が簡単だった点をまとめます。
メモリ管理を考慮しなくてよい
これ、大きいです。
Ruby言語のバインディングを作る時に一番難しいのは、メモリーの管理です。メモリーが開放されないとメモリーリークしますし、参照しようとした時にメモリがすでに開放されていると、セグメンテーション違反が発生します。バインディングを作成していると、これらの問題は頻繁に発生し、Gemの作者を悩ませます。(正直に言うと、自分は完全には理解できていません)
しかし、ALGLIBは「クラス」を使わずに提供されている関数がすくなくありませn。これらはメモリについて考える必要はありません。関数をモジュールファンクションとしてラップするだけです。
AIはバインディングの作成が大得意!
バインディングのコードは、ボイラープレートコード(単純なコードの繰り返し)が続くことが多いですが、AIはこういったコードの記載が非常に得意ですね。いくつかのサンプルを提供すれば、あとは関数のシグネチャーを渡すと、たちどころにバインディング用のコードを生成してくれます。
人間はその確認と、修正を行うだけでよいので、コーディングの時間が非常に短くなります。冒頭で「半日〜1日」でプロトタイプが完成することが、Gemを作成することが許容できる損益分岐点と書きましたが、AIの登場で、この目標は達成しやすくなりました。
依存ライブラリが少ない
これはALGLIBの特徴であり、他のC++の数値計算ライブラリには当てはまらないと思います。
C++のライブラリはCMakeなどを使ってビルドすることが多い。通常、どのようにプロジェクトを構成して、どのように GitHub ActionsでCIを回せばいいか頭を悩ませることになります。しかし、ALGLIBは依存するライブラリがなかったので extconf.rb
を書くのが簡単でした。
そもそもバインディングは、難しいアルゴリズムを自分で実装せずに、インターフェースから呼び出すものですから、難しいはずがありません。C拡張作成の難しさの大半は、コンパイルの難しさから来ています。
ライセンスに注意
このように、C++で書かれた数値計算用ライブラリALGLIBにはバインディングを作成しやすい特徴が揃っていることがわかりました。しかし注意しなければならないのはライセンスです。ALGLIBのフリーエディションはGPLで配布されています。これは、ALGLIBのライブラリにリンクするGemもGPLの影響が及ぶということを意味しています。
FAQを見るとサーバー上で動作させても問題ないということですが、商用利用では注意が必要です。冒頭で紹介したGNU Scientific LibraryのライセンスもGPLですから、一般的な傾向として、数値計算ライブラリは自由なライセンスで公開されているものが多いかもしれません。私はGPLでも全く困りませんが、中には困る人もいるかもしれませんのでご注意ください。
まとめ
- Rubyで数値計算をしたいときはC++のバインディングの作成が有効
- 半日〜1日程度でプロトタイプを作りたい
- 数値計算用ライブラリはバインディングを作りやすい特徴が揃っている
- ライブラリは関数を提供しているので、メモリ管理の必要性が薄い
- AIはバインディング用のコードを生成するのが得意
- 依存ライブラリが少ないとコンパイルが楽
- ライセンスは要注意
この記事は以上です。
-
https://github.com/SciRuby/statsample の開発は5年前でとまっている ↩