【问题标题】:Ising Model: How to shorten simulation time?Ising Model:如何缩短仿真时间?
【发布时间】:2023-03-07 07:26:02
【问题描述】:

我正在使用简单的编码结构模拟尺寸大于 3 的铁磁体的Ising Model,但在效率方面存在一些问题。在我的代码中,有一个特定的功能是瓶颈。

在模拟过程中,有必要找到给定站点的所谓最近邻居。例如,在 2D Ising 模型中,自旋占据晶格的每个点,用两个数字表示:(x,y)。 (x,y)点的最近邻是四个相邻值,即(x+1,y),(x-1,y),(x,y+1),(x,y-1) .在 5D 中,某个格点的自旋具有 10 个最近邻的坐标 (a,b,c,d,e),形式与之前相同,但针对元组中的每个点。

下面是给出以下输入的代码:

"site_i is a random value between 0 and n-1 denoting the site of the ith spin"
"coord is an array of size (n**dim,dim) that contains the coordinates of ever spin"
"spins is an array of shape (n**dim,1) that contains the spin values (-1 or 1)"
"n is the lattice size and dim is the dimensionality"
"neighbor_coupling is the number that tells the function to return the neighbor spins that are one spacing away, two spacing away, etc."

def calc_neighbors(site_i,coord,spins,n,dim,neighbor_coupling):
    # Extract all nearest neighbors
    # Obtain the coordinates of each nearest neighbor
    # How many neighbors to extract
    num_NN = 2*dim
    # Store the results in a result array 
    result_coord = np.zeros((num_NN,dim))
    result_spins = np.zeros((num_NN,1))
    # Get the coordinates of the ith site
    site_coord = coord[site_i]
    # Run through the + and - for each scalar value in the vector in site_coord
    count = 0
    for i in range(0,dim):
        assert count <= num_NN, "Accessing more than nearest neighbors values."
        site_coord_i = site_coord[i]
        plus = site_coord_i + neighbor_coupling
        minus = site_coord_i - neighbor_coupling

        # Implement periodic boundaries
        if (plus > (n-1)): plus = plus - n
        if (minus < 0): minus = n - np.abs(minus)

        # Store the coordinates
        result_coord[count] = site_coord
        result_coord[count][i] = minus
        # Store the spin value
        spin_index = np.where(np.all(result_coord[count]==coord,axis=1))[0][0]
        result_spins[count] = spins[spin_index]
        count = count + 1

        # Store the coordinates
        result_coord[count] = site_coord
        result_coord[count][i] = plus
        # Store the spin value
        spin_index = np.where(np.all(result_coord[count]==coord,axis=1))[0][0]
        result_spins[count] = spins[spin_index]
        count = count + 1 

我真的不知道如何才能使这更快,但它会很有帮助。也许是另一种存储所有内容的方式?

【问题讨论】:

  • 检查是否可以在您的情况下使用 SciPy 的 cKDTree,它对于查找最近的邻居非常有效
  • 所以你的格子是正方形的?在这种情况下,最好将自旋存储在 N 维数组中。
  • 我没有意识到 numpy 有一个 ndarray 类型。哇,那会让事情变得容易得多。

标签: python arrays numpy indexing


【解决方案1】:

不是答案,只是一些纠正建议:当您尝试记录计算的每一步时,有很多复制。在不牺牲这一点的情况下,您可以删除site_coord_i,然后

    # New coords, implement periodic boundaries
    plus = (site_coord[i] + neighbor_coupling) % n
    minus = (site_coord[i] - neighbor_coupling + n) % n

这避免了中间步骤(“如果...”)。 另一个建议是推迟使用子数组,直到你真正需要它:

    # Store the coordinates
    rcc = site_coord
    rcc[i] = plus
    # Store the spin value
    spin_index = np.where(np.all(rcc==coord,axis=1))[0][0]
    result_spins[count] = spins[spin_index]
    result_coord[count] = rcc
    count += 1

目标是减少比较中使用的变量的维数,并优先选择局部变量。

【讨论】:

    猜你喜欢
    • 2018-09-14
    • 1970-01-01
    • 2016-05-04
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多