赞
踩
Eigen 中所有的矩阵和向量都是 Matrix 类。Matrix 模板类需要指定三个量:Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
。其中,Scalar
是类型;RowsAtCompileTime
和 ColsAtCompileTime
时所在的行数和列数。后三个参数是 <Options, MaxRowAtCompileTime, MaxColsAtCompileTime>
;Options
可以选为 RowMajor
变为行主格式。
当矩阵的行或者列为1时即是向量。Eigen::Dynamic
是该维度为动态。构造 Matrix 时,可以指动态矩阵的大小。eg.
Eigen::MatrixXf a(10, 15); // 形状为 10, 15 的动态矩阵
所有的矩阵都默认是列主存储格式。在 Eigen 的操作中,列主和行主矩阵可以混合运算,相互赋值,不受影响。但是 Eigen 默认支持列主矩阵,对列主阵的运算会更快,更安全。
// Initialize Vector
Matrix<int, 5, 1> b {1, 2, 3, 4, 5}; // A row-vector containing the elements {1, 2, 3, 4, 5}
// Initialize Matrix
Matrix<double, 2, 3> b {
{2, 3, 4}, // First Row
{5, 6, 7}, // Second Row
};
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Additional Notes
Vector 可以由 Eigen::all
初始化。即
Eigen::Matrix3f m;
m<< 1, 2, 3,
4, 5, 6,
7, 8, 9;
Eigen::Vector3f vec3 = m(Eigen::all, 1);
()
索引。可以作为左值和右值。// Simple Example
MatrixXd m(2,2);
m(0,0) = 3;
VectorXd v(2);
v(0) = 4;
索引方式分为四种:
Eigen:all
代表所有元素。(类似于 numpy 中的 :
)。// 第二列加到第一列上 -- 相当于 m[:, 0] += m[:, 1]
m(Eigen:all, 0) += m(Eigen:all, 1);
int[N]
).Eigen::seq
, Eigen::seqN
, or Eigen::lastN
functions;见页面Map
Slice,见 Map 章节。.resize(row, col)
变形矩阵。变形时,原矩阵对象会析构,矩阵内的值会改变。尤其是当前后大小不同时,变形后矩阵值会初始化为0。使用 conservativeResize()
保持矩阵内的值不变。Eigen 中的矩阵定义的运算法则为线性代数中的运算法则。如果需要做额外的运算,比如对应元素相乘,则需要用到 Array 类。 Array 类的初始化和 Matrix 类相同。
可以使用 .array()
和 .matrix()
在两者间转换。但是 Array 和 Matrix 不能相运算。
从 (i, j) 开始,大小为 (p, q) 的块:动态 .block(i, j, p, q)
;静态 .block<p, q>(i, j)
。Matrix 和 Array 都可以使用。分块对象可以作为左值和右值。
Eigen::MatrixXf m(4, 4);
Eigen::Matrix2f s;
s << 1, 1, 1, 1;
m.block(0, 0, 2, 2) = s; // 作为左值
.col(j)
与 .row(i)
将单独行、列作为块(与上相同)。对于向量,采用 .head(n)
/ .tail(n)
/ .segment(n)
分块。
每个类下都有静态函数初始化。(类似于 np.zeros
;np.ones
)
Eigen::MatrixXd m = Eigen::MatrixXd::Random(3, 3);
Eigen::MatrixXd m = Eigen::MatrixXd::Zeros(3, 3);
Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 3, 1);
矩阵或者矩阵块可以使用 setIdentity
/ setZero
/ setLinspaced
设置矩阵值。
名称 | 作用 |
---|---|
.sum() | 求和 |
.prod() | 累乘 |
.mean() | 求均值 |
.minCoeff() | 求最小值 |
.maxCoeff() | 求最大值 |
.trace() | 求迹 |
.norm() | 范数 |
.lpNorm<p>() | p 范数 |
.count() | 所有非零值个数 |
对 .maxCoeff()
和 .minCoeff()
可以传入指针,得到最大值所在的位置。
Eigen::Matrix2d m;
m << 1, 2, 3, 4;
double min;
float x, y;
min = m.minCoeff(&x, &y);
.colwise()
和 .rowwise()
对单独的行和列操作。这些可以和之前的 Reduction 操作结合。Eigen::Matrix2d m;
m << 1, 2, 3, 4;
m.colwise().sum(); // 对列求和,类似于 np.sum(m, axis=0)
复用内存,避免重新分配内存。
Map 声明:Map<Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> >
,只需要传入一个 Matrix
即可。构造函数要传入指针和矩阵大小:Map<MatrixXf> mf(pf, 3, 3)
。Map 和其他 Eigen 类型使用方法相同。
介绍 Stride
类。
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
class Eigen::Stride< _OuterStrideAtCompileTime, _InnerStrideAtCompileTime >
InnerStride
表示行主矩阵每行(或者列主矩阵每列)中两个相邻元素的距离。OuterStride
表示行主矩阵中相邻两行间相隔元素数。
在 (4, 4) 连续矩阵中,Innerstride 是 1,outerstride 是 4。
在声明 Map
时可以传入 Stride 切片。
Eigen::MatrixXf m(8, 8);
m = Eigen::MatrixXf::Random(8, 8);
// m[::2, ::2] 间隔一行一列索引
Eigen::Map<Eigen::MatrixXf, 0, Eigen::Stride<Eigen::Dynamic, 2>> map(m.data(), (m.rows() + 1) / 2, (m.cols() + 1) / 2, Eigen::Stride<Eigen::Dynamic, 2>(m.outerstride() * 2, 2));
Alias 指表达式中的元素同时出现在赋值符号的左右两侧,而且赋值顺序会影响最后的结果。Eigen 采用 Lazy Evaluation,并不会构造临时对象全部完成右值所有计算后再赋给左值。解决方法是使用 .eval()
完成右侧运算后再赋给左值。
// alias issue
mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2);
// use .eval() to resolve
mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2).eval();
或者采用 Inplace 操作
mat.transposeInplace();
所有的矩阵乘法都不受 Alias 影响。如果运算中并没有重叠的元素,也不会有 Alias 运算。
Eigen 中的几何变换模块,需要添加头文件 #include <Eigen/Geometry>
几何模块中基类 Eigen::Transform
, 可以由此构建任何变换矩阵:
// -- Recommand
Transform t(AngleAxis(angle, axis));
Transform t;
t = AngleAxis(angle, axis);
// -- DO NOT DO THIS
Transform t = AngleAxis(angle,axis);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。