Eigen入门之密集矩阵 2-- Matrix及Vector的计算方法

简介

Eigen内的Matrix和Vector提供了类似C++的运算符,如+,-,*;也提供了编程的函数方法,如点乘和叉乘的dot(), cross(),如此等等。

在Eigen的Matrix类,代表矩阵matrics和向量vector,重载的运算符仅用于支持线性代数的运算,而不支持标量计算。比如matrix1 * matrix2,表示矩阵matrix 乘以 matrix2,而matrix1 + 10则不允许。

加法和减法

如大家所知,如果2个矩阵运行运算,对2个矩阵的行数和列数是有条件要求的。另外,在Eigen内,用于计算时,矩阵的系数类型必须统一,并不会内部进行类型转换。

二元运算符 + : ma + mb;

二元运算符 - : ma - mb;

一元运算符 - : - ma;

组合运算符 +=: ma+=mb;

组合运算符 -=: ma-=mb;

示例:

// matrix_cal1.cpp
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;

int main()
{
  Matrix2d a;
  a << 1, 2,
       3, 4;

  MatrixXd b(2,2);
  b << 5, 6,
       7, 8;

  std::cout << "a + b =\n" << a + b << std::endl;
  std::cout << "a - b =\n" << a - b << std::endl;
  std::cout << "Doing a += b;" << std::endl;
  a += b;
  std::cout << "Now a =\n" << a << std::endl;

  std::cout << endl;
  Vector3d v(1,2,3);
  Vector3d w(1,0,0);
  std::cout << "-v + w - v =\n" << -v + w - v << std::endl;
}

执行后输出:

$ ./matrix_cal1 
a + b =
 6  8
10 12
a - b =
-4 -4
-4 -4
Doing a += b;
Now a =
 6  8
10 12
-v + w - v =
-1
-4
-6

与标量的乘、除

与标量的乘法和除法计算是支持的,重载的操作符如下:

二元运算符 * : matrix * scalar;

二元运算符 * : scalar * matrix;

二元运算符 / : matrix / scalar;

组合运算符 *=: matrix *= scalar;

组合运算符 /=: matrix /= scalar;

示例:

// matrix_cal2.cpp
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;

int main()
{
  Matrix2d a;
  a << 1, 2,
       3, 4;

  std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl;

  Vector3d v(1,2,3);
  std::cout << "calculating v *= 2;" << std::endl;
  v *= 2;
  std::cout << "2.0 * v =\n" << 2.0 * v << std::endl;
  std::cout << "Now v =\n" << v << std::endl;

}

执行结果:

$ ./matrix_cal2
a * 2.5 =
2.5   5
7.5  10
calculating v *= 2;
2.0 * v =
 4
 8
12
Now v =
2
4
6

转置和共轭

在线性代数中,矩阵有转置操作,共轭计算,共轭转置计算: a T a^T aT, a ˉ \bar a aˉ, a ∗ a^* a, Matrix提供了对应的函数:transpose(), conjugate(), and adjoint()
说明一下: 共轭是针对复数而言的,共轭矩阵也是复数矩阵的对应的共轭矩阵。

示例程序:

// matrix_cal3.cpp
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

int main()
{
    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 conjugate of a\n" << a.conjugate() << endl;
    cout << "Here is the matrix a^*\n" << a.adjoint() << endl;
}

执行:

$ g++   matrix_cal3.cpp -o matrix_cal3 -I /usr/local/include/eigen3
$ ./matrix_cal3
Here is the matrix a
(-0.999984,-0.736924) (0.0655345,-0.562082)
(0.511211,-0.0826997)  (-0.905911,0.357729)
Here is the matrix a^T
(-0.999984,-0.736924) (0.511211,-0.0826997)
(0.0655345,-0.562082)  (-0.905911,0.357729)
Here is the conjugate of a
 (-0.999984,0.736924)  (0.0655345,0.562082)
 (0.511211,0.0826997) (-0.905911,-0.357729)
Here is the matrix a^*
 (-0.999984,0.736924)  (0.511211,0.0826997)
 (0.0655345,0.562082) (-0.905911,-0.357729)

对实数矩阵,并没有对应的共轭矩阵,其共轭转置矩阵就是其转置矩阵。

matrix-matrix与matrix-vector的乘法

矩阵的matrix-matrix乘法,及矩阵*矩阵,是由操作符operator *完成的。而在Eigen内,向量vector也是一种特殊的矩阵,所以,matrix-vector和vector-vector的乘法也是由operator *来完成。

这里有2种运算:

  • 二元运算符 * : a * b;
  • 复合运算符 *=: a *= b;

示例:

// matrix_cal4.cpp
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;

int main()
{
  Matrix2d mat;
  mat << 1, 2,
         3, 4;

  Vector2d u(-1,1), v(2,0);

  std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;
  std::cout << "Here is mat*u:\n" << mat*u << std::endl;
  std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl;
  std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;
  std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;
  std::cout << "Let's multiply mat by itself" << std::endl;

  mat = mat*mat;

  std::cout << "Now mat is mat:\n" << mat << std::endl;
}

执行

$ g++   matrix_cal4.cpp -o matrix_cal4 -I /usr/local/include/eigen3
$
$ ./matrix_cal4
Here is mat*mat:
 7 10
15 22
Here is mat*u:
1
1
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 mat:
 7 10
15 22

aliasing issues与运算模板

矩阵的点乘与叉乘

使用matrix类的dot(), cross()函数,来执行矩阵的点乘和叉乘。

点乘的结果可以看出是1X1的矩阵,u * v 还可以使用u.adjoint()*v进行计算.

示例:

#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

int main()
{
  Vector3d v(1,2,3);
  Vector3d w(0,1,2);
  cout << "Dot product: " << v.dot(w) << endl;
  double dp = v.adjoint() * w; // automatic conversion of the inner product to a scalar
  cout << "Dot product via a matrix product: " << dp << endl;
  cout << "Cross product:\n" << v.cross(w) << endl;
}

执行输出:

Dot product: 8
Dot product via a matrix product: 8
Cross product:
1
-2
1

基础算数操作–arithmetic reduction

对矩阵matrix或向量vector,提供了一些算数分解操作,比如获取矩阵的系数之和,最大值,最小值,平均值、及对角线的相关算数。

  • sum() : 系数之和
  • prod() : 系数乘积
  • maxCoeff() : 最大系数
  • minCoeff() : 最小系数
  • trace() : 对角线系数和。
#include <iostream>
#include <Eigen/Dense>
using namespace std;
int main()
{
  Eigen::Matrix2d mat;
  mat << 1, 2,
         3, 4;
  cout << "Here is mat.sum():       " << mat.sum()       << endl;   // 10
  cout << "Here is mat.prod():      " << mat.prod()      << endl;   // 24
  cout << "Here is mat.mean():      " << mat.mean()      << endl;   // 2.5
  cout << "Here is mat.minCoeff():  " << mat.minCoeff()  << endl;   // 1
  cout << "Here is mat.maxCoeff():  " << mat.maxCoeff()  << endl;   // 4 
  cout << "Here is mat.trace():     " << mat.trace()     << endl;   // 5
}

注意这些函数的重载,还可以同时获取该系数的位置。

// matrix_cal5.cpp
#include <iostream>
#include <Eigen/Dense>

using namespace Eigen;
using namespace std;

int main()
{
  Matrix3f m = Matrix3f::Random();
  std::ptrdiff_t i, j;

  float minOfM = m.minCoeff(&i,&j);

  cout << "Here is the matrix m:\n" << m << endl;
  cout << "Its minimum coefficient (" << minOfM 
       << ") is at position (" << i << "," << j << ")\n\n";

  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;

}

执行结果如下:

$ g++   matrix_cal5.cpp -o matrix_cal5 -I /usr/local/include/eigen3
$ ./matrix_cal5
Here is the matrix m:
 -0.999984 -0.0826997  -0.905911
 -0.736924  0.0655345   0.357729
  0.511211  -0.562082   0.358593
Its minimum coefficient (-0.999984) is at position (0,0)

Here is the vector v:  933495885 -250177384   41696341  710742668
Its maximum coefficient (933495885) is at position 0
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值