About
Contents
STL
Android
Eigen
enchant.js
Firefox OS
OpenGL
OpenGL ES 2.0
pukiwiki
UE4
Unity
Windows Phone
Xamarin
Materials Link
その他
PR
STL
Android
Eigen
enchant.js
Firefox OS
OpenGL
OpenGL ES 2.0
pukiwiki
UE4
Unity
Windows Phone
Xamarin
行列やベクトルを便利に扱える、Eigenの組み込み方法と基本的な使い方を学びます。
ソースを書く際は「Eigen/Dense」をインクルードしておけば行列やベクトルの一通りの機能が使えます。 メモリを節約できる特殊なスパース行列を使う場合は「Eigen/Sparse」をインクルードします。
以下のテストコードでは、冗長なコード簡略化のために簡単なマクロとEigen名前空間を定義しています。
using namespace Eigen; // 名前空間 #define Log(var) std::cout << #var" = \n"<<var<<std::endl // ログ出力マクロ
Eigenでは、各要素は不定値になっています。 従って使う際には初期化が必要になってきます。
void initVector() { const int n = 4; // 次元数。 Vector3f vec3; // float型の3次元ベクトル。 VectorXf vecX(n); // float型の多次元ベクトル。 // カンマ演算で初期化。 vec3 << 1, 2, 3; vecX << 1, 2, 3, 4; // 全て0。 VectorXd v1 = VectorXd::Zero(n); // 全て1。 VectorXd v2 = VectorXd::Ones(n); // 単位ベクトル。 VectorXd v3 = VectorXd::Unit(n, 3); // 定数ベクトル。 VectorXd v4 = VectorXd::Constant(n, 3); // 線形補間。 VectorXd v5 = VectorXd::LinSpaced(n, 1, 3); // ランダム。 VectorXd v6 = VectorXd::Random(n); Log(vec3); Log(vecX); Log(v1); Log(v2); Log(v3); Log(v4); Log(v5); Log(v6); }
行列の初期化もベクトルとあまり変わりません。
void initMatrix() { const int n = 4; // 次元数。 Matrix3f mat3; // float型の行列。 MatrixXf matX(n,n); // float型の多次元行列。 // カンマ演算で初期化。 mat3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; matX << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16; // 全て0。 MatrixXf m1 = MatrixXf::Zero(n,n); // 全て1。 MatrixXf m2 = MatrixXf::Ones(n,n); // 単位行列。 MatrixXf m3 = MatrixXf::Identity(n,n); MatrixXf m3fix = Matrix3f::Identity(); // 定数行列。 MatrixXf m4 = MatrixXf::Constant(n,n, 3); // ランダム。 MatrixXf m5 = MatrixXf::Random(n,n); Log(mat3); Log(matX); Log(m1); Log(m2); Log(m3); Log(m3fix); Log(m4); Log(m5); }
行列の代入は参照渡しではなく値渡しなので、関数に渡す時は参照渡しを心がける様にします。
void copyMatrix() { Matrix3f src; Matrix3f dst; src << 1, 2, 3, 4, 5, 6, 7, 8, 9; dst = src; Log(src); Log(dst); }
Swapマクロを自作しても良いですが、MatrixXfがSwap関数を持っています。
void swapMatrix() { Matrix3f matA; Matrix3f matB; matA << 1, 2, 3, 4, 5, 6, 7, 8, 9; matB << 9, 8, 7, 6, 5, 4, 3, 2, 1; // スワップ前。 Log(matA); Log(matB); // スワップ! matA.swap(matB); // スワップ後。 Log(matA); Log(matB); }
各要素へのアクセスは()で行います。
void accessMember() { Matrix3f matA; matA << 1, 2, 3, 4, 5, 6, 7, 8, 9; // 添え字アクセス(添え字チェックも行ってくれる) float value = matA(0, 0); Log(value); // 添え字アクセス(添え字チェックも行わない。少し高速。) float value2 = matA.coeff(0, 0); Log(value2); // 添え字アクセス(添え字チェックも行わない。少し高速。) float value3 = matA.coeffRef(0, 0); Log(value3); // 行の取得。 for( int i = 0; i < matA.cols(); i++ ) { Vector3f col = matA.col(i); Log(col); } // 列の取得。 for( int i = 0; i < matA.rows(); i++ ) { Vector3f row = matA.row(i); Log(row); } // matA( 0, 0 )書き換え。 matA.coeffRef(0, 0) = 999; Log(matA); // 行の書き換え。 matA.col(0) = Vector3f(10, 20, 30); Log(matA); }