Eigen教程(2)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html
Matrix类
在Eigen,所有的矩阵和向量都是Matrix模板类的对象,Vector只是一种特殊的矩阵(一行或者一列)。
Matrix有6个模板参数,主要使用前三个参数,剩下的有默认值。
Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
Scalar是表示元素的类型,RowsAtCompileTime为矩阵的行,ColsAtCompileTime为矩阵的列。
库中提供了一些类型便于使用,比如:
typedef Matrix<float, 4, 4> Matrix4f;
Vectors向量
列向量
typedef Matrix<float, 3, 1> Vector3f;
行向量
typedef Matrix<int, 1, 2> RowVector2i;
Dynamic
Eigen不只限于已知大小(编译阶段)的矩阵,有些矩阵的尺寸是运行时确定的,于是引入了一个特殊的标识符:Dynamic
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1> VectorXi;
Matrix<float, 3, Dynamic>
构造函数
默认的构造函数不执行任何空间分配,也不初始化矩阵的元素。
Matrix3f a;
MatrixXf b;
这里,a是一个3*3的矩阵,分配了float[9]的空间,但未初始化内部元素;b是一个动态大小的矩阵,定义是未分配空间(0*0)。
指定大小的矩阵,只是分配相应大小的空间,未初始化元素。
MatrixXf a(10,15);
VectorXf b(30);
这里,a是一个10*15的动态大小的矩阵,分配了空间但未初始化元素;b是一个30大小的向量,同样分配空间未初始化元素。
为了对固定大小和动态大小的矩阵提供统一的API,对指定大小的Matrix传递sizes也是合法的(传递也被忽略)。
Matrix3f a(3,3);
可以用构造函数提供4以内尺寸的vector的初始化。
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);
获取元素
通过中括号获取元素,对于矩阵是:(行,列);对于向量,只是传递它的索引,以0为起始。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
MatrixXd m(2,2);
m(0,0) = 3;
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << "Here is the matrix m:\n" << m << std::endl;
VectorXd v(2);
v(0) = 4;
v(1) = v(0) - 1;
std::cout << "Here is the vector v:\n" << v << std::endl;
}
输出
Here is the matrix m:
3 -1
2.5 1.5
Here is the vector v:
4
3
m(index)也可以用于获取矩阵元素,但取决于matrix的存储顺序,默认是按列存储的,当然也可以改为按行。
[]操作符可以用于向量元素的获取,但是不能用于matrix,因为C++中[]不能传递超过一个参数。
逗号初始化
Matrix3f m;
m << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << m;
resizing
matrix的大小可以通过rows()、cols()、size()获取,resize()可以重新调整动态matrix的大小。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
MatrixXd m(2,5);
m.resize(4,3);
std::cout << "The matrix m is of size "
<< m.rows() << "x" << m.cols() << std::endl;
std::cout << "It has " << m.size() << " coefficients" << std::endl;
VectorXd v(2);
v.resize(5);
std::cout << "The vector v is of size " << v.size() << std::endl;
std::cout << "As a matrix, v is of size "
<< v.rows() << "x" << v.cols() << std::endl;
}
输出:
The matrix m is of size 4x3
It has 12 coefficients
The vector v is of size 5
As a matrix, v is of size 5x1
如果matrix的实际大小不改变,resize函数不做任何操作。resize操作会执行析构函数:元素的值会被改变,如果不想改变执行 conservativeResize()。
为了统一API,所有的操作可用于指定大小的matrix,当然,实际中它不会改变大小。尝试去改变一个固定大小的matrix到一个不同的值,会出发警告失败。只有如下是合法的。
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
Matrix4d m;
m.resize(4,4); // no operation
std::cout << "The matrix m is of size "
<< m.rows() << "x" << m.cols() << std::endl;
}
assignment 和 resizing
assignment(分配)是复制一个矩阵到另外一个,操作符=。Eigen会自动resize左变量大小等于右变量大小,比如:
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;
a is of size 2x2
a is now of size 3x3
当然,如果左边量是固定大小的,上面的resizing是不允许的。
固定尺寸 vs 动态尺寸
实际中,应该使用固定尺寸还是动态尺寸,简单的答案是:小的尺寸用固定的,大的尺寸用动态的。使用固定尺寸可以避免动态内存的开辟,固定尺寸只是一个普通数组。
Matrix4f mymatrix; 等价于 float mymatrix[16];
MatrixXf mymatrix(rows,columns); 等价于 float *mymatrix = new float[rows*columns];
使用固定尺寸(<=4*4)需要编译前知道矩阵大小,而且对于足够大的尺寸,如大于32,固定尺寸的收益可以忽略不计,而且可能导致栈崩溃。而且基于环境,Eigen会对动态尺寸做优化(类似于std::vector)
其他模板参数
上面只讨论了前三个参数,完整的模板参数如下:
Matrix<typename Scalar,
int RowsAtCompileTime,
int ColsAtCompileTime,
int Options = 0,
int MaxRowsAtCompileTime = RowsAtCompileTime,
int MaxColsAtCompileTime = ColsAtCompileTime>
Options是一个比特标志位,这里,我们只介绍一种RowMajor,它表明matrix使用按行存储,默认是按列存储。Matrix<float, 3, 3, RowMajor>
MaxRowsAtCompileTime和MaxColsAtCompileTime表示在编译阶段矩阵的上限。主要是避免动态内存分配,使用数组。
Matrix<float, Dynamic, Dynamic, 0, 3, 4> 等价于 float [12]
一些方便的定义
Eigen定义了一些类型
- MatrixNt = Matrix<type, N, N> 特殊地有 MatrxXi = Matrix<int, Dynamic, Dynamic>
- VectorNt = Matrix<type, N, 1> 比如 Vector2f = Matrix<float, 2, 1>
- RowVectorNt = Matrix<type, 1, N> 比如 RowVector3d = Matrix<double, 1, 3>
N可以是2,3,4或X(Dynamic)
t可以是i(int)、f(float)、d(double)、cf(complex)、cd(complex)等。
Eigen教程(2)的更多相关文章
- Eigen教程(7)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 归约.迭代器和广播 归约 在Eigen中,有些函数可以统计matrix/array的 ...
- Eigen教程(6)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 高级初始化方法 本篇介绍几种高级的矩阵初始化方法,重点介绍逗号初始化和特殊矩阵(单位 ...
- Eigen教程(11)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 存储顺序 对于矩阵和二维数组有两种存储方式,列优先和行优先. 假设矩阵: 按行优先存 ...
- Eigen教程(9)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html Eigen并没有为matrix提供直接的Reshape和Slicing的API,但是 ...
- Eigen教程(10)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 混淆 在Eigen中,当变量同时出现在左值和右值,赋值操作可能会带来混淆问题.这一篇 ...
- Eigen教程(8)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 原生缓存的接口:Map类 这篇将解释Eigen如何与原生raw C/C++ 数组混合 ...
- Eigen教程(5)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 块操作 块是matrix或array中的矩形子部分. 使用块 函数.block(), ...
- Eigen教程(4)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html Array类和元素级操作 为什么使用Array 相对于Matrix提供的线性代数运算 ...
- Eigen教程(3)
整理下Eigen库的教程,参考:http://eigen.tuxfamily.org/dox/index.html 矩阵和向量的运算 提供一些概述和细节:关于矩阵.向量以及标量的运算. 介绍 Eige ...
随机推荐
- Python学习笔记(四)——编码和字符串
一.编码 1.编码类别: (1)ASCII码:127个字母被编码到计算机里,也就是大小写英文字母.数字和一些符号 (2)GB2312码:中国制定的用于加入中文汉字的编码 (3)Unicode:防止由于 ...
- 【Redis】Redis的常规操作命令
NoSQL是一种非关系型数据库,非关系型数据库库和传统的关系型数据库不同,非关系性体现在不需要依赖表进行数据存储.常见的非关系型数据库有Redis.MonoDB.HBase等,这些是基于key-val ...
- Linux下实现脚本监测特定进程占用内存情况
Linux系统下,我们可以利用以下命令来获取特定进程的运行情况: cat /proc/$PID/status 其中PID是具体的进程号,这个命令打印出/proc/特定进程/status文件的内容,信息 ...
- C++的坑真的多吗?
先说明一下,我不希望本文变成语言争论贴.希望下面的文章能让我们客观理性地了解C++这个语言.(另,我觉得技术争论不要停留在非黑即白的二元价值观上,这样争论无非就是比谁的嗓门大,比哪一方的观点强,毫无价 ...
- Loader Lock引起的一个Bug
在Windows中,让程序模块化实现的一种方式,就是让事实上现为动态链接库. 然后在主程序启动的时候隐式或者显示的去载入动态链接库.可是假设不恰当的编写动态链接库的DllMain函数,将会引起意想不到 ...
- springboot 1.5.x 使用tomcat8设置cookie的domain以dot开头报错
"C:\Program Files\Java\jdk1.7.0_75\bin\java" -XX:TieredStopAtLevel=1 -noverify -Dspring.ou ...
- netty LEAK: ByteBuf.release() was not called before it's garbage-collected
背景.netty抛出完整的error信息如下: 2018-02-08 14:30:43.098 [nioEventLoopGroup-5-1] ERROR io.netty.util.Resource ...
- 尼康G镜头与D镜头的差别
尼康系统实现自动对焦必须:机身和镜头,两者至少其一拥有马达. 尼康现在新出的G头,几乎都带马达.但在胶片时代的G头,几乎都不带马达. G只表示:没有手动光圈环. D只表示:镜头能提供距离信息给机身. ...
- OpenSSL证书生成及Mac上Apache服务器配置HTTPS(也适用centos)
自签名证书 配置Apache服务器SSL 自己作为CA签发证书 这里是OpenSSL和HTTPS的介绍OpenSSLHTTPS 开启HTTPS配置前提是已在Mac上搭建Apache服务器→Mac上Ap ...
- 如何使用 t-sql 更新数据库中日期字段的部分数据(年?月?日?时?分?秒?)
嗯,从网上找到了一些内容,综合利用了sql server的一些内置方法 首先是 convert 方法:https://msdn.microsoft.com/zh-cn/library/ms187928 ...