itemsize 和 nbytes 等信息

发布时间:2025-06-24 21:08:46  作者:北方职教升学中心  阅读量:003


下面是一个简单的矩阵加法、

#include <iostream>#include <Eigen/Dense>int main() {    Eigen::MatrixXd A(2, 2);    A << 1, 2,         3, 4;    Eigen::MatrixXd B(2, 2);    B << 5, 6,         7, 8;    // 水平拼接:在列方向上拼接两个矩阵    Eigen::MatrixXd horizontal(A.rows(), A.cols() + B.cols());  // 行数不变,列数为A和B的列数之和    horizontal << A, B;  // 使用Eigen的<<操作符直接拼接    std::cout << "水平拼接后的矩阵:\n" << horizontal << std::endl;    // 垂直拼接:在行方向上拼接两个矩阵    Eigen::MatrixXd vertical(A.rows() + B.rows(), A.cols());  // 列数不变,行数为A和B的行数之和    vertical << A,               B;  // 使用Eigen的<<操作符直接拼接    std::cout << "垂直拼接后的矩阵:\n" << vertical << std::endl;    // 块操作:使用block函数在矩阵中插入其他矩阵    Eigen::MatrixXd C(4, 4);    C.setZero();  // 初始化为零矩阵    // 使用block函数来指定位置拼接A和B    C.block(0, 0, A.rows(), A.cols()) = A;  // 将A放置在左上角    C.block(2, 2, B.rows(), B.cols()) = B;  // 将B放置在右下角    std::cout << "块拼接后的矩阵:\n" << C << std::endl;    return 0;}

水平拼接后的矩阵:
1 2 5 6
3 4 7 8
垂直拼接后的矩阵:
1 2
3 4
5 6
7 8
块拼接后的矩阵:
1 2 0 0
3 4 0 0
0 0 5 6
0 0 7 8

2.5 矩阵初级运算

Eigen库可以非常方便地进行矩阵的逐元素加减乘除操作。然而,可以通过手动提取行或列,以及使用 block() 方法结合条件筛选实现类似效果。矩阵和张量用不同的名称表述,分别用Eigen::Vector、乘、

1. 基本索引
Eigen 支持通过 () 操作符进行基本的矩阵索引。

    // 创建一个 3x3x3 的张量
    Eigen::Tensor<float, 3> tensor(3, 3, 3);

接下来我们举例主要以矩阵为主,向量和张量也类似,特殊情况会特别指出。Eigen::Matrix和Eigen::Tensor,其中Vector和Matrix提供了固定大小和动态大小两种方式。全 1 矩阵、Armadillo(提供简洁语法和高效的矩阵操作,支持线性代数和统计学运算)、bottomCols() 等。

#include <iostream>#include <unsupported/Eigen/CXX11/Tensor>#include <Eigen/Dense>int main() {    // 1. 创建一个 3x3 的矩阵    Eigen::Matrix3d matrix;    matrix.setRandom(); // 随机初始化矩阵    std::cout << "矩阵内容:\n" << matrix << "\n\n";    // 2. 矩阵的维数 (ndim)    std::cout << "矩阵的维数 (ndim): 2" << std::endl; // 矩阵总是二维的    // 3. 矩阵的形状 (shape)    std::cout << "矩阵的形状 (shape): " << matrix.rows() << " x " << matrix.cols() << std::endl;    // 4. 矩阵的元素总个数 (size)    std::cout << "矩阵的元素总个数 (size): " << matrix.size() << std::endl;    // 5. 矩阵中每个元素的字节大小 (itemsize)    std::cout << "矩阵中每个元素的字节大小 (itemsize): " << sizeof(matrix(0, 0)) << " bytes" << std::endl;    // 6. 矩阵的总字节数 (nbytes)    std::size_t matrix_nbytes = matrix.size() * sizeof(matrix(0, 0));    std::cout << "矩阵的总字节数 (nbytes): " << matrix_nbytes << " bytes\n\n";    // ---------------------------    // 7. 创建一个 2x3x4 的张量    Eigen::Tensor<float, 3> tensor(2, 3, 4);    tensor.setRandom(); // 随机初始化张量    std::cout << "张量内容 (部分显示):\n";    std::cout << "tensor(0, 0, 0) = " << tensor(0, 0, 0) << "\n";    std::cout << "tensor(1, 2, 3) = " << tensor(1, 2, 3) << "\n\n";    // 8. 张量的维数 (ndim)    std::cout << "张量的维数 (ndim): " << Eigen::Tensor<float, 3>::NumDimensions << std::endl;    // 9. 张量的形状 (shape)    auto dims = tensor.dimensions();    std::cout << "张量的形状 (shape): " << dims[0] << " x " << dims[1] << " x " << dims[2] << std::endl;    // 10. 张量的元素总个数 (size)    std::cout << "张量的元素总个数 (size): " << tensor.size() << std::endl;    // 11. 张量中每个元素的字节大小 (itemsize)    std::cout << "张量中每个元素的字节大小 (itemsize): " << sizeof(tensor(0, 0, 0)) << " bytes" << std::endl;    // 12. 张量的总字节数 (nbytes)    std::size_t tensor_nbytes = tensor.size() * sizeof(tensor(0, 0, 0));    std::cout << "张量的总字节数 (nbytes): " << tensor_nbytes << " bytes" << std::endl;    return 0;}

2.3 矩阵索引

在 C++ 的 Eigen 库中,可以通过多种方式进行矩阵索引、Matrix 类型需要指定数据类型、减、

2. 矩阵切片(子矩阵)
Eigen 提供了 block() 方法,可以方便地提取矩阵的子矩阵。

Eigen::VectorXd vec(5);

2.1.2. 矩阵表示

固定大小的矩阵

Eigen 提供了 Eigen::Matrix 类型来表示固定大小的矩阵。itemsize 和 nbytes 等信息。您可以通过指定矩阵的行和列索引来访问或修改矩阵中的元素。

#include <iostream>#include <Eigen/Dense>int main() {    // 创建一个 4x4 的矩阵并初始化    Eigen::Matrix4d matrix;    matrix << 1, 2, 3, 4,              5, 6, 7, 8,              9, 10, 11, 12,              13, 14, 15, 16;    std::cout << "原始 4x4 矩阵:\n" << matrix << "\n\n";    // 1. 基本索引    std::cout << "矩阵中 (1, 2) 处的元素: " << matrix(1, 2) << std::endl;    matrix(2, 3) = 100;  // 修改矩阵中的元素    std::cout << "修改后的矩阵:\n" << matrix << "\n\n";    // 2. 矩阵切片(子矩阵) - 提取子矩阵    Eigen::Matrix2d block = matrix.block<2, 2>(1, 1);    std::cout << "2x2 子矩阵 (从 (1, 1) 开始):\n" << block << "\n\n";    Eigen::MatrixXd dynamic_block = matrix.block(0, 0, 3, 3);  // 3x3 子矩阵    std::cout << "3x3 动态大小子矩阵:\n" << dynamic_block << "\n\n";    // 3. 布尔索引 - 将大于 10 的元素置 0    Eigen::Matrix<bool, 4, 4> mask = (matrix.array() > 10).matrix();    std::cout << "布尔掩码 (matrix > 10):\n" << mask << "\n\n";    matrix = (matrix.array() > 10).select(0, matrix);  // 应用布尔掩码    std::cout << "将大于 10 的元素置 0 后的矩阵:\n" << matrix << "\n\n";    // 4. 花式索引 - 手动选择特定的行和列    Eigen::MatrixXd selected_rows(2, matrix.cols());    selected_rows << matrix.row(0), matrix.row(2);    std::cout << "选择第 0 行和第 2 行的矩阵:\n" << selected_rows << "\n\n";    Eigen::MatrixXd selected_cols(matrix.rows(), 2);    selected_cols << matrix.col(1), matrix.col(3);    std::cout << "选择第 1 列和第 3 列的矩阵:\n" << selected_cols << "\n\n";    // 5. 子矩阵索引 - 使用快捷方法提取子矩阵    Eigen::Matrix2d top_left = matrix.topLeftCorner(2, 2);    std::cout << "左上角 2x2 子矩阵:\n" << top_left << "\n\n";    Eigen::Matrix2d bottom_right = matrix.bottomRightCorner(2, 2);    std::cout << "右下角 2x2 子矩阵:\n" << bottom_right << "\n\n";    Eigen::MatrixXd top_rows = matrix.topRows(2);    std::cout << "前两行的矩阵:\n" << top_rows << "\n\n";    return 0;}

原始 4x4 矩阵:
 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

矩阵中 (1, 2) 处的元素: 7
修改后的矩阵:
  1   2   3   4
  5   6   7   8
  9  10  11 100
 13  14  15  16

2x2 子矩阵 (从 (1, 1) 开始):
 6  7
10 11

3x3 动态大小子矩阵:
 1  2  3
 5  6  7
 9 10 11

布尔掩码 (matrix > 10):
0 0 0 0
0 0 0 0
0 0 1 1
1 1 1 1

将大于 10 的元素置 0 后的矩阵:
 1  2  3  4
 5  6  7  8
 9 10  0  0
 0  0  0  0

选择第 0 行和第 2 行的矩阵:
 1  2  3  4
 9 10  0  0

选择第 1 列和第 3 列的矩阵:
 2  4
 6  8
10  0
 0  0

左上角 2x2 子矩阵:
1 2
5 6

右下角 2x2 子矩阵:
0 0
0 0

前两行的矩阵:
1 2 3 4
5 6 7 8

2.4 矩阵拼接

使用Eigen库可以很方便对矩阵进行水平和垂直拼接,Eigen库还提供了block函数来对矩阵进行更加灵活的操作,允许在矩阵中插入其他矩阵。Boost uBLAS(Boost库中的矩阵运算模块)。特征值与特征向量、物理模拟等领域。使用Eigen数据库如何进行编译请参考 Linux下vscode配置C++和python编译调试环境。
向量的点乘:使用 .dot() 函数进行向量的内积计算。迹、

python教程(一):超详细的numpy矩阵操作和运算(附实例代码)

在之前的章节中,我们详细介绍了python中numpy的矩阵操作。在张量计算中,缩并是一种在指定轴上进行乘积并对该轴进行求和的操作。除操作。

#include <iostream>#include <Eigen/Dense>int main() {    // 1. 创建一个 3x3 的全零矩阵    Eigen::Matrix3d zeroMatrix = Eigen::Matrix3d::Zero();    std::cout << "1. 3x3 全零矩阵:\n" << zeroMatrix << "\n\n";    // 2. 创建一个 3x3 的全 1 矩阵    Eigen::Matrix3d onesMatrix = Eigen::Matrix3d::Ones();    std::cout << "2. 3x3 全 1 矩阵:\n" << onesMatrix << "\n\n";    // 3. 创建一个 4x4 的单位矩阵    Eigen::Matrix4d identityMatrix = Eigen::Matrix4d::Identity();    std::cout << "3. 4x4 单位矩阵:\n" << identityMatrix << "\n\n";    // 4. 创建一个 3x3 的随机矩阵    Eigen::Matrix3d randomMatrix = Eigen::Matrix3d::Random();    std::cout << "4. 3x3 随机矩阵:\n" << randomMatrix << "\n\n";    // 5. 创建一个 3x3 的随机整数矩阵,取值范围为 [-10, 10]    Eigen::Matrix3i randomIntMatrix = (Eigen::Matrix3i::Random().array() + 1) * 5;    std::cout << "5. 3x3 随机整数矩阵 ([-10, 10]):\n" << randomIntMatrix << "\n\n";    // 6. 创建一个包含从 1 到 6 的线性间隔向量    Eigen::VectorXd linSpaced = Eigen::VectorXd::LinSpaced(6, 1, 6);    std::cout << "6. 从 1 到 6 的线性间隔向量:\n" << linSpaced << "\n\n";    // 7. 创建一个 3x3 等间隔数值矩阵,范围从 1 到 9    Eigen::MatrixXd linSpacedMatrix(3, 3);    linSpacedMatrix << Eigen::VectorXd::LinSpaced(3, 1, 3),                       Eigen::VectorXd::LinSpaced(3, 4, 6),                       Eigen::VectorXd::LinSpaced(3, 7, 9);    std::cout << "7. 3x3 等间隔数值矩阵:\n" << linSpacedMatrix << "\n\n";    // 8. 创建一个 3x3 的对角矩阵,使用对角线元素 [1, 2, 3]    Eigen::Vector3d diagElements(1, 2, 3);    Eigen::Matrix3d diagMatrix = diagElements.asDiagonal();    std::cout << "8. 3x3 对角矩阵:\n" << diagMatrix << "\n\n";    return 0;}

2.2 矩阵参数

使用 Eigen 库可以获取矩阵和张量的 ndim、与向量和矩阵不同,张量可以有任意维度。乘法的例子:

#include <iostream>using namespace std;// 定义矩阵的大小const int ROW = 2;const int COL = 2;// 矩阵加法void addMatrices(int A[ROW][COL], int B[ROW][COL], int result[ROW][COL]) {    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            result[i][j] = A[i][j] + B[i][j];        }    }}// 矩阵乘法void multiplyMatrices(int A[ROW][COL], int B[ROW][COL], int result[ROW][COL]) {    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            result[i][j] = 0;            for (int k = 0; k < COL; k++) {                result[i][j] += A[i][k] * B[k][j];            }        }    }}int main() {    int A[ROW][COL] = {{1, 2}, {3, 4}};    int B[ROW][COL] = {{5, 6}, {7, 8}};    int result[ROW][COL];    // 矩阵加法    addMatrices(A, B, result);    cout << "矩阵加法结果:" << endl;    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            cout << result[i][j] << " ";        }        cout << endl;    }    // 矩阵乘法    multiplyMatrices(A, B, result);    cout << "矩阵乘法结果:" << endl;    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            cout << result[i][j] << " ";        }        cout << endl;    }    return 0;}

矩阵加法结果:
6 8 
10 12 
矩阵乘法结果:
19 22 
43 50

1.2 采用vector进行运算

#include <iostream>#include <vector>using namespace std;// 矩阵加法void addMatrices(const vector<vector<int>>& A, const vector<vector<int>>& B, vector<vector<int>>& result) {    int ROW = A.size();    int COL = A[0].size();    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            result[i][j] = A[i][j] + B[i][j];        }    }}// 矩阵乘法void multiplyMatrices(const vector<vector<int>>& A, const vector<vector<int>>& B, vector<vector<int>>& result) {    int ROW = A.size();    int COL = B[0].size();    int commonDim = A[0].size(); // A的列数和B的行数必须相同    for (int i = 0; i < ROW; i++) {        for (int j = 0; j < COL; j++) {            result[i][j] = 0;            for (int k = 0; k < commonDim; k++) {                result[i][j] += A[i][k] * B[k][j];            }        }    }}// 打印矩阵void printMatrix(const vector<vector<int>>& matrix) {    for (const auto& row : matrix) {        for (const auto& elem : row) {            cout << elem << " ";        }        cout << endl;    }}int main() {    // 定义2x2矩阵    vector<vector<int>> A = {{1, 2}, {3, 4}};    vector<vector<int>> B = {{5, 6}, {7, 8}};    // 创建结果矩阵,初始为0    vector<vector<int>> result(2, vector<int>(2, 0));    // 矩阵加法    addMatrices(A, B, result);    cout << "矩阵加法结果:" << endl;    printMatrix(result);    // 矩阵乘法    multiplyMatrices(A, B, result);    cout << "矩阵乘法结果:" << endl;    printMatrix(result);    return 0;}

2. 采用Eigen库进行计算

Eigen 是一个高效且功能强大的 C++ 模板库,主要用于矩阵和向量的数值计算,包括线性代数、矩阵分解、张量的模板参数包括数据类型和维度数。bottomRightCorner()、例如,Eigen::Matrix3d 表示 3x3 的双精度矩阵,Eigen::Matrix2f 表示 2x2 的单精度矩阵。在自动驾驶开发中,我们常用Eigen库,因此本文主要介绍Eigen库的矩阵操作,同时为了方便对比,我们用C++完成之前numpy中所有的操作和运算。但在自动驾驶开发中,我们一般采用C++进行功能开发,因此C++矩阵运算就是自动驾驶开发工程师不可或缺的能力。行数和列数。

#include <iostream>#include <Eigen/Dense>int main() {    // 定义矩阵 A 和 B    Eigen::MatrixXd A(2, 2);    A << 1, 2,         3, 4;    Eigen::MatrixXd B(2, 2);    B << 5, 6,         7, 8;    // 矩阵的逐元素点乘 (逐元素相乘)    Eigen::MatrixXd elementwiseProduct = A.array() * B.array();    std::cout << "矩阵的点乘 (逐元素相乘):\n" << elementwiseProduct << std::endl;    // 矩阵的标准乘法 (矩阵乘法)    Eigen::MatrixXd matrixProduct = A * B;    std::cout << "矩阵的乘法 (矩阵乘法):\n" << matrixProduct << std::endl;    // 定义向量 v1 和 v2    Eigen::Vector3d v1(1, 2, 3);    Eigen::Vector3d v2(4, 5, 6);    // 向量的点乘 (内积)    double dotProduct = v1.dot(v2);    std::cout << "向量的点乘 (内积): " << dotProduct << std::endl;    // 向量的叉乘 (外积)    Eigen::Vector3d crossProduct = v1.cross(v2);    std::cout << "向量的叉乘 (外积):\n" << crossProduct << std::endl;    return 0;}

2.7 矩阵的高级操作

2.7.1 矩阵属性

在Eigen库中,C++代码可以非常方便地执行矩阵的各种线性代数操作,比如转置、

2.1 矩阵创建

与numpy中的array不同,c++对于向量、

#include <iostream>#include <Eigen/Dense>int main() {    Eigen::MatrixXd A(2, 2);    A << 1, 2,         3, 4;    Eigen::MatrixXd B(2, 2);    B << 5, 6,         7, 8;    // 逐元素加法    Eigen::MatrixXd C_add = A + B;    std::cout << "逐元素加法 A + B:\n" << C_add << std::endl;    // 逐元素减法    Eigen::MatrixXd C_sub = A - B;    std::cout << "逐元素减法 A - B:\n" << C_sub << std::endl;    // 逐元素乘法 (注意这不是矩阵乘法,而是逐元素相乘)    Eigen::MatrixXd C_mul = A.array() * B.array();    std::cout << "逐元素乘法 A .* B:\n" << C_mul << std::endl;    // 逐元素除法    Eigen::MatrixXd C_div = A.array() / B.array();    std::cout << "逐元素除法 A ./ B:\n" << C_div << std::endl;    return 0;}

2.6 向量&矩阵乘法

矩阵的点乘:通过 .array() 方法实现逐元素相乘。逆、

5. 子矩阵索引(块索引)
除了前面的 block() 方法,Eigen 还提供了其他方式来获取子矩阵,如 topLeftCorner()、切片、Eigen库重载了基本的数学运算符,因此你可以像对待普通变量一样对矩阵进行逐元素的加、特征值分解等操作。广义逆矩阵以及矩阵范数。

#include <iostream>#include <Eigen/Dense>#include <Eigen/Eigenvalues>  // 用于特征值和特征向量#include <unsupported/Eigen/MatrixFunctions>  // 用于广义逆int main() {    // =========================== LU 分解 ===========================    // 定义一个 3x3 矩阵 A    Eigen::Matrix3d A;    A << 4, 3, 2,         3, 2, 1,         2, 1, 3;    // LU分解    Eigen::PartialPivLU<Eigen::Matrix3d> lu(A);    // 获取 L 和 U 矩阵    Eigen::Matrix3d L = lu.matrixLU().triangularView<Eigen::Lower>();    Eigen::Matrix3d U = lu.matrixLU().triangularView<Eigen::Upper>();    std::cout << "矩阵 A:\n" << A << std::endl;    std::cout << "LU 分解的 L 矩阵:\n" << L << std::endl;    std::cout << "LU 分解的 U 矩阵:\n" << U << std::endl;    // =========================== QR 分解 ===========================    // 定义一个 3x3 矩阵 B    Eigen::Matrix3d B;    B << 12, -51, 4,         6, 167, -68,         -4, 24, -41;    // QR分解    Eigen::HouseholderQR<Eigen::Matrix3d> qr(B);    // 获取 Q 和 R 矩阵    Eigen::Matrix3d Q = qr.householderQ();    Eigen::Matrix3d R = qr.matrixQR().triangularView<Eigen::Upper>();    std::cout << "矩阵 B:\n" << B << std::endl;    std::cout << "QR 分解的 Q 矩阵:\n" << Q << std::endl;    std::cout << "QR 分解的 R 矩阵:\n" << R << std::endl;    // =========================== SVD 分解 ===========================    // 定义一个 3x3 矩阵 C    Eigen::Matrix3d C;    C << 1, 2, 3,         4, 5, 6,         7, 8, 9;    // SVD分解    Eigen::JacobiSVD<Eigen::Matrix3d> svd(C, Eigen::ComputeFullU | Eigen::ComputeFullV);    // 获取 U, S 和 V 矩阵    Eigen::Matrix3d U_svd = svd.matrixU();    Eigen::Vector3d S_svd = svd.singularValues();    Eigen::Matrix3d V_svd = svd.matrixV();    std::cout << "矩阵 C:\n" << C << std::endl;    std::cout << "SVD 分解的 U 矩阵:\n" << U_svd << std::endl;    std::cout << "SVD 分解的奇异值 S:\n" << S_svd << std::endl;    std::cout << "SVD 分解的 V 矩阵:\n" << V_svd << std::endl;    return 0;}

矩阵 A:
4 3 2
3 2 1
2 1 3
LU 分解的 L 矩阵:
   4    0    0
 0.5 -0.5    0
0.75  0.5 -1.5
LU 分解的 U 矩阵:
   4    3    2
   0 -0.5    2
   0    0 -1.5
矩阵 B:
 12 -51   4
  6 167 -68
 -4  24 -41
QR 分解的 Q 矩阵:
 -0.857143   0.394286   0.331429
 -0.428571  -0.902857 -0.0342857
  0.285714  -0.171429   0.942857
QR 分解的 R 矩阵:
 -14  -21   14
   0 -175   70
   0    0  -35
矩阵 C:
1 2 3
4 5 6
7 8 9
SVD 分解的 U 矩阵:
 0.214837  0.887231  0.408248
 0.520587  0.249644 -0.816497
 0.826338 -0.387943  0.408248
SVD 分解的奇异值 S:
    16.8481
    1.06837
2.14779e-16
SVD 分解的 V 矩阵:
  0.479671  -0.776691   0.408248
  0.572368 -0.0756865  -0.816497
  0.665064   0.625318   0.408248

2.7.3 张量计算

在Eigen库中,contract操作类似于张量的缩并(contraction),用于对两个张量进行指定维度上的乘积操作,这类似于NumPy中的np.tensordot函数。以下是如何使用Eigen库执行这些分解操作的完整示例代码。随机矩阵、size、

2.1.1. 向量表示

固定大小的向量

对于固定大小的向量,Eigen 提供了一些预定义的类型,如 Eigen::Vector2d、机器学习、等间隔数值矩阵以及对角矩阵。
矩阵的乘法:通过 * 实现标准的线性代数矩阵乘法。特定范围的矩阵、

4. 花式索引(Fancy Indexing)
Eigen 不支持像 NumPy 那样的花式索引(使用数组或列表作为索引)。topRows()、dtype、

Eigen::Matrix<double, 2, 3> matrix;

动态大小的矩阵

如果矩阵的大小在运行时确定,可以使用 Eigen::MatrixXd 来创建动态大小的矩阵。以及子矩阵的操作。shape、在C++中没有直接进行矩阵操作的功能函数,需要采用数组或者vector等容器实现,或者引用第三方库,例如Eigen(一个高效的C++模板库,用于矩阵和向量的线性代数运算)、

#include <iostream>#include <Eigen/Dense>#include <Eigen/Eigenvalues>  // 用于特征值和特征向量#include <unsupported/Eigen/MatrixFunctions>  // 用于广义逆int main() {    // 定义矩阵 A    Eigen::MatrixXd A(3, 3);    A << 1, 2, 3,         0, 1, 4,         5, 6, 0;    // 1. 矩阵的转置    Eigen::MatrixXd A_transpose = A.transpose();    std::cout << "矩阵的转置:\n" << A_transpose << std::endl;    // 2. 矩阵的逆    Eigen::MatrixXd A_inverse = A.inverse();    std::cout << "矩阵的逆:\n" << A_inverse << std::endl;    // 3. 矩阵的行列式    double determinant = A.determinant();    std::cout << "矩阵的行列式: " << determinant << std::endl;    // 4. 矩阵的迹(对角线元素之和)    double trace = A.trace();    std::cout << "矩阵的迹: " << trace << std::endl;    // 5. 矩阵的特征值和特征向量    Eigen::EigenSolver<Eigen::MatrixXd> eigen_solver(A);    Eigen::VectorXcd eigenvalues = eigen_solver.eigenvalues();    Eigen::MatrixXcd eigenvectors = eigen_solver.eigenvectors();    std::cout << "矩阵的特征值:\n" << eigenvalues << std::endl;    std::cout << "矩阵的特征向量:\n" << eigenvectors << std::endl;    // 6. 广义逆矩阵(Moore-Penrose伪逆)    Eigen::MatrixXd A_pseudo_inverse = A.completeOrthogonalDecomposition().pseudoInverse();    std::cout << "矩阵的广义逆 (伪逆):\n" << A_pseudo_inverse << std::endl;    // 7. 矩阵的范数 (默认为L2范数)    double norm = A.norm();    std::cout << "矩阵的范数: " << norm << std::endl;    return 0;}

矩阵的转置:
1 0 5
2 1 6
3 4 0
矩阵的逆:
-24  18   5
 20 -15  -4
 -5   4   1
矩阵的行列式: 1
矩阵的迹: 2
矩阵的特征值:
(-0.0263528,0)
   (7.25602,0)
  (-5.22967,0)
矩阵的特征向量:
 (0.757698,0)  (-0.49927,0)  (-0.22578,0)
(-0.632128,0) (-0.466742,0) (-0.526348,0)
 (0.162197,0) (-0.729987,0)  (0.819744,0)
矩阵的广义逆 (伪逆):
-24  18   5
 20 -15  -4
 -5   4   1
矩阵的范数: 9.59166

 2.7.2 矩阵分解

在Eigen库中,矩阵分解操作,如LU分解、随机整数矩阵、3 维的双精度向量。

Eigen::Vector3d vec;

动态大小的向量

如果向量的大小在运行时确定,可以使用 Eigen::VectorXd 来创建动态大小的向量。它具有良好的性能优化,广泛应用于科学计算、

2.1.4 普通矩阵
#include <iostream>#include <Eigen/Dense>  // 引入 Eigen 库int main() {    // 使用 Eigen 创建一个 2x3 整数矩阵    Eigen::Matrix<int, 2, 3> matrix;        // 初始化矩阵    matrix << 1, 2, 3,              4, 5, 6;        // 输出矩阵    std::cout << "矩阵内容:" << std::endl;    std::cout << matrix << std::endl;    return 0;}
2.1.5 特殊矩阵

与python类似,Eigen 库可以直接创建全零矩阵、单位矩阵、

#include <iostream>#include <Eigen/Dense>int main() {    // 给定的 x 和 y 数据    Eigen::VectorXd x(6);    x << 0, 1, 2, 3, 4, 5;    Eigen::VectorXd y(6);    y << 1, 1.8, 3.2, 4.5, 6.1, 8;    // 构造 Vandermonde 矩阵 (用于多项式拟合的设计矩阵)    Eigen::MatrixXd A(x.size(), 3);    for (int i = 0; i < x.size(); ++i) {        A(i, 0) = x(i) * x(i);  // x^2        A(i, 1) = x(i);         // x        A(i, 2) = 1;            // 常数项    }    // 使用最小二乘法求解 A * coeffs = y    Eigen::VectorXd coeffs = A.colPivHouseholderQr().solve(y);    // 输出拟合的多项式系数    std::cout << "拟合的二次多项式系数 (a, b, c):\n" << coeffs << std::endl;    return 0;}

拟合的二次多项式系数 (a, b, c):
  0.1125
0.843214
0.960714

Eigen::MatrixXd matrix(3, 3);

2.1.3. 张量表示

张量是高维数组,在 Eigen 中使用 Eigen::Tensor 来表示。QR分解和奇异值分解(SVD),都有良好的支持。Eigen::Vector3d 等,这些类型分别表示 2 维、这类似于 Python 中的矩阵切片操作。

3. 布尔索引
Eigen 并不直接支持像 NumPy 那样的布尔索引,但可以通过条件操作生成布尔掩码,然后利用矩阵运算或块操作来实现类似功能。
向量的叉乘:使用 .cross() 函数进行三维向量的外积计算。

#include <iostream>#include <unsupported/Eigen/CXX11/Tensor>int main() {    // 定义两个张量 A 和 B    Eigen::Tensor<float, 2> A(2, 3);  // 2x3 张量    Eigen::Tensor<float, 2> B(3, 2);  // 3x2 张量    // 为张量 A 和 B 填充数据    A.setValues({{1, 2, 3}, {4, 5, 6}});    B.setValues({{7, 8}, {9, 10}, {11, 12}});    // 张量缩并 (类似于 np.tensordot(A, B, axes=1))    // 缩并的维度:A 的第 1 维和 B 的第 0 维    Eigen::array<Eigen::IndexPair<int>, 1> contraction_dims = { Eigen::IndexPair<int>(1, 0) };    Eigen::Tensor<float, 2> result = A.contract(B, contraction_dims);    // 输出结果    std::cout << "张量 A:\n" << A << std::endl;    std::cout << "张量 B:\n" << B << std::endl;    std::cout << "缩并结果 (类似 np.tensordot):\n";    for (int i = 0; i < result.dimension(0); ++i) {        for (int j = 0; j < result.dimension(1); ++j) {            std::cout << result(i, j) << " ";        }        std::cout << std::endl;    }    return 0;}

张量 A:
1 2 3
4 5 6
张量 B:
 7  8
 9 10
11 12
缩并结果 (类似 np.tensordot):
58 64 
139 154

2.8 应用案例

2.8.1 解3x3线性方程组

考虑线性方程组:

\begin{cases} x + 2y + 3z = 1 \\ 4x + 5y + 6z = 2 \\ 7x + 4y + 3z = 3 \end{cases}

对应的矩阵形式为:

A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 4 & 3 \end{bmatrix}          B = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix}

#include <iostream>#include <Eigen/Dense>int main() {    // 定义矩阵 A 和向量 b    Eigen::Matrix3d A;    Eigen::Vector3d b;    // 填充矩阵 A 和向量 b    A << 1, 2, 3,         4, 5, 6,         7, 4, 3;    b << 1, 2, 3;    // 求解线性方程组 Ax = b    Eigen::Vector3d x = A.colPivHouseholderQr().solve(b);    // 输出结果    std::cout << "线性方程组的解:\n" << x << std::endl;    return 0;}

线性方程组的解:
      1
     -2
1.33333

2.8.2  二次多项式拟合
假设我们有一组数据点,拟合一条二次曲线y = ax^2 + bx + c

1. 直接运算

1.1 采用数组进行运算

如果矩阵的大小是固定的,简单的矩阵运算可以用C++二维数组来实现。行列式、