使用python进行梯度计算

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17901363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:26:10  来源:igfitidea点击:

Gradient calculation with python

pythonnumpygradient

提问by Avulso Malloru

I would like to know how does numpy.gradientwork. I used gradient to try to calculate group velocity(group velocity of a wave packet is the derivative of frequencies respect to wavenumbers, not a group of velocities). I fed a 3 column array to it, the first 2 colums are x and y coords, the third column is the frequency of that point (x,y). I need to calculate gradient and I did expect a 2d vector, being gradient definition

我想知道它是如何numpy.gradient工作的。我使用梯度来尝试计算群速度(波包的群速度是频率对波数的导数,而不是一组速度)。我给它提供了一个 3 列数组,前 2 列是 x 和 y 坐标,第三列是该点 (x,y) 的频率。我需要计算梯度,我确实期望一个 2d 向量,即梯度定义

df/dx*i+df/dy*j+df/dz*k 

and my function only a function of x and y i did expect something like

而我的函数只是 x 和 yi 的函数确实期望像

df/dx*i+df/dy*j 

But i got 2 arrays with 3 colums each, i.e. 2 3d vectors; at first i thought that the sum of the two would give me the vector i were searchin for but the z component doesn't vanish. I hope i've been sufficiently clear in my explanation. I would like to know how numpy.gradientworks and if it's the right choice for my problem. Otherwise i would like to know if there's any other python function i can use.

但是我得到了 2 个数组,每个数组有 3 个列,即 2 个 3d 向量;起初我认为两者的总和会给我我正在搜索的向量,但 z 分量不会消失。我希望我的解释已经足够清楚。我想知道numpy.gradient它是如何工作的,以及它是否适合我的问题。否则我想知道是否还有其他我可以使用的 python 函数。

What i mean is: I want to calculate gradient of an array of values:

我的意思是:我想计算一组值的梯度:

data=[[x1,x2,x3]...[x1,x2,x3]]

where x1,x2 are point coordinates on an uniform grid (my points on the brillouin zone) and x3 is the value of frequency for that point. I give in input also steps for derivation for the 2 directions:

其中 x1,x2 是均匀网格上的点坐标(我在布里渊区上的点),x3 是该点的频率值。我还给出了两个方向的推导步骤:

stepx=abs(max(unique(data[:,0])-min(unique(data[:,0]))/(len(unique(data[:,0]))-1)

the same for y direction. I didn't build my data on a grid, i already have a grid and this is why kind examples given here in answers do not help me. A more fitting example should have a grid of points and values like the one i have:

y 方向相同。我没有在网格上构建我的数据,我已经有了一个网格,这就是为什么答案中给出的善意示例对我没有帮助的原因。一个更合适的例子应该有一个像我这样的点和值的网格:

data=[]
for i in range(10):
  for j in range(10):
    data.append([i,j,i**2+j**2])

data=array(data,dtype=float)

gx,gy=gradient(data)

another thing i can add is that my grid is not a square one but has the shape of a polygon being the brillouin zone of a 2d crystal.

我可以补充的另一件事是我的网格不是正方形,而是具有多边形形状,即二维晶体的布里渊区。

I've understood that numpy.gradientworks properly only on a square grid of values, not what i'm searchin for. Even if i make my data as a grid that would have lots of zeroes outside of the polygon of my original data, that would add really high vectors to my gradient affecting (negatively) the precision of calculation. This module seems to me more a toy than a tool, it has severe limitations imho.

我知道它numpy.gradient只能在方形值网格上正常工作,而不是我正在搜索的内容。即使我将我的数据作为一个网格,在我的原始数据的多边形之外有很多零,这会给我的梯度增加非常高的向量,影响(负面)计算精度。这个模块在我看来更像是一个玩具而不是一个工具,恕我直言,它有严重的局限性。

Problem solved using dictionaries.

使用字典解决问题。

采纳答案by seth

You need to give gradienta matrix that describes your angular frequency values for your (x,y)points. e.g.

您需要给出gradient一个矩阵来描述您的(x,y)点的角频率值。例如

def f(x,y):
    return np.sin((x + y))
x = y = np.arange(-5, 5, 0.05)
X, Y = np.meshgrid(x, y)
zs = np.array([f(x,y) for x,y in zip(np.ravel(X), np.ravel(Y))])
Z = zs.reshape(X.shape)

gx,gy = np.gradient(Z,0.05,0.05)

You can see that plotting Z as a surface gives:

您可以看到将 Z 绘制为曲面给出:

sinxpy

罪魁祸首

Here is how to interpret your gradient:

以下是解释梯度的方法:

gxis a matrix that gives the change dz/dxat all points. e.g. gx[0][0] is dz/dxat (x0,y0). Visualizing gxhelps in understanding:

gx是一个矩阵,它给出了dz/dx所有点的变化。例如 gx[0][0]dz/dx(x0,y0)。可视化gx有助于理解:

gx

gx

Since my data was generated from f(x,y) = sin(x+y)gy looks the same.

因为我的数据是从f(x,y) = sin(x+y)gy生成的,所以看起来是一样的。

Here is a more obvious example using f(x,y) = sin(x)...

这是一个更明显的例子,使用f(x,y) = sin(x)...

f(x,y)enter image description here

f(x,y)在此处输入图片说明

and the gradients

和梯度

g2

g2

g1

g1

updateLet's take a look at the xy pairs.

更新让我们来看看 xy 对。

This is the code I used:

这是我使用的代码:

def f(x,y):
    return np.sin(x)
x = y = np.arange(-3,3,.05)
X, Y = np.meshgrid(x, y)
zs = np.array([f(x,y) for x,y in zip(np.ravel(X), np.ravel(Y))])
xy_pairs = np.array([str(x)+','+str(y) for x,y in zip(np.ravel(X), np.ravel(Y))])
Z = zs.reshape(X.shape)
xy_pairs = xy_pairs.reshape(X.shape)

gy,gx = np.gradient(Z,.05,.05)

Now we can look and see exactly what is happening. Say we wanted to know what point was associated with the value atZ[20][30]? Then...

现在我们可以看看到底发生了什么。假设我们想知道什么点与 处的值相关联Z[20][30]?然后...

>>> Z[20][30]
-0.99749498660405478

And the point is

重点是

>>> xy_pairs[20][30]
'-1.5,-2.0'

Is that right? Let's check.

那正确吗?让我们检查。

>>> np.sin(-1.5)
-0.99749498660405445

Yes.

是的。

And what are our gradient components at that point?

那时我们的梯度分量是什么?

>>> gy[20][30]
0.0
>>> gx[20][30]
0.070707731517679617

Do those check out?

那些检查吗?

dz/dy always 0check. dz/dx = cos(x)and...

dz/dy always 0查看。 dz/dx = cos(x)和...

>>> np.cos(-1.5)
0.070737201667702906

Looks good.

看起来挺好的。

You'll notice they aren't exactly correct, that is because my Z data isn't continuous, there is a step size of 0.05and gradientcan only approximate the rate of change.

您会注意到它们并不完全正确,这是因为我的 Z 数据不是连续的,步长为0.05并且gradient只能近似于变化率。