格子

时间:2017-11-22 02:00:08

标签: arrays algorithm list data-structures nearest-neighbor

我正在研究Ising模型,我正在尝试有效地计算函数H(σ),其中σ是L x的当前状态L格子(即{+1, -1}i,j的σ_ij∈{1,2,...,L}。要计算特定σ的H,我需要执行以下计算:

enter image description here

其中⟨ij⟩表示站点σ_i和σ_j是最近邻居(假设)J是常数。

几个问题:

  1. 我应该将状态σ存储为L x L矩阵还是L 2 列表? RAM中的内存访问是否比另一个更好(我想这取决于我访问元素的方式......)?
  2. 在任何一种情况下,我如何才能最好地计算H
  3. 真的,我认为这可以归结为如何最有效地访问(和操纵)每个州的邻居。

    一些想法:

    1. 我看到如果我遍历列表或矩阵中的每个元素,我将重复计算,那么是否有一种“最佳”方式来返回唯一的邻居?
    2. 我有没有更好的数据结构?

2 个答案:

答案 0 :(得分:1)

你的问题有点宽泛,对我来说有点混乱,所以请原谅我,如果我的回答不是你要找的那个,但我希望它会有所帮助(有点)。

在索引编制时,数组比列表更快。矩阵是一个2D数组,例如这样(其中NM都是L):

enter image description here

这意味着您首先访问a[i],然后a[i][j]

但是,您可以通过使用1D阵列模拟2D数组来避免此双重访问。在这种情况下,如果您想要访问矩阵中的元素a[i][j],现在就可以a[i * L + j]

这样你加载一次,但是你会增加并添加你的变量,但在某些情况下可能会更快。

现在关于最近邻问题,您似乎正在使用square-lattice Ising model,这意味着您正在进行二维工作。

低维最近邻搜索的一种非常有效的数据结构是kd-tree。该树的构造需要O(nlogn),其中n是数据集的大小。

现在应该考虑是否值得建立这样的数据结构。

PS:有很多库实现了kd-tree,例如CGAL。

答案 1 :(得分:1)

我在学校任务期间遇到了这个问题,我认为解决方案取决于您使用的是哪种编程语言。

就效率而言,没有比将一个for循环写入和邻居(实际上是给定的4个点{(i +/- 1,j +/- 1)}的集合更好的方法(i, j)。但是,当simd(sse等)函数可用时,您可以将其重新表达为带有2d内核{0 1 0; 1 0 1; 0 1 0}的卷积。所以如果使用数值库利用simd函数可以获得显着的性能提升。您可以在此处看到此示例实现(https://github.com/zawlin/cs5340/blob/master/a1_code/denoiseIsingGibbs.py)。 请注意,在这种情况下,性能提升是巨大的,因为要在python中进行评估,我需要编写一个昂贵的for循环。

就工作而言,实际上有一些浪费是不必要的乘法,并且在角落和中心与零相加。因此,您是否可以体验性能改进在很大程度上取决于您的编程环境(如果您已经使用c / c ++,那么可能很困难,您需要使用mkl等来获得良好的改进)