Eigen常规矩阵定义

1.使用

Eigen的使用在官网上有详细的介绍,这里对我学习过程中用到的基本操作进行介绍。首先是矩阵的定义。
在矩阵类的模板参数共有6个。一般情况下我们只需要关注前三个参数即可。前三个模板参数如下所示:

  1. Matrix<typename Scalar,int RowsAtCompileTime,int ColsAtCompileTime>
  1. Scalar参数为矩阵元素的类型,该参数可以是int,float,double等。
  2. RowsAtCompileTime和ColsAtCompileTime是矩阵的行数和列数。

Matrix<float,4,4> M44是定义一个4×4的矩阵,矩阵元素以float类型存储。直接使用矩阵模板定义一个矩阵往往会觉得麻烦,Eigen提供了一些基本矩阵的别名定义,如typedef Matrix<float,4,4> Matrix4f.下面是一些内置的别名定义.来源于官方手册

  1. typedef Matrix< std::complex<double> , 2 , 2 > Matrix2cd
  2. typedef Matrix< std::complex<float> , 2 , 2 > Matrix2cf
  3. typedef Matrix< double , 2 , 2 > Matrix2d
  4. typedef Matrix< float , 2 , 2 > Matrix2f
  5. typedef Matrix< int , 2 , 2 > Matrix2i
  6. typedef Matrix< std::complex<double> , 3 , 3 > Matrix3cd
  7. typedef Matrix< std::complex<float> , 3 , 3 > Matrix3cf
  8. typedef Matrix< double , 3 , 3 > Matrix3d
  9. typedef Matrix< float , 3 , 3 > Matrix3f
  10. typedef Matrix< int , 3 , 3 > Matrix3i
  11. typedef Matrix< std::complex<double> , 4 , 4 > Matrix4cd
  12. typedef Matrix< std::complex<float> , 4 , 4 > Matrix4cf
  13. typedef Matrix< double , 4 , 4 > Matrix4d
  14. typedef Matrix< float , 4 , 4 > Matrix4f
  15. typedef Matrix< int , 4 , 4 > Matrix4i
  16. typedef Matrix< std::complex<double> , Dynamic , Dynamic > MatrixXcd
  17. typedef Matrix< std::complex<float> , Dynamic , Dynamic > MatrixXcf
  18. typedef Matrix< double , Dynamic , Dynamic > MatrixXd
  19. typedef Matrix< float , Dynamic , Dynamic > MatrixXf
  20. typedef Matrix< int , Dynamic , Dynamic > MatrixXi
  21. typedef Matrix< std::complex<double> , 1, 2 > RowVector2cd
  22. typedef Matrix< std::complex<float> , 1, 2 > RowVector2cf
  23. typedef Matrix< double , 1, 2 > RowVector2d
  24. typedef Matrix< float , 1, 2 > RowVector2f
  25. typedef Matrix< int , 1, 2 > RowVector2i
  26. typedef Matrix< std::complex<double> , 1, 3 > RowVector3cd
  27. typedef Matrix< std::complex<float> , 1, 3 > RowVector3cf
  28. typedef Matrix< double , 1, 3 > RowVector3d
  29. typedef Matrix< float , 1, 3 > RowVector3f
  30. typedef Matrix< int , 1, 3 > RowVector3i
  31. typedef Matrix< std::complex<double> , 1, 4 > RowVector4cd
  32. typedef Matrix< std::complex<float> , 1, 4 > RowVector4cf
  33. typedef Matrix< double , 1, 4 > RowVector4d
  34. typedef Matrix< float , 1, 4 > RowVector4f
  35. typedef Matrix< int , 1, 4 > RowVector4i
  36. typedef Matrix< std::complex<double> , 1, Dynamic > RowVectorXcd
  37. typedef Matrix< std::complex<float> , 1, Dynamic > RowVectorXcf
  38. typedef Matrix< double , 1, Dynamic > RowVectorXd
  39. typedef Matrix< float , 1, Dynamic > RowVectorXf
  40. typedef Matrix< int , 1, Dynamic > RowVectorXi
  41. typedef Matrix< std::complex<double> , 2 , 1> Vector2cd
  42. typedef Matrix< std::complex<float> , 2 , 1> Vector2cf
  43. typedef Matrix< double , 2 , 1> Vector2d
  44. typedef Matrix< float , 2 , 1> Vector2f
  45. typedef Matrix< int , 2 , 1> Vector2i
  46. typedef Matrix< std::complex<double> , 3 , 1> Vector3cd
  47. typedef Matrix< std::complex<float> , 3 , 1> Vector3cf
  48. typedef Matrix< double , 3 , 1> Vector3d
  49. typedef Matrix< float , 3 , 1> Vector3f
  50. typedef Matrix< int , 3 , 1> Vector3i
  51. typedef Matrix< std::complex<double> , 4 , 1> Vector4cd
  52. typedef Matrix< std::complex<float> , 4 , 1> Vector4cf
  53. typedef Matrix< double , 4 , 1> Vector4d
  54. typedef Matrix< float , 4 , 1> Vector4f
  55. typedef Matrix< int , 4 , 1> Vector4i
  56. typedef Matrix< std::complex<double> , Dynamic , 1> VectorXcd
  57. typedef Matrix< std::complex<float> , Dynamic , 1> VectorXcf
  58. typedef Matrix< double , Dynamic , 1> VectorXd
  59. typedef Matrix< float , Dynamic , 1> VectorXf
  60. typedef Matrix< int , Dynamic , 1> VectorXi

2 向量

向量被作为一种特殊的矩阵进行处理,即要么行为一要么列为一。除非显式的说明为行向量,否则这里将向量默认为列向量。请看下面两个别名定义:

  1. typedef Matrix<float,3,1> Vector3f;
  2. typedef Matrix<int,1,2> RowVector2i;

3 矩阵的动态空间分配

很多时候在程序的编译阶段也许我们并不知道矩阵具体的行列数,这时候使用动态控件分配就显得很必要了。当我们给矩阵模板中参数RowsAtCompileTime或者ColsAtCompileTime参数指定为Dynamic时,表示该矩阵对应行或列为一个动态分配的值。下面是两个动态矩阵的别名定义:

  1. typedef Matrix<double,Dynamic,Dynamic> MatrixXd;
  2. typedef Matrix<int,Dynamic,1> VectorXi;

4 矩阵的构建

经过上面的介绍以后,我们应该能定义一些基本的矩阵了。如:

  1. Matrix3f a; //定义一个float类型3×3固定矩阵a
  2. MatrixXf b; //定义一个float类型动态矩阵b(0×0)
  3. Matrix<int,Dynamic,3> b; //定义一个int类型动态矩阵(0×3)

对应动态矩阵,我们也可以在构造的时候给出矩阵所占用的空间,比如:

  1. MatrixXf a(10,15); //定义float类型10×15动态矩阵
  2. VectorXf b(30); //定义float类型30×1动态矩阵(列向量)

为了保持一致性,我们也可以使用上面构造函数的形式定义一个固定的矩阵,即Matrix3f a(3,3)也是允许的。

上面矩阵在构造的过程中并没有初始化,Eigen还为一些小的(列)向量提供了可以初始化的构造函数。如:

  1. Vector2d a(5.0,6.0);
  2. Vector3d b(5.0,6.0,7.0);
  3. Vector4d c(5.0,6.0,7.0,8.0);

5 矩阵元素的访问

Eigen提供了矩阵元素的访问形式和matlab中矩阵的访问形式非常相似,最大的不同是matlab中元素从1开始,而Eigen的矩阵中元素是从0开始访问。对于矩阵,第一个参数为行索引,第二个参数为列索引。而对于向量只需要给出一个索引即可。

  1. #include <iostream>
  2. #include "Eigen\Core"
  3. //import most common Eigen types
  4. using namespace Eigen;
  5. int main()
  6. {
  7. MatrixXd m(2,2);
  8. m(0,0) = 3;
  9. m(1,0) = 2.5;
  10. m(0,1) = -1;
  11. m(1,1) = m(1,0) + m(0,1);
  12. std::cout<<"Hear is the matrix m:\n"<<m<<std::endl;
  13. VectorXd v(2);
  14. v(0) = 4;
  15. v(1) = v(0) - 1;
  16. std::cout<<"Here is the vector v:\n"<<v<<std::endl;
  17. }

输出结果如下:

  1. Hear is the matrix m:
  2. 3 -1
  3. 2.5 1.5
  4. Here is the vector v:
  5. 4
  6. 3

m(index)这种访问形式并不仅限于向量之中,对于矩阵也可以这样访问。这一点和matlab相同,我们知道在matlab中定义一个矩阵a(3,4),如果我访问a(5)相当于访问a(2,2),这是因为在matlab中矩阵是按列存储的。这里比较灵活,默认矩阵元素也是按列存储的,但是我们也可以通过矩阵模板构造参数Options=RowMajor改变存储方式(这个参数是我们还没有提到的矩阵构造参数的第4个参数)。

6 一般初始化方法

对于矩阵的初始化,我们可以采用下面的方法方便且直观的进行:

  1. Matrix3f m;
  2. m<<1,2,3,
  3. 4,5,6,
  4. 7,8,9;
  5. std:cout<<m;

7 矩阵的大小

Eigen提供了rows(),cols(),size()方法来获取矩阵的大小,同时也同了resize()方法从新改变动态数组的大小。

  1. #include <iostream>
  2. #include "Eigen\Core"
  3. using namespace Eigen;
  4. int main()
  5. {
  6. MatrixXd m(2,5);
  7. m<<1,2,3,4,5,
  8. 6,7,8,9,10;
  9. m.resize(4,3);
  10. std::cout<<"The matrix m is:\n"<<m<<std::endl;
  11. std::cout<<"The matrix m is of size "
  12. <<m.rows()<<"x"<<m.cols()<<std::endl;
  13. std::cout<<"It has "<<m.size()<<" coefficients"<<std::endl;
  14. VectorXd v(2);
  15. v<<1,2;
  16. v.resize(5);
  17. std::cout<<"The vector v is:\n"<<v<<std::endl;
  18. std::cout<<"The vector v is of size "<<v.size()<<std::endl;
  19. std::cout<<"As a matrix,v is of size "<<v.rows()
  20. <<"x"<<v.cols()<<std::endl;
  21. }

输出结果如下:

  1. The matrix m is:
  2. 1 3 5
  3. 6 8 10
  4. 2 4 9.58787e-315
  5. 7 9 1.17493e-309
  6. The matrix m is of size 4x3
  7. It has 12 coefficients
  8. The vector v is:
  9. 1
  10. 2
  11. 1.17477e-309
  12. 7.0868e-304
  13. 0
  14. The vector v is of size 5
  15. As a matrix,v is of size 5x1

可以看到我们可以把矩阵任意的resize,但是resize后矩阵的元素会改变,如果resize后的矩阵比之前的大会出现一些未初始化的元素。如果被resize的矩阵按列存储(默认),那么resize命令和matlab中的reshape执行结果相同,只是matlab要求reshape的矩阵前后元素必须相同,也就是不允许resize后不能出现未初始化的元素。
对于固定大小的矩阵虽然也支持resize命令,但是resize后的大小只能是它本身的大小,否则就会报错。因为resize前后如果矩阵大小一样,就不会执行resize。如果我们不想在resize后改变矩阵的对应元素,那么可以使用conservativeResize()方法。对应上面程序中的m矩阵我们调用m.conservativeResize(4,3)后得到结果如下。其中因为行数增加了,增加的行会以未初始化的形式出现。

  1. The matrix m is:
  2. 1 2 3
  3. 6 7 8
  4. 9.58787e-315 2.122e-314 1.52909e+249
  5. 0 0 2.47039e+249

http://eigen.tuxfamily.org/dox/group__TutorialMatrixClass.html

8 赋值和大小变换

在Eigen中使用=可以直接将一个矩阵复制给另外一个矩阵,如果被复制的和赋值矩阵大小不一致,会自动对被复制矩阵执行resize函数。当然如果被复制的矩阵为固定矩阵当然就不会执行resize函数。当然也可以通过一些设置取消这个自动resize的过程。

  1. using namespace Eigen;
  2. int main()
  3. {
  4. MatrixXf a(2,2);
  5. MatrixXf b(3,3);
  6. b<<1,2,3,
  7. 4,5,6,
  8. 7,8,9;
  9. a = b;
  10. std::cout<<a<<std::endl;
  11. }

输出结果:

  1. 1 2 3
  2. 4 5 6
  3. 7 8 9

9 固定矩阵和动态矩阵

什么时候使用固定矩阵什么时候使用动态矩阵呢?简单的说:当矩阵尺寸比较小时使用固定矩阵(一般小于16),当矩阵尺寸较大时使用动态矩阵(一般大于32)。使用固定矩阵有更好的表现,它可以避免重复的动态内存分配,固定矩阵实际上是一个array。即Matrix4f mymatrix;事实上是float mymatrix[16];。所以这个是真的不花费任何运行时间。相反动态矩阵的建立需要在
heap中分配空间。即MatrixXf mymatrix(rows,colums);实际上是float *mymatrix = new float[rows*colums];.此外动态矩阵还要保存行和列的值。
当然固定矩阵也存在着显而易见的弊端。当数组的大小过大时,固定数组的速度优势就不那么明显了,相反过大的固定数组有可能造成stack的溢出。这时候动态矩阵的灵活性就显得十分重要了。

10 其他模板参数

最开始我们已经提到了建立一个矩阵一共有6个模板参数,其中有3个我们还没有提到(其实第三个参数已经提到过了)。

  1. Matrix<typename Scalar,
  2. int RowsAtCompileTime,
  3. int ColsAtCompileTime,
  4. int Options=0,
  5. int MaxRowsAtCompileTime = RowsAtCompileTime,
  6. int MaxColsAtCompileTime = ColsAtCompileTime>
  1. Options:这个参数决定了矩阵在存储过程中实际是按行还是按列存储。这个存储方式在前面我们提到的矩阵变换时必须要注意。默认是按列存储,我们可以显示的使用Options=RowMajor让矩阵实际按行存储。如Matrix<float,2,3,RowMajor> a;.
  2. MaxRowsAtCompileTime和MaxColsAtCompileTime:这两个值是设定动态矩阵在分配空间时最大的行数和列数。如Matrix<float,Dynamic,Dynamic,0,3,4>;.

11 常规的矩阵typedef

我们前面给出了一些常用的矩阵typedef.其实可以总结如下:

  1. MatrixNt对应的是Matrix
  2. VectorNt对应的是Matrix
  3. RowVectorNt对应的是Matrix

其中:

  1. N可以是2,3,4或者X(表示Dynamic).
  2. t可以是i(int),f(float),d(double),cf(complex

Eigen学习笔记2:C++矩阵运算库Eigen介绍的更多相关文章

  1. c++矩阵运算库Eigen简介

    C++矩阵运算库Eigen介绍 C++中的矩阵运算库常用的有Armadillo,Eigen,OpenCV,ViennaCL,PETSc等.我自己在网上搜了一下不同运算库的特点,最后选择了Eigen.主 ...

  2. python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑

    python3.4学习笔记(八) Python第三方库安装与使用,包管理工具解惑 许多人在安装Python第三方库的时候, 经常会为一个问题困扰:到底应该下载什么格式的文件?当我们点开下载页时, 一般 ...

  3. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  4. openresty 学习笔记六:使用session库

    openresty 学习笔记六:使用session库 lua-resty-session 是一个面向 OpenResty 的安全和灵活的 session 库,它实现了 Secure Cookie Pr ...

  5. Kinect开发学习笔记之(一)Kinect介绍和应用

    Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...

  6. Nodejs学习笔记(十六)--- Pomelo介绍&入门

    目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json 配置servers.json ...

  7. Nodejs学习笔记(十六)—Pomelo介绍&入门

    前言&介绍 Pomelo:一个快速.可扩展.Node.js分布式游戏服务器框架 从三四年前接触Node.js开始就接触到了Pomelo,从Pomelo最初的版本到现在,总的来说网易出品还算不错 ...

  8. WebGL three.js学习笔记 6种类型的纹理介绍及应用

    WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...

  9. Duanxx的Design abroad: C++矩阵运算库Eigen 概要

    一.概要 这两天想起来要做神经网络的作业了,要求用C++完毕神经网络的算法. 摆在面前的第一个问题就是,神经网络算法中大量用到了矩阵运算.可是C++不像matlab那样对矩阵运算有非常好的支持.本来准 ...

  10. Linux学习笔记——如何使用共享库交叉编译

    0.前言     在较为复杂的项目中会利用到交叉编译得到的共享库(*.so文件).在这样的情况下便会产生下面疑问,比如:     [1]交叉编译时的共享库是否须要放置于目标板中,假设须要放置在哪个文件 ...

随机推荐

  1. 10款好用的 jQuery 图片切换效果插件

    jQuery 是一个非常优秀的 Javascript 框架,使用简单灵活,同时还有许多成熟的插件可供选择.其中,最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入一些让人惊叹的效 ...

  2. 天梯赛 L1-009 N个数求和 (模拟)

    本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数"分子/分母"的形式给出的,你输出的和也必须是有理数的形式. 输入格式: 输入第一行给出一个正整数N(<=1 ...

  3. 天梯赛 L2-012 关于堆的判断 (二叉树)

    将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: "x is the root":x是根结点: "x and y ar ...

  4. 巅峰极客CTF writeup[上]

    经验教训 1.CTF不比实战,最好不要死磕.死磕就输了.我就是死磕在缓存文件死的.真的惭愧: 2.对于flag的位置不要太局限于web目录下,如果是命令执行直接上find / -name flag*: ...

  5. 高通msm mdm 总结

    1. svn 获取工程代码命令:svn co svn+ssh://10.20.30.18/svn-repos/msm8916/branches/LA1.1-CS-r113502.2 2. 如何确定那些 ...

  6. linux device tree源代码解析--转

    //Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...

  7. Web服务器处理动态程序三种方式及Apache配置

    模块.CGI.FastCGI三种方式介绍 以PHP脚本为例: 模块方式是指Web服务器通过libphp5.so模块调用PHP服务,模块将相关函数嵌入Web服务请求处理流程,不需要额外解释器进程.注意, ...

  8. centos6下mysql的主从复制的配置

    2015年9月17日 23:00:36 update 想要好好了解mysql复制,还是去看看<高性能MySQL>(第三版)好了,上面说的比较详细. =========== 在本地用virt ...

  9. 完美解决wordpress邮件链接无效的问题

    教程介绍:解决wordpress新用户注册邮件链接无效以及重新设置密码链接无效的问题 解决流程 案例一.用户注册 当用户注册站点时,用户会收到如下注册信: 当用户点击链接时,却发现链接无效: 仔细观察 ...

  10. 「Ionic」WebStorm的使用錯誤-

    前言:遇到這個錯誤,不要慌張,搶按照濤叔下面的方式處理就可以了. 1.Couldn't find ionic.config.json file. Are you in an Ionic project ...