部分行列[Eigen vs Arrayfire]
2021/04/05 追記:
記述に誤りがあったので修正しました。
大変申し訳ありません。
六花です。
部分行列についてArrayfireの公式サイト(英語)しか見当たらなかったので、Eigenの実装と照らし合わせつつ、記録を残そうと思います。
■環境
Visual Studio Community 2019 Version 16.4.0
Eigen 3.3.7
Arrayfire 3.6.4
■Eigenの部分行列
Eigenにおける部分行列の指定方法は、二種類あります。
Eigen::MatrixXf mat(100, 100);
// どちらも左上座標(0, 5)から(10,15)の大きさの部分行列の参照を得る。
auto block_A = mat.block<10,15>(0, 5);
auto block_B = mat.block(0, 5, 10, 15);
■Arrayfireの部分行列
Arrayfireで同じような部分行列を得るには、af::seqを使って定義します。
af::array mat = af::randu(100, 100);
// 左上座標(0, 5)から(10,15)の大きさの部分行列の参照を得る。
// つまり、行方向に0~(10-1)、列方向に5~(15-1)の範囲の行列を指定している。
//auto block_A = mat(af::seq(0, 10-1), af::seq(5, 15-1));
// 2021/04/05 追記 日本語と違う式を書いてしまい申し訳ありませんでした。
auto block_A = mat(af::seq(0, 0 + 10-1), af::seq(5, 5 + 15-1));
// リファレンス(https://arrayfire.org/docs/classaf_1_1seq.htm)より
// [begin, end, step]
seq a0(10); // [0, 9, 1] => 0, 1, 2....9
seq a(10, 20); // [10, 20, 1] => 10, 11, 12....20
seq b(10, 20, 2); // [10, 20, 2] => 10, 12, 14....20
seq c(-5, 5); // [-5, 5, 1] => -5, -4, -3....0, 1....5
seq d(-5, -15, -1); // [-5,-15, -1] => -5, -6, -7....-15
seq e(-15, -5, 1); // [-15, -5, 1] => -15, -14, -13....-5
注意しなければならないのは、以下の三つのaf::seqが同じ意味を持つことです。
af::seq(10);
af::seq(0, 9);
af::seq(0, 9, 1);
一つ目の引数が始点、二つ目の引数が終点、三つ目の引数がBASICのFOR文にあったstepです。
引数が一つしか指定されていないとき、終点は-1されます。
これらの書き方を混ぜると非常にややこしいので、通常は二つの引数を指定する書き方を使うことになると思います。
私が知っている中で、行列の座標を指定できるものは以下のものがあります。
・int // 負の値を入れると最終の要素から逆に数える……らしい
・af::end // その次元の最終の要素
・af::array // 1行1列のもので、参照型ではいけないので自動変数に入れてから使う
・af::seq
・af::span // af::seqの特殊な値で、af::seq(その次元の要素数)と同義です。mat(af::span, 0)では0列目のn行1列の部分行列の参照が戻ります。