首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用python计算梯度

用python计算梯度
EN

Stack Overflow用户
提问于 2013-07-27 10:59:41
回答 1查看 34.1K关注 0票数 10

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

代码语言:javascript
运行
AI代码解释
复制
df/dx*i+df/dy*j+df/dz*k 

我的函数只是x和y的函数,我期望

代码语言:javascript
运行
AI代码解释
复制
df/dx*i+df/dy*j 

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

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

代码语言:javascript
运行
AI代码解释
复制
data=[[x1,x2,x3]...[x1,x2,x3]]

其中,x1,x2是统一网格上的点坐标(我在brillouin区域上的点),x3是该点的频率值。我在输入中也给出了两个方向的推导步骤:

代码语言:javascript
运行
AI代码解释
复制
stepx=abs(max(unique(data[:,0])-min(unique(data[:,0]))/(len(unique(data[:,0]))-1)

方向也是一样。我没有在网格上构建我的数据,我已经有了一个网格,这就是为什么这里给出的好例子对我没有帮助。一个更合适的例子应该有一个点和值的网格,就像我拥有的那样:

代码语言:javascript
运行
AI代码解释
复制
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晶体的布里渊区。

我已经理解,numpy.gradient只在值的正方形网格上正确工作,而不是我搜索的内容。即使我把我的数据作为一个网格,在原始数据的多边形之外有大量的零,这也会给我的梯度增加很高的向量,对计算的精度产生负面影响。在我看来,这个模块更像是一个玩具,而不是一个工具,它有严重的局限性。

用字典解决问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-27 13:04:27

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

代码语言:javascript
运行
AI代码解释
复制
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作为一个表面给出:

下面是如何解释梯度:

gx是一个矩阵,它在所有点上都给出了变更dz/dx。例如gx是dz/dx at (x0,y0)。可视化gx有助于理解:

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

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

f(x,y)

与梯度

更新让我们来看看xy对。

这是我使用的代码:

代码语言:javascript
运行
AI代码解释
复制
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]值相关的点是什么?然后..。

代码语言:javascript
运行
AI代码解释
复制
>>> Z[20][30]
-0.99749498660405478

重点是

代码语言:javascript
运行
AI代码解释
复制
>>> xy_pairs[20][30]
'-1.5,-2.0'

是那么回事吗?让我们来检查一下。

代码语言:javascript
运行
AI代码解释
复制
>>> np.sin(-1.5)
-0.99749498660405445

是。

在这一点上,我们的梯度成分是什么?

代码语言:javascript
运行
AI代码解释
复制
>>> gy[20][30]
0.0
>>> gx[20][30]
0.070707731517679617

那些退房了吗?

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

代码语言:javascript
运行
AI代码解释
复制
>>> np.cos(-1.5)
0.070737201667702906

看起来不错。

您会注意到它们是不完全正确的,这是因为我的Z数据不是连续的,有一个步骤大小的0.05gradient只能接近变化的速度。

票数 31
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17901363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档