我不知道我是否正确理解了这个问题,所以我将说明我的理解:
- 您有一个给定大小的数组,它代表一个多维矩阵。
- 您想将 5 维向量转换为数组的实际位置
我会首先创建一个类来封装它,然后我会提供使用 5 个参数(std::size_t、unsigned int 左右)定义的 operator()。这个 operator() 应该首先检查范围(可能会抛出异常并将所有参数转换为最终位置。
最简单的转换是:
size_t position( size_t idx_r, size_t idx_l, size_t idx_rho, size_t idx_alpha, size_t idx_beta )
{
size_t pos = (((((((idx_r * dim_l) + idx_l) * dim_rho) + idx_rho) * dim_alpha) + idx_alpha) * dim_beta) + idx_beta;
return pos;
}
其中dim_XXX表示第 XXX 维矩阵的大小。
如果您正在执行许多操作,您可能需要考虑在内部以不同的顺序表示数据,而不更改接口以获得更好的缓存命中率。
一般算法是将一个维度中的每个索引转换为后续维度元素,并在该维度添加偏移量。最简单的例子是二维系统。要访问 10 列数组上的第 3 行第 2 列(假设您按行存储,并且为了参数从 1 开始计数),您将首先计算第三行的开始,即每行 3 * 10 个元素。然后在第 2 行(第 2 列)内添加偏移量。
如果您将其扩展为 3 维数组,首先您必须通过将平面索引乘以平面的大小来找到您正在寻找的平面,然后使用前面的算法:
size_t position( size_t x, size_t y, size_t z )
{
size_t start_of_plane_z = z * dim_y * dim_x; // z * size_of_plane
size_t start_of_row_y = y * dim_x; // y * size_of_row
size_t offset_inside_row = x;
return start_of_plane_z + start_of_row_y + offset_inside_row;
}
现在,应用一些基本代数,您可以将方程变为:
size_t pos = (((z * dim_y) + y) * dim_x) + x;
这将减少乘法的数量,并且更容易为更多的维度定义。