Skip to content

【Eigen】稠密矩阵的索引和访问01

finish time:2025-05-23 11:24

https://www.cnblogs.com/aksoam/p/18159486

python 中numpy库可以实现类似matlab多维数组的运算.但两者在索引方式上存在一些差异.

  • 在matlab中按行按列索引

在MATLAB中,下面这个索引操作实际上返回的是矩阵A中第1行和第2行的第2列和第3列元素组成的矩阵,即:

% 定义一个4*4矩阵
A=1:16;
A=reshape(A,[4,4]);

% 提取2*2的子矩阵
a=A([1,4],[1,4])

% 得到一个2*2矩阵:
% [ A(1,1) A(1,4);
%   A(4,1) A(4,4) ]
  • Python

在Python中使用NumPy库,要得到与MATLAB相同的结果,您需要使用如下的索引方式:

import numpy as np

A = np.array([[1, 2, 3, 4],
              [5, 6, 7, 8],
              [9, 10, 11, 12],
              [13, 14, 15, 16]])
# 错误用法,只能得到 输出结果:[ 1 16]
# a = A[[0,3],[0,3]]
# 获取与MATLAB相同的2x2矩阵
a = A[np.ix_([0, 1], [1, 2])]

print(a)
# [[ 2  3]
#  [ 6  7]]

这里np.ix_函数用于创建一个索引数组,它允许我们按照MATLAB的索引方式来选择矩阵的子集.这段代码将得到与MATLAB相同的2x2矩阵

  • Eigen

在eigen中实现类似的功能,需要使用 operator() 和 std::vector 或 Eigen::VectorXi 索引

#include <Eigen/Dense>
#include <vector>
#include <iostream>
int main() {
   Eigen::MatrixXd mat(5, 5); // 假设有一个 5x5 矩阵
   mat <<  1, 2, 3, 4, 5,
           6, 7, 8, 9, 10,
           11, 12, 13, 14, 15,
           16, 17, 18, 19, 20,
           21, 22, 23, 24, 25;
   std::cout << "Original Matrix:\n" << mat << std::endl;
   // 假设我们要提取的行和列索引
   std::vector<int> rows = { 0, 2, 4 }; // 选择的行索引
   std::vector<int> cols = { 1, 3 };    // 选择的列索引

   // 转换为 Eigen::VectorXi
   Eigen::VectorXi row_indices = Eigen::Map<Eigen::VectorXi>(rows.data(), rows.size());
   Eigen::VectorXi col_indices = Eigen::Map<Eigen::VectorXi>(cols.data(), cols.size());

   // 方法1:遍历提取子矩阵
   Eigen::MatrixXd submatrix(rows.size(), cols.size());
   for (int i = 0; i < rows.size(); ++i) {
       for (int j = 0; j < cols.size(); ++j) {
           submatrix(i, j) = mat(rows[i], cols[j]);
       }
   }
    // 方法二:直接用Eigen::VectorXi 
    Eigen::MatrixXd submatrix = mat(row_indices, col_indices);

   // 打印子矩阵
   std::cout << "Submatrix:\n" << submatrix << std::endl;
   return 0;
}
Img

如果需要对连续范围的子矩阵,则可以使用Eigen::seq()生成算术序列;

#include <Eigen/Dense>
#include <vector>
#include <iostream>
int main() {
   Eigen::MatrixXd mat(5, 5); // 假设有一个 5x5 矩阵
   mat <<  1, 2, 3, 4, 5,
           6, 7, 8, 9, 10,
           11, 12, 13, 14, 15,
           16, 17, 18, 19, 20,
           21, 22, 23, 24, 25;
   std::cout << "Original Matrix:\n" << mat << std::endl;

    // 选取第2~4行,第3~5列的子矩阵
   auto submatrix = mat(Eigen::seq(1, 3), Eigen::seq(2, 4));
   // 打印子矩阵
   std::cout << "Submatrix:\n" << submatrix << std::endl;
   std::cout << "Submatrix size: " << submatrix.rows() << "x" << submatrix.cols() << std::endl;

   return 0;
}

Img