====== 001 基本的な使い方 ====== ===== 概要 ===== 行列やベクトルを便利に扱える、Eigenの組み込み方法と基本的な使い方を学びます。 ==== ライブラリのインストール ==== * ダウンロードページ:http://eigen.tuxfamily.org/ * ここではEigen 3.2.2 released をダウンロードしました。 ==== 使用方法(Visual Studioの場合) ==== * ダウンロードした圧縮ファイルを解凍します。 * 任意の場所にフォルダを移動します。 * Visual Studioを起動して、解凍したフォルダをヘッダーのディレクトリパスに通します。 ==== インクルードファイルについて ==== ソースを書く際は「Eigen/Dense」をインクルードしておけば行列やベクトルの一通りの機能が使えます。 メモリを節約できる特殊なスパース行列を使う場合は「Eigen/Sparse」をインクルードします。 ==== テストコードについて ==== 以下のテストコードでは、冗長なコード簡略化のために簡単なマクロとEigen名前空間を定義しています。 using namespace Eigen; // 名前空間 #define Log(var) std::cout << #var" = \n"< ==== 初期化について ==== 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); }