一、逗号初始化式
Eigen提供了一个逗号初始化语法,允许用户轻松设置矩阵、向量或数组的所有系数。简单地列出系数,从左上角开始,从左到右,从上到下。对象的大小需要事先指定。如果你列出的系数太少或太多,Eigen就会报错。
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
//输出
1 2 3
4 5 6
7 8 9
此外,初始化列表的元素本身可以是向量或矩阵。一个常见的用法是将向量或矩阵连接在一起。
例如,这里是如何将两个行向量连接在一起。记住,必须先设置大小,然后才能使用逗号初始化器。
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
逗号初始化器也可用于填充块表达式,如 m.row(i)。下面是一种更复杂的方法,可以获得与上面第一个示例相同的结果:
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
二、特殊矩阵和数组
Matrix 和 Array 类具有 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(value) 将所有系数设置为 value。如果需要指定对象的大小,则附加参数放在value参数之前,如MatrixXd::Constant(rows, cols, value)。
Random() 方法用随机系数填充矩阵或数组。单位矩阵可以通过调用identity()得到;这种方法只适用于矩阵,不适用于数组,因为“单位矩阵”是线性代数的概念。方法 LinSpaced(size, low, high) 只适用于向量和一维数组;它产生一个指定大小的矢量,其系数在低和高之间的间隔相等。下面的示例说明了 LinSpaced() 方法,它打印一个表,其中包含以度为单位的角度、以弧度为单位的对应角度以及它们的正弦和余弦。
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
这个例子显示了 LinSpaced() 返回的对象可以被赋值给变量(和表达式)。Eigen定义了像 setZero(), MatrixBase::setIdentity() 和DenseBase::setLinSpaced() 这样的实用函数来方便地做到这一点。
下面的示例对比了构造矩阵 J= 的三种方法:使用静态方法和赋值,使用静态方法和逗号初始化器,或使用 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;
//输出
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
所有预定义的矩阵,矢量和数组对象的摘要可以在快速参考指南中找到。
三、作为临时对象使用
如上所示,静态方法 Zero() 和 Constant() 可用于在声明时或赋值操作符右侧初始化变量。你可以把这些方法想象成返回一个矩阵或数组;实际上,它们返回所谓的表达式对象,在需要时计算为矩阵或数组,因此这种语法不会产生任何开销。
这些表达式也可以用作临时对象。我们在这里复制了入门指南中的第二个示例,它已经说明了这一点。
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
using Eigen::VectorXd;
int main()
{
MatrixXd m = MatrixXd::Random(3,3);
m = (m + MatrixXd::Constant(3,3,1.2)) * 50;
std::cout << "m =" << std::endl << m << std::endl;
VectorXd v(3);
v << 1, 2, 3;
std::cout << "m * v =" << std::endl << m * v << std::endl;
}
//输出
m =
94 89.8 43.5
49.4 101 86.8
88.3 29.8 37.8
m * v =
404
512
261
表达式 m + MatrixXf::Constant(3, 3 , 1.2) 构造3 × 3矩阵表达式,其所有系数等于1.2加上m的相应系数。
逗号初始化器也可用于构造临时对象。下面的例子构造了一个大小为2 × 3的随机矩阵,然后将这个矩阵与左边的[0110]相乘。文章来源:https://www.toymoban.com/news/detail-859760.html
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
完成临时子矩阵的逗号初始化后,这里需要 finished() 方法来获取实际的矩阵对象。文章来源地址https://www.toymoban.com/news/detail-859760.html
到了这里,关于Eigen-高级矩阵初始化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!