我正在寻找一个矢量场,其中两个分量是从数值积分中确定的,并且使用空间中要绘制矢量的坐标来计算积分。
在下面的代码中,我将被积函数定义为依赖于r
和z
,然后在循环中定义它们的值并评估每个(r,z)处的积分。
我有两个问题:
1)是否有更多的pythonic方法用变量r
和z
来评估这些积分?
2)存储积分值及其坐标以从quiver
生成meshgrid
图的最佳方法是什么?
import scipy.integrate as spi
import scipy.special as sps
import numpy as np
R = 2
V = 10
def Efield_r_integrand(k):
return np.exp(-k*z)*k*R*V*sps.jv(1,k*r)*sps.jv(1,k*R)
def Efield_z_integrand(k):
return np.exp(-k*z)*k*R*V*sps.jv(0,k*r)*sps.jv(1,k*R)
x_max = 3.0
z_max = 3.0
n_pts = 20
for i in xrange(n_pts):
r = float(i)/float(n_pts)*r_max
for j in xrange(n_pts):
z = float(j)/float(n_pts)*z_max
current_Efield_r = spi.quad(Efield_r_integrand,0,np.inf)[]
current_Efield_z = spi.quad(Efield_z_integrand,0,np.inf)[]
答案 0 :(得分:0)
您的代码已经相当pythonic,但构造
除外for i in xrange(n_pts):
r = float(i)/float(n_pts)*r_max
这是其他一些编程语言的一部分。在Python中,编写
会更加pythonicfor r in np.arange(0, rmax, rmax/n_pts):
因为您不需要中间变量i
。
话虽如此,评估在网格上定义的函数的积分是我不会再编写双for循环的东西,但是让便捷函数np.vectorize
处理:
import scipy.integrate as spi
import scipy.special as sps
import numpy as np
import matplotlib.pyplot as plt
def Efield_r_integrand(k, z, r, R, V):
return np.exp(-k*z)*k*R*V*sps.jv(1,k*r)*sps.jv(1,k*R)
def Efield_z_integrand(k, z, r, R, V):
return np.exp(-k*z)*k*R*V*sps.jv(0,k*r)*sps.jv(1,k*R)
x_max, z_max, n_pts = 3.0, 3.0, 20
R, V = 2, 10
Z, X = np.mgrid[0:z_max:n_pts*1j, 0:x_max:n_pts*1j] # note that this creates a grid with the boundaries (0 and 3.0) included!
def integrate_on_grid(func, lo, hi, *args):
"""Returns a callable that can be evaluated on a grid."""
return np.vectorize(lambda n,m: spi.quad(func, lo, hi, (n,m)+args)[0])
Efield_r, Efield_z = [integrate_on_grid(func, 0, np.inf, R, V)(Z,X)
for func in (Efield_r_integrand, Efield_z_integrand)]
plt.quiver(X, Z, Efield_r, Efield_z)
最后一行显示了如何轻松使用到目前为止获得的结果来生成quiver
图。
仍然可以删除一些重复:Efield_r_integrand
最多与Efield_z_integrand
相同的一个因素,理想情况下可以通过让quad
理解如果调用的返回值来解决integrand是一个数组,它意味着对数组的每个元素进行集成。然而,这不是它的工作方式,但我离题了。你可以再创建一个函数来获取那些方程式中的公因子并称之为,但这取决于个人品味。