Eigen-Matrix矩阵

这篇具有很好参考价值的文章主要介绍了Eigen-Matrix矩阵。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、概述

在Eigen中,所有矩阵和向量都是矩阵模板类的对象。向量只是矩阵的一种特殊情况,要么有一行,要么有一列。矩阵就是一个二维数表,可以有多行多列。

二、矩阵的前三个模板参数

Matrix类有六个模板参数,但现在只需要了解前三个参数就足够了。剩下的三个参数都有默认值,我们暂时不碰它们,我们将在下面讨论它们。

Matrix的三个必备模板参数为:

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
  • 参数Scalar, 标量是标量类型,即系数的类型。也就是说,如果你想要一个浮点数的矩阵,在这里选择float。有关所有支持的标量类型的列表,以及如何扩展对新类型的支持,请参阅标量类型。
  • RowsAtCompileTime和ColsAtCompileTime是在编译时已知的矩阵的行数和列数(如果在编译时不知道该数,请参见下文)。

Eigen提供了许多方便的类型来涵盖通常的情况。例如,Matrix4f是一个4x4的浮点数矩阵。Eigen是这样定义的:

typedef Matrix<float, 4, 4> Matrix4f;

三、向量

如上所述,在Eigen中,向量只是矩阵的一种特殊情况,要么有一行,要么有一列。它们只有一列的情况是最常见的;这样的向量称为列向量,通常简称为向量。在另一种情况下,它们只有一行,它们被称为行向量。

例如,方便的类型pedef Vector3f是一个3个浮点数的(列)向量。Eigen对其定义如下:

typedef Matrix<float, 3, 1> Vector3f;

我们还为行向量提供了方便的类型,例如:

typedef Matrix<int, 1, 2> RowVector2i;

四、动态维度参数

当然,Eigen并不局限于在编译时已知维数的矩阵。RowsAtCompileTime和ColsAtCompileTime模板参数可以采用特殊值Dynamic,这表示在编译时大小未知,因此必须作为运行时变量处理。

在Eigen学术语中,这样的尺寸被称为动态尺寸;而在编译时已知的大小称为固定大小。例如,方便类型pedef MatrixXd,表示具有动态大小的双精度矩阵,定义如下:

typedef Matrix<double, Dynamic, Dynamic> MatrixXd;

同样,我们定义了一个自解释的类型pedef VectorXi如下:

typedef Matrix<int, Dynamic, 1> VectorXi;

你可以完美地拥有固定数量的行和动态数量的列,如下所示:

Matrix<float, 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}
Matrix<int, 5, 1> b {1, 2, 3, 4, 5};   // A row-vector containing the elements {1, 2, 3, 4, 5}
Matrix<int, 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
};
Matrix<double, 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/Dense>
 
int 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/Dense>
 
int 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/Dense>
 
int main()
{
  Eigen::Matrix4d m;
  m.resize(4,4); // no operation
  std::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类接受六个模板参数,但到目前为止我们只讨论了前三个。其余三个参数为可选参数。下面是模板参数的完整列表:

Matrix<typename Scalar,
       int RowsAtCompileTime,
       int ColsAtCompileTime,
       int Options = 0,
       int MaxRowsAtCompileTime = RowsAtCompileTime,
       int MaxColsAtCompileTime = ColsAtCompileTime>
  • Options是位字段。在这里,我们只讨论一个比特:RowMajor。它指定这种类型的矩阵使用行为主存储顺序;默认情况下,存储顺序是以列为主的。请参阅存储订单页面。例如,此类型表示行为主的3x3矩阵:
Matrix<float, 3, 3, RowMajor>
  • MaxRowsAtCompileTime和MaxColsAtCompileTime在需要指定时非常有用,即使在编译时不知道矩阵的确切大小,但在编译时知道一个固定的上限。这样做的最大原因可能是为了避免动态内存分配。例如,下面的矩阵类型使用12个浮点数的普通数组,没有动态内存分配:
Matrix<float, Dynamic, Dynamic, 0, 3, 4>

十二、方便预定义

Eigen定义了以下矩阵类型:

都是用的 Matrix 不同模板参数,预定义为不同类型。

  • MatrixNt :Matrix<type, N, N>.
    例如, MatrixXi 实际上是 :Matrix<int, Dynamic, Dynamic>.
  • MatrixXNt :Matrix<type, Dynamic, N>.
    例如, MatrixX3i 实际上是 :Matrix<int, Dynamic, 3>.
  • MatrixNXt :Matrix<type, N, Dynamic>.
    例如, Matrix4Xd 实际上是 :Matrix<d, 4, Dynamic>.
  • VectorNt :Matrix<type, N, 1>.
    例如, Vector2f 实际上是 :Matrix<float, 2, 1>.
  • RowVectorNt :Matrix<type, 1, N>.
    例如, RowVector3d 实际上是 :Matrix<double, 1, 3>.

注意:文章来源地址https://www.toymoban.com/news/detail-837484.html

  • N 可以是2、3、4或者X(表示动态 Dynamic ) 中的任意一个。
  • t 可以是I (int)、f (float)、d (double)、cf (complex)或CD (complex)中的任意一个。虽然只为这五种类型定义了类型定义,但这并不意味着它们是唯一受支持的标量类型。例如,支持所有标准整数类型,请参阅标量类型。

到了这里,关于Eigen-Matrix矩阵的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Eigen中文文档] 矩阵与向量运算

    专栏总目录 英文原文(Matrix and vector arithmetic) 本文章旨在提供有关如何使用 Eigen 在矩阵、向量和标量之间执行算术操作的概述和一些详细信息。 介绍 Eigen 通过重载常见的 C++ 算术运算符(如 + 、 - 、 * )或通过特殊方法(如 dot() 、 cross() 等)提供矩阵/向量算术运算。对于

    2024年01月24日
    浏览(36)
  • eigen旋转矩阵与欧拉角的转换

    2024年02月11日
    浏览(36)
  • Eigen 对矩阵的每个元素取绝对值

      使用Eigen库对矩阵的每一个元素进行取绝对值操作非常简单。可以使用array()函数将矩阵转换为数组,然后使用abs()函数对数组中的每个元素取绝对值,最后使用matrix()函数将数组转换回矩阵。下面是一个示例代码:

    2024年02月04日
    浏览(30)
  • c++矩阵计算性能对比:Eigen和GPU

    生成随机矩阵 生成随机矩阵有多种方式,直接了当的方式是使用显式循环的方式为矩阵的每个元素赋随机值。 另一种方式是使用Eigen库,它提供了矩阵运算的库。 生成随机矩阵: 计算矩阵点积 使用显式循环计算 直接上代码: 使用Eigen库 代码: 使用GPU 代码片断: 结果分析

    2024年02月12日
    浏览(26)
  • C++矩阵计算-杂记(包含Eigen库的安装)

    C++可以使用多种方法进行矩阵计算,其中常见的两种方式为使用已有的矩阵库或手写矩阵运算代码。 在C++中可以使用许多开源矩阵库进行矩阵计算,比如Eigen、Armadillo等。这些库提供了简单易用的API,可以完成矩阵的基本运算,如加减乘除、转置、求逆、求特征值和特征向量

    2024年02月02日
    浏览(32)
  • Eigen笔记1:矩阵和向量的定义和赋值

    列向量也可以用矩阵来表示 行向量也可以用矩阵来表示 2.3.1 列向量赋值方法 2.3.2 行向量举例 2.3.3 其他赋值方法 逐个元素赋值 注意索引是从0开始,和数组是一样的! 用矩阵赋值 3.2.1 每个矩阵元素单独赋值 注意索引是从0开始,和数组是一样的! 3.2.3 逗号赋值

    2024年02月12日
    浏览(22)
  • 矩阵补充(matrix completion)

    这篇文章介绍矩阵补充(matrix completion),它是一种向量召回通道。矩阵补充的本质是对用户 ID 和物品 ID 做 embedding,并用两个 embedding 向量的內积预估用户对物品的兴趣。值得注意的是,矩阵补充存在诸多缺点,在实践中效果远不及双塔模型。 上篇文章介绍了embedding,它可

    2024年01月19日
    浏览(32)
  • 对角矩阵(diagonal matrix)

    对角矩阵(英语:diagonal matrix)是一个 主对角线之外的元素皆为 0 的矩阵。对角线上的元素可以为 0 或其他值。 对角矩阵参与矩阵乘法 矩阵 A 左乘一个对角矩阵 D,是分别用 D 的对角线元素分别作用于矩阵 A 的每一行; 相似地,矩阵 A 右乘一个对角矩阵 D,是分别将 D 的对

    2024年02月11日
    浏览(37)
  • C++借助Eigen库实现矩阵开方(开根号)运算

    在matlab中我们可以通过sqrtm()函数实现简单的矩阵开方运算,当使用C++时,可以通过以下函数实现。 1、添加头文件: 2、开方函数: 3、主函数调用 在matlab中我们可以通过sqrtm()函数实现简单的矩阵开方运算,当使用C++时,可以通过以上函数实现。

    2024年02月15日
    浏览(23)
  • 【Eigen库使用】角轴、旋转矩阵、欧拉角、四元数转换

    在slam中经常用到的四种描述机器人orientation的变量,他们之间可以相互转化,使用Eigen库可以很容易的做到这一点, 需要特别关注的是:欧拉角与其余量之间的转换关系 : 1)首先要明确的是, 必须要明确欧拉角的旋转次序 ,你可以选择RPY、YPR等方式,在相同的orientation下,

    2024年01月18日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包