結論
密な(通常使う)1行列型(Matrix**
)やベクトル型(Vector**
, RowVector**
)に対して使えるメソッドは、以下のページを見ればよい。
-
Eigen::Matrix型のリファレンス
- (「行列同士の演算結果」2などではない)単一の行列でないとできない処理はここにある。Map処理(全要素に対する繰り返し処理)など。
-
Eigen::MatrixBase型のリファレンス
- 一番お世話になるのはたぶんここ。行列に対する演算(加算、乗算、内積、ノルムなど)は主にここを見ればよい。
-
Eigen::DenseCoeffsBase型のリファレンス
- メソッド数少数。「●行■列の要素を取得」などのメソッドはここ。
-
Eigen::EigenBase型のリファレンス
- メソッド数少数。「行列の行数・列数を取得」などのメソッドはここ。
経緯
仕事の関係で、C++の行列演算ライブラリ「Eigen」を利用している。
これのリファレンスのうち、行列型に使えるメソッドを調べたかったのだが、最初に目が行ったEigen::MatrixBase
型のリファレンスを見ても、当たり前にありそうな「行数・列数を得るためのメソッド」が見当たらなかったのである。
「これはおそらく継承関係の都合で表示されていないんだろうな」と思いつつ、とりあえずその方法は別の場所で把握したのでしばらく放置していたのだが、思い立って「じゃあ使えるメソッドを全部見るにはどうすればいいんだろう」と考えて調べてみた。
調査の流れ
まず、行列型はどのような継承関係にあるのかを把握しないとならない。これはリファレンス内に、まさにそのままの名称のページ「The class hierarchy」というのがあった。
これを見ると、継承関係は親クラスから順に
EigenBase<Matrix>
DenseCoeffsBase<Matrix>
DenseBase<Matrix>
MatrixBase<Matrix>
PlainObjectBase<Matrix>
Matrix
となっていた。ただ、リファレンスを見ていると、DenseBase
にあるものはMatrixBase
にも基本的にあったし、PlainObjectBase
にあるものはMatrix
にも基本的にあった(オーバーロードの関係で若干の差はあるが、それ以外は一致していた)。なので見る必要があるのはDenseBase
とPlainObjectBase
を除いた四つということになる。
ちなみに、先程の「行数・列数を得るためのメソッド」はEigenBase
クラスで定義されていたとわかったわけなのだが、このクラスはAPIとして提供されているメソッドが非常に少なく(Eigen::DenseCoeffsBase型のリファレンス)、主に使うのはrows
(行数)、cols
(列数)、size
(全要素数)の三つのメソッドぐらいであろう。またDenseCoeffsBase
クラスについても、定義されているもので主に使うのはほとんど「●行■列の要素を取得」などであった。
こういった形で継承関係を設計することで、柔軟性の高いAPIの提供ができるというのはもちろんあるのでしょうけど、リファレンスの一覧性が低いのは改善してくれるとうれしいな、という話でした。
-
Eigenにおける行列やベクトルの表現方法には、各要素にメモリをすべて割り当てる「密な(Dense)」ものと、0でない要素のみにメモリを割り当てる「疎な(Sparse)」ものが存在する。Sparseのほうは、0でない要素のみにメモリを割り当てるとはいえ「どこに0でない要素があるか」の情報も必要なため、単純にDenseに比べて要素数の比でメモリ消費が減るわけではなく、また各種演算のコストも高くなる。そのため、本当にかなりの大部分を0が占めるという場合でなければDenseなものを使えばよい。 ↩
-
それを表現するためのクラスもある。実際の演算を本当に必要になったときに遅延評価するための機構である。 ↩