提问人:MrTLane 提问时间:8/21/2018 最后编辑:MrTLane 更新时间:8/22/2018 访问量:524
Python - 生成一个数组,其中元素是可变参数的函数,而无需每次都构建数组
Python - Generate an array where elements are a function of a varying parameter, without building the array each time
问:
TLDR :我怎样才能生成一个数组,其元素依赖于某个任意(浮点数)值 k,而不必在每次更改 k 值时都经历从头开始构建数组的极其耗时的过程。
我想要实现的目标如下所示:
我正在 2D 晶格(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)
提前致谢!
答:
这不是一个工作示例,但是......
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,只需更改类中的值即可,例如 。k也一样。device.h = 14
评论
仔细想想,我认为这不是你想要的。而是尝试: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
在下文中,初始化设备一次(给定 的预期形状)。然后选择一个(和一个位置,如果你愿意)。然后调用 的方法。 从不归因于 ,但如果您愿意,可以归因于 (如 Eatmeinadanish 所述)。h
k
locn
get_H
device
k
device
self.k=k
然后,您可以随时访问。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 的答案。
评论
k
locn
locn
h
k
e^{i k.x}
评论
k
Device
k
k