如何打包3 dim数组/如何在1 dim数组上映射它

时间:2014-08-08 10:19:33

标签: arrays algorithm fortran

我有一个关于多维数组打包的问题。我此刻陷入困境,也许有人可以帮助我,因为我认为这是一项相当简单的任务。我在Fortran编程,但语言在这里非常重要。

在我工作期间,我必须在三元组i,j,k上存储信息,其中i <= j <= k,其中i,j,k从1变为n。

因为我的程序中的内存需求很关键,所以我不想浪费内存并尝试将数组行程(i,j,k)打包到一维数组中。到目前为止,我使用对ij并将它们映射到1d数组(通常用于对称矩阵)并计算1d数组中的索引:

ijpair = i*(i+1)/2+j

具有最大对数

npair = n*(n+1)/2+n

为了合并第三个索引,我生成了n个副本块(对于每个k)。三元组的索引是:

ijktrip = npair*(k-1) + ijpair

以这种方式,内存需求已经减少,但仍然不是最优的,目前我无法弄清楚如何充分利用限制i&lt; = j&lt; = k。

感谢您的提前帮助

1 个答案:

答案 0 :(得分:0)

正如您已经注意到的那样,对于特定的k,您有k*(k+1)/2个元素。让我们按k的递增顺序枚举元素,然后增加j的顺序,然后增加i的顺序。

对于给定的k,您已使用sum_{1 <= p < k} p*(p+1)/2个索引。该总和评估为(见Wolfram alpha

k*(k-1)*(k+1)/6

k - 平面中,您需要对j执行类似的操作:对于给定的j您已使用sum_{1 <= p < j} p = j*(j-1)/2个索引。

jk - 行上,您重复此操作:对于给定的i您已使用i-1个索引。

这产生总公式:

index(i, j, k) = k*(k-1)*(k+1)/6 + j*(j-1)/2 + i

请注意(再次参见Wolfram alpha

index(n, n, n) = n*(n-1)*(n+1)/6 + n*(n-1)/2 + n = n*(n+1)*(n+2)/6

这正是您拥有的元素数量,因此不会浪费任何索引。