2016-11-02 110 views
0

最近在Python中工作,我想從一門課程中移植一段簡短的Matlab代碼,但是說實話我無法確定如果有可能以同樣的方式進行,如果是的話,該怎麼做。Python中的「嵌套」匿名函數/函數句柄

這裏的重要組成部分,我正在與Python中掙扎如下:

nk = @(x)1 
for l=1:3 % calculate basis 
    nk = @(x)(nk(x).*(x-1)); 
end 

如何代碼工作在Matlab:

nk = @(x)1創建了一個函數處理nk(x),可以通過調用例如, xi=[1,2,3,4],但截至目前它只會返回1,因爲它不依賴於變量x

在for循環,nk(x)乘以(x-1)每次迭代(這裏x被認爲是一種「象徵性」的變量,或者叫什麼呢,類似於你如何定義lambda函數),以及它到底應該顯示爲nk = (x-1)*(x-1)*(x-1)

它仍然是一個函數,我可以稱爲nk(x),其中x是一個數組,其中我希望它具有任何值。

+0

即使你已經給出了例子,我不明白函數的期望行爲。你可以更具體一些,因爲我喜歡很多其他人不會知道matlab –

+0

當然。有關Matlab中匿名函數的一般概述,您可以查看https://se.mathworks.com/help/matlab/matlab_prog/anonymous-functions.html#f4-70285。 對於我粘貼的代碼,目標是獲得插值多項式作爲函數句柄,以便可以在不同的時間間隔內對其進行評估,而無需對每組數據進行全部計算。假設我想插入一些我知道P(x)= 0.25 *(x-3)^ 2 + 0.31 *(x-7.21)^ 3的數據,上面的代碼恰好給出了這個P(x)它作爲(x,P(x))(類似於numpy.polyval)。通常我不會先驗地知道這個P(x)。 – ritualmagick

+0

在你的Python上工作......到目前爲止你嘗試過了什麼?有什麼問題? – chapelo

回答

0

下面的分段線性插值的原油例子可能給你一個想法:

def interpolate(xs,ys): 
    #assumes that xs and ys are same-length lists 
    #of real numbers, with xs sorted 
    def N(x): 
     if x < min(xs) or x > max(xs): return False #we don't extrapolate 
     if x == max(xs): return ys[-1] 
     i = 0 
     while xs[i] <= x: 
      i+= 1 
     m = (ys[i]-ys[i-1])/(xs[i]-xs[i-1]) 
     return ys[i-1] + m*(x - xs[i-1]) 
    return N 

例如,

>>> f = interpolate([0,1,2],[1,2,4]) 
>>> f(0) 
1.0 
>>> f(0.7) 
1.7 
>>> f(1.9) 
3.8 
>>> f(2) 
4 
>>> f(2.1) 
False 

的關鍵概念是關閉。請參閱this博客文章進行討論(特別是討論函數工廠的部分)。

順便說一句,你可以創建一個匿名函數關閉,儘管得到的代碼不是很易讀:

>>> f = (lambda x: (lambda y: x+y)) 
>>> g = f(3) 
>>> g(2) 
5 

既然你提功能「手柄」,我不認爲你真的想要匿名函數(特別是給你的原始問題有更多的Matlab代碼)。

+0

感謝您的詳細解答。現在有點清楚了,但我顯然必須深入挖掘內部功能。如果我理解正確,那麼內部函數可以訪問在「外部」函數內定義的所有變量,即使變量沒有作爲參數明確傳遞給內部函數? 至於原始問題中的插值部分,它不是我的問題的核心,但我接受,我沒有足夠的具體的開始,所以這對我來說。 – ritualmagick

+0

是的,你是對的。外部函數提供了定義內部函數的上下文,即使在外部函數調用結束之後,該上下文仍被「記住」。外部函數的不同調用將創建不同的閉包,因此您可以使用'interpolate'來創建任意數量的可以同時使用的分段線性函數(順便說一句,我的插值代碼效率不高,更好的方法可能是使用模塊「bisect」來確定哪個「 xs'用於'N(x)' - 而不是我使用的線性搜索)。 –