织梦做的网站如何修改,辽宁省工程造价信息网官网,怎样将自己做的网站给别人看,东道设计公司招聘Eigen-Matrix矩阵 一、概述二、矩阵的前三个模板参数三、向量四、动态维度参数五、构造函数六、索引访问器七、逗号初始化八、矩阵维度调整九、赋值和调整大小十、固定尺寸vs.动态尺寸十一、可选模板参数十二、方便预定义 一、概述
在Eigen中#xff0c;所有矩阵和向量都是矩… Eigen-Matrix矩阵 一、概述二、矩阵的前三个模板参数三、向量四、动态维度参数五、构造函数六、索引访问器七、逗号初始化八、矩阵维度调整九、赋值和调整大小十、固定尺寸vs.动态尺寸十一、可选模板参数十二、方便预定义 一、概述
在Eigen中所有矩阵和向量都是矩阵模板类的对象。向量只是矩阵的一种特殊情况要么有一行要么有一列。矩阵就是一个二维数表可以有多行多列。
二、矩阵的前三个模板参数
Matrix类有六个模板参数但现在只需要了解前三个参数就足够了。剩下的三个参数都有默认值我们暂时不碰它们我们将在下面讨论它们。
Matrix的三个必备模板参数为:
Matrixtypename Scalar, int RowsAtCompileTime, int ColsAtCompileTime参数Scalar 标量是标量类型即系数的类型。也就是说如果你想要一个浮点数的矩阵在这里选择float。有关所有支持的标量类型的列表以及如何扩展对新类型的支持请参阅标量类型。RowsAtCompileTime和ColsAtCompileTime是在编译时已知的矩阵的行数和列数(如果在编译时不知道该数请参见下文)。
Eigen提供了许多方便的类型来涵盖通常的情况。例如Matrix4f是一个4x4的浮点数矩阵。Eigen是这样定义的:
typedef Matrixfloat, 4, 4 Matrix4f;三、向量
如上所述在Eigen中向量只是矩阵的一种特殊情况要么有一行要么有一列。它们只有一列的情况是最常见的;这样的向量称为列向量通常简称为向量。在另一种情况下它们只有一行它们被称为行向量。
例如方便的类型pedef Vector3f是一个3个浮点数的(列)向量。Eigen对其定义如下:
typedef Matrixfloat, 3, 1 Vector3f;我们还为行向量提供了方便的类型例如:
typedef Matrixint, 1, 2 RowVector2i;四、动态维度参数
当然Eigen并不局限于在编译时已知维数的矩阵。RowsAtCompileTime和ColsAtCompileTime模板参数可以采用特殊值Dynamic这表示在编译时大小未知因此必须作为运行时变量处理。
在Eigen学术语中这样的尺寸被称为动态尺寸而在编译时已知的大小称为固定大小。例如方便类型pedef MatrixXd表示具有动态大小的双精度矩阵定义如下:
typedef Matrixdouble, Dynamic, Dynamic MatrixXd;同样我们定义了一个自解释的类型pedef VectorXi如下:
typedef Matrixint, Dynamic, 1 VectorXi;你可以完美地拥有固定数量的行和动态数量的列如下所示:
Matrixfloat, 3, Dynamic五、构造函数
默认构造函数始终可用从不执行任何动态内存分配也从不初始化矩阵系数。你可以这样做:
Matrix3f a;
MatrixXf b;在这里,
a 是一个3 × 3矩阵其系数为未初始化的浮点[9]数组;b 是一个动态大小的矩阵其大小目前为0 × 0其系数数组还没有被分配。
构造函数也可以接受大小。对于矩阵总是先传递行数。对于向量只需传递向量的大小。它们用给定的大小分配系数数组但不初始化系数本身:
MatrixXf a(10,15);
VectorXf b(30);在这里,
a 是一个10x15的动态大小矩阵具有已分配但当前未初始化的系数。b 是一个大小为30的动态大小向量具有已分配但当前未初始化的系数。
为了在固定大小和动态大小的矩阵之间提供统一的API在固定大小的矩阵上使用这些构造函数是合法的即使在这种情况下传递大小是无用的。所以这是合法的:
Matrix3f a(3,3);这是一个无操作。
矩阵和向量也可以从系数列表初始化。在c 11之前此功能仅限于固定大小的小列或大小不超过4的向量:
Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0);如果启用c 11可以通过传递任意数量的系数来初始化任意大小的固定大小的列向量或行向量:
Vector2i a(1, 2); // A column vector containing the elements {1, 2}
Matrixint, 5, 1 b {1, 2, 3, 4, 5}; // A row-vector containing the elements {1, 2, 3, 4, 5}
Matrixint, 1, 5 c {1, 2, 3, 4, 5}; // A column vector containing the elements {1, 2, 3, 4, 5}在一般情况下无论是固定大小还是运行时大小的矩阵和向量系数必须按行分组并作为初始化列表的初始化列表传递:
MatrixXi a { // construct a 2x2 matrix{1, 2}, // first row{3, 4} // second row
};
Matrixdouble, 2, 3 b {{2, 3, 4},{5, 6, 7},
};对于列向量或行向量允许隐式转置。这意味着可以从单行初始化列向量:
VectorXd a {{1.5, 2.5, 3.5}}; // A column-vector with 3 coefficients
RowVectorXd b {{1.0, 2.0, 3.0, 4.0}}; // A row-vector with 4 coefficients六、索引访问器
在eigen中主要的系数访问器和变量是重载括号操作符。对于矩阵总是先传递行索引。对于向量只传递一个下标。编号从0开始。这个例子不言自明:
#include iostream
#include Eigen/Denseint main()
{Eigen::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;Eigen::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)并不局限于向量它也可用于一般矩阵这意味着在系数数组中基于索引的访问。然而这取决于矩阵的存储顺序。所有特征矩阵默认为列为主的存储顺序但可以将其更改为行为主请参阅存储顺序。
对于vector中的基于索引的访问操作符 [ ] 也被重载但请记住c不允许操作符 [ ] 接受多个参数。我们将运算符 [ ] 限制为向量只有向量支持使用 [ ] 符号索引因为c语言中的一个笨拙会使 matrix[i,j] 编译成与 matrix[j] 相同的东西
七、逗号初始化
可以使用所谓的逗号初始化语法方便地设置矩阵和向量系数。现在知道这个例子就足够了:
Matrix3f m;
m 1, 2, 3,4, 5, 6,7, 8, 9;
std::cout m;输出
1 2 3
4 5 6
7 8 9八、矩阵维度调整
矩阵的当前大小可以通过rows()、cols()和size()来获取。这些方法分别返回行数、列数和系数数。通过resize()方法调整动态大小矩阵的大小。
#include iostream
#include Eigen/Denseint main()
{Eigen::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;Eigen::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如果实际矩阵大小没有改变resize()方法是不操作的否则它是破坏性的系数的值可能会改变。如果你想要一个不改变系数的 resize()的 保守变体使用conservativeResize()更多细节请参阅本页。
为了API的一致性所有这些方法在固定大小的矩阵上仍然可用。当然您实际上无法调整固定大小的矩阵的大小。尝试将固定大小更改为实际不同的值将触发断言失败;但是下面的代码是合法的:
例如:输出:
#include iostream
#include Eigen/Denseint main()
{Eigen::Matrix4d m;m.resize(4,4); // no operationstd::cout The matrix m is of size m.rows() x m.cols() std::endl;输出
The matrix m is of size 4x4九、赋值和调整大小
赋值是使用操作符将一个矩阵复制到另一个矩阵的操作。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输出
a is of size 2x2
a is now of size 3x3当然如果左侧是固定大小则不允许调整其大小。
如果您不希望发生这种自动调整大小(例如为了调试目的)您可以禁用它请参阅此页。
十、固定尺寸vs.动态尺寸
什么时候应该使用固定大小(例如Matrix4f)什么时候应该使用动态大小(例如MatrixXf)?简单的答案是:对于非常小的尺寸尽可能使用固定大小对于较大的尺寸或必须使用动态大小。对于较小的大小特别是小于(大约)16的大小使用固定大小对性能非常有益因为它允许Eigen避免动态内存分配并展开循环。在内部固定大小的特征矩阵只是一个普通数组即做
Matrix4f mymatrix; 其实就是去做
float mymatrix[16]; 这真的是零运行费用。相比之下动态大小矩阵的数组总是在堆上分配所以这样做
MatrixXf mymatrix(rows,columns); 等于做某事
float *mymatrix new float[rows*columns]; 除此之外MatrixXf对象将其行数和列数存储为成员变量。
当然使用固定大小的限制是只有在编译时知道大小时才有可能。此外对于足够大的大小例如大于(大约)32的大小使用固定大小的性能优势变得可以忽略不计。更糟糕的是尝试在函数内部使用固定大小创建一个非常大的矩阵可能会导致堆栈溢出因为Eigen会尝试将数组自动分配为局部变量而这通常是在堆栈上完成的。最后根据具体情况当使用动态大小时Eigen也可以更积极地尝试向量化(使用SIMD指令)请参阅向量化。
十一、可选模板参数
我们在本页开头提到Matrix类接受六个模板参数但到目前为止我们只讨论了前三个。其余三个参数为可选参数。下面是模板参数的完整列表:
Matrixtypename Scalar,int RowsAtCompileTime,int ColsAtCompileTime,int Options 0,int MaxRowsAtCompileTime RowsAtCompileTime,int MaxColsAtCompileTime ColsAtCompileTimeOptions是位字段。在这里我们只讨论一个比特:RowMajor。它指定这种类型的矩阵使用行为主存储顺序;默认情况下存储顺序是以列为主的。请参阅存储订单页面。例如此类型表示行为主的3x3矩阵:
Matrixfloat, 3, 3, RowMajorMaxRowsAtCompileTime和MaxColsAtCompileTime在需要指定时非常有用即使在编译时不知道矩阵的确切大小但在编译时知道一个固定的上限。这样做的最大原因可能是为了避免动态内存分配。例如下面的矩阵类型使用12个浮点数的普通数组没有动态内存分配:
Matrixfloat, Dynamic, Dynamic, 0, 3, 4十二、方便预定义
Eigen定义了以下矩阵类型:
都是用的 Matrix 不同模板参数预定义为不同类型。
MatrixNt Matrixtype, N, N. 例如, MatrixXi 实际上是 Matrixint, Dynamic, Dynamic.MatrixXNt Matrixtype, Dynamic, N. 例如, MatrixX3i 实际上是 Matrixint, Dynamic, 3.MatrixNXt Matrixtype, N, Dynamic. 例如, Matrix4Xd 实际上是 Matrixd, 4, Dynamic.VectorNt Matrixtype, N, 1. 例如, Vector2f 实际上是 Matrixfloat, 2, 1.RowVectorNt Matrixtype, 1, N. 例如, RowVector3d 实际上是 Matrixdouble, 1, 3.
注意:
N 可以是2、3、4或者X(表示动态 Dynamic ) 中的任意一个。t 可以是I (int)、f (float)、d (double)、cf (complex)或CD (complex)中的任意一个。虽然只为这五种类型定义了类型定义但这并不意味着它们是唯一受支持的标量类型。例如支持所有标准整数类型请参阅标量类型。