在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