2

TLDR如何生成一个数组,其元素取决于某个任意(浮点)值 k,而不必在每次更改 k 的值时都从头开始构建数组的极其耗时的过程。

我想要实现的效果如下:

代码的预期结构

我在二维晶格(N x N numpy 数组)的原子基础上生成了一个巨大的哈密顿量。填充此数组需要针对我想要包含的每种不同耦合类型多次比较原子位点的位置 (xyz),随着系统规模的增长,这会变得非常耗时。(通常 N > 16,000 个站点)。

该数组的元素依赖于其他一些浮点类型变量 k(在程序的物理上下文中,这是一个我想要迭代的量子计数)。对于 1000 k 值的范围,我需要多次计算这个数组。

即生成256,000,000个元素的数组 1000 次...

目前,我每次更改为新的 k 值时都必须创建数组,这显然是非常低效的。这看起来(非常普遍)的基本结构如下:

class Device():

    def __init__(self, xyz, energy, ... other input parameters ...):

        self.xyz = xyz           # N x 3 array of positions
        self.energy = energy     # Length N list of energies
        # + A range of other parameters that define the device


     # -------- OTHER OPERATIONS ON THE DEVICE -------- #


     def get_H(self, k):
        """ Get the Hamiltonian for a given k - value """

        # Initialise the N x N array
        h = np.zeros((len(self.xyz), len(self.xyz)))

        # - Fill THE HAMILTONIAN BY COMPARING ALL ATOMIC POSITIONS IN self.xyz - #

        return h

这需要我每次调用整个构建过程。

我想知道是否有一种方法可以一次性生成这个数组,将 k 作为一个自由参数保留下来,以后可以填写。即返回一个数组,它是k 的函数。优先级是只需要构造一次数组,因为测试表明这占用了我总运行时间的很大一部分。

下面是我想通过对测试数组进行操作来实现的最小(非工作)示例。我想让哈密顿量成为一个对象变量,而不是每次都必须制作的方法,但对 k 有一定的依赖性(我意识到这在语法上将是灾难性的,但希望这将是一个好的开始答案)。

class Test_device():

def __init__():

    self.get_H = self.make_H()

def make_H(self):

    h = np.linspace(1,9,9).reshape((3,3)) # Test array

    # The below clearly will not work because k is not defined, but this is
    # where I want to achieve this

    h[1,1] += k # Give some k-dependence to the middle element of the array

    def ham(k, h = h):

        # Somehow set the value of k in h

        return h

    return ham

然后我将通过

device = Test_device()
device.get_H(k = k_value)

提前致谢!

4

2 回答 2

0

经过反思,我认为这不是np.fromfunction()您想要的。而是尝试:

import numpy as np

class Test_device(object):

    def __init__(self, h_shape):
        self.h_shape = h_shape

        # Create array once
        self.h = np.linspace(1, h_shape[0] ** 2, h_shape[1] ** 2).reshape(self.h_shape)

    def get_H(self, k, locn=(1, 1)):
        self.h[locn] += k  # Give some k-dependence to the middle element of the array

        # Somehow set the value of k in h
        pass

在下文中,初始化设备一次(给定一个预期的形状h)。然后选择一个k(和一个位置locn,如果你愿意的话)。然后调用 的get_H方法devicek从未归因于device,但如果您愿意参考self.k=k(如eatmeinadanish 所述),则可能是。

然后,您可以随时访问device.h

h_shape = (3, 3)
device = Test_device(h_shape)
k = 1.3
locn = (1, 1)
device.get_H(k, locn=locn)
print device.h

我不确定这最终对你有多大帮助,无论这是否是你真正想要的,并注意它并没有真正增加eatmeinadanish 的答案。

于 2018-08-22T10:46:45.953 回答
0

这不是一个工作示例,但是...

class Test_device():

    def __init__(self, h):
        self.k = 0
        self.h = h

    def get_H(self):

        self.h = np.linspace(1,9,9).reshape((3,3)) # Test array

        # The below clearly will not work because k is not defined, but this is
        # where I want to achieve this

        self.h[1,1] += self.k # Give some k-dependence to the middle element of the array

    def ham(self):

        # Somehow set the value of k in h
        return self.h

你可以这样做:

device = Test_Device(10)
device.get_H()
device.h = 12
device.get_H()
h = device.ham()

您可以随时更改 h 或 k,只需更改类中的值,例如device.h = 14. 与 k 相同。

于 2018-08-21T15:05:07.930 回答