本章介绍矩阵初始化的一些高级方法,包括逗号初始化和一些特殊矩阵(单位矩阵、零矩阵)初始化
逗号初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int main() { RowVectorXd vec1(3); vec1 << 1, 2, 3; cout << "vec1 = " << vec1 << endl; RowVectorXd vec2(4); vec2 << 1, 4, 9, 16; cout << "vec2 = " << vec2 << endl; RowVectorXd joined(7); joined << vec1, vec2; cout << "joined = " << joined << endl; }
|
输出:
1 2 3
| vec1 = 1 2 3 vec2 = 1 4 9 16 joined = 1 2 3 1 4 9 16
|
1 2 3 4 5 6 7 8
| int main() { MatrixXf matA(2, 2); matA << 1, 2, 3, 4; MatrixXf matB(4, 4); matB << matA, matA/10, matA/10, matA; cout << matB << endl; }
|
输出:
1 2 3 4
| 1 2 0.1 0.2 3 4 0.3 0.4 0.1 0.2 1 2 0.3 0.4 3 4
|
1 2 3 4 5 6 7 8
| int main() { 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; cout << m; }
|
输出:
特殊矩阵与数组
参考手册 Quick Reference Guide - Predefined Matrices
Zero()
初始化所有系数为0,共有三种形式:
Zero()
: 不接收任何变量,仅用于固定大小的对象;
Zero(size)
: 接收一个变量,仅用于一维动态大小的对象;
Zero(rows,cols)
: 接收两个变量,仅用于二维动态大小的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int main() { cout << "A fixed-size array:\n"; Array33f a1 = Array33f::Zero(); cout << a1 << "\n\n";
cout << "A one-dimensional dynamic-size array:\n"; ArrayXf a2 = ArrayXf::Zero(3); cout << a2 << "\n\n";
cout << "A two-dimensional dynamic-size array:\n"; ArrayXXf a3 = ArrayXXf::Zero(3, 4); cout << a3 << "\n"; }
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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
|
Ones()
初始化所有系数为1,三种形式与 Zero()
相同
Random()
初始化所有系数为随机数,三种形式与 Zero()
相同
Constant(value)
初始化所有系数为value,同样三种形式:
Constant(value)
Constant(size,value)
Constant(rows,cols,value)
Identity()
返回单位矩阵,仅用于 Matrix 类,包括 Identity()
和 Identity(rows,cols)
LinSpaced(size, low, high)
仅用于向量或一维数组,返回一个指定大小的向量,其系数在参数 low
和 high
之间等距分布
1 2 3 4 5 6 7 8 9 10
| int main() { 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(); cout << " Degrees Radians Sine Cosine\n"; cout << table << std::endl; }
|
输出:
1 2 3 4 5 6 7 8 9 10 11
| 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()
等。下面这个例程展示了如何使用静态方法、逗号初始化和 setXxx()
函数来初始化矩阵:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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;
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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
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
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
|
除此之外,Eigen还定义了一些用于生成基向量的方法:
Vector3f::UnitX()
: (1, 0, 0)
Vector3f::UnitY()
: (0, 1, 0)
Vector3f::UnitZ()
: (0, 0, 1)
VectorXf::Unit(size,i)
:
- 例如 :
VectorXf::Unit(4,1)
== Vector4f(0,1,0,0)
== Vector4f::UnitY()
用作临时对象
无论是逗号初始化程序还是上面介绍的几种类内静态方法,都可以用作表达式中的临时对象。
逗号初始化程序用作临时对象时,需要调用 finished()
方法获取实际的矩阵对象。
1 2 3 4 5 6 7 8 9 10 11 12 13
| int main() { MatrixXd m = MatrixXd::Random(3,3); m = (m + MatrixXd::Constant(3,3,1.2)) * 50; cout << "m =" << endl << m << endl; VectorXd v(3); v << 1, 2, 3; cout << "m * v =" << endl << m * v << endl; MatrixXf mat = MatrixXf::Random(2, 3); cout << "mat =\n" << mat << endl; mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat; cout << "mat =\n" << mat << endl; }
|
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| m = 10 55.9 14.7 23.2 63.3 77.9 85.6 31.9 77.9 m * v = 166 383 383 mat = -1 0.511 0.0655 -0.737 -0.0827 -0.562 mat = -0.737 -0.0827 -0.562 -1 0.511 0.0655
|