我有一個N維numpy陣列S
。每次迭代,數組中的恰好一個值將會改變。有效重新計算具有未知維度的numpy陣列的梯度
我有第二個數組,G
,它存儲S
,如numpy的gradient()
函數計算的梯度。目前,我的代碼不必要地重新計算所有G
每次我更新S
,但這是不必要的,因爲S
中只有一個值已更改,所以我只需要重新計算G
中的1+d*2
值,其中d
是維數S
。
如果我知道陣列的維數,這將是一個更容易解決的問題,但是我在缺乏這些知識的情況下提出的解決方案效率相當低(不僅僅是重新計算所有的G
) 。
有沒有一種有效的方法來重新計算G
中的必要值?
編輯:加入我的嘗試,如請求
函數在每個維度在coords
返回指示的S
梯度的矢量。它計算這個時不需要計算每個點的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 = 25
和nDim = 4
)。
再次編輯,添加我的最終解決方案
這裏是我最終使用。此功能更新S
,將X
處的值更改爲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]
'如果輸入是一維和數組列表,如果輸入有許多比1其它尺寸的gradient'返回數組。它看起來並不意味着與運行時確定的維度數組一起使用,並且該列表將排除可以對數組執行的大部分巧妙的片分配。 – user2357112