如何在Eigen C++中使用for循环正确初始化3D张量?
Eigen 3D张量正确初始化方法
原代码问题分析
你当前代码的核心问题是线性索引计算错误。Eigen Tensor默认采用列优先内存布局(和MATLAB一致),线性索引的计算规则是按维度顺序累加:索引 = 维度0索引 + 维度0大小*维度1索引 + 维度0大小*维度1大小*维度2索引
原代码里的j + (nz+1)*i + k完全不符合这个规则,导致大部分元素没有被正确赋值。
另外,直接使用线性索引容易出错,更推荐通过张量的维度索引直接访问元素,可读性和正确性更高。
正确初始化实现
方法1:嵌套循环(直观易理解)
根据你的需求,每个i(对应第1维)对应的所有k(第0维)和j(第2维)元素值都是i*dx,代码如下:
static const int nx = 4; static const int ny = 4; static const int nz = 4; const double dx = M_PI / 2; // 对应示例中的1.5708 // 构造5×4×4的张量:维度0(nz+1)=5,维度1(nx)=4,维度2(ny)=4 Eigen::Tensor<double, 3> test(nz+1, nx, ny); test.setZero(); // 按维度索引赋值:test(k, i, j) 对应第0维k,第1维i,第2维j for(int i = 0; i < nx; ++i){ for(int j = 0; j < ny; ++j){ for(int k = 0; k < nz+1; ++k){ test(k, i, j) = i * dx; } } }
方法2:Eigen张量操作(高效无循环)
利用Eigen的broadcast操作可以避免嵌套循环,更符合张量库的使用习惯:
static const int nx = 4; static const int ny = 4; static const int nz = 4; const double dx = M_PI / 2; // 先创建1×4×1的张量,存储0, dx, 2dx, 3dx Eigen::Tensor<double, 3> base(1, nx, 1); for(int i = 0; i < nx; ++i){ base(0, i, 0) = i * dx; } // 将base在第0维广播5次,第2维广播4次,得到5×4×4的目标张量 Eigen::Tensor<double, 3> test = base.broadcast(Eigen::array<Eigen::Index, 3>{nz+1, 1, ny});
验证说明
两种方法都会生成你期望的5×4×4张量:
- 第0维(共5个切片)的每个切片都是相同的4×4矩阵
- 矩阵的每一列(对应i)的所有元素都是
i*dx,即第0列全0,第1列全1.5708,第2列全3.1416,第3列全4.7124,完全匹配你给出的示例输出。
内容的提问来源于stack exchange,提问作者Jamie
相关产品推荐
相关产品推荐

