簡體   English   中英

有效地重新計算維數未知的numpy數組的梯度

[英]Efficiently recalculating the gradient of a numpy array with unknown dimensionality

我有一個N維的numpy數組S 每次迭代,此數組中的一個值都會更改。

我有第二個數組G ,它存儲S的梯度,由numpy的gradient()函數計算得出。 目前,我每次更新S時,我的代碼都不必要重新計算G全部,但這是不必要的,因為S只有一個值發生了變化,因此我只需要重新計算G 1+d*2值,其中dS的維數。

如果我知道數組的維數,這將是一個更容易解決的問題,但是在我缺乏這些知識的情況下,我想出的解決方案效率很低(實質上不比重新計算所有G更好)。

是否有一種有效的方法來僅重新計算G的必要值?

編輯:根據要求添加我的嘗試

該函數返回一個向量,該向量指示每個維度上coordsS的梯度。 它在不計算每個點的S梯度的情況下進行計算,但是問題在於它似乎不是很有效。

它在某些方面看起來與已經發布的答案相似,但也許效率不高?

想法如下:我遍歷每個維度,創建一個僅在該維度上是矢量的切片。 對於這些切片中的每一個,我都會計算梯度並將該梯度中的適當值放入返回的矢量grad的正確位置。

min()max()是為了處理邊界條件。

    def getSGradAt(self,coords) :
        """Returns the gradient of S at position specified by
           the vector argument 'coords'.

           self.nDim : the number of dimensions of S
           self.nBins : the width of S (same in every dim)
           self.s : S  """
        grad = zeros(self.nDim)
        for d in xrange(self.nDim) :
            # create a slice through S that has size > 1 only in the current
            # dimension, d. 
            slices = list(coords)
            slices[d] = slice(max(0,coords[d]-1),min(self.nBins,coords[d]+2))
            # take the middle value from the gradient vector
            grad[d] = gradient(self.s[sl])[1] 
        return grad

問題在於這不會很快運行。 實際上,僅取整個數組S的梯度似乎運行得更快(對於nBins = 25nDim = 4 )。

再次編輯,添加我的最終解決方案

這是我最終使用的。 此函數更新S ,將X處的值change數量change 然后,使用Jaime提出的技術的一種變化來更新G

    def changeSField(self,X,change) :
        # change s 
        self.s[X] += change

        # update g (gradient field)
        slices = tuple(slice(None if j-2 <= 0 else j-2, j+3, 1) for j in X)
        newGrads = gradient(self.s[slices])
        for i in arange(self.nDim) :
            self.g[i][slices] = newGrads[i]

您需要解決的問題很多,您可以獲得一個好的答案:發布效率低下的代碼始終是一個好主意,以便潛在的答復者可以更好地為您提供幫助。 無論如何,可以說您知道已更改點的坐標,並將其存儲在名為coords的元組中。 首先,讓我們構造一個包含您要點的切片元組:

slices = tuple(slice(None if j-1 <= 0 else j-1, j+2, 1) for j in coords)

您可能希望將限制擴展到j-2j+3以便在可能的情況下使用中心差來計算梯度,但是會慢一些。

您現在可以執行以下操作來更新數組:

G[slices] = np.gradient(N[slices])

嗯,如果有一個示例,我會做得更好,但是僅創建一個輔助數組S2(順便說一句,我會為您的變量選擇更長更有意義的名稱)並重新計算它的梯度G2和然后將其引入G?

另一個問題是:如果您不知道S的維數,您如何更改所更改的特定元素? 您只是重新計算整個S?

我建議您澄清這些事情,以便人們可以更好地幫助您。 干杯!

暫無
暫無

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

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