Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
Laurent series: expansions with negative powers in an annulus#
Pierre Alphonse Laurent (1843, after Weierstrass in 1841) expanded a function holomorphic in an annulus \(r < |z - a| < R\) as \(\sum_{n=-\infty}^{\infty} a_n (z-a)^n\), with every coefficient a contour integral \(a_n = \frac{1}{2\pi i}\oint f(z)(z-a)^{-n-1}dz\). For \(f(z) = 1/((z-1)(z-2))\) the expansion depends on the annulus: in \(1 < |z| < 2\) it is \(a_n = -2^{-n-1}\) for \(n \ge 0\) and \(a_n = -1\) for \(n < 0\).
import matplotlib.pyplot as plt
import numpy as np
from mathematicskit.complex_analysis import circle_contour, contour_integral
def f(z):
return 1.0 / ((z - 1.0) * (z - 2.0))
def laurent_coefficient(n, radius):
return contour_integral(lambda z: f(z) * z ** (-n - 1), circle_contour(0.0, radius)) / (2j * np.pi)
Coefficients by contour integration in three annuli#
orders = np.arange(-5, 6)
closed_form = np.where(orders >= 0, -(2.0 ** (-orders - 1.0)), -1.0)
fig, ax = plt.subplots()
for radius, label in ((0.5, "|z| < 1 (Taylor)"), (1.5, "1 < |z| < 2"), (3.0, "|z| > 2")):
coefficients = np.array([laurent_coefficient(n, radius) for n in orders]).real
ax.plot(orders, coefficients, "o-", label=label)
if radius == 1.5:
print(f"max |numeric - closed form| in 1 < |z| < 2: {np.max(np.abs(coefficients - closed_form)):.1e}")
ax.set_xlabel("n")
ax.set_ylabel("$a_n$")
ax.set_title("Laurent coefficients of 1/((z-1)(z-2)) depend on the annulus")
ax.legend()

max |numeric - closed form| in 1 < |z| < 2: 1.4e-12
<matplotlib.legend.Legend object at 0x7fd7e8ee3e60>
The truncated series converges only inside its annulus#
5 terms each side: |partial sum - f(z)| = 7.32e-02
10 terms each side: |partial sum - f(z)| = 3.21e-02
20 terms each side: |partial sum - f(z)| = 2.13e-03
40 terms each side: |partial sum - f(z)| = 5.78e-06
Total running time of the script: (0 minutes 0.095 seconds)