Eigen教程1 - 基础
来源:互联网 发布:java attribute用法 编辑:程序博客网 时间:2024/05/01 18:18
固定大小的矩阵和向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; // import most common Eigen typesint main(int, char *[]){ Matrix3f m3; //3x3单精度矩阵 m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9; Matrix4f m4 = Matrix4f::Identity(); //4x4单位矩阵(单精度) Vector4i v4(1, 2, 3, 4); // 长度为4的整型向量 // 输出结果 std::cout << "m3\n" << m3 << "\nm4:\n" << m4 << "\nv4:\n" << v4 << std::endl;}
- Matrix表示矩阵,Vector表示向量,数字表示维度,最后的f和i分别表示单精度和整型数据类型。
- 固定大小表示编译时,行数和列数是固定的。这时,Eigen不会分配动态内存。这对于比较小的尺寸比较适合,比如16x16。
动态大小的矩阵和向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ // 动态矩阵 for (int size=1; size<=4; ++size) { MatrixXi m(size,size+1); // 一个整型的大小为 (size)x(size+1) 的矩阵 for (int j=0; j<m.cols(); ++j) // 遍历列 for (int i=0; i<m.rows(); ++i) // 遍历行 m(i,j) = i+j*m.rows(); // 使用圆括号m(i,j)访问矩阵的元素 std::cout << m << "\n\n"; //打印矩阵 } // 动态向量 VectorXf v(4); // 定义一个4维单精度向量 // 使用圆括号()或方括号[]访问向量元素 v[0] = 1; v[1] = 2; v(2) = 3; v(3) = 4; std::cout << "\nv:\n" << v << std::endl;}
- 小结:X表示动态大小。
#include <Eigen/Eigen>
将包含所有的Eigen函数。#include <Eigen/Dense>
包含所有普通矩阵函数,不包括稀疏矩阵函数。它们会增加编译时间。
矩阵和向量类型
- Eigen中的所有密集矩阵和向量都是通过Matrix类来表示的。Matrix通过一系列的模板参数来生成具体的类别。
Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime>
中,Scalar表示数据类型,RowsAtCompileTime和ColsAtCompileTime分别表示编译时的行数和列数。Vector3d
定义为Matrix<double, 3, 1>
- 对于动态大小的类型,在编译时不指定行数和列数,使用Eigen::Dynamic。比如,
VectorXd
定义为Matrix<double, Dynamic, 1>
。
访问元素
- Eigen支持以下的读/写元素语法:
matrix(i,j);vector(i)vector[i]vector.x() // first coefficientvector.y() // second coefficientvector.z() // third coefficientvector.w() // fourth coefficient
- 矩阵只能通过圆括号()访问;
- 向量可以通过圆括号()和方括号[]访问。
- 上述的元素访问方法都通过断言检查范围,代价比较大。
- 通过定义EIGEN_NO_DEBUG 或 NDEBUG,取消断言。
- 通过使用
coeff()
和coeffRef()
,来取消检查。比如,MatrixBase::coeff(int,int) const, MatrixBase::coeffRef(int,int)等。
创建和初始化矩阵和向量
通过预定义矩阵初始化
创建固定大小的矩阵和向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ float value = 3.0; Matrix3f x; // 创建一个3x3的单精度矩阵 x = Matrix3f::Zero(); //全零矩阵 cout << x << endl << endl; x = Matrix3f::Ones(); //全一矩阵 cout << x << endl << endl; x = Matrix3f::Constant(value); //全value矩阵 cout << x << endl << endl; x = Matrix3f::Identity(); //单位矩阵 cout << x << endl << endl; x = Matrix3f::Random(); // 随机矩阵 cout << x << endl << endl; x.setZero(); cout << x << endl << endl; x.setOnes(); cout << x << endl << endl; x.setIdentity(); cout << x << endl << endl; x.setConstant(value); cout << x << endl << endl; x.setRandom(); cout << x << endl << endl;}
创建动态大小的矩阵
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ float value = 3.0f; int rows = 3; int cols = 4; MatrixXf x; x = MatrixXf::Zero(rows, cols); cout << x << endl << endl; x = MatrixXf::Ones(rows, cols); cout << x << endl << endl; x = MatrixXf::Constant(rows, cols, value); cout << x << endl << endl; x = MatrixXf::Identity(rows, cols); cout << x << endl << endl; x = MatrixXf::Random(rows, cols); cout << x << endl << endl; x.setZero(rows, cols); cout << x << endl << endl; x.setOnes(rows, cols); cout << x << endl << endl; x.setConstant(rows, cols, value); cout << x << endl << endl; x.setIdentity(rows, cols); cout << x << endl << endl; x.setRandom(rows, cols); cout << x << endl << endl; return 0;}
创建动态大小的向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ int size = 3; float value = 3.0f; VectorXf x; // 定义动态向量 x = VectorXf::Zero(size); //全0向量 cout << x << endl << endl; x = VectorXf::Ones(size); //全1向量 cout << x << endl << endl; x = VectorXf::Constant(size, value);//全value向量 cout << x << endl << endl; //x = VectorXf::Identity(size);//报错 x = VectorXf::Random(size); cout << x << endl << endl; x.setZero(size); cout << x << endl << endl; x.setOnes(size); cout << x << endl << endl; x.setConstant(size, value); cout << x << endl << endl; //x.setIdentity(size); x.setRandom(size); cout << x << endl << endl; return 0;}
创建固定大小的基向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ Vector3f x; x = Vector3f::UnitX(); // 1 0 0 cout << x << endl << endl; x = Vector3f::UnitY(); // 0 1 0 cout << x << endl << endl; x = Vector3f::UnitZ(); // 0 0 1 cout << x << endl << endl; return 0;}
创建动态大小的基向量
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ VectorXf x; x = VectorXf::Unit(4,1); cout << x << endl << endl; x = Vector4f(0,1,0,0); cout << x << endl << endl; x = Vector4f::UnitY(); cout << x << endl << endl; return 0;}
例子
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ cout << MatrixXf::Constant(2, 3, sqrt(2)) << endl; // 2x3的单精度矩阵 RowVector3i v; //3维行向量 v.setConstant(6); cout << "v = " << v << endl; return 0;}
通过Cast的方式初始化
相同尺寸的矩阵兼容
- 元素类型通过
MatrixBase::cast()
自动转换。
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>#include <Eigen/Eigen>using namespace Eigen; using namespace std; int main(int, char *[]){ Vector3d md(1,2,3); Vector3f mf = md.cast<float>(); cout << "md = " << md << endl; cout << "mf = " << mf << endl; return 0;}
相同类型的矩阵兼容
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ MatrixXf res(10,10); Matrix3f a, b; a = Matrix3f::Identity(); b = Matrix3f::Constant(3); res = a+b; // OK: res is resized to size 3x3 cout << a << endl << endl; cout << b << endl << endl; cout << res << endl << endl; return 0;}
通过Map方式初始化
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ std::vector<float> stlarray(10); VectorXf::Map(&stlarray[0], stlarray.size()).squaredNorm(); return 0;}
- 下面的代码没有完全调通
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ const int rows = 3; const int cols = 4; float array[rows*cols]; Map<MatrixXf> m(array,rows,cols); Matrix3f othermatrix1 = Matrix3f::Identity();//单位矩阵 MatrixXf othermatrix2(3,4); othermatrix2 = MatrixXf::Constant(3,4,5);//3x4的常量矩阵,值都为5 m = othermatrix1 * othermatrix2; //m.eigenvalues(); std::vector<float> stlarray(10); VectorXf::Map(&stlarray[0], stlarray.size()).squaredNorm(); cout << m << endl; return 0;}
通过逗号初始化
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ Matrix3f m; m << 1, 2, 3, 4, 5, 6, 7, 8, 9; cout << m << endl; return 0;}
- 使用逗号和子矩阵,初始化矩阵。
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ int rows=5, cols=5; MatrixXf m(rows,cols); m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),//左上角3x3 MatrixXf::Zero(3,cols-3), //右上角3x2 MatrixXf::Zero(rows-3,3), //左下角2x3 MatrixXf::Identity(rows-3,cols-3); //右下角2x2 cout << m << endl; return 0;}
.finished()
用于当临时矩阵初始化完成时,获取实际的矩阵对象。尽管看起来很复杂,但实际上编译时已经优化。
算术操作
传统的数学运算
- 矩阵/向量乘法:
col2 = mat1 * col1; //矩阵x列向量row2 = row1 * mat1; // 行向量x矩阵row1 *= mat1;mat3 = mat1 * mat2; mat3 *= mat1;
- 矩阵/向量加法/减法:
mat3 = mat1 + mat2; mat3 += mat1;mat3 = mat1 - mat2; mat3 -= mat1;
- 标量加法/减法:
mat3 = mat1 * s1; mat3 = s1 * mat1; mat3 *= s1;mat3 = mat1 / s1; mat3 /= s1;
逐元素的操作
逐元素的操作,请查阅
.cwise()
。逐元素乘法
mat3 = mat1.cwise() * mat2;
- 加/减标量
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise() + scalar;mat3.cwise() += scalar;mat3.cwise() -= scalar;
- 逐元素除法
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise() / mat2;
- 逐元素取倒数
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise().inverse();
- 逐元素比较运算
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise() < mat2;mat3 = mat1.cwise() <= mat2;mat3 = mat1.cwise() > mat2;//等
- 三角余弦
- sin(), cos()等。
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise().sin();// 等
- 指数
- pow(), square(), cube(), sqrt(), exp(), log()等。
//需要Array模块 #include <Eigen/Array>mat3 = mat1.cwise().square();mat3 = mat1.cwise().pow(5);mat3 = mat1.cwise().log();//等
- 最小值,最大值,绝对值
mat3 = mat1.cwise().min(mat2);mat3 = mat1.cwise().max(mat2);mat3 = mat1.cwise().abs();mat3 = mat1.cwise().abs2();
各种乘法运算
- 矩阵乘法:
m1*m2
- 逐元素乘法:
mat1.cwise()*mat2
- 点积:
scalar = vec1.dot(vec2);
- 外积:
mat = vec1 * vec2.transpose();
- 交叉积:
#include <Eigen/Geometry> vec3 = vec1.cross(vec2);
- 矩阵乘法:
逐元素操作示例:
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Eigen>using namespace Eigen; using namespace std; int main(int, char *[]){ Matrix3f x, y; x << 5,3,1,2,-7,8,9,-4,6; y << 5,3,1,2,-7,8,9,4,7; cout << x << endl << endl; cout << x.cwiseAbs() << endl << endl;//绝对值 cout << x.cwiseAbs2() << endl << endl; //平方 cout << x.cwiseEqual(y) << endl << endl; //是否相等 cout << x.cwiseMax(y) << endl << endl; //逐元素最大值 cout << x.cwiseMin(y) << endl << endl; cout << x.cwiseInverse() << endl << endl; //倒数 cout << x.cwiseNotEqual(y) << endl << endl; //不相等 cout << x.cwiseProduct(y) << endl << endl; //逐元素乘法 cout << x.cwiseQuotient(y) << endl << endl; //除法 cout << x.cwiseSqrt() << endl << endl; // return 0;}
Reductions
- Eigen提供了一些reduction方法: minCoeff() , maxCoeff() , sum() , trace() , norm() , squaredNorm() , all() , 和 any()。
- 上述这些方法都可以逐列或逐行的执行。如下所示:
/* * 参考链接:http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted*/#include <iostream>#include <vector>#include <Eigen/Core>using namespace Eigen; using namespace std; int main(int, char *[]){ Matrix3f x; x << 5,3,1,2,7,8,9,4,6; cout << x.minCoeff() << endl; cout << x.colwise().minCoeff() << endl; cout << x.rowwise().minCoeff() << endl; return 0;}
- maxCoeff()和minCoeff()函数可以通过设置可选参数,返回最大/小值的位置:maxCoeff(int* i, int* j) , minCoeff(int* i, int* j) 。
- all() 和 any()在使用逐元素操作时,非常有用。
参考
- http://eigen.tuxfamily.org/dox-2.0/TutorialCore.html#TutorialCoreGettingStarted
- 备注:该链接的内容过时了。。。
1 0
- Eigen教程1 - 基础
- Eigen教程1
- eigen教程
- Eigen基础
- Eigen教程2 - 入门
- Eigen教程2-Dense
- Eigen教程-sparse
- Eigen初步1:初步体验Eigen库
- Eigen教程7 - Eigen和Matlab的比较
- Eigen
- Eigen
- Eigen教程3 - 稀疏矩阵操作
- Eigen教程5 - 求解稀疏线性方程组
- Eigen教程6 - Matrix-free solvers
- 线性代数Eigen库安装使用教程
- Eigen教程-Solving Sparse Linear Systems
- eigen学习(1)-入门
- Eigen教程4 - 稀疏矩阵快速参考指南
- spring-data-jpa原理探秘(3)-QueryMethod类
- office转pdf和图片实现在线预览
- Linux I/O文件open函数
- 自行安装apache的经历(非集成软件安装)
- 未选择的路
- Eigen教程1 - 基础
- 【UOJ】#241. 【UR #16】破坏发射台
- 【HDU 3038 How Many Answers Are Wrong】+ 并查集
- LeetCode 412. Fizz Buzz(Java)
- 深入理解JVM—JVM内存模型
- BZOJ2301: [HAOI2011]Problem b 莫比乌斯反演+容斥原理
- poj 3259 Wormholes
- N个有序整数数列已放在一维数组中,利用二分查找法查找整数m在数组中的位置,若找到,则输出其下标值;反之,则输出 “Not be found”
- Elasticsearch创建索引和映射结构详解