• Eigen 矩阵库学习笔记


    最近为了在C++中使用矩阵运算,简单学习了一下Eigen矩阵库。Eigen比Armadillo相对底层一点,但是只需要添加头文库即可使用,不使用额外的编译和安装过程。

    基本定义

    • Matrix3f3*3矩阵,MatrixXf表示矩阵维数不确定,MatrixXf m(3,4)表示3*4矩阵。
    • 'MatrixXddouble型,MatrixXffloat`型。

    列优先和行优先

    Eigen中存储Matrix用的是column-major,但是初始化赋值的时候是row-major

    Matrix3d m;
    m << 1,2,3,4,5,6,7,8,9;
    	/*	1 2 3
    		4 5 6
    		7 8 9*/
    

    m(3)=2,而不是4

    矩阵运算

    矩阵相乘:m1*m2
    element-wise 相乘:m1.cwiseProduct(m2)
    没有除法,但是有倒数,m1.cwiseInverse(),所以m1除m2即m1.cwiseProduct(m2.cwiseInverse())

    元素操作

    可以对Matrix中的所有元素使用常用函数或自定义函数进行运算,首先需要将Matrix转换为Array,例如

    m1.array().sqrt()
    

    等价于将m1矩阵中的所有元素xsqrt(x)

    注意:m1.array()将矩阵m1转换成了Array,此时m1不再是矩阵,不能够和其他矩阵出现在同一个表达式中,除非是=赋值运算符。Eigen允许将一个Array赋值给Matrix,也可以将一个Matrix赋值给Array。可以使用.matrix()将Array转换回矩阵。以下面代码为例:

    out = out.cwiseProduct(bn_var.array().sqrt().cwiseInverse());
    

    上面代码会报错,因为bn_var.array().sqrt().cwiseInverse()现在是Array,而不是Matrix。正确的表达式应该是

    out = out.cwiseProduct(bn_var.array().sqrt().cwiseInverse().matrix());
    

    可以使用.unaryExpr自定义函数,
    出处:https://stackoverflow.com/questions/33786662/apply-function-to-all-eigen-matrix-element @vsoftco

    #include <cmath>
    #include <iostream>
    
    #include <Eigen/Core>
    
    double Exp(double x) // the functor we want to apply
    {
        return std::exp(x);
    }
    
    int main()
    {
        Eigen::MatrixXd m(2, 2);
        m << 0, 1, 2, 3;
        std::cout << m << std::endl << "becomes: ";
        std::cout << std::endl << m.unaryExpr(&Exp) << std::endl;
    }
    

    从CSV中读取矩阵

    函数出处:https://gist.github.com/infusion/43bd2aa421790d5b4582 @Robert Eisele

    #include <iostream>
    #include <fstream>
    #include <Eigen/Dense>
    
    Eigen::MatrixXd readCSV(std::string file, int rows, int cols) {
    
      std::ifstream in(file);
      
      std::string line;
    
      int row = 0;
      int col = 0;
    
      Eigen::MatrixXd res = Eigen::MatrixXd(rows, cols);
    
      if (in.is_open()) {
    
        while (std::getline(in, line)) {
    
          char *ptr = (char *) line.c_str();
          int len = line.length();
    
          col = 0;
    
          char *start = ptr;
          for (int i = 0; i < len; i++) {
    
            if (ptr[i] == ',') {
              res(row, col++) = atof(start);
              start = ptr + i + 1;
            }
          }
          res(row, col) = atof(start);
    
          row++;
        }
    
        in.close();
      }
      return res;
    }
    

    replicate

    vec.replicate(times) 
    mat.replicate(vertical_times, horizontal_times)
    mat.colwise().replicate(vertical_times, horizontal_times)
    mat.rowwise().replicate(vertical_times, horizontal_times) 
    
  • 相关阅读:
    CodeForces 52B Right Triangles 矩阵上的计数
    电影节
    怎样高速生成随机数
    VS2010版快捷键
    两个下拉框选择后取出这两个框的区间值
    vs操作快捷键
    输入框限制,条件是左边输入框输入的数字要小于右边输入框的值,两边输入框要为整型数字。
    DateTime.Parse
    清空文本输入框的值
    sql 随机函数newid()
  • 原文地址:https://www.cnblogs.com/yaos/p/14014217.html
Copyright © 2020-2023  润新知