概述
Eigen库学习 ---- 2.矩阵向量的算数运算
上篇:Eigen库学习 ---- 1.矩阵类
本篇为这个链接的学习总结。
Eigen库提供了矩阵向量的算数运算,如‘+ - * /’,或者特殊运算,如’dot(),cross()’。
一、加法和减法运算
加减运算必须保证两边的矩阵向量的维度相同,即有相同的rows和cols,元素的类型也必须相同,因为Eigen不会自动提升数据类型。加减运算有如下:
√ binary operator + as in a+b ( 二元运算符)
√ binary operator – as in a-b’ (二元运算符)
√ unary operator – as in -a (一元运算符)
√ compound operator += as in a+=b(混合运算符)
√ compound operator -= as in a-=b (混合运算符)
例如:
Matrix2d a;
a << 1,2,3,4;
MatrixXd b(2,2);
b << 2, 3, 1, 4;
cout << "a+b=n" << a + b << endl;
cout << "a-b=n" << a - b << endl;
a += b;
cout << "Now a=n" << a << endl;
Vector3d v(1, 2, 3);
Vector3d w(1, 0, 0);
cout << "-v+w-v=n" << -v + w - v << endl;
输出结果如下:
a+b=
3 5
4 8
a-b=
-1 -1
2 0
Now a=
3 5
4 8
-v+w-v=
-1
-4
-6
二、标量 与 矩阵向量 的 乘除法 运算
标量的乘法和除法很简单,运算符如下:
√ binary operator * as in ‘matrix * scalar’( 二元运算符)
√ binary operator * as in ‘scalar * matrix’( 二元运算符)
√ unary operator / as in ‘matrix/scalar’( 一元运算符)
√ compound operator * = as in ‘matrix*=scalar’( 混合运算符)
√ compound operator /= as in ‘matrix/=scalar’( 混合运算符)
例如:
Matrix2d a;
a << 1, 2, 3, 4;
Vector3d v(1,2,3);
cout << "a*2.5=n" << a*2.5 << endl;
cout << "0.1*v=n" << 0.1*v << endl;
v *= 2;
cout << "v*=2,v=n" << v << endl;
输出结果如下:
a*2.5=
2.5 5
7.5 10
0.1*v=
0.1
0.2
0.3
v*=2,v=
2
4
6
三、Eigen乘法运算的简洁表达
Eigen对代码做了许多优化,可以不用写一些很冗余的代码,如下面的表达式:
VectorXf a(50), b(50), c(50), d(50);
for (int i = 0; i<50; i++)
a[i] = 3 * b[i] + 4 * c[i] + 5 * d[i];
在Eigen库中,可以这样简洁的写:
a = 3 * b + 4 * c + 5 * d;
四、矩阵的转置、伴随、共轭
A
T
A^T
AT
A
∗
A^*
A∗
A
ˉ
bar{A}
Aˉ
转置、伴随、共轭的使用如下:
MatrixXcf a = MatrixXcf::Random(2,2);
cout << "Here is the matrix a:n" << a << endl;
cout << "Here is the matrix a^T:n" << a.transpose() << endl;
cout << "Here is the matrix a^*:n" << a.adjoint() << endl;
cout << "Here is the conjugate of matrix a:n" << a.conjugate() << endl;
输出结果如下:
Here is the matrix a:
(0.127171,-0.997497) (-0.0402539,0.170019)
(0.617481,-0.613392) (0.791925,-0.299417)
Here is the matrix a^T:
(0.127171,-0.997497) (0.617481,-0.613392)
(-0.0402539,0.170019) (0.791925,-0.299417)
Here is the matrix a^*:
(0.127171,0.997497) (0.617481,0.613392)
(-0.0402539,-0.170019) (0.791925,0.299417)
Here is the conjugate of matrix a:
(0.127171,0.997497) (-0.0402539,-0.170019)
(0.617481,0.613392) (0.791925,0.299417)
对于基本的算数运算符,transpose()和adjuint()只返回一个代理对象,而不执行实际的转置。如果执行b=transpose(),则将结果写入b的同时计算转置。如果执行a=a.transpose(),则在转置求完值之前,Eigen开始将结果写入a。因此,a=a.transpose()不会像预期的那样转置替换a。如下:
Matrix2i a;
a << 1, 2, 3, 4;
cout << "Here is the matrix a:n" << a << endl;
//a = a.transpose();//这一句如果运行,会报错,报错类型是:别名问题。
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
3 4
如果要执行原地转置,例如在a=a.transpose()中,只需使用transposeInPlace ()函数即可。例如:
Matrix2i a;
a << 1, 2, 3, 4;
cout << "Here is the initial matrix a:n" << a << endl;
a.transposeInPlace();
cout << "after being transposed:n" << a << endl;
输出结果如下:
Here is the initial matrix a:
1 2
3 4
after being transposed:
1 3
2 4
五、矩阵乘矩阵/矩阵乘向量
矩阵与矩阵相乘用的是操作符*。因为向量是一种特殊的矩阵,所以矩阵与向量的积实际上只是矩阵与矩阵的积的一种特殊情况,向量外积也是。所以操作符只有两个:
√ binary operator * as in a * b( 二元运算符)
√ compound operator * = as in a * =b( 混合运算符)
例如:
Matrix2d mat;
mat << 1, 2,
3, 4;
Vector2d u(-1, 1), v(2, 0);
cout << "Here is mat*mat:n" << mat * mat << endl << endl;
cout << "Here is mat*u:n" << mat * u << endl << endl;
cout << "Here is mat*v:n" << mat * v << endl << endl;
cout << "Here is u^T*mat:n" << u.transpose() * mat << endl << endl;
cout << "Here is u^T*v:n" << u.transpose() * v << endl << endl;
cout << "Here is u*v^T:n" << u * v.transpose() << endl << endl;
cout << "Let's multiply mat by itself." << endl;
mat = mat * mat;
cout << "Now mat is:" << endl;
cout << mat << endl;
输出结果如下:
Here is mat*mat:
7 10
15 22
Here is mat*u:
1
1
Here is mat*v:
2
6
Here is u^T*mat:
2 2
Here is u^T*v:
-2
Here is u*v^T:
-2 -0
2 0
Let's multiply mat by itself.
Now mat is:
7 10
15 22
六、点乘和叉乘
点乘和叉乘是用的dot()和cross()方法。点乘可以理解为1x1的矩阵,如u.adjoint()*v
例如:
Vector3d v(1,2,3);
Vector3d w(0,1,2);
cout << "点乘:" << v.dot(w) << endl;
double dp = v.adjoint()*w;
cout << "通过矩阵乘法的点乘:" << dp << endl;
cout << "叉乘:n" << v.cross(w) << endl;
输出结果为:
点乘:8
通过矩阵乘法的点乘:8
叉乘:
1
七、基本算数运算简化计算
Eigen提供了一些基本运算来简化矩阵和向量的运算。如sum()求和,prod()求积,maxCoeff()求元素的最大值,minCoeff()求元素最小值。
例如:
Matrix2d mat;
mat << 1,2,
3,4;
cout << "Here is mat.sum(): " << mat.sum() << endl;
cout << "Here is mat.prob(): " << mat.prod() << endl;
cout << "Here is mat.mean(): " << mat.mean() << endl;
cout << "Here is mat.minCoeff():" << mat.minCoeff() << endl;
cout << "Here is mat.maxCoeff():" << mat.maxCoeff() << endl;
cout << "Here is mat.trace(): " << mat.trace() << endl;
输出结果如下:
Here is mat.sum(): 10
Here is mat.prob(): 24
Here is mat.mean(): 2.5
Here is mat.minCoeff():1
Here is mat.maxCoeff():4
Here is mat.trace(): 5
函数trance()返回的是矩阵的对角线之和,也可以用diagonal().sum()来高效地计算。minCoeff和maxCoeff也存在变体,可以通过给定参数来返回相应元素的坐标。
例如:
Matrix3f m = Matrix3f::Random();
ptrdiff_t i, j;
float minOfM = m.minCoeff(&i, &j);
cout << "Here is the matrix m:n" <<m<< endl;
cout << "Its minimum cofficient (" << minOfM << ") is at position (" << i << "," << j << ")nn";
RowVector4i v = RowVector4i::Random();
int maxOfV = v.maxCoeff(&i);
cout << "Here is the vector v:" << v << endl;
cout << "Its maximum coefficient (" << maxOfV << ") is at position " << i << endl;
输出结果如下:
Here is the matrix m:
-0.997497 0.617481 -0.299417
0.127171 0.170019 0.791925
-0.613392 -0.0402539 0.64568
Its minimum cofficient (-0.997497) is at position (0,0)
Here is the vector v: 8080 -10679 11761 6897
Its maximum coefficient (11761) is at position 2
下篇:Eigen库学习 ---- 3.数组类和系数运算
最后
以上就是默默灯泡为你收集整理的Eigen库学习 ---- 2.矩阵\向量的算数运算的全部内容,希望文章能够帮你解决Eigen库学习 ---- 2.矩阵\向量的算数运算所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复