sin(x)/ x的数字积分

时间:2018-06-10 15:24:59

标签: python python-3.x numpy scipy integral

我想使用scipy在python中使用sin(x)/ x的quadratures来定量积分。 n = 256.它看起来效果不好:

 from scipy import integrate

 exact = integrate.quad(lambda x : (np.sin(x))/x, 0, 2*np.pi)[0]
 print("Exact value of integral:", exact)

 # Approx of sin(x)/x by Trapezoidal rule
 x = np.linspace(0, 2*np.pi, 257)
 f = lambda x : (np.sin(x))/x
 approximation = np.trapz(f(x), x)
 print ("Estimated value of trapezoidal O(h^2):", round(approximation, 5), 
   '+', round((2/256)**2, 5))
 print ("real error:", exact - approximation)

 # Approx of sin(x)/x by Simpsons 1/3 rule
 approximation = integrate.simps(f(x), x)
 print("Estimated value of simpsons O(h^4):", round(approximation, 9), 
   '+', round((2/256)**4, 9))
 print ("real error:", exact - approximation)

 plt.figure()
 plt.plot(x, f(x))
 plt.show()

精确积分计算得很好,但是我得到了一个带有正交误差的错误......出了什么问题?

Exact value of integral: 1.4181515761326284
Estimated value of trapezoidal O(h^2): nan + 6e-05
real error: nan
Estimated value of simpsons O(h^4): nan + 4e-09
real error: nan

提前致谢!

3 个答案:

答案 0 :(得分:2)

您的代码中至少存在一些问题:

  1. linspace 0开始,因此当您评估要集成的函数时,在梯形积分的开头,您有:sin(0)/0 = nan。您应该使用数字零而不是精确零(在下面的示例中我使用1e-12
  2. 当您获得第一个nannan + 1.0 = nan时:这意味着在您的代码中,当您在某个时间间隔内总计积分时,第一个nan会弄乱所有你的结果。
  3. 仅适用于python 2 :除法2/256是2个整数之间的除法,结果为0。请尝试使用2.0/256.0(感谢@MaxU指出这一点)。
  4. 这是你修改的代码(我在python2中运行它,这是我现在使用的pc中安装的代码):

    from scipy import integrate
    import numpy as np
    
    exact = integrate.quad(lambda x : (np.sin(x))/x, 0, 2*np.pi)[0]
    print("Exact value of integral:", exact)
    
    # Approx of sin(x)/x by Trapezoidal rule
    x = np.linspace(1e-12, 2*np.pi, 257) # <- 0 has become a numeric 0
    f = lambda x : (np.sin(x))/x
    approximation = np.trapz(f(x), x)
    print ("Estimated value of trapezoidal O(h^2):", round(approximation, 5), 
      '+', round((2.0/256.0)**2, 5))
    print ("real error:", exact - approximation)
    
    # Approx of sin(x)/x by Simpsons 1/3 rule
    approximation = integrate.simps(f(x), x)
    print("Estimated value of simpsons O(h^4):", round(approximation, 9), 
      '+', round((2/256)**4, 9))
    print ("real error:", exact - approximation)
    

    输出:

    ('Exact value of integral:', 1.4181515761326284)
    ('Estimated value of trapezoidal O(h^2):', 1.41816, '+', 6e-05)
    ('real error:', -7.9895502944626884e-06)
    ('Estimated value of simpsons O(h^4):', 1.418151576, '+', 0.0)
    ('real error:', 2.7310242955991271e-10)
    

    Discalimer sin(x)/x -> 1 for x -> 0的限制,但由于sin(1e-12)/1e-13 = 1的浮动四舍五入!

答案 1 :(得分:2)

对于x == 0,你可以使函数返回1(sin(x)/ x的极限为0)而不是NaN。这样,你就不必作弊和改变您为了排除0而整合的时间间隔。

import numpy as np
import matplotlib.pyplot as plt
from scipy import integrate

exact = integrate.quad(lambda x : (np.sin(x))/x, 0, 2*np.pi)[0]
print("Exact value of integral:", exact)


def f(x):
    out = np.sin(x) / x
    # For x == 0, we get nan. We replace it by the 
    # limit of sin(x)/x in 0
    out[np.isnan(out)] = 1
    return out

# Approx of sin(x)/x by Trapezoidal rule

x = np.linspace(0, 2*np.pi, 257)

approximation = np.trapz(f(x), x)
print ("Estimated value of trapezoidal O(h^2):", round(approximation, 5), 
  '+', round((2/256)**2, 5))
print ("real error:", exact - approximation)
 # Approx of sin(x)/x by Simpsons 1/3 rule
approximation = integrate.simps(f(x), x)
print("Estimated value of simpsons O(h^4):", round(approximation, 9), 
  '+', round((2/256)**4, 9))
print ("real error:", exact - approximation)
plt.figure()
plt.plot(x, f(x))
plt.show()

输出:

Exact value of integral: 1.4181515761326284
Estimated value of trapezoidal O(h^2): 1.41816 + 6e-05
real error: -7.98955129322e-06
Estimated value of simpsons O(h^4): 1.418151576 + 4e-09
real error: 2.72103006793e-10

答案 2 :(得分:1)

NaN表示&#34;不是数字&#34;。在你的情况下基本无限。创建时:

x = np.linspace(0, 2*np.pi, 257)

你创建一个值为0的数组,然后你试着除以x,你就不能被0 ...

一种解决方案是使用它:

x = np.linspace(0.1, 2*np.pi, 257)

给你这个:

Exact value of integral: 1.4181515761326284
Estimated value of trapezoidal O(h^2): 1.31822 + 6e-05
real error: 0.099935104987
Estimated value of simpsons O(h^4): 1.318207115 + 4e-09
real error: 0.0999444614012

越接近零,近似值就越好!