Edited at

[C++] 行列演算ライブラリ「Eigen」のリファレンスを読む際の注意

More than 3 years have passed since last update.


結論

密な(通常使う)1行列型(Matrix**)やベクトル型(Vector**, RowVector**)に対して使えるメソッドは、以下のページを見ればよい。


経緯

仕事の関係で、C++の行列演算ライブラリ「Eigen」を利用している。

これのリファレンスのうち、行列型に使えるメソッドを調べたかったのだが、最初に目が行ったEigen::MatrixBase型のリファレンスを見ても、当たり前にありそうな「行数・列数を得るためのメソッド」が見当たらなかったのである。

「これはおそらく継承関係の都合で表示されていないんだろうな」と思いつつ、とりあえずその方法は別の場所で把握したのでしばらく放置していたのだが、思い立って「じゃあ使えるメソッドを全部見るにはどうすればいいんだろう」と考えて調べてみた。


調査の流れ

まず、行列型はどのような継承関係にあるのかを把握しないとならない。これはリファレンス内に、まさにそのままの名称のページ「The class hierarchy」というのがあった。

これを見ると、継承関係は親クラスから順に


  • EigenBase<Matrix>

  • DenseCoeffsBase<Matrix>

  • DenseBase<Matrix>

  • MatrixBase<Matrix>

  • PlainObjectBase<Matrix>

  • Matrix

となっていた。ただ、リファレンスを見ていると、DenseBaseにあるものはMatrixBaseにも基本的にあったし、PlainObjectBaseにあるものはMatrixにも基本的にあった(オーバーロードの関係で若干の差はあるが、それ以外は一致していた)。なので見る必要があるのはDenseBasePlainObjectBaseを除いた四つということになる。

ちなみに、先程の「行数・列数を得るためのメソッド」はEigenBaseクラスで定義されていたとわかったわけなのだが、このクラスはAPIとして提供されているメソッドが非常に少なく(Eigen::DenseCoeffsBase型のリファレンス)、主に使うのはrows(行数)、cols(列数)、size(全要素数)の三つのメソッドぐらいであろう。またDenseCoeffsBaseクラスについても、定義されているもので主に使うのはほとんど「●行■列の要素を取得」などであった。

こういった形で継承関係を設計することで、柔軟性の高いAPIの提供ができるというのはもちろんあるのでしょうけど、リファレンスの一覧性が低いのは改善してくれるとうれしいな、という話でした。






  1. Eigenにおける行列やベクトルの表現方法には、各要素にメモリをすべて割り当てる「密な(Dense)」ものと、0でない要素のみにメモリを割り当てる「疎な(Sparse)」ものが存在する。Sparseのほうは、0でない要素のみにメモリを割り当てるとはいえ「どこに0でない要素があるか」の情報も必要なため、単純にDenseに比べて要素数の比でメモリ消費が減るわけではなく、また各種演算のコストも高くなる。そのため、本当にかなりの大部分を0が占めるという場合でなければDenseなものを使えばよい。 



  2. それを表現するためのクラスもある。実際の演算を本当に必要になったときに遅延評価するための機構である。