常德規(guī)劃建設(shè)局網(wǎng)站/深圳做推廣哪家比較好
Eigen-Matrix矩陣
- 一、概述
- 二、矩陣的前三個(gè)模板參數(shù)
- 三、向量
- 四、動(dòng)態(tài)維度參數(shù)
- 五、構(gòu)造函數(shù)
- 六、索引訪問(wèn)器
- 七、逗號(hào)初始化
- 八、矩陣維度調(diào)整
- 九、賦值和調(diào)整大小
- 十、固定尺寸vs.動(dòng)態(tài)尺寸
- 十一、可選模板參數(shù)
- 十二、方便預(yù)定義
一、概述
在Eigen中,所有矩陣和向量都是矩陣模板類的對(duì)象。向量只是矩陣的一種特殊情況,要么有一行,要么有一列。矩陣就是一個(gè)二維數(shù)表,可以有多行多列。
二、矩陣的前三個(gè)模板參數(shù)
Matrix類有六個(gè)模板參數(shù),但現(xiàn)在只需要了解前三個(gè)參數(shù)就足夠了。剩下的三個(gè)參數(shù)都有默認(rèn)值,我們暫時(shí)不碰它們,我們將在下面討論它們。
Matrix的三個(gè)必備模板參數(shù)為:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
- 參數(shù)Scalar, 標(biāo)量是標(biāo)量類型,即系數(shù)的類型。也就是說(shuō),如果你想要一個(gè)浮點(diǎn)數(shù)的矩陣,在這里選擇float。有關(guān)所有支持的標(biāo)量類型的列表,以及如何擴(kuò)展對(duì)新類型的支持,請(qǐng)參閱標(biāo)量類型。
- RowsAtCompileTime和ColsAtCompileTime是在編譯時(shí)已知的矩陣的行數(shù)和列數(shù)(如果在編譯時(shí)不知道該數(shù),請(qǐng)參見下文)。
Eigen提供了許多方便的類型來(lái)涵蓋通常的情況。例如,Matrix4f是一個(gè)4x4的浮點(diǎn)數(shù)矩陣。Eigen是這樣定義的:
typedef Matrix<float, 4, 4> Matrix4f;
三、向量
如上所述,在Eigen中,向量只是矩陣的一種特殊情況,要么有一行,要么有一列。它們只有一列的情況是最常見的;這樣的向量稱為列向量,通常簡(jiǎn)稱為向量。在另一種情況下,它們只有一行,它們被稱為行向量。
例如,方便的類型pedef Vector3f是一個(gè)3個(gè)浮點(diǎn)數(shù)的(列)向量。Eigen對(duì)其定義如下:
typedef Matrix<float, 3, 1> Vector3f;
我們還為行向量提供了方便的類型,例如:
typedef Matrix<int, 1, 2> RowVector2i;
四、動(dòng)態(tài)維度參數(shù)
當(dāng)然,Eigen并不局限于在編譯時(shí)已知維數(shù)的矩陣。RowsAtCompileTime和ColsAtCompileTime模板參數(shù)可以采用特殊值Dynamic,這表示在編譯時(shí)大小未知,因此必須作為運(yùn)行時(shí)變量處理。
在Eigen學(xué)術(shù)語(yǔ)中,這樣的尺寸被稱為動(dòng)態(tài)尺寸;而在編譯時(shí)已知的大小稱為固定大小。例如,方便類型pedef MatrixXd,表示具有動(dòng)態(tài)大小的雙精度矩陣,定義如下:
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
同樣,我們定義了一個(gè)自解釋的類型pedef VectorXi如下:
typedef Matrix<int, Dynamic, 1> VectorXi;
你可以完美地?fù)碛泄潭〝?shù)量的行和動(dòng)態(tài)數(shù)量的列,如下所示:
Matrix<float, 3, Dynamic>
五、構(gòu)造函數(shù)
默認(rèn)構(gòu)造函數(shù)始終可用,從不執(zhí)行任何動(dòng)態(tài)內(nèi)存分配,也從不初始化矩陣系數(shù)。你可以這樣做:
Matrix3f a;
MatrixXf b;
在這里,
- a 是一個(gè)3 × 3矩陣,其系數(shù)為未初始化的浮點(diǎn)[9]數(shù)組;
- b 是一個(gè)動(dòng)態(tài)大小的矩陣,其大小目前為0 × 0,其系數(shù)數(shù)組還沒(méi)有被分配。
構(gòu)造函數(shù)也可以接受大小。對(duì)于矩陣,總是先傳遞行數(shù)。對(duì)于向量,只需傳遞向量的大小。它們用給定的大小分配系數(shù)數(shù)組,但不初始化系數(shù)本身:
MatrixXf a(10,15);
VectorXf b(30);
在這里,
- a 是一個(gè)10x15的動(dòng)態(tài)大小矩陣,具有已分配但當(dāng)前未初始化的系數(shù)。
- b 是一個(gè)大小為30的動(dòng)態(tài)大小向量,具有已分配但當(dāng)前未初始化的系數(shù)。
為了在固定大小和動(dòng)態(tài)大小的矩陣之間提供統(tǒng)一的API,在固定大小的矩陣上使用這些構(gòu)造函數(shù)是合法的,即使在這種情況下傳遞大小是無(wú)用的。所以這是合法的:
Matrix3f a(3,3);
這是一個(gè)無(wú)操作。
矩陣和向量也可以從系數(shù)列表初始化。在c++ 11之前,此功能僅限于固定大小的小列或大小不超過(guò)4的向量:
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);
如果啟用c++ 11,可以通過(guò)傳遞任意數(shù)量的系數(shù)來(lái)初始化任意大小的固定大小的列向量或行向量:
Vector2i a(1, 2); // A column vector containing the elements {1, 2}
Matrix<int, 5, 1> b {1, 2, 3, 4, 5}; // A row-vector containing the elements {1, 2, 3, 4, 5}
Matrix<int, 1, 5> c = {1, 2, 3, 4, 5}; // A column vector containing the elements {1, 2, 3, 4, 5}
在一般情況下,無(wú)論是固定大小還是運(yùn)行時(shí)大小的矩陣和向量,系數(shù)必須按行分組,并作為初始化列表的初始化列表傳遞:
MatrixXi a { // construct a 2x2 matrix{1, 2}, // first row{3, 4} // second row
};
Matrix<double, 2, 3> b {{2, 3, 4},{5, 6, 7},
};
對(duì)于列向量或行向量,允許隱式轉(zhuǎn)置。這意味著可以從單行初始化列向量:
VectorXd a {{1.5, 2.5, 3.5}}; // A column-vector with 3 coefficients
RowVectorXd b {{1.0, 2.0, 3.0, 4.0}}; // A row-vector with 4 coefficients
六、索引訪問(wèn)器
在eigen中,主要的系數(shù)訪問(wèn)器和變量是重載括號(hào)操作符。對(duì)于矩陣,總是先傳遞行索引。對(duì)于向量,只傳遞一個(gè)下標(biāo)。編號(hào)從0開始。這個(gè)例子不言自明:
#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::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 << "Here is the matrix m:\n" << m << std::endl;Eigen::VectorXd v(2);v(0) = 4;v(1) = v(0) - 1;std::cout << "Here is the vector v:\n" << v << std::endl;
}
輸出:
Here is the matrix m:3 -1
2.5 1.5
Here is the vector v:
4
3
請(qǐng)注意,語(yǔ)法m(index)并不局限于向量,它也可用于一般矩陣,這意味著在系數(shù)數(shù)組中基于索引的訪問(wèn)。然而,這取決于矩陣的存儲(chǔ)順序。所有特征矩陣默認(rèn)為列為主的存儲(chǔ)順序,但可以將其更改為行為主,請(qǐng)參閱存儲(chǔ)順序。
對(duì)于vector中的基于索引的訪問(wèn),操作符 [ ] 也被重載,但請(qǐng)記住,c++不允許操作符 [ ] 接受多個(gè)參數(shù)。我們將運(yùn)算符 [ ] 限制為向量,只有向量支持使用 [ ] 符號(hào)索引,因?yàn)閏++語(yǔ)言中的一個(gè)笨拙會(huì)使 matrix[i,j] 編譯成與 matrix[j] 相同的東西!
七、逗號(hào)初始化
可以使用所謂的逗號(hào)初始化語(yǔ)法方便地設(shè)置矩陣和向量系數(shù)?,F(xiàn)在,知道這個(gè)例子就足夠了:
Matrix3f m;
m << 1, 2, 3,4, 5, 6,7, 8, 9;
std::cout << m;
輸出
1 2 3
4 5 6
7 8 9
八、矩陣維度調(diào)整
矩陣的當(dāng)前大小可以通過(guò)rows()、cols()和size()來(lái)獲取。這些方法分別返回行數(shù)、列數(shù)和系數(shù)數(shù)。通過(guò)resize()方法調(diào)整動(dòng)態(tài)大小矩陣的大小。
#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::MatrixXd m(2,5);m.resize(4,3);std::cout << "The matrix m is of size "<< m.rows() << "x" << m.cols() << std::endl;std::cout << "It has " << m.size() << " coefficients" << std::endl;Eigen::VectorXd v(2);v.resize(5);std::cout << "The vector v is of size " << v.size() << std::endl;std::cout << "As a matrix, v is of size "<< v.rows() << "x" << v.cols() << std::endl;
輸出
The matrix m is of size 4x3
It has 12 coefficients
The vector v is of size 5
As a matrix, v is of size 5x1
如果實(shí)際矩陣大小沒(méi)有改變,resize()方法是不操作的;否則它是破壞性的:系數(shù)的值可能會(huì)改變。如果你想要一個(gè)不改變系數(shù)的 resize()的 保守變體,使用conservativeResize(),更多細(xì)節(jié)請(qǐng)參閱本頁(yè)。
為了API的一致性,所有這些方法在固定大小的矩陣上仍然可用。當(dāng)然,您實(shí)際上無(wú)法調(diào)整固定大小的矩陣的大小。嘗試將固定大小更改為實(shí)際不同的值將觸發(fā)斷言失敗;但是下面的代碼是合法的:
例如:輸出:
#include <iostream>
#include <Eigen/Dense>int main()
{Eigen::Matrix4d m;m.resize(4,4); // no operationstd::cout << "The matrix m is of size "<< m.rows() << "x" << m.cols() << std::endl;
輸出
The matrix m is of size 4x4
九、賦值和調(diào)整大小
賦值是使用操作符=將一個(gè)矩陣復(fù)制到另一個(gè)矩陣的操作。Eigen自動(dòng)調(diào)整左手邊矩陣的大小,使其與右手邊矩陣的大小相匹配。例如:
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 is of size 2x2
a is now of size 3x3
當(dāng)然,如果左側(cè)是固定大小,則不允許調(diào)整其大小。
如果您不希望發(fā)生這種自動(dòng)調(diào)整大小(例如為了調(diào)試目的),您可以禁用它,請(qǐng)參閱此頁(yè)。
十、固定尺寸vs.動(dòng)態(tài)尺寸
什么時(shí)候應(yīng)該使用固定大小(例如Matrix4f),什么時(shí)候應(yīng)該使用動(dòng)態(tài)大小(例如MatrixXf)?簡(jiǎn)單的答案是:對(duì)于非常小的尺寸盡可能使用固定大小,對(duì)于較大的尺寸或必須使用動(dòng)態(tài)大小。對(duì)于較小的大小,特別是小于(大約)16的大小,使用固定大小對(duì)性能非常有益,因?yàn)樗试SEigen避免動(dòng)態(tài)內(nèi)存分配并展開循環(huán)。在內(nèi)部,固定大小的特征矩陣只是一個(gè)普通數(shù)組,即做
Matrix4f mymatrix;
其實(shí)就是去做
float mymatrix[16];
這真的是零運(yùn)行費(fèi)用。相比之下,動(dòng)態(tài)大小矩陣的數(shù)組總是在堆上分配,所以這樣做
MatrixXf mymatrix(rows,columns);
等于做某事
float *mymatrix = new float[rows*columns];
除此之外,MatrixXf對(duì)象將其行數(shù)和列數(shù)存儲(chǔ)為成員變量。
當(dāng)然,使用固定大小的限制是,只有在編譯時(shí)知道大小時(shí)才有可能。此外,對(duì)于足夠大的大小,例如大于(大約)32的大小,使用固定大小的性能優(yōu)勢(shì)變得可以忽略不計(jì)。更糟糕的是,嘗試在函數(shù)內(nèi)部使用固定大小創(chuàng)建一個(gè)非常大的矩陣可能會(huì)導(dǎo)致堆棧溢出,因?yàn)镋igen會(huì)嘗試將數(shù)組自動(dòng)分配為局部變量,而這通常是在堆棧上完成的。最后,根據(jù)具體情況,當(dāng)使用動(dòng)態(tài)大小時(shí),Eigen也可以更積極地嘗試向量化(使用SIMD指令),請(qǐng)參閱向量化。
十一、可選模板參數(shù)
我們?cè)诒卷?yè)開頭提到,Matrix類接受六個(gè)模板參數(shù),但到目前為止我們只討論了前三個(gè)。其余三個(gè)參數(shù)為可選參數(shù)。下面是模板參數(shù)的完整列表:
Matrix<typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime,int Options = 0,int MaxRowsAtCompileTime = RowsAtCompileTime,int MaxColsAtCompileTime = ColsAtCompileTime>
- Options是位字段。在這里,我們只討論一個(gè)比特:RowMajor。它指定這種類型的矩陣使用行為主存儲(chǔ)順序;默認(rèn)情況下,存儲(chǔ)順序是以列為主的。請(qǐng)參閱存儲(chǔ)訂單頁(yè)面。例如,此類型表示行為主的3x3矩陣:
Matrix<float, 3, 3, RowMajor>
- MaxRowsAtCompileTime和MaxColsAtCompileTime在需要指定時(shí)非常有用,即使在編譯時(shí)不知道矩陣的確切大小,但在編譯時(shí)知道一個(gè)固定的上限。這樣做的最大原因可能是為了避免動(dòng)態(tài)內(nèi)存分配。例如,下面的矩陣類型使用12個(gè)浮點(diǎn)數(shù)的普通數(shù)組,沒(méi)有動(dòng)態(tài)內(nèi)存分配:
Matrix<float, Dynamic, Dynamic, 0, 3, 4>
十二、方便預(yù)定義
Eigen定義了以下矩陣類型:
都是用的 Matrix 不同模板參數(shù),預(yù)定義為不同類型。
- MatrixNt :Matrix<type, N, N>.
例如, MatrixXi 實(shí)際上是 :Matrix<int, Dynamic, Dynamic>. - MatrixXNt :Matrix<type, Dynamic, N>.
例如, MatrixX3i 實(shí)際上是 :Matrix<int, Dynamic, 3>. - MatrixNXt :Matrix<type, N, Dynamic>.
例如, Matrix4Xd 實(shí)際上是 :Matrix<d, 4, Dynamic>. - VectorNt :Matrix<type, N, 1>.
例如, Vector2f 實(shí)際上是 :Matrix<float, 2, 1>. - RowVectorNt :Matrix<type, 1, N>.
例如, RowVector3d 實(shí)際上是 :Matrix<double, 1, 3>.
注意:
- N 可以是2、3、4或者X(表示動(dòng)態(tài) Dynamic ) 中的任意一個(gè)。
- t 可以是I (int)、f (float)、d (double)、cf (complex)或CD (complex)中的任意一個(gè)。雖然只為這五種類型定義了類型定義,但這并不意味著它們是唯一受支持的標(biāo)量類型。例如,支持所有標(biāo)準(zhǔn)整數(shù)類型,請(qǐng)參閱標(biāo)量類型。