我正在使用一个库,该库需要两个函数作为多次计算这两个函数的方法的输入。例如
def the_func ( H, dH ):
many_iterations = 10
for i in xrange( many_iterations ):
# internal calculations to yield a value of x
x = np.random.randn(10) # say!
foo = H(x)
bar = dH(x)
# do something with foo and bar e.g
print foo,bar
但是,计算H
和dH
共享大量代码,并且评估每个代码都很昂贵,所以我将它们计算在一个返回两者的函数中。例如,请考虑此函数返回两个值,这些值对应于上面的H和dH。
def my_func ( x ):
# lots of calculations...
return x.sum(), x/2.
如果the_func
评估my_func
和{{1 }}。目前,我正在解决将the_func
称为
H
这样可以正常工作,但对于dH
内的每次迭代,它需要the_func
两次相同的函数,并使用完全相同的参数。我想每次迭代只评估一次这个函数,但不改变任何the_func ( H=lambda x: my_func(x)[0], dH=lambda x: my_func(x)[1] )
。
答案 0 :(得分:0)
所以在我看来使用了一个memoization模式,但是假设x将是一个numpy数组(因此是不可用的),这需要对库代码进行一些探索,以使数组可以清除,我想避免。 / p>
所以我仍然不太了解你的问题,就像其他人一样,但是如果你只想记住一些带有数组参数的函数,你可以看一下这个问题:Most efficient property to hash for numpy array tl; dr version :如果数组不是太大,使用tostring()
方法计算底层数组的哈希键。由于字节序/布局/等等,这可能无法很好地移植,所以要小心龙。对于大型数组,您可能需要考虑一个快速的实际哈希函数,例如xxhash
,并管理哈希冲突。
现在有一个名为cachetools
的好库,可用于构建记事本功能。它实际上提供了自己的实现作为方便的装饰器,但它不能很好地处理自定义散列函数。如果你不介意的话,你可以看看我的(诚然是临时的)尝试为cachetools
import simplecache # that's my module
class ThingClass(simplecache.ArrayMethodCacheMixin, ...):
... ...
@simplecache.memoized()
def _common_code_for_both(self, x): # x is array argument
... ... # expensive computation using x
return intermediate_state
def h(self, x):
intermediate_state = self._common_code_for_both(x)
return do_something_with(x, intermediate_state)
def dh(self, x):
intermediate_state = self._common_code_for_both(x)
return do_something_else_with(x, intermediate_state)
thing = ThingClass(...)
thing.h()
之上的数组获取方法创建方法装饰器。它可能不灵活或优雅但你有一些想法来建立自己的;)
对于你的情况,你可以在伪Python中做这样的事情:
thing.dh()
现在,如果使用相同的参数连续调用thing.h
和thing.dh
,则不会重复中间计算。现在,您只需将{{1}}和{{1}}传递给库函数。
它不漂亮,但它可以节省一些不必要的评估。