项目要进行比较多的矩阵操作,特别是二维矩阵。刚开始做实验时,使用了动态二维数组,于是写了一堆Matrix函数,作矩阵的乘除加减求逆求行列式。实验做完了,开始做代码优化,发现Matrix.h文件里适用性太低,而且动态二维数组的空间分配与释放也影响效率,于是寻找其他解决方案。

首先考虑的是与Matlab混合编程,折腾了半天把Matlab环境与VS2010环境之后,发现Matlab编译出来的函数使用起来也比较麻烦,要把数组转化成该函数适用的类型后才能使用这些函数。我的二维数组也不是上千万维的,估计这个转化的功夫就牺牲了一部分效率了。(如果谁有混合编程的心得,求帮忙,囧。。。)

接着想到使用一维数组的方法,或者把一维数组封装在一个类里边。想着又要写一堆矩阵操作函数头就大,索性谷歌了一下矩阵处理库,除了自己之前知道的OpenCV库(之前由于转化cvarr麻烦,于是放弃),还有Eigen, Armadillo。

http://blog.csdn.net/houston11235/article/details/8501135该博客对这三个库的效率做了一个简单的评测,OpenCV库的矩阵操作效率是最低的,还好我没使用。Eigen速度最快,与自己定义数组的操作效率相当(- -,才相当吗?我本来还想找个更快的呢)。于是选择使用Eigen。

进入正题。

安装:

http://eigen.tuxfamily.org/index.php?title=Main_Page这里是官网,直接把包下载下来,不大,也就几M,我是直接放在自己项目文件夹(考虑项目封装时,这样比较方便),放在VS2010 <INCLUDE>文件夹。

简单使用:

看了一下官方文档,Eigen库除了能实现各种矩阵操作外,貌似还提供《数学分析》中的各种矩阵操作(包括L矩阵U矩阵)。目前我使用到的还是简单的矩阵操作,如加减乘除,求行列式,转置,逆,这些基本操作只要:

[cpp] view plaincopyprint?

  1. #include "Eigen/Eigen"
  2. using namespace Eigen;

就能实现,别忘了名空间Eigen。

包含的类型:

Matrices

Arrays

Matrix<float,Dynamic,Dynamic> <=> MatrixXf

Matrix<double,Dynamic,1> <=> VectorXd

Matrix<int,1,Dynamic> <=> RowVectorXi

Matrix<float,3,3> <=> Matrix3f

Matrix<float,4,1> <=> Vector4f

Array<float,Dynamic,Dynamic> <=> ArrayXXf

Array<double,Dynamic,1> <=> ArrayXd

Array<int,1,Dynamic> <=> RowArrayXi

Array<float,3,3> <=> Array33f

Array<float,4,1> <=> Array4f

如上表,主要包括两种类型,Matrices与Arryays,接着是这两种类型的派生类型。现在我用到的是Matrices(我不明白这两种类型在效率间有什么差距,囧。。。),

其中Matrix代表二维矩阵,Vector代表列向量RowVector代表行向量。如果后面跟着X,则代表是动态的数组,运行时可以根据需求改变,如果是数字,则代表是静态的(根据实验,最多能建立4维的静态矩阵或者数组,- -,为嘛不是6维,实验正好需要)。i代表int类型,f代表float类型,d代表double。

对应关系:

Matrix

二维矩阵

Vector

列向量

RowVector

行向量

X

动态

固定数字n

静态,4>=n>=1

i

int

f

float

d

double

Arrays类型的话也跟Matrices差不多。

基本操作,定义,初始化,矩阵操作:

[cpp] view plaincopyprint?

#include <iostream>
#include "Eigen/Eigen"
using namespace std;
using namespace Eigen; void foo(MatrixXf& m)
{
Matrix3f m2=Matrix3f::Zero(3,3);
m2(0,0)=1;
m=m2;
} int main() { /* 定义,定义时默认没有初始化,必须自己初始化 */
MatrixXf m1(3,4); //动态矩阵,建立3行4列。
MatrixXf m2(4,3); //4行3列,依此类推。
MatrixXf m3(3,3);
Vector3f v1; //若是静态数组,则不用指定行或者列
/* 初始化 */
m1 = MatrixXf::Zero(3,4); //用0矩阵初始化,要指定行列数
m2 = MatrixXf::Zero(4,3);
m3 = MatrixXf::Identity(3,3); //用单位矩阵初始化
v1 = Vector3f::Zero(); //同理,若是静态的,不用指定行列数 m1 << 1,0,0,1, //也可以以这种方式初始化
1,5,0,1,
0,0,9,1;
m2 << 1,0,0,
0,4,0,
0,0,7,
1,1,1; /* 元素的访问 */
v1[1] = 1;
m3(2,2) = 7;
cout<<"v1:\n"<<v1<<endl;
cout<<"m3:\n"<<m3<<endl;
/* 复制操作 */
VectorXf v2=v1; //复制后,行数与列数和右边的v1相等,matrix也是一样,
//也可以通过这种方式重置动态数组的行数与列数
cout<<"v2:\n"<<v2<<endl; /* 矩阵操作,可以实现 + - * / 操作,同样可以实现连续操作(但是维数必须符合情况),
如m1,m2,m3维数相同,则可以m1 = m2 + m3 + m1; */
m3 = m1 * m2;
v2 += v1;
cout<<"m3:\n"<<m3<<endl;
cout<<"v2:\n"<<v2<<endl;
//m3 = m3.transpose(); 这句出现错误,估计不能给自己赋值
cout<<"m3转置:\n"<<m3.transpose()<<endl;
cout<<"m3行列式:\n"<<m3.determinant()<<endl;
m3 = m3.reverse();
cout<<"m3求逆:\n"<<m3<<endl; system("pause"); return 0;
}

  

输出:

[html] view plaincopyprint?

  1. v1:
  2. 0
  3. 1
  4. 0
  5. m3:
  6. 1 0 0
  7. 0 1 0
  8. 0 0 7
  9. v2:

10. 0

11. 1

12. 0

13. m3:

  1. 14.  2  1  1
  2. 15.  2 21  1
  3. 16.  1  1 64

17. v2:

18. 0

19. 2

20. 0

21. m3转置:

  1. 22.  2  2  1
  2. 23.  1 21  1
  3. 24.  1  1 64

25. m3行列式:

26. 2540

27. m3求逆:

28. 64  1  1

  1. 29.  1 21  1
  2. 30.  1  1 64

基本的操作就是以上这些,有了这个库,以后就不用做重复工作了!

C++矩阵处理工具——Eigen

分类: C/C++ MATLAB Linux & MAC2012-07-24 20:37 18047人阅读 评论(32) 收藏 举报

工具c++matrixrandominitializationmatlab

最近和一些朋友讨论到了C++中数学工具的问题,以前总是很2地自己写矩阵运算,或者有时候在matlab里计算了一些数据再往C程序里倒,唉~想想那些年,我们白写的代码啊……人家早已封装好了!首先推荐几个可以在C++中调用的数学平台:eigen、bias、lapack、svd、CMatrix,本文着重eigen做以讲解,希望对各位有所帮助。

下面是本文主线,主要围绕下面几点进行讲解:

**********************************************************************************************

Eigen是什么?

Eigen3哪里下载?

Eigen3的配置

Eigen3 样例代码有没有?

去哪里更深入学习?

**********************************************************************************************

Eigen是什么?

Eigen是C++中可以用来调用并进行矩阵计算的一个库,里面封装了一些,需要的头文件和功能如下:

Eigen的主页上有一些更详细的Eigen介绍。

Eigen3哪里下载?

这里是我下好的,这里是官网主页,请自行下载,是个code包,不用安装。

Eigen的配置

直接上图了,附加包含目录那里填上你放Eigen文件夹的位置即可。

Eigen的样例代码有没有?

当然有,这篇文章重点就是这里!

以下是我整理的一些常用操作,基本的矩阵运算就在下面了,算是个入门吧~主要分以下几部分:

建议大家放到编译环境里去看,因为我这里有一些region的东西,编译器下更方便看~

[cpp] view plaincopy

  1. #include <iostream>
  2. #include <Eigen/Dense>
  3. //using Eigen::MatrixXd;
  4. using namespace Eigen;
  5. using namespace Eigen::internal;
  6. using namespace Eigen::Architecture;
  7. using namespace std;
  8. 10.
  9. 11.

12. int main()

13. {

  1. 14.

15. #pragma region one_d_object

  1. 16.
  2. 17.     cout<<"*******************1D-object****************"<<endl;
  3. 18.
  4. 19.     Vector4d v1;
  5. 20.     v1<< 1,2,3,4;
  6. 21.     cout<<"v1=\n"<<v1<<endl;
  7. 22.
  8. 23.     VectorXd v2(3);
  9. 24.     v2<<1,2,3;
  10. 25.     cout<<"v2=\n"<<v2<<endl;
  11. 26.
  12. 27.     Array4i v3;
  13. 28.     v3<<1,2,3,4;
  14. 29.     cout<<"v3=\n"<<v3<<endl;
  15. 30.
  16. 31.     ArrayXf v4(3);
  17. 32.     v4<<1,2,3;
  18. 33.     cout<<"v4=\n"<<v4<<endl;
  19. 34.

35. #pragma endregion

  1. 36.

37. #pragma region two_d_object

  1. 38.
  2. 39.     cout<<"*******************2D-object****************"<<endl;
  3. 40.     //2D objects:
  4. 41.     MatrixXd m(2,2);
  5. 42.
  6. 43.     //method 1
  7. 44.     m(0,0) = 3;
  8. 45.     m(1,0) = 2.5;
  9. 46.     m(0,1) = -1;
  10. 47.     m(1,1) = m(1,0) + m(0,1);
  11. 48.
  12. 49.     //method 2
  13. 50.     m<<3,-1,
  14. 51.         2.5,-1.5;
  15. 52.     cout <<"m=\n"<< m << endl;
  16. 53.

54. #pragma endregion

  1. 55.

56. #pragma region Comma_initializer

  1. 57.
  2. 58.     cout<<"*******************Initialization****************"<<endl;
  3. 59.
  4. 60.     int rows=5;
  5. 61.     int cols=5;
  6. 62.     MatrixXf m1(rows,cols);
  7. 63.     m1<<( Matrix3f()<<1,2,3,4,5,6,7,8,9 ).finished(),
  8. 64.         MatrixXf::Zero(3,cols-3),
  9. 65.         MatrixXf::Zero(rows-3,3),
  10. 66.         MatrixXf::Identity(rows-3,cols-3);
  11. 67.     cout<<"m1=\n"<<m1<<endl;
  12. 68.

69. #pragma endregion

  1. 70.

71. #pragma region Runtime_info

  1. 72.
  2. 73.     cout<<"*******************Runtime Info****************"<<endl;
  3. 74.
  4. 75.     MatrixXf m2(5,4);
  5. 76.     m2<<MatrixXf::Identity(5,4);
  6. 77.     cout<<"m2=\n"<<m2<<endl;
  7. 78.
  8. 79.     MatrixXf m3;
  9. 80.     m3=m1*m2;
  10. 81.     cout<<"m3.rows()="<<m3.rows()<<"  ;  "
  11. 82.              <<"m3.cols()="<< m3.cols()<<endl;
  12. 83.
  13. 84.     cout<<"m3=\n"<<m3<<endl;
  14. 85.

86. #pragma endregion

  1. 87.

88. #pragma region Resizing

  1. 89.
  2. 90.     cout<<"*******************Resizing****************"<<endl;
  3. 91.
  4. 92.     //1D-resize
  5. 93.     v1.resize(4);
  6. 94.     cout<<"Recover v1 to 4*1 array : v1=\n"<<v1<<endl;
  7. 95.
  8. 96.     //2D-resize
  9. 97.     m.resize(2,3);
  10. 98.     m.resize(Eigen::NoChange, 3);
  11. 99.     m.resizeLike(m2);
  12. 100.     m.resize(2,2);
  13. 101.

102. #pragma endregion

  1. 103.

104. #pragma region Coeff_access

  1. 105.
  2. 106.     cout<<"*******************Coefficient access****************"<<endl;
  3. 107.
  4. 108.     float tx=v1(1);
  5. 109.     tx=m1(1,1);
  6. 110.     cout<<endl;
  7. 111.

112. #pragma endregion

  1. 113.

114. #pragma  region Predefined_matrix

  1. 115.
  2. 116.     cout<<"*******************Predefined Matrix****************"<<endl;
  3. 117.
  4. 118.     //1D-object
  5. 119.     typedef  Matrix3f   FixedXD;
  6. 120.     FixedXD x;
  7. 121.
  8. 122.     x=FixedXD::Zero();
  9. 123.     x=FixedXD::Ones();
  10. 124.     x=FixedXD::Constant(tx);//tx is the value
  11. 125.     x=FixedXD::Random();
  12. 126.     cout<<"x=\n"<<x<<endl;
  13. 127.
  14. 128.     typedef ArrayXf Dynamic1D;
  15. 129.     //或者 typedef VectorXf Dynamic1D
  16. 130.     int size=3;
  17. 131.     Dynamic1D xx;
  18. 132.     xx=Dynamic1D::Zero(size);
  19. 133.     xx=Dynamic1D::Ones(size);
  20. 134.     xx=Dynamic1D::Constant(size,tx);
  21. 135.     xx=Dynamic1D::Random(size);
  22. 136.     cout<<"xx=\n"<<x<<endl;
  23. 137.
  24. 138.     //2D-object
  25. 139.     typedef MatrixXf Dynamic2D;
  26. 140.     Dynamic2D y;
  27. 141.     y=Dynamic2D::Zero(rows,cols);
  28. 142.     y=Dynamic2D::Ones(rows,cols);
  29. 143.     y=Dynamic2D::Constant(rows,cols,tx);//tx is the value
  30. 144.     y=Dynamic2D::Random(rows,cols);
  31. 145.

146. #pragma endregion

  1. 147.

148. #pragma region Arithmetic_Operators

  1. 149.
  2. 150.     cout<<"******************* Arithmetic_Operators****************"<<endl;
  3. 151.
  4. 152.     //add & sub
  5. 153.     MatrixXf m4(5,4);
  6. 154.     MatrixXf m5;
  7. 155.     m4=m2+m3;
  8. 156.     m3-=m2;
  9. 157.
  10. 158.     //product
  11. 159.     m3=m1*m2;
  12. 160.
  13. 161.     //transposition
  14. 162.     m5=m4.transpose();
  15. 163.     //m5=m.adjoint();//伴随矩阵
  16. 164.
  17. 165.     //dot product
  18. 166.     double xtt;
  19. 167.     cout<<"v1=\n"<<v1<<endl;
  20. 168.     v2.resize(4);
  21. 169.     v2<<VectorXd::Ones(4);
  22. 170.     cout<<"v2=\n"<<v2<<endl;
  23. 171.
  24. 172.     cout<<"*************dot product*************"<<endl;
  25. 173.     xtt=v1.dot(v2);
  26. 174.     cout<<"v1.*v2="<<xtt<<endl;
  27. 175.
  28. 176.     //vector norm
  29. 177.
  30. 178.     cout<<"*************matrix norm*************"<<endl;
  31. 179.     xtt=v1.norm();
  32. 180.     cout<<"norm of v1="<<xtt<<endl;
  33. 181.     xtt=v1.squaredNorm();
  34. 182.     cout<<"SquareNorm of v1="<<xtt<<endl;
  35. 183.

184. #pragma endregion

  1. 185.

186. cout<<endl;

187. }

去哪里更深入学习?

Please refer to Eigen中的类及函数Eigen的官方教程,和一些教程上的相关内容

C++矩阵处理库--Eigen初步使用的更多相关文章

  1. C++矩阵库 Eigen 快速入门

    最近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了. Eigen 是一个基于C++模板的线性代数库, ...

  2. C++矩阵库 Eigen 简介

    最近需要用 C++ 做一些数值计算,之前一直采用Matlab 混合编程的方式处理矩阵运算,非常麻烦,直到发现了 Eigen 库,简直相见恨晚,好用哭了. Eigen 是一个基于C++模板的线性代数库, ...

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

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

  4. Eigen学习笔记2:C++矩阵运算库Eigen介绍

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

  5. C++ 矩阵库 eigen

    找了好久才发现了一个这么方便的C++矩阵库. 官网 http://eigen.tuxfamily.org/index.php?title=Main_Page 参考文章 http://blog.csdn ...

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

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

  7. C++ 矩阵计算库 :Eigen库

    Eigen http://eigen.tuxfamily.org/index.php?title=Main_Page 下载http://bitbucket.org/eigen/eigen/get/3. ...

  8. c++ 数值计算库Eigen

    http://eigen.tuxfamily.org/index.php?title=Main_Page

  9. OpenGL进阶(十四) - UVN Camera实现

    提要 3D游戏中最基本的一个功能就是3D漫游了,玩家可以通过键盘或者鼠标控制自己的视角. 之前我们也学习过一个相关的函数,glLookAt,用来制定摄像机的位置,摄像机观察目标位置,还有摄像机的放置方 ...

随机推荐

  1. 【LeetCode】423. Reconstruct Original Digits from English

    Given a non-empty string containing an out-of-order English representation of digits 0-9, output the ...

  2. 浙大pat 1011题解

    With the 2010 FIFA World Cup running, football fans the world over were becoming increasingly excite ...

  3. git三个区域详解

    一.可以将git简单的分为三个区域    1.工作区(working directory)    2.暂缓区(stage index)    3.历史记录区(history) 二.三个区域关系:工作区 ...

  4. 在线用户管理--ESFramework 4.0 进阶(05)

    无论我们采用何种通信框架来构建我们的分布式系统,在服务端进行用户管理都是非常重要的一个环节.然而用户管理是否应该隶属于通信框架了?这个并不一定,通常来说,用户管理是与具体应用紧密相关的,应该是由应用解 ...

  5. FZU 1893 内存管理 模拟

    比赛的时候队友要做这道题…… 他没做出来自己也被误导了…… 也算是个教训 自己还是要有自己的思路…… 又是模拟题…… 网上都是用vector做的 我最近才会stl 怎么会用那么高大上的的东西…… 强力 ...

  6. 单例:用AFNetworking封装举例

    创建单例的方式 import AFNetworking class NetworkTools: AFHTTPSessionManager { //let是线程安全的 //使用单例实例只需要拿到Netw ...

  7. 将MyEclipse中的项目导入到Eclipse中报错的解决放法

    1.导入项目后,会报红色感叹号, 将项目右键,点击红色框.

  8. HDU 1969 Pie

    二分答案+验证(这题精度卡的比较死) #include<stdio.h> #include<math.h> #define eps 1e-7 ; double a[ff]; d ...

  9. Emacs阅读chm文档

    .title { text-align: center; margin-bottom: .2em } .subtitle { text-align: center; font-size: medium ...

  10. 《Windows驱动开发技术详解》之自定义StartIO

    自定义StartIO 系统定义的StartIO队列只能使用一个队列(DDK提供的StartIO内部只有一个队列),这个队列将所有的IRP进行处理化.例如,读.写操作都会混在一起进行串行处理.然而,有时 ...