簡體   English   中英

記住Python方法中的單個參數

[英]Memoize a single argument in Python method

我編寫了一個使用Cox-de Boor遞歸算法來計算B樣條基函數的Numpy實現。 我想memoize給定order的對象實例,但相對於xi保留可調用的功能。

換句話說,在實例化對象之后,應“設置”遞歸函數,但在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)

並用作

knot_vector = np.array([0,0,0,0,0,1,2,2,3,3,3,4,4,4,4,5,5,5,5,5])
basis = Bspline(knot_vector,4)
basis(1.2)

它返回在1.2求值的基函數。 但是,我需要多次調用此函數,並且如現在所寫,每次調用都將重構遞歸函數,這是不必要的,因為遞歸級別在實例化時設置為4

這很容易使用,以memoize的任何functools.lru_cache在Python3使用類似的,或在Python2.7 這個

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM