Eigen學習筆記(1)-入門

原文:Eigen官網-Getting started

Eigen 是一個基於C++的線性代數庫,其中實現大量常用的線性代數算法,包括常規矩陣計算,矩陣變換,矩陣分解,矩陣塊操作。Eigen 廣泛地應用在開源項目中,例如OpenCV,PCL(Point Cloud Library),ROS等。其實Eigen中算法都可以在matlab中找到,但是由於matlab是半開源的。所以,如果想在自己的項目中使用,還是要義無反顧地選擇Eigen。Eigen目前的版本是3.3.7(2019.12.09)。

Eigen只包含頭文件,因此它不需要實現編譯,只需要你include到你的項目,指定好Eigen的頭文件路徑,編譯項目即可。而且跨平臺,當然這是必須的。

模塊和頭文件

Eigen庫被分爲一個Core模塊和其他一些模塊,每個模塊有一些相應的頭文件。 爲了便於引用,Dense模塊整合了一系列模塊;Eigen模塊整合了所有模塊。一般情況下,include<Eigen/Dense> 就夠了。

Module Header file Contents
Core #include <Eigen/Core> Matrix和Array類,基礎的線性代數運算和數組操作
Geometry #include <Eigen/Geometry> 旋轉、平移、縮放、2維和3維的各種變換
LU #include <Eigen/LU> 求逆,行列式,LU分解
Cholesky #include <Eigen/Cholesky> LLT和LDLT Cholesky分解
Householder #include <Eigen/Householder> 豪斯霍爾德變換,用於線性代數運算
SVD #include <Eigen/SVD> SVD分解
QR #include <Eigen/QR> QR分解
Eigenvalues <include <Eigen/Eigenvalues> 特徵值,特徵向量分解
Sparse #include <Eigen/Sparse> 稀疏矩陣的存儲和一些基本的線性運算
- #include <Eigen/Dense> 包含了Core/Geometry/LU/Cholesky/SVD/QR/Eigenvalues模塊
- #include <Eigen/Eigen> 包括Dense和Sparse(整個Eigen庫)

一個簡單的例子

#include <iostream>
#include <Eigen/Dense> 

using Eigen::MatrixXd;

int main()
{
  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);
  std::cout << m << std::endl;
  return 0;
}

編譯:
Eigen是不需要進行庫連接的,只需要讓編譯器能找到Eigen的頭文件即可,因此Eigen的源代碼必須要放到inclue目錄下面。當用GCC進行編譯時,可以通過-I來指定Eigen文件的路徑。

g++ -I /path/to/eigen/ my_program.cpp -o my_program 

當在Linux或者Mac OS X系統下,可以將Eigen源代碼放到/usr/local/include目錄下,然後直接通過如下指令編譯代碼:

g++ my_program.cpp -o my_program

結果如下:

  3  -1
2.5 1.5

代碼解釋:
首先,代碼引入了eigen的頭文件,這裏Eigen/Dense 一次引入了多個常用的模塊。

程序首先定義了一個2 x 2的矩陣。根據Eigen的定義 ,MatrixXd,這個類型可以拆成三部分來看,Matrix-X-d,Matrix表示定義的是一個矩陣,X表示定義的矩陣維度不確定,d表示double,指矩陣中每一個元素都是double類型的。m(2,2)指定了矩陣的大小是2x2的。從第9 行到第12 行則爲矩陣中的元素進行了賦值操作。

最後輸出矩陣。

第二個例子

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
  // 創建一個3 x 3的隨機矩陣,每個元素的範圍都在(-1,1)之間
  MatrixXd m = MatrixXd::Random(3,3);
  // 將每個元素的範圍設置在 (10,110)之間,MatrixXd::Cosntant() 用於產生每個元素都相同的矩陣,這裏每個元素都是1.2
  m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
  // 輸出m
  cout << "m =" << endl << m << endl;
  // 創建一個長度爲 3 的列向量
  VectorXd v(3);
  // 爲向量元素賦值,這裏Eigen 將 << 操作符重載了。
  v << 1, 2, 3;
  // 矩陣和向量做乘法並輸出結果
  cout << "m * v =" << endl << m * v << endl;
}
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
int main()
{
  Matrix3d m = Matrix3d::Random();
  m = (m + Matrix3d::Constant(1.2)) * 50;
  cout << "m =" << endl << m << endl;
  Vector3d v(1,2,3);
  
  cout << "m * v =" << endl << m * v << endl;
}

輸出結果如下:

m =
  94 89.8 43.5
49.4  101 86.8
88.3 29.8 37.8
m * v =
404
512
261

上面的例子展示生成矩陣和向量的不同方法,其實向量就是列數爲1 的矩陣。

使用固定大小的矩陣或向量有兩個好處:(1)編譯更快,因爲編譯器知道矩陣或向量的大小;
(2)指定大小可以進行更爲嚴格的檢查,比如你將Matrix4d(4*4 matrix)和Vector3d進行乘法操作。

當然使用太多類別(Matrix3d、Matrix4d、Matrix5d…)會增加編譯時間和可執行文件大小,原則對於4*4或者更小的矩陣使用固定大小的矩陣。

參考:

“Eigen教程(1)”
“Eigen學習”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章