5. 高级初始化方法(Advanced Initialization)
本文介绍几种高级的初始化矩阵的方法。将更详细的介绍先前提到的comma-initializer,还会介绍获取一些特殊矩阵的方法。
5.1 The comma initializer
Eigen提供了一种comma-initializer的初始化方法,使得我们可以很方便地定义一个矩阵(Matrix)、向量(Vector)或者是数组(Array)的所有元素。 comma-initializer允许我们从左上角到右下角依次列出矩阵的所有元素,但是元素个数必须和声明的矩阵大小匹配。 这就是我们在 初识Eigen中见到使用"<<"进行初始化的方法:
|
输出结果如下:
|
此外,comma-initializer进行初始化时也可以赋予向量或者是矩阵。逗号的使用则是把矩阵或者向量拼接起来。 需要强调的是用于初始化的矩阵大小应当能够匹配目标矩阵的大小。参考如下例程:
|
输出结果如下:
|
comma-initializer还可以用来给分块表达式(block expression)赋值。参考如下例程:
|
输出结果如下:
|
5.2 特殊的矩阵和数组
Matrix和Array类都有一个静态函数::Zero(), 用来将所有元素都赋0,有三个重载函数。 第一种没有参数只能用于fixed-size的矩阵或数组。如果想将dynamic-size的矩阵或数组初始化为0,必须提供矩阵或数组的大小。 因此,剩余两种重载函数分别要求一个和两个参数用来声明矩阵或数组的大小。参考如下例程:
|
输出结果如下:
|
类似的,还有一些其它的静态函数
- ::Constant(value)可以把各个元素都设置为value。 如果需要声明对象的大小,可以在value之前添加大小的参数,例如MatrixXd::Constant(rows, cols, value)。
- ::Random()则用来给矩阵或者数组的元素赋予随机值。
- ::Identity()可以用来构建单位矩阵,这个函数只适用于Matrix因为单位矩阵是线性代数里的概念。
- ::LinSpaced(size, low, high)只适用于Vector和一维的Array,它用来生成一个从low到high的长度为size的等差数列。
下面是一个使用LinSpaced()的一个例子,生成一个等差数列表示角度,然后计算它们的正弦和余弦函数值:
|
输出结果如下:
|
上面的例子展示了把初始化函数的输出赋值给一个对象或者表达式。 为了方便Eigen还提供了像.setZero(),.setIdentity(),.setLinSpaced()这样的函数直接操作对象。 下面的一个例子用了三种方法构造矩阵\(J=\begin{bmatrix}0 & I \\ I & 0\end{bmatrix}\), 依次为静态函数+赋值、静态函数+comma-initializer、和.SetXxx()函数
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;
5.3 临时对象的使用
如前面提到的,静态函数Zero()和Constant()可以在声明变量时用于初始化对象,也可以作为赋值运算的右值。 我们可以认为这些函数返回的是一个Matrix或者一个Array。实际上,它们返回的是一个被称为expression的对象, 这个对象可以在必要时转换为Matrix或者Array。
这些expression也可以用作临时对象。在 初识Eigen 中的第二个例程中我们就已经涉及到了,这里再详细介绍一下:
|
输出结果如下:
|
在上面的例子中表达式MatrixXd::Constant(3,3,1.2)生成了一个临时的对象。comma-initializer也可以生成临时对象。 下面的例子里,先构建了一个2*3的矩阵,然后与\(\begin{bmatrix}0 & 1 \\ 1 & 0\end{bmatrix}\)相乘。
|
输出结果如下:
|
为了和后面的实际的矩阵对象相乘必须调用finished()。