使用python进行梯度计算 [英] Gradient calculation with python

查看:1138
本文介绍了使用python进行梯度计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to know how does numpy.gradient work. 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

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

我的函数只有x和y的函数,我确实期望像

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

df/dx*i+df/dy*j 

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

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.gradient works 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.

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

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

data=[[x1,x2,x3]...[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:

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

与y方向相同. 我没有在网格上构建数据,我已经有网格,这就是为什么答案中给出的此类示例对我没有帮助. 一个更合适的示例应该具有点和值的网格,例如我所拥有的:

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:

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)

我要补充的另一件事是,我的网格不是正方形,而是多边形,它是2d晶体的Brillouin区域.

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.

我知道numpy.gradient仅在值的正方形网格上正常工作,而不在我要搜索的值上正常工作.即使我将数据作为网格在原始数据的多边形之外有很多零,也将为梯度增加非常高的向量,从而(不利地)影响了计算精度.在我看来,该模块更像是玩具而不是工具,它存在严重的局限性.

I've understood that numpy.gradient works 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.

使用字典解决的问题.

推荐答案

您需要为gradient提供一个矩阵,该矩阵描述您的(x,y)点的角频率值.例如

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

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)

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

You can see that plotting Z as a surface gives:

以下是解释渐变的方法:

Here is how to interpret your gradient:

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

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

由于我的数据是从f(x,y) = sin(x+y) gy生成的,因此看起来相同.

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

这是使用f(x,y) = sin(x) ...

f(x,y)

和渐变

更新,让我们看一下xy对.

update Let's take a look at the xy pairs.

这是我使用的代码:

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)

现在,我们可以查看并准确了解正在发生的事情.假设我们想知道与Z[20][30]的值关联的点?然后...

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

重点是

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

是吗?让我们检查一下.

Is that right? Let's check.

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

是的

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

And what are our gradient components at that point?

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

那些结帐吗?

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

>>> np.cos(-1.5)
0.070737201667702906

看起来不错.

您会发现它们并不完全正确,这是因为我的Z数据不连续,步长为0.05,而gradient只能近似变化率.

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

这篇关于使用python进行梯度计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆