EigenのMatrixXdの中身を壊さずサイズを変更する方法


EigenのMatrixXdの中身を壊さずサイズを変更する方法

行列計算に用いられるc++用のライブラリEigenで

行列Eigen::MatrixXdのサイズを変更する際はよくメンバ関数resizeを使いますが

どうやら中身が変更されてしまうようです。

どうしても中身を壊さずサイズを変更したい場合は

conservativeResize

を使えば良いそう。

http://eigen.tuxfamily.org/dox/classEigen_1_1PlainObjectBase.html

 

ちなみに計算時間は圧倒的にconservativeResizeが遅く、

10000回同じ処理をした場合

約900倍の時間がかかりました。

 

#include <iostream>
#include <Eigen/Dense>
#include <sys/time.h> 

int main(int argc,char* argv[])
{

	Eigen::MatrixXd mat1(4,4);
	mat1 << 0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15;
	Eigen::MatrixXd mat2 = mat1;
	std::cout << mat1 << "\n";

	// resize
	mat1.resize(4,5);
	std::cout << "Eigen::MatrixXd::resize\n";
	std::cout << mat1 << "\n";
	// conservativeResize
	mat2.conservativeResize(4,5);
	std::cout << "Eigen::MatrixXd::conservativeResize\n";
	std::cout << mat2 << "\n";

	struct timeval s,e;
	int iterationNum = 10000;
	// resize
	gettimeofday(&s, NULL);                         // 開始時の時刻取得
	for( int i=0; i<iterationNum; ++i )
	{
		mat1.resize(i,1);
	}
	gettimeofday(&e, NULL);                         // 終了時の時刻取得
	double time1 = ((e.tv_sec - s.tv_sec) + (e.tv_usec - s.tv_usec)*1.0E-6);
	std::cout << "resize calculation time:" << time1 << "\n";
	// conservativeResize
	gettimeofday(&s, NULL);                         // 開始時の時刻取得
	for( int i=0; i<iterationNum; ++i )
	{
		mat2.conservativeResize(i,1);
	}
	gettimeofday(&e, NULL);                         // 終了時の時刻取得
	double time2 = ((e.tv_sec - s.tv_sec) + (e.tv_usec - s.tv_usec)*1.0E-6);
	std::cout << "conservativeResize calculation time:" << time2 << "\n";

	std::cout << "ratio:" << time2/time1 << "\n";

	return 0;
}

実行結果

 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15
Eigen::MatrixXd::resize
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Eigen::MatrixXd::conservativeResize
 0  1  2  3  0
 4  5  6  7  0
 8  9 10 11  0
12 13 14 15  0
resize calculation time:0.001745
conservativeResize calculation time:1.58885
ratio:910.515

About Author

ラプリエム

ラプリエム

奈良のどこかに住んでる院生 プログラミングが趣味?
Twitter

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>