5D数组哈希表

时间:2009-05-28 05:45:33

标签: c++ matlab hashtable

我目前在名为template的变量中有一个5D数组,写入名为template1D的1D数组,其哈希表为3456(8 * 12 * 3 * 4 * 3)个条目。在Matlab中,多维数组的访问如下:

template{idx_r, idx_l, idx_rho, idx_alpha, idx_beta}

然而,由于我的索引分别来自0-7,0-11,0-2,0-3和0-2,我不完全确定检索整体的最简单方法是什么来自这五个索引的索引号,以便正确获取模板数组中的正确段。什么是最简单的方法来正确地制作这样的哈希函数?

5 个答案:

答案 0 :(得分:7)

不确定你到底想要做什么,但是你考虑过函数ind2sub和sub2ind吗?他们可能会帮忙。您可能需要担心0和1基于索引,因为MATLAB是基于1的。

- 洛伦

答案 1 :(得分:3)

如果它是一个排列为平面数组的二维数组,您可以将第一个索引乘以第一个维的大小并添加第二个索引。同样,使用5个维度,您可以执行以下操作:

index = (((i1*l1 + i2)*l2 + i3)*l3 + i4)*l4 + i5;

答案 2 :(得分:2)

您是否考虑过使用字符串进行哈希?你甚至可以把它变成十六进制数,

5个字符

#Character 0 is in the range '0'...'7',
#Character 1 is in the range '0'...'B',
#Character 2 is in the range '0'...'2',
#Character 3 is in the range '0'...'3',
#Character 4 is in the range '0'...'2'

字符串作为十六进制数字的部分优点在于它有一个简单的int ... err ...无符号长long表示,如果你需要转换。

答案 3 :(得分:2)

虽然你自己可以自己计算线性索引(正如Tal所指出的那样),但使用内置函数SUB2IND更清晰,更容易阅读(如指出的那样)出自Loren)。对于您的示例,您将按以下方式使用它:

index = sub2ind([8 12 3 4 3], idx_r, idx_l, idx_rho, idx_alpha, idx_beta);

如果所有索引都是从0开始的,那么在将它们传递给SUB2IND之前,你必须先为每个索引添加1。

修改

如果您想了解如何在MATLAB中自己正确计算线性索引,以便它们与SUB2IND的结果一致,这里是您将使用的代码:

index = (((idx_beta*4 + idx_alpha)*3 + idx_rho)*12 + idx_l)*8 + idx_r + 1;

注意需要与此公式一起使用的索引必须基于0,而传递给SUB2IND的索引必须基于1。要将此等式推广到任意数量的维度 N

index = (...(idx(N)*sz(N-1) + idx(N-1))*sz(N-2) + ...)*sz(1) + idx(1) + 1;

或更简洁:

index = 1 + sum(idx.*cumsum([1 sz(1:(N-1))]));

其中 idx 是每个维度的基于0的索引值数组, sz 是每个维度的大小数组。

答案 4 :(得分:0)

我不知道我是否正确理解了这个问题所以我会说出我的理解:

  • 您有一个给定大小的数组,代表一个多维矩阵。
  • 您想将5维向量转换为数组的实际位置

我首先要创建一个类来封装它,我会提供带有5个参数的定义的operator()(std :: size_t,unsigned int等)。这个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中矩阵的大小。

如果您正在执行许多操作,您可能需要考虑使用不同的顺序在内部表示数据而不更改接口以获得更好的缓存命中率。

通用算法是将一个维度中的每个索引转换为以下维度元素,并在该维度上添加偏移量。最简单的例子是2维系统。要访问10列数组上的第3行第2列(假设您按行存储,并且为了参数而从1开始计数),您将首先计算第3行的开始,即每行3 * 10个元素。然后在第2行(第2列)中添加偏移量。

如果你将它增长到一个三维数组,首先你必须通过将平面索引乘以平面的大小来找到你正在寻找的平面,然后使用前面的算法:

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;

这将减少乘法次数,并且更容易为更多维度定义。