Skip to content

Commit 55b7dd8

Browse files
committed
Add "Romberg method"
1 parent a1affa0 commit 55b7dd8

3 files changed

Lines changed: 67 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ python3 main.py
7171

7272
- Composite Trapezoidal method
7373
- Composite 1/3 Simpson's method
74+
- Romberg method
7475

7576
### Initial-value problems for ordinary differential equations
7677

integration.py

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Methods for numerical integration."""
22

3+
import numpy as np
4+
35

46
def simpson(f, a, b, n):
57
"""Calculate the integral from 1/3 Simpson's Rule.
@@ -11,7 +13,7 @@ def simpson(f, a, b, n):
1113
n (int): number of intervals.
1214
1315
Returns:
14-
xi (float): integral value.
16+
xi (float): numerical approximation of the definite integral.
1517
"""
1618
h = (b - a) / n
1719

@@ -39,7 +41,7 @@ def trapezoidal(f, a, b, n):
3941
n (int): number of intervals.
4042
4143
Returns:
42-
xi (float): integral value.
44+
xi (float): numerical approximation of the definite integral.
4345
"""
4446
h = (b - a) / n
4547

@@ -61,7 +63,7 @@ def simpson_array(x, y):
6163
y (numpy.ndarray): y values.
6264
6365
Returns:
64-
xi (float): integral value.
66+
xi (float): numerical approximation of the definite integral.
6567
"""
6668
if y.size != y.size:
6769
raise ValueError("'x' and 'y' must have same size.")
@@ -90,7 +92,7 @@ def trapezoidal_array(x, y):
9092
y (numpy.ndarray): y values.
9193
9294
Returns:
93-
xi (float): integral value.
95+
xi (float): numerical approximation of the definite integral.
9496
"""
9597
if y.size != y.size:
9698
raise ValueError("'x' and 'y' must have same size.")
@@ -105,3 +107,40 @@ def trapezoidal_array(x, y):
105107

106108
xi = h / 2 * (y[0] + 2 * sum_x + y[n - 1])
107109
return [xi]
110+
111+
112+
def romberg(f, a, b, n):
113+
"""Calculate the integral from the Romberg method.
114+
115+
Args:
116+
f (function): the equation f(x).
117+
a (float): the initial point.
118+
b (float): the final point.
119+
n (int): number of intervals.
120+
121+
Returns:
122+
xi (float): numerical approximation of the definite integral.
123+
"""
124+
# Initialize the Romberg integration table
125+
r = np.zeros((n, n))
126+
127+
# Compute the trapezoid rule for the first column (h = b - a)
128+
h = b - a
129+
r[0, 0] = 0.5 * h * (f(a) + f(b))
130+
131+
# Iterate for each level of refinement
132+
for i in range(1, n):
133+
h = 0.5 * h # Halve the step size
134+
# Compute the composite trapezoid rule
135+
sum_f = 0
136+
for j in range(1, 2**i, 2):
137+
x = a + j * h
138+
sum_f += f(x)
139+
r[i, 0] = 0.5 * r[i - 1, 0] + h * sum_f
140+
141+
# Richardson extrapolation for higher order approximations
142+
for k in range(1, i + 1):
143+
r[i, k] = r[i, k - 1] + \
144+
(r[i, k - 1] - r[i - 1, k - 1]) / ((4**k) - 1)
145+
146+
return [float(r[n - 1, n - 1])]

main.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,28 @@ def f(x):
468468
print(f"xi = {xi:.5f}")
469469

470470

471+
@print_docstring
472+
def example_romberg():
473+
"""Run an example 'Integration: Romberg method'."""
474+
def f(x):
475+
return x ** 2 * math.log(x ** 2 + 1)
476+
477+
a = 0.0
478+
b = 2.0
479+
h = 0.25
480+
n = int((b - a) / h)
481+
482+
print("Inputs:")
483+
print(f"a = {a}")
484+
print(f"b = {b}")
485+
print(f"n = {n}")
486+
487+
[xi] = integration.romberg(f, a, b, n)
488+
489+
print("Output:")
490+
print(f"xi = {xi:.5f}")
491+
492+
471493
@print_docstring
472494
def example_ode_euler():
473495
"""Run an example 'ODE: Euler'."""
@@ -739,6 +761,7 @@ def main():
739761
example_trapezoidal()
740762
example_simpson_array()
741763
example_simpson()
764+
example_romberg()
742765

743766
# Initial-value problems for ordinary differential equations
744767
example_ode_euler()

0 commit comments

Comments
 (0)