Comparison with Python¶
This page documents the Python script compute_integral.py
, which re-runs numerical integrations on data generated by the C++ program and compares those results against the C++ outputs.
Numerical integration in Python¶
The script imports:
The trapezoidal rule is implemented using scipy.integrate.trapezoid
, and Simpson's rule is implemented using scipy.integrate.simpson
. Instead, Romberg integration is not directly available in SciPy, so we implement it manually.
Romberg integration in Python¶
The Romberg integration method is implemented in Python as follows:
# ============================
# Romberg integration function
# ============================
def romberg(f, a, b, tol=ROMBERG_TOL, rtol=ROMBERG_RTOL, divmax=ROMBERG_DIVMAX):
"""
Compute the Romberg integration of function f on the interval [a, b]
using the trapezoidal rule and Richardson extrapolation.
"""
R = [] # Romberg table: a list of lists
R.append([(b - a) * (f(a) + f(b)) / 2.0])
for i in range(1, divmax):
n_intervals = 2**i
h = (b - a) / n_intervals
sum_ = 0.0
for k in range(1, n_intervals, 2):
sum_ += f(a + k * h)
R0 = 0.5 * R[i-1][0] + h * sum_
row = [R0]
for j in range(1, i+1):
factor = 4**j
extrap = row[j-1] + (row[j-1] - R[i-1][j-1]) / (factor - 1.0)
row.append(extrap)
R.append(row)
if i > 0 and abs(R[i][i] - R[i-1][i-1]) < tol:
return R[i][i]
return R[-1][-1]
Comparison with C++ results¶
The script reads the sampled data from the C++ output files and computes the integrals using the same methods as in C++. The results are then compared:
The script then computes the integrals:
N_AB = int(round((B - A) / dx)) + 1
integral_trapz = trapezoid(fx_subset, x_subset)
integral_simpson = simpson(fx_subset, x_subset)
f_interp = interp1d(x_subset, fx_subset, kind='cubic', fill_value="extrapolate")
integral_romberg = romberg(f_interp, A, B, tol=ROMBERG_TOL, rtol=ROMBERG_RTOL, divmax=ROMBERG_DIVMAX)
Finally, the script computes the absolute errors between C++ and Python results: