使用NumPy计算梯度

30

我真的不明白numpy.gradient函数是做什么的,以及如何使用它来计算多变量函数梯度

例如,我有这样一个函数:

def func(q, chi, delta):
    return q * chi * delta

我需要计算它的三维梯度(换句话说,我想计算相对于所有变量(q、chi、delta)的偏导数)。

如何使用NumPy计算此梯度?

5个回答

26

问题在于,numpy不能直接提供导数,您有两个选择:

使用NUMPY

您需要在三维空间中定义网格,并在此网格上评估函数。之后,将这个函数值的表格提供给numpy.gradient,以获取每个维度(变量)的数值导数数组。

以下是示例

from numpy import *

x,y,z = mgrid[-100:101:25., -100:101:25., -100:101:25.]

V = 2*x**2 + 3*y**2 - 4*z # just a random function for the potential

Ex,Ey,Ez = gradient(V)

没有使用NUMPY

您也可以使用中心差商来自行计算导数。 中心差商

本质上,这就是numpy.gradient为预定义网格中的每个点所做的事情


1
谢谢,Stefan!实际上,我知道如何手动计算导数(不使用任何框架),但我无法理解np.gradient的工作原理。以前我用C++和gsl的组合来完成这个任务,但这种方法需要编写太多代码。 - Mikhail Elizarev
3
准确来说,这个公式就是 numpy.diff 所做的事情;numpy.gradient 类似,但在边界处有特殊行为。 - Mark
@Mark: numpy.gradient 更像是这个公式(使用 $+\Delta x$ 和 $-\Delta x$ 的中心差分商)而不是 numpy.diff - user66081
1
它们两者非常相似。gradient确实在网格点处使用中心差分,这是类似的,但对边界的处理不同。可以说diff在网格点之间的中心差分(具有半个网格间距的delta)中获得,不会特别处理边界,而只是使梯度网格小1个点。它们都遵循表达式,但评估点和delta不同,并且具有不同的边界行为。由于答案没有提及如何处理其中任何一个,我猜想哪个更相似是主观的... - Mark

14
Numpy和Scipy用于数值计算。由于您想要计算解析函数的梯度,因此必须使用支持符号数学的Sympy软件包。不同iation的方法在这里解释(实际上可以在左下角的Web控制台中使用它)。
您可以在Ubuntu下安装Sympy。
sudo apt-get install python-sympy

或在任何Linux发行版下使用pip

sudo pip install sympy

4

2
虽然这个链接可能回答了问题,但最好在这里包含答案的关键部分,并提供该链接供参考。如果链接页面发生变化,仅有链接的回答可能会失效。 - Gugu72

3
你可以使用 scipy.optimize.approx_fprime 来实现。
f = lambda x: x**2
approx_fprime(np.array([2]), f, epsilon=1e-6)  # array([ 4.000001])

0

你能否从链接中发布直接回答问题的相关部分? - codeananda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接