Published May 5, 2021|4 minute read

This post documents the implementation of the error function erf(z)\mathrm{erf}(z) used in my complex function plotter. For small zz, I use the asympotic series by Abramowitz & Stegun. For large zz, I use a custom expansion around the 45° line.

Let ω:=eiπ/4\omega := e^{i\pi/4}, and parameterize the complex plane via z=rω+s iωz = r\omega + s \, i \omega. Consider the piecewise linear contour travelling from 00 to rωr \omega, and then from rωr \omega to rω+s iωr \omega + s \, i \omega. Using this contour, we compute

π2 erf(z)=∫0ze−x2 dx=∫0re−(tω)2ω dt+∫0se−(rω+tiω)2iω dt=ω [C(r)−i S(r)]+iωe−ir2∫0se2rt+it2 dt,\begin{aligned} \frac{\sqrt{\pi}}{2} \, \mathrm{erf}(z) &= \int_0^z e^{-x^2} \, \mathrm{d}x \\ &= \int_0^r e^{-(t\omega)^2} \omega \, \mathrm{d}t + \int_0^s e^{-(r \omega + t i \omega)^2} i \omega \, \mathrm{d}t \\ &= \omega \, [C(r) - i \, S(r)] + i \omega e^{-ir^2} \int_0^s e^{2rt + it^2} \, \mathrm{d}t, \end{aligned}

where S(x)S(x) and C(x)C(x) are the Fresnel integrals. From Wikipedia, we have the asymptotic expansion

C(x)−i S(x)=π2ω−1−[1+O(x−4)]cos⁡x2−isin⁡x22x[12x2−i]C(x) - i \, S(x) = \frac{\sqrt{\pi}}{2} \omega^{-1} - [1 + \mathcal{O}(x^{-4})] \frac{\cos{x^2} - i \sin{x^2}}{2x} \left[\frac{1}{2x^2} - i\right]

for large positive xx. The second term is more annoying. For large a>0a > 0, consider the integral

Ia(x):=e−ax∫−∞xeateit2 dt=a∫−∞x∫x∞ea (t−s)eit2 ds dt.\begin{aligned} I_a(x) &:= e^{-ax} \int_{-\infty}^x e^{at} e^{it^2} \, \mathrm{d}t \\ &= a \int_{-\infty}^x \int_x^{\infty} e^{a \, (t-s)} e^{it^2} \, \mathrm{d}s \, \mathrm{d}t. \end{aligned}

Making the change of variables (u,v):=(a (s−t), x−t)(u, v) := (a \, (s-t), \, x-t), we obtain

Ia(x)=∫0∞e−u∫0u/aei (x−v)2 dv du.I_a(x) = \int_0^\infty e^{-u} \int_0^{u/a} e^{i \, (x-v)^2} \, \mathrm{d}v \, \mathrm{d}u.

The inner integral can be evaluated as a sum of four Fresnel integrals, and is therefore bounded by a constant. Then for large aa, it is fruitful to perform the Taylor expansion

∫0u/aei (x−v)2 dv=eix2∫0u/ae−2ixv+iv2 dv=eix2∫0u/a[1−2ixv+iv2−2x2v2+O(v3)] dv=eix2[ua−ixu2a2+(i−2x2) u33a3+O(a−4)].\begin{aligned} \int_0^{u/a} e^{i \, (x-v)^2} \, \mathrm{d}v &= e^{ix^2} \int_0^{u/a} e^{-2ixv + iv^2} \, \mathrm{d}v \\ &= e^{ix^2} \int_0^{u/a} [1 - 2ixv + iv^2 - 2x^2 v^2 + \mathcal{O}(v^3)] \, \mathrm{d}v \\ &= e^{ix^2} \left[\frac{u}{a} - \frac{ixu^2}{a^2} + \frac{(i - 2x^2) \, u^3}{3a^3} + \mathcal{O}(a^{-4})\right]. \end{aligned}

Evaluating the standard gamma integrals, we thus obtain

Ia(x)=e−ix2 [a−1−2ixa−2+(2i−4x2) a−3+O(a−4)].I_a(x) = e^{-ix^2} \, [a^{-1} - 2ixa^{-2} + (2i-4x^2) \, a^{-3} + \mathcal{O}(a^{-4})].

We were a bit handwavy with the justification for Fubini. Indeed, the above expansion works well for x>0x>0, but fails catastrophically for x<0x < 0. From the definition of Ia(x)I_a(x), it is evident that small errors in the integral are exponentially amplified for negative xx. Empirically, however, we find that the approximation

∫0xeateit2 dt=eax Ia(x)−Ia(0)≈eax+ix2 [a−1−2ixa−2+(2i−4x2) a−3]−a−1−2ia−3\begin{aligned} \int_0^x e^{at} e^{it^2} \, \mathrm{d}t &= e^{ax} \, I_a(x) - I_a(0) \\ &\approx e^{ax + ix^2} \, [a^{-1} - 2ixa^{-2} + (2i - 4x^2) \, a^{-3}] - a^{-1} - 2ia^{-3} \end{aligned}

works very well, and could probably be derived rigorously with more effort. Combining all the above, we have

erf(z)=2πω[C(r)−i S(r)]+2πiωe−ir2[e2rsI2r(s)−I2r(0)]≈1−2πcos⁡r2−isin⁡r22r[12r−i]+iω2πe−ir2[e2rs+is2(2r−1−2isr−2+(i+2s2) r−3)−2r−1−ir−3],\begin{aligned} \mathrm{erf}(z) &= \frac{2}{\sqrt{\pi}} \omega [C(r) - i \, S(r)] + \frac{2}{\sqrt{\pi}} i\omega e^{-ir^2} [e^{2rs} I_{2r}(s) - I_{2r}(0)] \\ &\approx 1 - \frac{2}{\sqrt{\pi}} \frac{\cos{r^2} - i \sin{r^2}}{2r} \left[\frac{1}{2r} - i\right] \\ &+ \frac{i\omega}{2 \sqrt{\pi}} e^{-ir^2} \left[e^{2rs + is^2} \left(2r^{-1} -2isr^{-2} + (i + 2s^2) \, r^{-3}\right) -2r^{-1} - ir^{-3}\right], \end{aligned}

which is the implementation I use in my complex function plotter. (I go up to fourth order in the app.)