Matrix
Matrix是一个类模板,代表矩阵
模板的前三个参数:
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Scalar
矩阵数据类型
Eigen中已经定义好了一些类
例如
-
Matrix3d 是 Matrix<double, 3,3>
-
MatrixXd是 大小不确定,数据类型为double的矩阵
-
Matrix4i Matrix<int,4,4>
可以自定义一个新的矩阵
typedef Matrix<int, 5, 5> Matrix5i;
动态参数
可以使用Dynamic
定义为止大小的矩阵
typedef Matrix<float, Dynamic, 1> VectorXfCol;
VectorXfCol m(2);
m << 1, 2;
cout << m << endl;
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
Matrix<float, 3, Dynamic>
可选模板参数
Matrix<typename Scalar,
int RowsAtCompileTime,
int ColsAtCompileTime,
int Options = 0,
int MaxRowsAtCompileTime = RowsAtCompileTime,
int MaxColsAtCompileTime = ColsAtCompileTime>
- Options是一个位域。这里,我们只讨论一个位:RowMajor。它指定这种类型的矩阵使用行主存储顺序;默认情况下,存储顺序是column-major。
Matrix<float, 3, 3, RowMajor>
- MaxRowsAtCompileTime和MaxColsAtCompileTime是有用的,当你想指定,即使你的矩阵的确切大小在编译时还不知道,一个固定的上限在编译时是已知的。您可能希望这样做的最大原因是为了避免动态内存分配。例如,下面的矩阵类型使用12个浮点数的普通数组,没有动态内存分配
Matrix<float, Dynamic, Dynamic, 0, 3, 4>
初始化
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);
Vector2i a(1, 2); // A column vector containing the elements {1, 2}
Matrix<int, 5, 1> b {1, 2, 3, 4, 5}; // A row-vector containing the elements {1, 2, 3, 4, 5}
Matrix<int, 1, 5> c = {1, 2, 3, 4, 5}; // A column vector containing the elements {1, 2, 3, 4, 5}
MatrixXi a { // construct a 2x2 matrix
{1, 2}, // first row
{3, 4} // second row
};
Matrix<double, 2, 3> b {
{2, 3, 4},
{5, 6, 7},
};
//Comma-initialization
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
其他操作
函数 | 作用 | 备注 |
---|---|---|
rows(), cols() | 获取行列数 | |
resize(a,b) | 重置大小 | 只对没有初始化的矩阵有用,使用=将一个矩阵赋值给另一个矩阵时,会自动重置等号左面矩阵大小 |
MatrixXd m(2,5);
m.resize(4,3);
VectorXd v(2);
v.resize(5);
Matrix4d m;
m.resize(4,4);
矩阵线性计算
ℹ️
值得注意,矩阵计算并不会直接计算结果,而是会返回一个计算表达式,当需要矩阵结果的时候,编译器会对表达式进行优化,再计算出结果
矩阵加减
- a+b
- a-b
- -a
- a+=b
- a-=b
标量乘除
- m*a
- a*m
- m/a
- m*=a
- m/=a
转置 a T a^T aT、共轭 a ‾ \overline{a} a、伴随矩阵 a ∗ a^* a∗
//转置
a.transpose() ;
//共轭
a.conjugate() ;
//伴随矩阵
a.adjoint() ;
注意:使用类似与 a = a.transpose()这样的语句时,会出错,因为会一边计算,一边将a中的值更新,导致数据不一致出错。称为混叠问题(aliasing issues)
//错误示例
Matrix2i a; a << 1, 2, 3, 4;
cout << "Here is the matrix a:\n" << a << endl;
a = a.transpose(); // !!! do NOT do this !!!
cout << "and the result of the aliasing effect:\n" << a << endl;
输出
Here is the matrix a:
1 2
3 4
and the result of the aliasing effect:
1 2
2 4
//正确用法
MatrixXf a(2,3); a << 1, 2, 3, 4, 5, 6;
cout << "Here is the initial matrix a:\n" << a << endl;
a.transposeInPlace();
cout << "and after being transposed:\n" << a << endl;
矩阵和矩阵(向量)乘法
- 使用
*
- 使用
*=
注意:矩阵乘矩阵不会造成混叠问题,因为使用了临时变量
例如,m=m*m
会被编译为
tmp=m*m;
m=tmp;
如果能够确保自己的表达式没有混叠问题,不适用临时变量,则可以使用 noalias()
函数
c.noalias() += a * b
点乘和叉乘
- 点乘: v.dot
- 叉乘 v.cross
:info
叉乘只适用于 大小为3的向量,点乘适用于任何大小的向量
Vector3d m1{1,2,3};
Vector3d m2 = m1 + Vector3d::Constant(1);
std::cout << m1.dot(m2) << endl;
std::cout << m1.cross(m2) << endl;
基本算数reduction操作
- 和 sum
- 均值 mean
- 乘积 prod
- 最值 maxCoeff minCoeff
- 迹 trace
Matrix4i m ;
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12,
13, 14, 15, 16;
int i, j;
std::cout << m << endl;
std::cout <<"sum\t"<< m.sum() << endl;
std::cout << "mean\t" << m.mean() << endl;
std::cout << "prod\t" << m.prod() << endl;
std::cout << "maxCoeff\t" << m.maxCoeff(&i,&j) <<"@"<<i<<","<<j << endl;
std::cout << "minCoeff\t" << m.minCoeff() << endl;
std::cout << "trace\t" << m.trace() << endl;