梯形法则对高斯积分估计的误差

计算科学 Python 数字 一体化
2021-12-18 10:21:37

我试图通过复合梯形规则与通过精确公式来估计计算高斯积分的百分比误差。为此,我在 Python 中生成了一个平均值为 0、标准偏差和振幅范围内个点的网格上, 并用于计算一系列不同近似积分σ=1A=1N[2σ,2σ]scipy.integrate.trapzAN

在此处输入图像描述

对于精确积分,我使用了公式计算两个均值标准差之间的精确积分,因为,或I=xxet22σ2dt=2πσerf(x2σ)±I=2σ2σet22σ2dt=2πσerf(2)

I=2πerf(2)

在这种的情况下。那么 % 错误是下面是σ=1E=|IA|I1001EN

在此处输入图像描述

并作为参考 verus的图。EN

在此处输入图像描述

现在我希望但这在这里看不到。谁能帮我弄清楚为什么?E1N2

我在下面包含了我的代码。先感谢您!

from scipy.integrate import trapz
from scipy.special import erf
import matplotlib.pyplot as plt
import numpy as np

errs = np.array([]) # Errors in integral estimates
Ns = np.array([]) # Sample sizes tried

def get_percent_err(N, errs, Ns):
    A = 1 # Amplitude of Gaussian
    std = 1 # Standard deviation of Gaussian
    r = 2*std # Extent of domain
    dt = 2*r/N # Step
    t = np.linspace(-r,r,N) # Domain
    gauss = A*np.exp(-((t)**2)/(2*(std**2))) # Gaussian function
    
    actual_area = np.sqrt(2*np.pi)*A*std*erf(np.sqrt(2)) # Exact gaussian integral from -2*std to +2*std
    est_area = trapz(gauss, dx=dt) # Estimated integral via trapezium rule
    percent_err = (abs(actual_area - est_area)/actual_area)*100 # Percentage error
    
    errs = np.append(errs, percent_err)
    Ns = np.append(Ns, N)
    
    return errs, Ns

# Sweep through a range of sample sizes and obtain errors for each
min_samples = 100
max_samples = 100100
sample_step = 100
samples = np.arange(min_samples,max_samples,sample_step)

for N in samples:
    errs, Ns = get_percent_err(N, errs, Ns)

# Plot reciprocal of error in integral against sample size
plt.figure()
plt.plot(1/Ns,errs)
plt.xlabel("1 / Samples (1 / N)")
plt.ylabel("% Error in Integral (E)")
plt.title("Plot of % Error (E) in Integral versus 1 / Samples (1 / N)")

更新:

由于我不知道的原因(尽管我相信它与数值精度有关),此代码改编自此链接,给出了预期的结果。

代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erf
from scipy.integrate import trapz as trapz_scipy
from pandas import DataFrame

def trapz(f,a,b,N=50):
    x = np.linspace(a,b,N+1) # N+1 points make N subintervals
    y = f(x)
    dx = (b - a)/N
    T = trapz_scipy(y, dx=dx)
    return T

def get_err(N, errs):
    A = 1
    std = 1
    f = lambda x : A*np.exp(-x**2/(2*std**2))
    a = -2*std; b = 2*std;
    
    I = np.sqrt(2*np.pi)*A*std*erf(np.sqrt(2))
    T = trapz(f,a,b,N)
    return np.append(errs, 100*np.abs(I - T)/T)

min_samples = 10
max_samples = 1000
sample_step = 10
sample_sizes = np.arange(min_samples,max_samples+sample_step,sample_step)

errs = np.array([], dtype=np.float64)

for s in sample_sizes:
    errs = get_err(s, errs)
    
err_vs_sample_size = DataFrame({'% Error' : errs, 'Samples' : sample_sizes})

plt.figure()
plt.plot(1/sample_sizes**2,errs)
plt.xlabel("1 / Samples (1 / N)")
plt.ylabel("% Error in Integral (E)")
plt.title("Plot of % Error (E) in Integral versus 1 / Samples (1 / N)")

错误图:

在此处输入图像描述

0个回答
没有发现任何回复~