このブログを検索

2019年9月14日土曜日

【C++】 Eigen行列の積

【C++】 Eigen行列の積
(2019年9月14日)


■使用ソフト
・Visual Studio Community 2019


■言語
・C/C++


■Windows SDK バージョン
・10.0.17763.0
 ※Windows SDK バージョンの変更方法


■使用ライブラリ
・Eigen 3.3.7
 ※Eigen行列計算ライブラリ導入方法


■手順
1.以下をベースにコード変更する。
【C++】 メッセージボックスの作成

2.C++ファイル(.cpp)を以下のとおり変更する。
#include <windows.h>
#include <Eigen/Core>
#include <chrono>
#include <vector>

//------------------------------------------------------------
// MultMtx()関数:行列の積
//------------------------------------------------------------
void MultMtx(std::vector<std::vector<double> >& mtx1, std::vector<std::vector<double> >& mtx2, std::vector<std::vector<double> >& resultMtx)
{
    for (int i = 0; i < (int)mtx1.size(); i++)
    {
        for (int j = 0; j < (int)mtx2[0].size(); j++)
        {
            double sum = 0;
            for (int k = 0; k < (int)mtx2.size(); k++)
            {
                sum += mtx1[i][k] * mtx2[k][j];
            }
            resultMtx[i][j] = sum;
        }
    }
}

//--------------------------------------------------------------------------------------
// wWinMain()関数:エントリーポイント
//--------------------------------------------------------------------------------------
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WCHAR wcText[256];

    //------------------------------------------------------------
    // Eigenを使用した行列の積
    //------------------------------------------------------------
    auto Start = std::chrono::system_clock::now();//時間計測開始

    Eigen::MatrixXd mat1 = Eigen::MatrixXd::Constant(100, 100, 0.011);
    Eigen::MatrixXd mat2 = Eigen::MatrixXd::Constant(100, 100, 0.011);
    
    for (int i = 0; i < 100; i++)
    {
        mat1 *= mat2;
    }
    
    auto End = std::chrono::system_clock::now();//時間計測終了
    auto Calc = End - Start;
    auto Time = std::chrono::duration_cast<std::chrono::milliseconds>(Calc).count();

    //------------------------------------------------------------
    // std::vectorを使用した行列の積
    //------------------------------------------------------------
    auto Start2 = std::chrono::system_clock::now();//時間計測開始

    std::vector<std::vector<double> > mat3(100, std::vector<double>(100, 0.011));
    std::vector<std::vector<double> > mat4(100, std::vector<double>(100, 0.011));
    std::vector<std::vector<double> > result(100, std::vector<double>(100));
    
    for (int i = 0; i < 100; i++)
    {
        MultMtx(mat3, mat4, result);
        mat3 = result;
    }

    auto End2 = std::chrono::system_clock::now();//時間計測終了
    auto Calc2 = End2 - Start2;
    auto Time2 = std::chrono::duration_cast<std::chrono::milliseconds>(Calc2).count();

    //------------------------------------------------------------
    // 出力
    //------------------------------------------------------------
    swprintf(wcText, 256, L"%lf, %lld, %lf, %lld", mat1(0, 0), Time, mat3[0][0], Time2);

    MessageBox(NULL, wcText, L"Eigen", MB_OK);

    return 0;
}

3.実行結果(Eigenを使用した行列の積とstd::vectorを使用した行列の積の速度比較)
【Debugモードの場合】
・Eigenを使用した行列の積→5.729秒
・std::vectorを使用した行列の積→8.552秒

【Releaseモードの場合】
・Eigenを使用した行列の積→0.025秒
・std::vectorを使用した行列の積→0.09秒

4.参考文献
ベクトル/行列演算の定番ライブラリEigen

【C++】Eigen関数一覧

C言語による標準アルゴリズム辞典

0 件のコメント:

コメントを投稿