元函数使用单一函数的输出

时间:2015-08-03 16:01:05

标签: python python-2.7 numpy

我正在使用一个库,该库需要两个函数作为多次计算这两个函数的方法的输入。例如

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

但是,计算HdH共享大量代码,并且评估每个代码都很昂贵,所以我将它们计算在一个返回两者的函数中。例如,请考虑此函数返回两个值,这些值对应于上面的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] )

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.hthing.dh,则不会重复中间计算。现在,您只需将{{1}}和{{1}}传递给库函数。

它不漂亮,但它可以节省一些不必要的评估。