Eigen是C++中可以用來調用并進行矩陣計算的一個庫,裡面封裝了一些類,需要的頭檔案和功能如下:
1.Eigen下載下傳
Eigen的官網下載下傳位址:http://eigen.tuxfamily.org/index.php?title=Main_Page#Download
另外,CSDN資源裡也可以下載下傳,http://download.csdn.net/detail/piaoxuezhong/9767251
2.Eigen的簡介
矩陣的定義:Eigen中關于矩陣類的模闆函數中,共有六個模闆參數,常用的隻有前三個。其前三個參數分别表示矩陣元素的類型、行數和列數。
矩陣定義時可以使用Dynamic來表示矩陣的行列數為未知。
Eigen中無論是矩陣還是數組、向量,無論是靜态矩陣還是動态矩陣都提供預設構造函數,也就是定義這些資料結構時都可以不用提供任何參數,其大小均由運作時來确定。矩陣的構造函數中隻提供行列數、元素類型的構造參數,而不提供元素值的構造,對于比較小的、固定長度的向量提供初始化元素的定義。
矩陣類型:Eigen中的矩陣類型一般都是用類似MatrixXXX來表示,可以根據該名字來判斷其資料類型,比如”d”表示double類型,”f”表示float類型,”i”表示整數,”c”表示複數;Matrix2f,表示的是一個2*2維的,其每個元素都是float類型。
資料存儲:Matrix建立的矩陣預設是按列存儲,Eigen在處理按列存儲的矩陣時會更加高效。如果想修改可以在建立矩陣的時候加入參數,如:
Matrix<int,3, 4, ColMajor> Acolmajor;
Matrix<int,3, 4, RowMajor> Arowmajor;
動态矩陣和靜态矩陣:動态矩陣是指其大小在運作時确定,靜态矩陣是指其大小在編譯時确定。
MatrixXd:表示任意大小的元素類型為double的矩陣變量,其大小隻有在運作時被指派之後才能知道。
Matrix3d:表示元素類型為double大小為3*3的矩陣變量,其大小在編譯時就知道。
在Eigen中行優先的矩陣會在其名字中包含有row,否則就是列優先。Eigen中的向量是一個特殊的矩陣,其次元為1。
矩陣元素的通路:在矩陣的通路中,行索引總是作為第一個參數,Eigen中矩陣、數組、向量的下标都是從0開始。矩陣元素的通路可以通過”()”操作符完成。例如m(2, 3)既是擷取矩陣m的第2行第3列元素。
針對向量還提供”[]”操作符,注意矩陣則不可如此使用。
設定矩陣的元素:在Eigen中重載了”<<”操作符,通過該操作符即可以一個一個元素的進行指派,也可以一塊一塊的指派。另外也可以使用下标進行指派。
重置矩陣大小:目前矩陣的行數、列數、大小可以通過rows()、cols()和size()來擷取,對于動态矩陣可以通過resize()函數來動态修改矩陣的大小。注意:
(1)、固定大小的矩陣是不能使用resize()來修改矩陣的大小;
(2)、resize()函數會析構掉原來的資料,是以調用resize()函數之後将不能保證元素的值不改變;
(3)、使用”=”操作符操作動态矩陣時,如果左右兩邊的矩陣大小不等,則左邊的動态矩陣的大小會被修改為右邊的大小。
如何選擇動态矩陣和靜态矩陣:
對于小矩陣(一般大小小于16)使用固定大小的靜态矩陣,它可以帶來比較高的效率;對于大矩陣(一般大小大于32)建議使用動态矩陣。注意:如果特别大的矩陣使用了固定大小的靜态矩陣則可能會造成棧溢出的問題。
矩陣和向量的算術運算:在Eigen中算術運算重載了C++的+、-、*
(1)、矩陣的運算:提供+、-、一進制操作符”-”、+=、-=;二進制操作符+/-,表示兩矩陣相加(矩陣中對應元素相加/減,傳回一個臨時矩陣);一進制操作符-表示對矩陣取負(矩陣中對應元素取負,傳回一個臨時矩陣);組合操作法+=或者-=表示(對應每個元素都做相應操作);矩陣還提供與标量(單一數字)的乘除操作,表示每個元素都與該标量進行乘除操作;
(2)、求矩陣的轉置、共轭矩陣、伴随矩陣:可以通過成員函數transpose()、conjugate()、adjoint()來完成。注意:這些函數傳回操作後的結果,而不會對原矩陣的元素進行直接操作,如果要讓原矩陣進行轉換,則需要使用響應的InPlace函數,如transpoceInPlace()等;
(3)、矩陣相乘、矩陣向量相乘:使用操作符*,共有*和*=兩種操作符;
(4)、矩陣的塊操作:有兩種使用方法:
matrix.block(i,j, p, q) : 表示傳回從矩陣(i, j)開始,每行取p個元素,每列取q個元素所組成的臨時新矩陣對象,原矩陣的元素不變;
matrix.block<p,q>(i, j) :<p, q>可了解為一個p行q列的子矩陣,該定義表示從原矩陣中第(i, j)開始,擷取一個p行q列的子矩陣,傳回該子矩陣組成的臨時矩陣對象,原矩陣的元素不變;
(5)、向量的塊操作:
擷取向量的前n個元素:vector.head(n);
擷取向量尾部的n個元素:vector.tail(n);
擷取從向量的第i個元素開始的n個元素:vector.segment(i,n);
3.配置
直接在屬性頁的包含目錄中加入eigen的目錄即可
4.驗證
執行個體1:(動态矩陣設定)
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
using namespace std;
int main(int argc, char* argv[])
{
MatrixXd m(2, 2);
m(0, 0) = 3;
m(1, 0) = 2.5;
m(0, 1) = -1;
m(1, 1) = m(1, 0) + m(0, 1);
cout << m << endl;
return 0;
}
運作結果:
執行個體2:(靜态矩陣設定,及簡單矩陣計算)
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix2d mat;
mat << 1, 2,
3, 4;
Vector2d u(-1, 1), v(2, 0);
cout << "the mat is: \n" << mat << endl;
cout << "the u is:\n" << u << endl;
cout << "the v is:\n" << v << endl;
cout << "Here is mat*mat:\n" << mat*mat << endl;
cout << "Here is mat*u:\n" << mat*u << endl;
cout << "here is u^T\n" << u.transpose() << endl;
cout << "Here is u^T*v:\n" << u.transpose()*v << endl;
cout << "Here is u*v^T:\n" << u*v.transpose() << endl;
}
運作結果:
執行個體3:(Map矩陣與數組轉換)
#include <iostream>
#include "Eigen\Dense"
using namespace Eigen;
using namespace std;
int main()
{
double *Mat1 = new double[6];
for (int i = 0; i < 6; i++)
{
Mat1[i] = i;
}
//靜态矩陣,map使用
Eigen:Map<Matrix<double, 2, 3>>staMat(Mat1);
cout << "顯示靜态矩陣:" << endl;
for (int i = 0; i < staMat.size(); i++)
cout << *(staMat.data() + i) << " ";
cout << endl;
//動态矩陣,map使用
Map <MatrixXd> dyMat(Mat1, 2, 3);
cout << "顯示動态矩陣:" << endl;
for (int i = 0; i < dyMat.size(); i++)
cout << *(dyMat.data() + i) << " ";
cout << endl;
}
執行個體4:(轉置矩陣,逆矩陣,伴随矩陣,特征值等求解)
#include <iostream>
#include "Eigen\Dense"
using namespace Eigen;
using namespace std;
int main()
{
Matrix3d Mat1;
Mat1 << 1, 2, 3,
4, 6, 8,
7, 9, 9;
cout << "Mat1=\n" << Mat1 << endl;
cout << "Mat1轉置矩陣:\n" << Mat1.transpose() << endl;
cout << "Mat1伴随矩陣:\n" << Mat1.adjoint() << endl;
cout << "Mat1逆矩陣:\n" << Mat1.inverse() << endl;
cout << "Mat1行列式:\n" << Mat1.determinant() << endl;
SelfAdjointEigenSolver<Matrix3d>eigensover(Mat1);
if (eigensover.info() != Success) abort();
cout << "特征值:\n" << eigensover.eigenvalues() << endl;
cout << "特征向量:\n" << eigensover.eigenvectors() << endl;
}
需要注意,在運作時需要設定:
在工程上右鍵-》屬性-》c/c++-》代碼生成-》運作庫
改成(release為MT,debug為MTD)
否則,可能會出現如下報錯:
error LNK2038: 檢測到“RuntimeLibrary”的不比對項: 值“MT_StaticRelease”不比對值“MD_DynamicRelease”
參考:
http://blog.csdn.net/chenbang110/article/details/12304123
http://blog.csdn.net/abcjennifer/article/details/7781936
http://blog.csdn.net/houjixin/article/details/8477522
http://blog.csdn.net/houjixin/article/details/8490941
http://blog.csdn.net/fengbingchun/article/details/47378515
http://blog.csdn.net/augusdi/article/details/12907341 (eigen較為詳細的介紹)
http://blog.csdn.net/wpc320/article/details/8496957