Eigen(3)矩阵Matrix及其简单操作

本文详细介绍了Eigen库中的矩阵和向量类,包括Matrix类的定义与使用、向量的表示方法、动态矩阵的概念及其操作,如构造、初始化、获取元素、调整大小等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Matrix

    在Eigen,所有的矩阵和向量都是Matrix模板类的对象,Vector只是一种特殊的矩阵(一行或者一列)。

    Matrix6个模板参数,主要使用前三个参数,剩下的有默认值。

Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>

Scalar是表示元素的类型,RowsAtCompileTime为矩阵的行,ColsAtCompileTime为矩阵的列。

库中提供了一些类型便于使用,比如:

typedef Matrix<float, 4, 4> Matrix4f;

2. Vectors向量

列向量

typedef Matrix<float, 3, 1> Vector3f;

行向量

typedef Matrix<int, 1, 2> RowVector2i;

3. Dynamic

    Eigen不只限于已知大小(编译阶段)的矩阵,有些矩阵的尺寸是运行时确定的,于是引入了一个特殊的标识符:Dynamic

typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
typedef Matrix<int, Dynamic, 1> VectorXi;
Matrix<float, 3, Dynamic>

4. 构造函数

    默认的构造函数不执行任何空间分配,也不初始化矩阵的元素。

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);

5. 获取元素

    通过中括号获取元素,对于矩阵是:(行,列);对于向量,只是传递它的索引,以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++[]不能传递超过一个参数。

6. 逗号初始化

Matrix3f m;
m << 1, 2, 3,
     4, 5, 6,
     7, 8, 9;
std::cout << m;

7. 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;
}

8. 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是不允许的。

9. 固定尺寸 vs 动态尺寸

    实际中,应该使用固定尺寸还是动态尺寸,简单的答案是:小的尺寸用固定的,大的尺寸用动态的。使用固定尺寸可以避免动态内存的开辟,固定尺寸只是一个普通数组。

  Matrix4f mymatrix; 等价于 float mymatrix[16];

  MatrixXf mymatrix(rows,columns); 等价于 float *mymatrix = new float[rows*columns];

    使用固定尺寸(<=4*4)需要编译前知道矩阵大小,而且对于足够大的尺寸,如大于32,固定尺寸的收益可以忽略不计,而且可能导致栈崩溃。而且基于环境,Eigen会对动态尺寸做优化(类似于std::vector

10. 其他模板参数

    上面只讨论了前三个参数,完整的模板参数如下:

Matrix<typename Scalar,
       int RowsAtCompileTime,
       int ColsAtCompileTime,
       int Options = 0,
       int MaxRowsAtCompileTime = RowsAtCompileTime,
       int MaxColsAtCompileTime = ColsAtCompileTime>

 

    Options是一个比特标志位,这里,我们只介绍一种RowMajor,它表明matrix使用按行存储,默认是按列存储。Matrix<float, 3, 3, RowMajor>

    MaxRowsAtCompileTimeMaxColsAtCompileTime表示在编译阶段矩阵的上限。主要是避免动态内存分配,使用数组。

Matrix<float, Dynamic, Dynamic, 0, 3, 4> 等价于 float [12]

11. 一些方便的定义

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,4X(Dynamic)

    t可以是i(int)f(float)d(double)cf(complex)cd(complex)等。

 

 

 

<think>好的,用户想知道如何在Eigen库中输入矩阵。首先,我需要回忆Eigen的基本用法。记得Eigen是一个C++的线性代数库,矩阵和向量的定义需要包含相应的头文件,比如<Eigen/Dense>。 接下来,用户可能需要的示例代码。对于固定大小的矩阵,可以使用MatrixXd或者Matrix3d这样的模板类。动态矩阵的话,MatrixXd指定行数和列数,或者在运行时调整大小。初始化方面,逗号初始化器应该很常用,比如matrix << 1,2,3,4,5,6,7,8,9。 然后,可能需要提到如何从文件或用户输入读取数据。这部分可能需要使用文件流,逐行读取数据然后填充到矩阵中。比如用ifstream读取文件,然后按行或按元素赋值给矩阵。 还要注意矩阵输入时的常见错误,比如动态矩阵未指定大小就直接赋值,或者逗号初始化器的元素数量不匹配。这些错误处理也应该提到,帮助用户避免问题。 另外,用户可能需要了解不同初始化方法,比如零矩阵、单位矩阵和随机矩阵的生成方法,比如MatrixXd::Zero(3,3)或者Matrix3d::Identity()。 最后,根据用户提供的引用,可能需要参考一些资料,比如引用中的C++算法库或者代码片段集合,来补充说明Eigen矩阵输入的最佳实践。不过用户提供的引用主要是关于调用Matlab和代码集合,可能与Eigen直接相关的内容不多,但可以适当提及相关的资源。 需要确保回答结构清晰,分步骤说明,并提供示例代码。同时,生成的相关问题要围绕矩阵操作的其他方面,比如运算、性能优化和文件操作等。</think>### 在Eigen中输入矩阵的方法 Eigen是一个高效的C++线性代数库,矩阵输入可以通过多种方式实现。以下是详细的步骤和示例: --- #### **1. 固定大小的矩阵输入** 对于已知维度的矩阵(如3x3),可直接使用逗号初始化: ```cpp #include <Eigen/Dense> Eigen::Matrix3d mat; mat << 1, 2, 3, 4, 5, 6, 7, 8, 9; ``` - `Matrix3d`表示3x3的双精度浮点矩阵。 - 使用`<<`运算符逐行填充元素[^2]。 --- #### **2. 动态大小的矩阵输入** 若矩阵大小在运行时确定,使用`MatrixXd`并指定维度: ```cpp Eigen::MatrixXd dynamic_mat(2, 3); // 2行3列 dynamic_mat << 1, 2, 3, 4, 5, 6; ``` - 也可以通过`resize()`调整动态矩阵的大小: ```cpp dynamic_mat.resize(3, 2); // 调整为3行2列 ``` --- #### **3. 从文件/用户输入读取** 逐元素或逐行读取数据: ```cpp #include <fstream> std::ifstream file("data.txt"); Eigen::MatrixXd file_mat(3, 3); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { file >> file_mat(i, j); } } ``` - 假设`data.txt`包含以空格分隔的数字。 --- #### **4. 特殊矩阵初始化** Eigen提供快速生成常用矩阵的方法: ```cpp // 零矩阵 Eigen::MatrixXd zero_mat = Eigen::MatrixXd::Zero(3, 3); // 单位矩阵 Eigen::Matrix3d identity_mat = Eigen::Matrix3d::Identity(); // 随机矩阵(范围[-1,1]) Eigen::MatrixXd random_mat = Eigen::MatrixXd::Random(2, 2); ``` --- #### **注意事项** - **逗号初始化要求元素数量严格匹配**,否则会报错。 - 动态矩阵未初始化时需先调用`resize()`或构造函数指定维度。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值