Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python方法中记忆单个参数_Python_Numpy_Recursion_Memoization - Fatal编程技术网

在Python方法中记忆单个参数

在Python方法中记忆单个参数,python,numpy,recursion,memoization,Python,Numpy,Recursion,Memoization,我已经编写了一个Numpy实现,它使用Cox de Boor递归算法来计算B样条基函数。我想为给定的顺序记忆对象实例,但让函数可以调用xi 换句话说,在实例化对象之后,递归函数应该是“set”,但在xi处仍然可以调用。为了提高速度,我确实需要这样做,因为我将多次调用该函数,不想一遍又一遍地重构递归函数 以下是当前的实施情况: import numpy as np #Turn off divide by zero warning because we explicitly check for i

我已经编写了一个Numpy实现,它使用Cox de Boor递归算法来计算B样条基函数。我想
为给定的
顺序
记忆对象实例,但让函数可以调用
xi

换句话说,在实例化对象之后,递归函数应该是“set”,但在
xi
处仍然可以调用。为了提高速度,我确实需要这样做,因为我将多次调用该函数,不想一遍又一遍地重构递归函数

以下是当前的实施情况:

import numpy as np

#Turn off divide by zero warning because we explicitly check for it
np.seterr(divide='ignore')

class Bspline():

    def __init__(self, knot_vector, order):

        self.knot_vector = knot_vector
        self.p = order


    def __basis0(self, xi):

        return np.where(np.all([self.knot_vector[:-1] <=  xi, 
                            xi < self.knot_vector[1:]],axis=0), 1.0, 0.0)

    def __basis(self, xi, p):

        if p == 0:
            return self.__basis0(xi)
        else:
            basis_p_minus_1 = self.__basis(xi, p - 1)

            first_term_numerator = xi - self.knot_vector[:-p] 
            first_term_denominator = self.knot_vector[p:] - self.knot_vector[:-p]

            second_term_numerator = self.knot_vector[(p + 1):] - xi
            second_term_denominator = self.knot_vector[(p + 1):] - self.knot_vector[1:-p]

            first_term = np.where(first_term_denominator > 1.0e-12, 
                              first_term_numerator / first_term_denominator, 0)
            second_term = np.where(second_term_denominator > 1.0e-12,
                               second_term_numerator / second_term_denominator, 0)

            return  first_term[:-1] * basis_p_minus_1[:-1] + second_term * basis_p_minus_1[1:]


    def __call__(self, xi):

        return self.__basis(xi, self.p)

它返回在
1.2
处计算的基函数。但是,我需要多次调用此函数,正如现在编写的那样,每次调用都会重构递归函数,这是不必要的,因为递归级别在实例化时设置为
4
,在Python3中,或者在Python2.7中,使用类似以下内容,可以很容易地记住任何内容:


创建一个保存函数结果的字典,然后在再次调用函数之前检查dict中是否有该值。根据您的设置,类似于此的功能应该可以正常工作

results = {}
for value in values:
    if results.get(value):
        answer = results[value]
    else:
        answer = basis(value)
        results[value] = answer
        print(answer)  # or just display the results dict once you are done

我喜欢这个解决方案,但是可以在类定义中使用它吗?我正在尝试创建一个干净的API,在这里这个备忘录将自动完成;还有蟒蛇2.7。谢谢!在Python 2.7中使用了链接的
memoize
函数
class Bspline(object):
    ...

    # Python2.7
    @memoize
    # or, Python3*
    @functools.lru_cache()
    def op(self, args):
        return self._internal_op(xi)
results = {}
for value in values:
    if results.get(value):
        answer = results[value]
    else:
        answer = basis(value)
        results[value] = answer
        print(answer)  # or just display the results dict once you are done