1

我有一个 N 维 numpy 数组S。每次迭代,这个数组中的一个值都会改变。

我有第二个数组,G它存储 的梯度S,由 numpy 的gradient()函数计算得出。目前,我的代码G每次更新时都会不必要地重新计算所有内容S,但这是不必要的,因为只有一个值S发生了变化,所以我只需要重新计算中的1+d*2G,其中d是 中的维数S

如果我知道数组的维数,这将是一个更容易解决的问题,但是在没有这些知识的情况下我提出的解决方案效率非常低(并不比仅仅重新计算所有的 更好G)。

有没有一种有效的方法来仅重新计算中的必要值G

编辑:根据要求添加我的尝试

S该函数返回一个向量,表示atcoords在每个维度上的梯度。它计算这个而不计算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,将 at 的值更改为Xamount changeG然后,它使用 Jaime 提出的技术的变体进行更新。

    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]
4

2 回答 2

1

你的问题很容易让你得到一个好的答案:发布你低效的代码总是一个好主意,这样潜在的回答者可以更好地帮助你。无论如何,假设您知道已更改点的坐标,并将这些坐标存储在名为 的元组中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])
于 2013-07-21T17:21:34.030 回答
0

嗯,如果我有一个例子,我可以做得更好,但是只创建一个辅助数组 S2(顺便说一下,我会为你的变量选择更长和更有意义的名称)并重新计算它的梯度 G2 和然后将其引入 G?

另一个问题是:如果你不知道 S 的维数,你如何改变改变的特定元素?你只是重新计算整个 S 吗?

我建议您澄清这些事情,以便人们可以更好地帮助您。干杯!

于 2013-07-21T16:53:25.553 回答