MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

Numpy, Scipy, MATLABの便利関数を実装したC++の行列演算ライブラリnumpycpp

目次

はじめに

PythonのNumpyやScipy、

またはMATLABなどを使って、

プロトタイプを作成し、

そのシステムをC++に移植しようとすると、

C++の行列演算ライブラリEigenの関数(API)の少なさに

悲しくなることがあります。(NumpyやMATLABがすごいだけなのですが...)

  

そこで、NumpyやScipy, MATLABの便利関数を

Eigenベースで実装したC++ヘッダライブラリを作り始めました。

github.com

 

このライブラリは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 行列をベースにしています。

www.mathworks.com

 

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.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com