我是靠谱客的博主 默默灯泡,这篇文章主要介绍Eigen库学习 ---- 2.矩阵\向量的算数运算,现在分享给大家,希望可以做个参考。

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 (混合运算符
例如:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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’( 混合运算符
例如:

复制代码
1
2
3
4
5
6
7
8
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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对代码做了许多优化,可以不用写一些很冗余的代码,如下面的表达式:

复制代码
1
2
3
4
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库中,可以这样简洁的写:

复制代码
1
2
a = 3 * b + 4 * c + 5 * d;

四、矩阵的转置、伴随、共轭

             A T A^T AT   A ∗ A^* A   A ˉ bar{A} Aˉ  
转置、伴随、共轭的使用如下:

复制代码
1
2
3
4
5
6
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
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。如下:

复制代码
1
2
3
4
5
6
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;

运行结果如下:

复制代码
1
2
3
4
5
6
7
Here is the matrix a: 1 2 3 4 and the result of the aliasing effect: 1 2 3 4

  如果要执行原地转置,例如在a=a.transpose()中,只需使用transposeInPlace ()函数即可。例如:

复制代码
1
2
3
4
5
6
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
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( 混合运算符
例如:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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
例如:

复制代码
1
2
3
4
5
6
7
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;

输出结果为:

复制代码
1
2
3
4
5
点乘:8 通过矩阵乘法的点乘:8 叉乘: 1

七、基本算数运算简化计算

  Eigen提供了一些基本运算来简化矩阵和向量的运算。如sum()求和,prod()求积,maxCoeff()求元素的最大值,minCoeff()求元素最小值。
例如:

复制代码
1
2
3
4
5
6
7
8
9
10
11
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
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也存在变体,可以通过给定参数来返回相应元素的坐标。
例如:

复制代码
1
2
3
4
5
6
7
8
9
10
11
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;

输出结果如下:

复制代码
1
2
3
4
5
6
7
8
9
10
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库学习内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部