目次
はじめに
PythonのNumpyやScipy、
またはMATLABなどを使って、
プロトタイプを作成し、
そのシステムをC++に移植しようとすると、
C++の行列演算ライブラリEigenの関数(API)の少なさに
悲しくなることがあります。(NumpyやMATLABがすごいだけなのですが...)
そこで、NumpyやScipy, MATLABの便利関数を
Eigenベースで実装したC++ヘッダライブラリを作り始めました。
このライブラリはEigenのみに依存しており、
またヘッダライブラリなのでincludeするだけで使えます。
またライセンスはMITです。
この記事では主要なAPIを日本語で紹介したいと思います。
また、もし実装してもらいたい関数があれば、
この記事のコメントか、GitHubのissueで教えて頂けると嬉しいです。
関数(APIs)
下記が各関数の説明です。
テストコードである numpycppTest.cpp
を見れもらえると、使い方がわかりやすいと思います。
reshape
データの中身をそのままで、
ある行列のサイズを変更した行列を生成する関数です。
numpy.reshape をベースにしています。
see: https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html
Eigen::MatrixXf x(6,1); x<<1.0,2.0,3.0,4.0,5.0,6.0; PRINT(x); Eigen::MatrixXf rx = reshape(x,2,3); PRINT(rx); //rx: //1 3 5 //2 4 6 Eigen::MatrixXf rx2 = reshape(x,3,2); PRINT(rx2); //rx2: //1 4 //2 5 //3 6
isdiag
入力された行列が対角行列であるかを判定する関数です。
また、入力された関数が正方行列で無い場合は、
falseが返ります。
MATLABのisdiag 行列をベースにしています。
Eigen::MatrixXf x(3,1); x<<5.0,6.0,7.0; bool flag = isdiag(x);//return false Eigen::MatrixXf x2(2,2); x2<<5.0,6.0,7.0,1.0; bool flag2 = isdiag(x2);//return false Eigen::MatrixXf x3(3,3); x3<<1.0,0.0,0.0, 0.0,1.0,0.0, 0.0,0.0,1.0; bool flag3 = isdiag(x3);//return true
vstack
垂直方向に行列を繋げる関数です。
numpy.vstackをベースにしています。
numpy.vstack — NumPy v1.14 Manual
Eigen::MatrixXf x(3,1); x<<5.0, 6.0, 7.0; Eigen::MatrixXf y(3,1); y<<1.0, 10.0, 100.0; Eigen::MatrixXf a = vstack(x,y); //ans<<5, // 6, // 7, // 1, // 10, // 100;
hstack
水平方向に行列を繋げる関数です。
numpy.hstackをベースにしています。
numpy.hstack — NumPy v1.14 Manual
Eigen::MatrixXf x(3,1); x<<5.0, 6.0, 7.0; Eigen::MatrixXf y(3,1); y<<1.0, 10.0, 100.0; Eigen::MatrixXf a = hstack(x,y); //a= //5 1 //6 10 //7 100
kron
クロネッカーのテンソル積を計算します。
numpy.kron をベースにしています。
numpy.kron — NumPy v1.14 Manual
Eigen::MatrixXf x(1,3); x<<1.0,10.0,100.0; Eigen::MatrixXf y(1,3); y<<5.0,6.0,7.0; Eigen::MatrixXf a = kron(x,y); // a = [5 50 500 6 60 600 7 70 700]
block_diag
与えられた行列から、区分対角行列を計算します。
入力された行列を対角に配置し、残りの要素は0に初期化されます。
scipy.linalg.block_diag をベースにしています。
scipy.linalg.block_diag — SciPy v0.14.0 Reference Guide
Eigen::MatrixXf x(3,1); x<<5.0, 6.0, 7.0; Eigen::MatrixXf y(1,3); y<<1.0,10.0,100.0; Eigen::MatrixXf a = block_diag(x,y); //a= 5, 0, 0, 0, // 6, 0, 0, 0, // 7, 0, 0, 0, // 0, 1, 10,100;
参考資料
MyEnigma Supporters
もしこの記事が参考になり、
ブログをサポートしたいと思われた方は、
こちらからよろしくお願いします。