Eigen Matrix 詳解


在Eigen中,所有的matrices 和vectors 都是模板類Matrix 的對象,Vectors 只是一種特殊的矩陣,行或者列為1.

Matrix的前三個模板參數

Matrix 類有6個模板參數,現在我們了解前三個足夠。剩下的三個參數都有默認值,后面會探討,現在不管他。
Matrix 的三個強制的模板參數:

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
  • 1
  • Scalar 就是矩陣元素標量類型。
  • RowsAtCompileTime 和ColsAtCompileTime 分別指代編譯時候的行和列值。
    Eigen中提供了許多typedefs ,例如Matrix4f 是4*4的float型矩陣:
typedef Matrix<float, 4, 4> Matrix4f;
  • 1

Vectors

正如前面提到的那樣,在Eigen中,vectors 只是一種特殊形式的矩陣,有一行或者一列。在大多數情況下一列比較多,這樣的向量也叫做列向量,也簡稱向量。其他情況叫做行向量。

例如typedef Vector3f 是一個(列)向量,它的定義如下:

typedef Matrix<float, 3, 1> Vector3f;
  • 1

同樣我們也提供了行向量的定義:

typedef Matrix<int, 1, 2> RowVector2i;
  • 1

特殊值Dynamic

當然,Eigen 不局限於在編譯時候確定大小的矩陣。模板參數RowsAtCompileTime 和ColsAtCompileTime 可以傳入特殊的值Dynamic ,來標志在編譯時大小無法確定,需要當做運行時變量來處理。在中的術語叫做動態大小,與之相應的在編譯時確定大小的叫做固定大小。
例如typedef MatrixXd,指的是元素為double,大小為動態的:

typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
  • 1

類似 typedef VectorXi如下:

typedef Matrix<int, Dynamic, 1> VectorXi;
  • 1

當然你可以定義一個固定行的,列是動態的float矩陣如下:

Matrix<float, 3, Dynamic>
  • 1

構造器

總是會有默認的構造器,不會進行動態內存分配,也不會初始化矩陣元素。

Matrix3f a; MatrixXf b;

這里,a是一個3*3的元素,其中還有一個float[9]數組,其中的元素沒有初始化;b是一個動態大小的矩陣,目前的大小是0*0,它的元素數組完全沒有分配。
構造器中全入大小的構造器也是有的,行是先傳入的。對於向量,直接傳入向量大小。他們會分配元素數組,但是不會初始化元素。

MatrixXf a(10,15); VectorXf b(30);

這里,a是10x15動態矩陣,數組內存已經分配,但是沒有初始化;b是一個大小為30的向量,數組內存已經分配,但是元素沒有初始化。
為了提供統一的API ,在固定類型的矩陣上指定大小也是合法的,例如:

Matrix3f a(3,3);

最后,我們提供了一些便捷方式為小的大小的向量元素提供初始化方法:

Vector2d a(5.0, 6.0); Vector3d b(5.0, 6.0, 7.0); Vector4d c(5.0, 6.0, 7.0, 8.0);

逗號初始化

void fun3() { Eigen::Matrix3f m; m << 1, 2, 3, 4, 5, 6, 7, 8, 9; std::cout << m; }

Matrix 和 vector元素可以通過逗號分隔初始化方法初始化

Resizing

rows(), cols() 和 size(). 分別返回矩陣的行數、列數和元素的個數.動態矩陣大小可以通過 resize()改變大小

void fun4()
{
    Eigen::MatrixXd m(2,5); cout<<"m "<<"rows="<<m.rows()<<"cols="<<m.cols()<<"coefficeints="<<m.size()<<endl; m.resize(4,5); cout<<"m "<<"rows="<<m.rows()<<"cols="<<m.cols()<<"coefficeints="<<m.size()<<endl; Eigen::VectorXd v(2); v.resize(5); cout<<"v "<<"rows="<<v.rows()<<"cols="<<v.cols()<<"coefficeints="<<v.size()<<endl; }

resize() 如果大小沒有變化將不會進行任何操作,否則則是破壞性的。如果你想使用resize() 同時不想改變元素的值,請使用conservativeResize()。
為了達到API 的一致性,所有固定大小的矩陣都有上面的方法,試着改變固定大小的矩陣會觸發斷言錯誤。以下代碼是合法的:

 Matrix4d m; m.resize(4,4); // no operation std::cout << "The matrix m is of size " << m.rows() << "x" << m.cols() << std::endl;

Assignment 和resizing

賦值是將一個矩陣拷貝進另外一個矩陣,使用操作符=。Eigen 會自動跳轉左面元素的大小,從而使得它和右側元素匹配。例如:

MatrixXf a(2,2); std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl; MatrixXf b(3,3); a = b; std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;

a原先大小 2x2
a現在大小 3x3
當然,如果左側是固定大小的矩陣,那么改變大小是不允許的。
如果你不需要這種自動調整大小,你可以將他關閉。

可選模板參數

我下面看看剩下的三個可選參數:

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options = 0, int MaxRowsAtCompileTime = RowsAtCompileTime, int MaxColsAtCompileTime = ColsAtCompileTime>
  • Options 是一個位字段。我們只討論一個RowMajor,是按行存儲,默認是按列存儲的。Matrix


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM