我需要在python中使用梯形规则集成这个函数:
theta = .518 / r ^ 2 * dr /(sqrt(2 * 1.158 + 2 / r - .518 ^ 2 / 2r ^ 2))
我已经编写了代码,我应该在绘制时看到椭圆形结构。 theta应该从0到2pi并且r_min = .16& r_max = .702
import numpy as np
import matplotlib.pyplot as plt
def trapezoidal(f, a, b, n):
h = float(b-a)/n
result = 0.5*f(a) + 0.5*f(b)
for i in range(1, n):
result += f(a + i*h)
result *= h
return result
intg =[]
v = lambda r: (0.5108/(r**2))* (1./np.sqrt(2*1.158+(2/r)-.5108**2/(2*r**2)))
n = np.arange(1,1000,100)
theta = np.arange(0,2*np.pi,100)
for j in n:
numerical = trapezoidal(v, .16,.702 , j)
intg.append(numerical)
plt.plot(numerical,theta)
plt.show()
我猜这是一个非常基本的错误,因为我没有得到任何阴谋。我认为梯形例程是正确的,因为它适用于其他功能。非常感谢您的帮助
答案 0 :(得分:1)
这里有几个问题。
首先,np.arrange
中的第三个参数不是要生成的值的数量,而是步骤。这意味着theta
只有一个值,而n
因此intg
将有10个而不是100个值。
假设这是你的意图(100个值)你可以做到这一点
intg =[]
v = lambda r: (0.5108/(r**2))* (1./np.sqrt(2*1.158+(2/r)-.5108**2/(2*r**2)))
n = np.arange(1,1000,10)
theta = np.arange(0,2*np.pi,2*np.pi/100)
#print theta
for j in n:
numerical = trapezoidal(v, .16,.702 , j)
intg.append(numerical)
然后你正在绘制numerical
,它基本上是一个数字,你可能想要绘制的是积分值intg
- 这样做你还需要转换intg
列表np.array
:
intg = np.array(intg)
通过这些更改,程序可以正常运行,
plt.plot(intg,theta)
plt.show()
答案 1 :(得分:1)
或者,你可以使用quadpy(我的一个项目)。
import numpy as np
import quadpy
val = quadpy.line_segment.integrate_split(
lambda r: 0.5108/r**2 / np.sqrt(2*1.158 + 2/r - 0.5108**2/(2*r**2)),
0.15, 0.702, 100,
quadpy.line_segment.Trapezoidal()
)
print(val)
给出0.96194633532
。然而,梯形公式主要是出于历史目的而实现的。一个更好,同样简单的规则是quadpy.line_segment.Midpoint
。更好的方法当然是自适应正交
val, error_estimate = quadpy.line_segment.integrate_adaptive(
lambda r: 0.5108/r**2 / np.sqrt(2*1.158 + 2/r - 0.5108**2/(2*r**2)),
[0.15, 0.702],
1.0e-10
)
print(val)
给出更准确的0.961715309492
,甚至是tanh-sinh正交
val, error_estimate = quadpy.line_segment.tanh_sinh(
lambda r: 0.5108/r**2 / np.sqrt(2*1.158 + 2/r - 0.5108**2/(2*r**2)),
0.15, 0.702,
1.0e-30
)
print(val)
给出了0.9617153094932353183036398697528
。
答案 2 :(得分:0)
如果您打印数字和theta的长度,您将看到它们是空列表/数组。
尝试以下方法:
import numpy as np
import matplotlib.pyplot as plt
def trapezoidal(f, a, b, n):
h = float(b-a)/n
result = 0.5*f(a) + 0.5*f(b)
for i in range(1, n):
result += f(a + i*h)
result *= h
return result
intg =[]
v = lambda r: (0.5108/(r**2))* (1./np.sqrt(2*1.158+(2/r)-.5108**2 /(2*r**2)))
n = np.arange(1, 1001)
theta = np.linspace(0,2.*np.pi,1000)
for j in n:
numerical = trapezoidal(v, .16,.702 , j)
intg.append(numerical)
plt.plot(intg,theta)
plt.show()