• Eigen : Matrix and Vector arithmetic


    Eigen库 有重载关于Matrix与Vector的计算符,这样我们可以很方便的得到矩阵运算后的结果。

    一些基本运算符:+,-,*,/,+=,-=,*=,/=

    普通的矩阵加减法运算:

    #include <iostream>
    #include <Eigen/Dense>
     
    using namespace Eigen;
     
    int main()
    {
      Matrix2d a;
      a << 1, 2,
           3, 4;
      MatrixXd b(2,2);
      b << 2, 3,
           1, 4;
      std::cout << "a + b =
    " << a + b << std::endl;
      std::cout << "a - b =
    " << a - b << std::endl;
      std::cout << "Doing a += b;" << std::endl;
      a += b;
      std::cout << "Now a =
    " << a << std::endl;
      Vector3d v(1,2,3);
      Vector3d w(1,0,0);
      std::cout << "-v + w - v =
    " << -v + w - v << std::endl;
    }

    Output:

    a + b =
    3 5
    4 8
    a - b =
    -1 -1
     2  0
    Doing a += b;
    Now a =
    3 5
    4 8
    -v + w - v =
    -1
    -4
    -6

    乘法运算:

    #include <iostream>
    #include <Eigen/Dense>
     
    using namespace Eigen;
     
    int main()
    {
      Matrix2d a;
      a << 1, 2,
           3, 4;
      Vector3d v(1,2,3);
      std::cout << "a * 2.5 =
    " << a * 2.5 << std::endl;
      std::cout << "0.1 * v =
    " << 0.1 * v << std::endl;
      std::cout << "Doing v *= 2;" << std::endl;
      v *= 2;
      std::cout << "Now v =
    " << v << std::endl;
    }

    Output:

    a * 2.5 =
    2.5   5
    7.5  10
    0.1 * v =
    0.1
    0.2
    0.3
    Doing v *= 2;
    Now v =
    2
    4
    6

    除此之外,Eigen库关于运算还有个很人性化的地方
    比如,VectorXf a(50),b(50),c(50),d(50);
    ...
    a = 3 * b + 4 * c + 5 * d;
    会自动编译为:
    for(int i = 0 ; i < 50 ; i++){
    a[i] = 3*b[i] + 4*c[i] + 5*d[i];
    }

    注意:如果你看了上面一段关于表达式模板的内容,担心做m=m*m会引起别名问题,暂时放心。Eigen将矩阵乘法作为一种特殊情况处理,并注意在这里引入一个临时的,所以它将把m=m*m编译为:

    temp = m*m;
    m = temp;

    然后是一些特殊的计算函数,十分便利:

    sum() //矩阵内元素和
    prod() //元素积
    mean() //元素平均
    minCoeff() //最小元素
    maxCoeff() //最大元素
    trace() //对角线和
    transpose() //转置
    conjugate() //共轭
    adjoint() //共轭转置

    普通计算函数示例代码:

    #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;
      cout << "Here is mat.prod():      " << 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;
    }

    Output:

    Here is mat.sum():       10
    Here is mat.prod():      24
    Here is mat.mean():      2.5
    Here is mat.minCoeff():  1
    Here is mat.maxCoeff():  4
    Here is mat.trace():     5

    并且minCoeff()与maxCoeff()能够得到相应元素的下标,可使用如下方法实现:

    int i,j;

    minCoeff(&i,&j);

    maxCoeff(&i,&j);

    得到的i,j就是相应元素的横纵坐标。

    转置,共轭,共轭转置示例代码:

    MatrixXcf a = MatrixXcf::Random(2,2); //随机2x2矩阵
    cout << "Here is the matrix a
    " << a << endl;
     
    cout << "Here is the matrix a^T
    " << a.transpose() << endl;
     
     
    cout << "Here is the conjugate of a
    " << a.conjugate() << endl;
     
     
    cout << "Here is the matrix a^*
    " << a.adjoint() << endl;

    Output:

    Here is the matrix a
        (-1,-0.737) (0.0655,-0.562)
    (0.511,-0.0827)  (-0.906,0.358)
    Here is the matrix a^T
        (-1,-0.737) (0.511,-0.0827)
    (0.0655,-0.562)  (-0.906,0.358)
    Here is the conjugate of a
         (-1,0.737)  (0.0655,0.562)
     (0.511,0.0827) (-0.906,-0.358)
    Here is the matrix a^*
         (-1,0.737)  (0.511,0.0827)
     (0.0655,0.562) (-0.906,-0.358)

    注意:至于基本的算术运算符,transpose()和 adjoint()只是返回一个代理对象,而不进行实际的转置。如果你做b = a.transpose(),那么在将结果写入b的同时就会对transpose进行评估。如果执行a = a.transpose(),那么在转置的评估完成之前,Eigen就开始将结果写入a中。因此,指令a = a.transpose()并不像人们所期望的那样,用它的转置替换a。

    还有两个函数差点忘记说了,分别是dot()与cross(),一个是计算点积,一个是计算叉积,非常实用的两个函数!

    补充两个编译时容易出现的错误:(官方文档详细说明)

    Eigen checks the validity of the operations that you perform. When possible, it checks them at compile time, producing compilation errors. These error messages can be long and ugly, but Eigen writes the important message in UPPERCASE_LETTERS_SO_IT_STANDS_OUT. For example:(Eigen会检查你所执行的操作的有效性,在可能的情况下,它会在编译时检查它们,产生编译错误。在可能的情况下,它在编译时检查它们,产生编译错误。这些错误信息可能又长又丑,但Eigen会把重要的信息用UPPERCASE_LETTERS_SO_IT_STANDS_OUT写出来,如下:)

    Matrix3f m;
    Vector4f v;
    v = m*v; // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
     
    Of course, in many cases, for example when checking dynamic sizes, the check cannot be performed at compile time. Eigenthen uses runtime assertions. This means that the program will abort with an error message when executing an illegal operation if it is run in "debug mode", and it will probably crash if assertions are turned off(当然,在很多情况下,比如检查动态大小时,不能在编译时进行检查。Eigen就会使用运行时断点。这意味着,如果在 "debug模式 "下运行,程序在执行非法操作时,会以错误信息中止,如果断点被关闭,程序很可能会崩溃).
     
    MatrixXf m(3,3);
    VectorXf v(4);
    v = m * v; // Run-time assertion failure here: "invalid matrix product"

     

    解释:第一个就是两种不同类型的矩阵相乘会出现SIZE报错,这是理所当然的,第二个就是检查动态大小时,不能在编译时进行检查!

     

    -------------------------------------------------------------------------------------------------------------

    有些内容暂时用不到,以后补充。

  • 相关阅读:
    input框限制只能输入正整数、字母、小数、
    css水平垂直居中
    Android开发之旅-获取地理位置的经度和纬度
    Android DDMS应用
    Android开发BUG及解决方法2
    Android开发BUG及解决方法1
    Android开发BUG及解决方法
    Android系统架构
    1.sql简介
    C语言笔试常考知识点
  • 原文地址:https://www.cnblogs.com/xiangqi/p/14212217.html
Copyright © 2020-2023  润新知