【Eigen教程】矩阵、数组和向量类(二)

  • Matrix Class 矩阵类

  • Vector Class 向量类

  • Array Class 数组类

    • Converting Array to Matrix 将数组转换为矩阵

    • Converting Matrix to Array 将矩阵转换为数组

  • Initialization 初始化

  • Accessing Elements (Coefficient) 访问元素(系数)

    • Accessing via parenthesis 通过括号访问

    • Accessing via pointer to data 通过指针访问数据

    • Row Major Access 行优先访问

    • Accessing a block of data 访问数据块

  • Reshaping, Resizing, Slicing 重塑,调整大小,切片

  • Tensor Module 张量模块

Matrix Class 矩阵类

矩阵类有六个模板参数,前三个是必需的:

cpp 复制代码
Eigen::Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>

例如:

ruby 复制代码
Eigen::Matrix<double, 2, 1> matrix;

如果维度在编译时已知,可以使用 Eigen::Dynamic 作为模板参数。例如:

ruby 复制代码
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>  matrix;

Eigen 提供了许多方便的 typedefs 来涵盖常见情况,这些矩阵(以及向量和数组)的定义形式如下:

cpp 复制代码
Eigen::MatrixSizeTypeEigen::VectorSizeTypeEigen::ArraySizeType

Type 可以是:

  • i:整数,

  • f:浮点数,

  • d:双精度,

  • c:复数,

  • cf:复浮点数,

  • cd:复双精度。

Size 可以是 2、3、4(固定大小方阵)或 X(动态大小)。

例如,Matrix4f 是一个 4x4 的浮点矩阵。Eigen 的定义如下:

cpp 复制代码
typedef Matrix<float, 4, 4> Matrix4f;

或者

sql 复制代码
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;

更多示例:

css 复制代码
Eigen::Matrix4d m; // 4x4 双精度
Eigen::Matrix4cd objMatrix4cd; // 4x4 复数双精度
//a 是一个 3x3 矩阵,具有一个未初始化系数的静态 float[9] 数组,Eigen::Matrix3f a;
//b 是一个动态大小的矩阵,其大小当前为 0x0,并且其系数数组尚未分配。Eigen::MatrixXf b;
//A 是一个 10x15 的动态大小矩阵,具有分配但当前未初始化的系数。Eigen::MatrixXf A(10, 15);

Vector Class 向量类

向量是单行/单列矩阵。例如:

css 复制代码
// Vector3f 是一个固定的 3 个浮点数的列向量:Eigen::Vector3f objVector3f;
// RowVector2i 是一个固定的 2 个整数的行向量:Eigen::RowVector2i objRowVector2i;
// VectorXf 是一个大小为 10 的浮点数列向量:Eigen::VectorXf objv(10);
//V 是一个大小为 30 的动态大小向量,具有分配但当前未初始化的系数。Eigen::VectorXf V(30);

您可以使用/从向量获取/设置矩阵的每一行或列:

ruby 复制代码
// 引入Eigen库的头文件(假设已经包含)#include <Eigen/Dense>
// 创建一个2x2的双精度浮点数矩阵Eigen::Matrix2d mat;
// 使用逗号初始化语法为矩阵赋值// 矩阵内容为:// 1 2// 3 4mat << 1, 2, 3, 4;
// 提取矩阵的第一行(索引从0开始),并将其存储为一个行向量// firstRow 是一个1x2的行向量,值为 [1, 2]Eigen::RowVector2d firstRow = mat.row(0);
// 提取矩阵的第一列(索引从0开始),并将其存储为一个列向量// firstCol 是一个2x1的列向量,值为 [1, 3]Eigen::Vector2d firstCol = mat.col(0);
// 将 firstRow 重新赋值为一个随机的1x2行向量// Eigen::RowVector2d::Random() 生成一个值在 [-1, 1] 范围内的随机行向量firstRow = Eigen::RowVector2d::Random();
// 将 firstCol 重新赋值为一个随机的2x1列向量// Eigen::Vector2d::Random() 生成一个值在 [-1, 1] 范围内的随机列向量firstCol = Eigen::Vector2d::Random();
// 将更新后的 firstRow 赋值回矩阵的第一行// 矩阵的第一行现在被替换为 firstRow 的值mat.row(0) = firstRow;
// 将更新后的 firstCol 赋值回矩阵的第一列// 矩阵的第一列现在被替换为 firstCol 的值mat.col(0) = firstCol;

Array Class 数组类

Eigen 矩阵类用于线性代数。数组类是通用数组,具有系数操作,例如向每个系数添加一个常数、逐个系数地乘两个数组等。

sql 复制代码
// 引入Eigen库的头文件(假设已经包含)#include <Eigen/Dense>
// 定义一个动态大小的浮点数数组(列向量)// Eigen::Array<float, Eigen::Dynamic, 1> 表示一个列数为1,行数动态的浮点数数组// a1 是一个动态大小的浮点数数组,初始时未分配大小Eigen::Array<float, Eigen::Dynamic, 1> a1;
// 定义一个固定大小为3x1的浮点数数组(列向量)// Eigen::Array<float, 3, 1> 表示一个3行1列的浮点数数组// a2 是一个固定大小的浮点数数组,大小为3x1Eigen::Array<float, 3, 1> a2;
// 定义一个动态大小的双精度浮点数数组(矩阵)// Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic> 表示一个行数和列数都动态的双精度浮点数数组// a3 是一个动态大小的双精度浮点数数组,初始时未分配大小Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic> a3;
// 定义一个固定大小为3x3的双精度浮点数数组(矩阵)// Eigen::Array<double, 3, 3> 表示一个3行3列的双精度浮点数数组// a4 是一个固定大小的双精度浮点数数组,大小为3x3Eigen::Array<double, 3, 3> a4;
// 将数组 a4 转换为一个3x3的双精度浮点数矩阵// a4.matrix() 将 Eigen::Array 转换为 Eigen::Matrix// matrix_from_array 是一个3x3的双精度浮点数矩阵,内容与 a4 相同Eigen::Matrix3d matrix_from_array = a4.matrix();

Converting Array to Matrix

将数组转换为矩阵

ruby 复制代码
Eigen::Array<double, 4,4> array1=Eigen::ArrayXd::Random(4,4);Eigen::Array<double, 4,4> mat1=array1.matrix();

Converting Matrix to Array

将矩阵转换为数组

ruby 复制代码
Eigen::Matrix<double, 4,4> mat1=Eigen::MatrixXd::Random(4,4);Eigen::Array<double, 4,4> array1=mat1.array();

Initialization 初始化

您可以使用逗号初始化矩阵:

ruby 复制代码
Eigen::Matrix<double, 2, 3> matrix;matrix << 1, 2, 3, 4, 5, 6;

还有各种现成的 API 用于特殊矩阵,例如:

css 复制代码
// 引入Eigen库的头文件(假设已经包含)#include <Eigen/Dense>
// 创建一个2x2的双精度浮点数矩阵 rndMatrixEigen::Matrix2d rndMatrix;
// 将 rndMatrix 的所有元素设置为随机值// setRandom() 方法会将矩阵中的每个元素设置为 [-1, 1] 范围内的随机值rndMatrix.setRandom();
// 创建一个2x2的双精度浮点数矩阵 constantMatrixEigen::Matrix2d constantMatrix;
// 将 constantMatrix 的所有元素设置为常量值 4.3// setConstant(value) 方法会将矩阵中的每个元素设置为指定的值constantMatrix.setConstant(4.3);
// 创建一个6x6的双精度浮点数单位矩阵 identity// Eigen::MatrixXd::Identity(rows, cols) 创建一个指定大小的单位矩阵// 单位矩阵是一个对角线元素为1,其余元素为0的矩阵Eigen::MatrixXd identity = Eigen::MatrixXd::Identity(6, 6);
// 创建一个3x3的双精度浮点数零矩阵 zeros// Eigen::MatrixXd::Zero(rows, cols) 创建一个指定大小的零矩阵// 零矩阵的所有元素均为0Eigen::MatrixXd zeros = Eigen::MatrixXd::Zero(3, 3);
// 创建一个10x4的浮点数数组 table// Eigen::ArrayXXf 表示一个动态大小的浮点数数组Eigen::ArrayXXf table(10, 4);
// 将 table 的第一列设置为从0到90的等间距值// Eigen::ArrayXf::LinSpaced(size, low, high) 生成一个从 low 到 high 的等间距数组// 这里生成一个包含10个元素的数组,值从0到90,并将其赋值给 table 的第一列table.col(0) = Eigen::ArrayXf::LinSpaced(10, 0, 90);

Accessing Elements (Coefficient)

访问元素(系数)

Accessing via parenthesis

通过括号访问

Eigen 重载了括号运算符,这意味着您可以使用行和列索引访问元素:matrix(row,col)

所有 Eigen 矩阵默认使用列优先存储顺序。这意味着 matrix(2) 是第一列的第三个元素 matix(2,0)

ruby 复制代码
// 引入Eigen库的头文件(假设已经包含)#include <Eigen/Dense>
// 创建一个4x4的浮点数矩阵 matrixEigen::MatrixXf matrix(4, 4);
// 使用逗号初始化语法为矩阵赋值// 矩阵内容为:// 1  2  3  4// 5  6  7  8// 9 10 11 12// 13 14 15 16matrix << 1, 2, 3, 4,          5, 6, 7, 8,          9, 10, 11, 12,          13, 14, 15, 16;
// 访问矩阵的第3个元素(按列优先顺序)// 在Eigen中,矩阵的元素是按列优先(Column-major)顺序存储的// 因此 matrix(2) 访问的是第1列的第3个元素,即 matrix(2, 0)// 值为 9std::cout << "matrix(2): " << matrix(2) << std::endl;
// 访问矩阵的第3行第1列的元素// matrix(2, 0) 访问的是第3行第1列的元素// 值为 9std::cout << "matrix(2, 0): " << matrix(2, 0) << std::endl;

Accessing via pointer to data

通过指针访问数据

如果需要直接访问底层数据,可以使用 matrix.data(),它返回一个指向第一个元素的指针:

ruby 复制代码
// 遍历矩阵的所有元素// matrix.size() 返回矩阵中元素的总数(行数 × 列数)for (int i = 0; i < matrix.size(); i++){    // 通过指针算术访问矩阵的第 i 个元素    // matrix.data() 返回指向矩阵数据存储区的指针    // *(matrix.data() + i) 访问矩阵的第 i 个元素(按列优先顺序)    std::cout << *(matrix.data() + i) << "  ";}

Row Major Access 行优先访问

默认情况下,Eigen 矩阵是列优先的,要更改它,只需传递模板参数:

sql 复制代码
// 引入Eigen库的头文件(假设已经包含)#include <Eigen/Dense>
// 创建一个4x4的双精度浮点数矩阵,并指定存储顺序为行优先(Row-major)// Eigen::Matrix<double, 4, 4, Eigen::RowMajor> 表示一个4行4列的矩阵,元素类型为 double,存储顺序为行优先// matrixRowMajor 是一个4x4的矩阵,初始时未赋值Eigen::Matrix<double, 4, 4, Eigen::RowMajor> matrixRowMajor(4, 4);

Accessing a block of data

访问数据块

您可以访问矩阵中的数据块。

ruby 复制代码
// 定义变量用于表示块的起始行、起始列、块的行数和列数int starting_row, starting_column, number_rows_in_block, number_cols_in_block;
// 设置块的起始行为1(第2行,索引从0开始)starting_row = 1;
// 设置块的起始列为1(第2列,索引从0开始)starting_column = 1;
// 设置块的行数为2number_rows_in_block = 2;
// 设置块的列数为2number_cols_in_block = 2;
// 从矩阵中提取一个子块(block)// matrix.block(starting_row, starting_column, number_rows_in_block, number_cols_in_block)// 返回一个从 (starting_row, starting_column) 开始的子矩阵,大小为 number_rows_in_block x number_cols_in_block// 子块是一个2x2的矩阵auto submatrix = matrix.block(starting_row, starting_column, number_rows_in_block, number_cols_in_block);

Reshaping, Resizing, Slicing

重塑,调整大小,切片

矩阵的当前大小可以通过 rows()cols()size() 方法获取。调整动态大小矩阵的大小可以通过 resize() 方法完成,如果实际矩阵大小未更改,即从 3x4 更改为 6x2,则为无操作。

sql 复制代码
// 定义变量 rows 和 cols,分别表示矩阵的行数和列数int rows, cols;
// 设置 rows 为 3rows = 3;
// 设置 cols 为 4cols = 4;
// 创建一个动态大小的双精度浮点数矩阵 dynamicMatrix// Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> 表示一个行数和列数都动态的矩阵Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> dynamicMatrix;
// 调整 dynamicMatrix 的大小为 rows x cols(3行4列)// resize(rows, cols) 方法会重新分配矩阵的内存,并将其大小调整为指定的行数和列数dynamicMatrix.resize(rows, cols);
// 将 dynamicMatrix 赋值为一个随机矩阵// Eigen::MatrixXd::Random(rows, cols) 生成一个大小为 rows x cols 的随机矩阵,元素值在 [-1, 1] 范围内dynamicMatrix = Eigen::MatrixXd::Random(rows, cols);
// 再次调整 dynamicMatrix 的大小为 2行6列// resize(2, 6) 会重新分配矩阵的内存,并将其大小调整为 2行6列// 注意:调整大小后,原矩阵的内容会被丢弃dynamicMatrix.resize(2, 6);

如果新大小与矩阵大小不同,并且您希望保留数据,则应使用 conservativeResize() 方法

ruby 复制代码
// 使用 conservativeResize 调整 dynamicMatrix 的大小// dynamicMatrix.rows() 返回当前矩阵的行数// dynamicMatrix.cols() + 1 表示将矩阵的列数增加1// conservativeResize 会保留原矩阵的内容,并在新增的列中填充未初始化的值dynamicMatrix.conservativeResize(dynamicMatrix.rows(), dynamicMatrix.cols() + 1);
// 将新增的最后一列赋值为一个列向量// dynamicMatrix.col(dynamicMatrix.cols() - 1) 访问矩阵的最后一列// Eigen::Vector2d(1, 4) 创建一个2行1列的列向量,值为 [1, 4]// 将最后一列的值设置为 [1, 4]dynamicMatrix.col(dynamicMatrix.cols() - 1) = Eigen::Vector2d(1, 4);
  1. 调整矩阵大小
  • 使用 conservativeResize() 方法将矩阵的列数增加1,同时保留原矩阵的内容。

  • 新增的列会被填充为未初始化的值。

赋值新增列

  • 使用 dynamicMatrix.col(dynamicMatrix.cols() - 1) 访问矩阵的最后一列。

  • 将最后一列的值设置为 [1, 4]

相关推荐
不能只会打代码38 分钟前
蓝桥杯例题一
算法·蓝桥杯
OKkankan44 分钟前
实现二叉树_堆
c语言·数据结构·c++·算法
ExRoc2 小时前
蓝桥杯真题 - 填充 - 题解
c++·算法·蓝桥杯
利刃大大3 小时前
【二叉树的深搜】二叉树剪枝
c++·算法·dfs·剪枝
肖田变强不变秃4 小时前
C++实现有限元计算 矩阵装配Assembly类
开发语言·c++·矩阵·有限元·ansys
天乐敲代码5 小时前
JAVASE入门九脚-集合框架ArrayList,LinkedList,HashSet,TreeSet,迭代
java·开发语言·算法
Kent_J_Truman5 小时前
【子矩阵——优先队列】
算法
快手技术6 小时前
KwaiCoder-23BA4-v1:以 1/30 的成本训练全尺寸 SOTA 代码续写大模型
算法·机器学习·开源
BlackPercy7 小时前
【线性代数】列主元法求矩阵的逆
线性代数·机器学习·矩阵