• eigen Matrix详解


    Eigen Matrix 详解

    在Eigen中,所有的matrices 和vectors 都是模板类Matrix 的对象,Vectors 只是一种特殊的矩阵,行或者列为1.

    Matrix的前三个模板参数

    Matrix 类有6个模板参数,现在我们了解前三个足够。剩下的三个参数都有默认值,后面会探讨,现在不管他。
    Matrix 的三个强制的模板参数:

    Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
    

    Scalar 就是矩阵元素标量类型。
    RowsAtCompileTime 和ColsAtCompileTime 分别指代编译时候的行和列值。
    Eigen中提供了许多typedefs ,例如Matrix4f 是4*4的float型矩阵:

    typedef Matrix<float, 4, 4> Matrix4f;
    

    正如前面提到的那样,在Eigen中,vectors 只是一种特殊形式的矩阵,有一行或者一列。在大多数情况下一列比较多,这样的向量也叫做列向量,也简称向量。其他情况叫做行向量。

    例如typedef Vector3f 是一个(列)向量,它的定义如下

    typedef Matrix<float, 3, 1> Vector3f;
    

    同样我们也提供了行向量的定义:

    typedef Matrix<int, 1, 2> RowVector2i;
    

    特殊值Dynamic

    当然,Eigen 不局限于在编译时候确定大小的矩阵。模板参数RowsAtCompileTime 和ColsAtCompileTime 可以传入特殊的值Dynamic ,来标志在编译时大小无法确定,需要当做运行时变量来处理。在中的术语叫做动态大小,与之相应的在编译时确定大小的叫做固定大小。
    例如typedef MatrixXd,指的是元素为double,大小为动态的:

    typedef Matrix<double, Dynamic, Dynamic> MatrixXd;1
    

    类似 typedef VectorXi如下:

    typedef Matrix<int, Dynamic, 1> VectorXi;1
    

    当然你可以定义一个固定行的,列是动态的float矩阵如下:

    Matrix<float, 3, Dynamic>1
    
    

    构造器

    总是会有默认的构造器,不会进行动态内存分配,也不会初始化矩阵元素。

    Matrix3f a;
    MatrixXf b;12
    

    这里,a是一个33的元素,其中还有一个float[9]数组,其中的元素没有初始化;b是一个动态大小的矩阵,目前的大小是00,它的元素数组完全没有分配。
    构造器中全入大小的构造器也是有的,行是先传入的。对于向量,直接传入向量大小。他们会分配元素数组,但是不会初始化元素。

    MatrixXf a(10,15);
    VectorXf b(30);12
    

    这里,a是10x15动态矩阵,数组内存已经分配,但是没有初始化;b是一个大小为30的向量,数组内存已经分配,但是元素没有初始化。
    为了提供统一的API ,在固定类型的矩阵上指定大小也是合法的,例如:

    Matrix3f a(3,3);1
    

    最后,我们提供了一些便捷方式为小的大小的向量元素提供初始化方法:

    Vector2d a(5.0, 6.0);
    Vector3d b(5.0, 6.0, 7.0);
    Vector4d c(5.0, 6.0, 7.0, 8.0);123
    

    逗号初始化

    
    void fun3()
    {
    Eigen::Matrix3f m;
    m << 1, 2, 3,
         4, 5, 6,
         7, 8, 9;
      std::cout << m;
    }12345678
    

    Matrix 和 vector元素可以通过逗号分隔初始化方法初始化

    Resizing

    rows(), cols() 和 size(). 分别返回矩阵的行数、列数和元素的个数.动态矩阵大小可以通过 resize()改变大小

    void fun4()
    {
        Eigen::MatrixXd m(2,5);
        cout<<"m "<<"rows="<<m.rows()<<"cols="<<m.cols()<<"coefficeints="<<m.size()<<endl;
        m.resize(4,5);
        cout<<"m "<<"rows="<<m.rows()<<"cols="<<m.cols()<<"coefficeints="<<m.size()<<endl;
        Eigen::VectorXd v(2);
        v.resize(5);
        cout<<"v "<<"rows="<<v.rows()<<"cols="<<v.cols()<<"coefficeints="<<v.size()<<endl;
    }12345678910
    

    resize() 如果大小没有变化将不会进行任何操作,否则则是破坏性的。如果你想使用resize() 同时不想改变元素的值,请使用conservativeResize()。
    为了达到API 的一致性,所有固定大小的矩阵都有上面的方法,试着改变固定大小的矩阵会触发断言错误。以下代码是合法的:

     Matrix4d m;
      m.resize(4,4); // no operation
      std::cout << "The matrix m is of size "
                << m.rows() << "x" << m.cols() << std::endl;1234
    

    Assignment 和resizing

    赋值是将一个矩阵拷贝进另外一个矩阵,使用操作符=。Eigen 会自动跳转左面元素的大小,从而使得它和右侧元素匹配。例如:

    MatrixXf a(2,2);
    std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;
    MatrixXf b(3,3);
    a = b;
    std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;12345
    

    a原先大小 2x2
    a现在大小 3x3
    当然,如果左侧是固定大小的矩阵,那么改变大小是不允许的。
    如果你不需要这种自动调整大小,你可以将他关闭。

    可选模板参数

    我下面看看剩下的三个可选参数:

    Matrix<typename Scalar,
           int RowsAtCompileTime,
           int ColsAtCompileTime,
           int Options = 0,
           int MaxRowsAtCompileTime = RowsAtCompileTime,
           int MaxColsAtCompileTime = ColsAtCompileTime>123456
    

    Options 是一个位字段。我们只讨论一个RowMajor,是按行存储,默认是按列存储的。Matrix

    引自:https://blog.csdn.net/sn_gis/article/details/79015488

  • 相关阅读:
    不懂数据库索引的底层原理?那是因为你心里没点b树
    你必须了解的java内存管理机制(三)-垃圾标记
    一次给女朋友转账引发我对分布式事务的思考
    看完此文,妈妈还会担心你docker入不了门?
    再过半小时,你就能明白kafka的工作原理了
    IEEE 754浮点数表示标准
    ROM正弦波发生器
    对分布式工程的初步认识和理解
    泛型(二)
    泛型(一)
  • 原文地址:https://www.cnblogs.com/ymd12103410/p/9720513.html
Copyright © 2020-2023  润新知