我正在研究Ising模型,我正在尝试有效地计算函数H(
σ)
,其中σ是L
x的当前状态L
格子(即{+1, -1}
∈i,j
的σ_ij∈{1,2,...,L}
。要计算特定σ的H
,我需要执行以下计算:
其中⟨ij⟩表示站点σ_i和σ_j是最近邻居(假设)J是常数。
几个问题:
L
x L
矩阵还是L
2 列表? RAM中的内存访问是否比另一个更好(我想这取决于我访问元素的方式......)?H
?真的,我认为这可以归结为如何最有效地访问(和操纵)每个州的邻居。
一些想法:
答案 0 :(得分:1)
你的问题有点宽泛,对我来说有点混乱,所以请原谅我,如果我的回答不是你要找的那个,但我希望它会有所帮助(有点)。
在索引编制时,数组比列表更快。矩阵是一个2D数组,例如这样(其中N
和M
都是L
):
这意味着您首先访问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等来获得良好的改进)