整理下Eigen庫的教程,參考:http://eigen.tuxfamily.org/dox/index.html
高級初始化方法
本篇介紹幾種高級的矩陣初始化方法,重點介紹逗號初始化和特殊矩陣(單位陣、零陣)。
逗號初始化
Eigen提供了逗號操作符允許我們方便地為矩陣/向量/數組中的元素賦值。順序是從左上到右下:自左到右,從上至下。對象的尺寸需要事先指定,初始化的參數也應該和要操作的元素數目一致。
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
初始化列表不僅可以是數值也可以是vectors或matrix。
RowVectorXd vec1(3);
vec1 << 1, 2, 3;
std::cout << "vec1 = " << vec1 << std::endl;
RowVectorXd vec2(4);
vec2 << 1, 4, 9, 16;
std::cout << "vec2 = " << vec2 << std::endl;
RowVectorXd joined(7);
joined << vec1, vec2;
std::cout << "joined = " << joined << std::endl;
輸出
vec1 = 1 2 3
vec2 = 1 4 9 16
joined = 1 2 3 1 4 9 16
也可以使用塊結構。
MatrixXf matA(2, 2);
matA << 1, 2, 3, 4;
MatrixXf matB(4, 4);
matB << matA, matA/10, matA/10, matA;
std::cout << matB << std::endl;
輸出
1 2 0.1 0.2
3 4 0.3 0.4
0.1 0.2 1 2
0.3 0.4 3 4
同時逗號初始化方式也可以用來為塊表達式賦值。
Matrix3f m;
m.row(0) << 1, 2, 3;
m.block(1,0,2,2) << 4, 5, 7, 8;
m.col(2).tail(2) << 6, 9;
std::cout << m;
1 2 3
4 5 6
7 8 9
特殊的矩陣和向量
零陣:類的靜態成員函數Zero(),有三種定義形式。
std::cout << "A fixed-size array:\n";
Array33f a1 = Array33f::Zero();
std::cout << a1 << "\n\n";
std::cout << "A one-dimensional dynamic-size array:\n";
ArrayXf a2 = ArrayXf::Zero(3);
std::cout << a2 << "\n\n";
std::cout << "A two-dimensional dynamic-size array:\n";
ArrayXXf a3 = ArrayXXf::Zero(3, 4);
std::cout << a3 << "\n";
輸出
A fixed-size array:
0 0 0
0 0 0
0 0 0
A one-dimensional dynamic-size array:
0
0
0
A two-dimensional dynamic-size array:
0 0 0 0
0 0 0 0
0 0 0 0
類似地,還有常量矩陣:Constant([rows],[cols],value),Random()隨機矩陣。
單位陣Identity()方法只能使用與Matrix不使用Array,因為單位陣是個線性代數概念。
LinSpaced(size, low, high)可以從low到high等間距的size長度的序列,適用於vector和一維數組。
ArrayXXf table(10, 4);
table.col(0) = ArrayXf::LinSpaced(10, 0, 90);
table.col(1) = M_PI / 180 * table.col(0);
table.col(2) = table.col(1).sin();
table.col(3) = table.col(1).cos();
std::cout << " Degrees Radians Sine Cosine\n";
std::cout << table << std::endl;
輸出
Degrees Radians Sine Cosine
0 0 0 1
10 0.175 0.174 0.985
20 0.349 0.342 0.94
30 0.524 0.5 0.866
40 0.698 0.643 0.766
50 0.873 0.766 0.643
60 1.05 0.866 0.5
70 1.22 0.94 0.342
80 1.4 0.985 0.174
90 1.57 1 -4.37e-08
功能函數
Eigen也提供可同樣功能的函數:setZero(), MatrixBase::setIdentity()和 DenseBase::setLinSpaced()。
const int size = 6;
MatrixXd mat1(size, size);
mat1.topLeftCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);
mat1.topRightCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);
mat1.bottomLeftCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);
mat1.bottomRightCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);
std::cout << mat1 << std::endl << std::endl;
MatrixXd mat2(size, size);
mat2.topLeftCorner(size/2, size/2).setZero();
mat2.topRightCorner(size/2, size/2).setIdentity();
mat2.bottomLeftCorner(size/2, size/2).setIdentity();
mat2.bottomRightCorner(size/2, size/2).setZero();
std::cout << mat2 << std::endl << std::endl;
MatrixXd mat3(size, size);
mat3 << MatrixXd::Zero(size/2, size/2), MatrixXd::Identity(size/2, size/2),
MatrixXd::Identity(size/2, size/2), MatrixXd::Zero(size/2, size/2);
std::cout << mat3 << std::endl;
輸出均為
0 0 0 1 0 0
0 0 0 0 1 0
0 0 0 0 0 1
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 0 0 0
三種賦值(初始化)的方式逗號初始化、特殊陣的靜態方法和功能函數setXxx()。
表達式變量
上面的靜態方法如 Zero()、Constant()並不是直接返回一個矩陣或數組,實際上它們返回的是是‘expression object’,只是臨時被使用/被用於優化。
m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
MatrixXf::Constant(3,3,1.2)
構建的是一個3*3的矩陣表達式(臨時變量)。
逗號初始化的方式也可以構建這種臨時變量,這是為了獲取真正的矩陣需要調用finished()函數:
MatrixXf mat = MatrixXf::Random(2, 3);
std::cout << mat << std::endl << std::endl;
mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat;
std::cout << mat << std::endl;
輸出
0.68 0.566 0.823
-0.211 0.597 -0.605
-0.211 0.597 -0.605
0.68 0.566 0.823