在python中使用梯形数值积分

时间:2017-09-26 16:44:01

标签: python numerical-methods numerical-integration

我需要在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()

我猜这是一个非常基本的错误,因为我没有得到任何阴谋。我认为梯形例程是正确的,因为它适用于其他功能。非常感谢您的帮助

3 个答案:

答案 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()