9.7. Improper integrals#

When the interval of integration or the integrand itself is unbounded, we say an integral is improper. Improper integrals present particular challenges to numerical computation.

Infinite interval#

When the integration domain is \((-\infty,\infty)\), the integrand has to decay as \(x \to \pm \infty\) in order for the improper integral to be finite. This fact brings up the possibility of truncating the domain:

(9.7.1)#\[\int_{-\infty}^{\infty} f(x)\, dx \approx \int_{-M}^{M} f(x)\, dx.\]

This integral can be discretized finitely by, say, the trapezoid formula, or an adaptive integrator. However, this approach can be inefficient.

Example 9.7.1

Consider the integral of \(f(x)=1/(1+x^2)\),

\[ \int_{-\infty}^\infty \frac{1}{1+x^{2}}\, dx = \pi. \]

In this case we can easily estimate the effect of truncation on the result. For large \(M\),

\[ \int_M^\infty f\,dx \approx \int_M^\infty x^{-2}\,dx = M^{-1}. \]

The same estimate applies to the integral over \((-\infty,-M)\). To get eight digits of accuracy, for instance, we need to truncate with \(M > 2 \times 10^8\).

Double exponential transformation#

In order to do better than direct truncation, we want to encourage the function to decay faster. In practice this means a change of variable, \(x(t)\). If \(|x(t)|\) grows rapidly as \(|t| \to \infty\), then \(f(x(t))\) will decay more rapidly in \(t\) than in \(x\).

One way to accomplish this feat is to use

(9.7.2)#\[ x(t) = \sinh\left( \sinh t \right).\]

Noting the asymptotic behavior as \(t \rightarrow \pm\infty\) that

(9.7.3)#\[ \left| \sinh(t) \right| \sim \frac{1}{2} e^{ |t| },\]

we find that in the same limits,

\[ x(t) \approx \pm \frac{1}{2} \exp\left( \frac{1}{2} e^{ |t| } \right). \]

Thus, (9.7.2) is often referred to as a double exponential transformation.

By the chain rule,

(9.7.4)#\[\begin{split}\int_{-\infty}^\infty f(x)\, dx &= \int_{-\infty}^\infty f(x(t))\frac{dx}{dt}\, dt \\ &= \int_{-\infty}^\infty f(x(t))\, \cosh\left( \sinh t \right) \cosh t \, dt.\end{split}\]

The exponential terms introduced by the chain rule grow double exponentially, but the more rapid decay of \(f\) in the new variable more than makes up for this.

Demo 9.7.2

Consider again \(f(x)=1/(1+x^2)\) from Example 9.7.1, with \(x(t)\) given by (9.7.2). As \(t\to\infty\),

\[ f(x(t)) \approx x^{-2} \approx 4 \exp\left( -e^{t} \right). \]

The chain rule terms in (9.7.4) become

\[ \cosh\left( \sinh t \right) \cosh t \approx \frac{1}{2} \exp\left( \frac{1}{2} e^t \right) \cdot \frac{1}{2} e^t, \]

yielding a product that is roughly

\[ 2 \exp\left( -\frac{1}{2} e^t \right). \]

The total integrand in (9.7.4) therefore has double exponential decay in \(t\), essentially because of the squaring of \(x\) in the denominator of \(f\). The same result holds as \(t\to-\infty\).

Hide code cell source
f = x -> 1/(1+x^2)
plot(f,-4,4,layout=(2,1),
    xlabel=L"x",yaxis=(:log10,L"f(x)",(1e-16,2)),
    title="Original integrand")

x = t -> sinh(π*sinh(t)/2)
dx_dt = t -> pi/2*cosh(t)*cosh(pi*sinh(t)/2)
g = t -> f(x(t))*dx_dt(t)

plot!(g,-4,4,subplot=2,
    xlabel=L"t",yaxis=(:log10,L"f(x(t))\cdot x'(t)",(1e-16,2)),
    title="Transformed integrand")
Original integrand Transformed integrand

This graph suggests that we capture all of the integrand values that are larger than machine epsilon by integrating in \(t\) from \(-4\) to \(4\).

Function 9.7.3 implements double exponential integration by applying the adaptive integrator Function 5.7.2 to (9.7.4). It truncates the interval to \(-M\le t \le M\) by increasing \(M\) until the integrand is too small to matter relative to the error tolerance.

Function 9.7.3 :  intinf

Integration of a function over \((-\infty,\infty)\)

 1"""
 2    intinf(f,tol)
 3
 4Perform adaptive doubly-exponential integration of function `f` 
 5over (-Inf,Inf), with error tolerance `tol`. Returns the integral 
 6estimate and a vector of the nodes used.
 7"""
 8function intinf(f,tol)   
 9    x = t -> sinh(sinh(t))
10    dx_dt = t -> cosh(t)*cosh(sinh(t))
11    g = t -> f(x(t))*dx_dt(t)
12
13    # Find where to truncate the integration interval.
14    M = 3
15    while (abs(g(-M)) > tol/100) || (abs(g(M)) > tol/100)
16        M += 0.5
17        if isinf(x(M)) 
18            @warn "Function may not decay fast enough."
19            M -= 0.5
20            break
21        end
22    end
23
24    I,t = intadapt(g,-M,M,tol)
25	return I,x.(t)
26end
Demo 9.7.4

We compare direct truncation in \(x\) to the double exponential method of Function 9.7.3 for \(f(x)=1/(1+x^2)\).

Hide code cell source
f = x -> 1/(1+x^2)
tol = [1/10^d for d in 5:0.5:14]
err = zeros(length(tol),2)
len = zeros(Int,length(tol),2)
for (i,tol) in enumerate(tol)
    I1,x1 = FNC.intadapt(f,-2/tol,2/tol,tol)
    I2,x2 = FNC.intinf(f,tol)
    @. err[i,:] = abs(π-[I1,I2])
    @. len[i,:] = length([x1,x2])
end
plot(len,err,m=:o,label=["direct" "double exponential"])
n = [100,10000]
plot!(n,1000n.^(-4),l=:dash,label="fourth-order",
     xaxis=(:log10,"number of nodes"),yaxis=(:log10,"error"),
     title="Comparison of integration methods",leg=:bottomleft)
number of nodes error Comparison of integration methods

Both methods are roughly fourth-order due to Simpson’s formula in the underlying adaptive integration method. At equal numbers of evaluation nodes, however, the double exponential method is consistently 2–3 orders of magnitude more accurate.

Integrand singularity#

If \(f\) asymptotically approaches infinity as \(x\) approaches an integration endpoint, its exact integral may or may not be finite. If \(f\) is integrable, then the part of the integration interval near the singularity needs to be more finely resolved than the rest of it.

Let’s consider

(9.7.5)#\[\int_0^1 f(x)\,dx,\]

where \(f\) and/or a derivative of \(f\) is unbounded at the left endpoint, zero. The change of variable

(9.7.6)#\[ x(t) = \frac{2}{1+\exp(2 \sinh t)}\]

satisfies \(x(0)=1\) and \(x\to 0^+\) as \(t\to \infty\), thereby transforming the integration interval to \(t\in(0,\infty)\) and placing the singularity at infinity. The chain rule implies

(9.7.7)#\[\begin{split} \int_{0}^1 f(x)\, dx &= \int_{0}^\infty f(x(t)) \frac{dx}{dt}\, dt \\ &= \int_{0}^\infty f(x(t)) \frac{\cosh t}{\cosh(\sinh t)^2} \, dt.\end{split}\]

Now the growth of \(f\) and \(\cosh t\) together are counteracted by the double exponential denominator, allowing easy truncation of (9.7.7). This variable transformation is paired with adaptive integration in Function 9.7.5.

Function 9.7.5 :  intsing

Integration of a function with endpoint singularities

 1"""
 2    intsing(f,tol)
 3
 4Adaptively integrate function `f` over (0,1), where `f` may be 
 5singular at zero, with error tolerance `tol`. Returns the
 6integral estimate and a vector of the nodes used.
 7"""
 8function intsing(f,tol)
 9    x = t -> 2/(1+exp(2sinh(t)))
10	dx_dt = t -> cosh(t)/cosh(sinh(t))^2
11	g = t -> f(x(t))*dx_dt(t)
12
13    # Find where to truncate the integration interval.
14    M = 3
15    while abs(g(M)) > tol/100
16        M += 0.5
17        if iszero(x(M)) 
18            @warn "Function may grow too rapidly."
19            M -= 0.5
20            break
21        end
22    end
23
24    I,t = intadapt(g,0,M,tol)
25	return I,x.(t)
26end
Demo 9.7.6

Let’s use Function 9.7.5 to compute

\[ \int_0^{0.01} \frac{1}{\sqrt{x}}\, dx. \]

Since the integration interval is not \([0,1]\), we must first use the change of variable \(s=100t\), yielding

\[ \int_0^{1} \frac{1}{10\sqrt{s}}\, ds = 0.2. \]

In order to use Function 5.7.2, we must truncate on the left to avoid evaluation at zero, where \(f\) is infinite. Since the integral from \(0\) to \(\delta\) is \(20\sqrt{\delta}\), we use \(\delta=(\epsilon/20)^2\) to achieve error tolerance \(\epsilon\).

Hide code cell source
f = x -> 1/(10*sqrt(x))
tol = [1/10^d for d in 5:0.5:14]
err = zeros(length(tol),2)
len = zeros(Int,length(tol),2)
for (i,tol) in enumerate(tol)
    I1,x1 = FNC.intadapt(f,(tol/20)^2,1,tol)
    I2,x2 = FNC.intsing(f,tol)
    @. err[i,:] = abs(0.2-[I1,I2])
    @. len[i,:] = length([x1,x2])
end
plot(len,err,m=:o,label=["direct" "double exponential"])
n = [30,3000]
plot!(n,30n.^(-4),l=:dash,label="fourth-order",
     xaxis=(:log10,"number of nodes"),yaxis=(:log10,"error"),
     title="Comparison of integration methods",leg=:bottomleft)
number of nodes error Comparison of integration methods

As in Demo 9.7.4, the double exponential method is more accurate than direct integration by a few orders of magnitude. Equivalently, the same accuracy can be reached with many fewer nodes.

Double exponential integration is an effective general-purpose technique for improper integrals that usually outperforms interval truncation in the original variable. There are specialized methods tailored to specific singularity types that can best it, but those require more analytical work to use properly.

Exercises#

  1. ⌨ Use Function 9.7.3 to estimate the given integral with error tolerances \(10^{-3},10^{-6},10^{-9},10^{-12}\). For each result, show the actual error and the number of nodes used.

    (a) \(\displaystyle\int_{-\infty}^\infty \dfrac{1}{1+x^2+x^4}\, dx = \dfrac{\pi}{\sqrt{3}}\)

    (b) \(\displaystyle\int_{-\infty}^\infty e^{-x^2}\cos(x)\, dx = e^{-1/4}\sqrt{\pi}\)

    (c) \(\displaystyle\int_{-\infty}^\infty (1+x^2)^{-2/3}\, dx = \dfrac{\sqrt{\pi}\,\Gamma(1/6)}{\Gamma(2/3)}\) (use gamma() for \(\Gamma()\))

  2. ⌨ Use Function 9.7.5 to estimate the given integral, possibly after rewriting the integral into the form (9.7.5) with a left-endpoint singularity. Use error tolerances \(10^{-3},10^{-6},10^{-9},10^{-12}\), and for each result, show the actual error and the number of nodes used.

    (a) \(\displaystyle\int_{0}^1 (\log x)^2\, dx = 2\)

    (b) \(\displaystyle\int_{0}^{\pi/4} \sqrt{\tan(x)}\, dx = \dfrac{\pi}{\sqrt{2}}\)

    (c) \(\displaystyle\int_{0}^1 \frac{1}{\sqrt{1-x^2}}\, dx = \dfrac{\pi}{2}\)

  3. For integration on a semi-infinite interval such as \(x\in [0,\infty)\), another double exponential transformation is useful: \(x(t)=\exp\left( \sinh t \right)\).

    (a) ✍ Show that \(t\in(-\infty,\infty)\) is mapped to \(x\in (0,\infty)\).

    (b) ✍ Derive an analog of (9.7.4) for the chain rule on \(\int_0^\infty f(x)\,dx\).

    (c) ✍ Show that truncation of \(t\) to \([-M,M]\) will truncate \(x\) to \([1/\mu,\mu]\) for some positive \(\mu\).

    (d) ⌨ Write a function intsemi(f,tol) for the semi-infinite integration problem. Test it on the integral

    \[ \displaystyle\int_0^\infty \frac{e^{-x}}{\sqrt{x}}\,dx = \sqrt{\pi}. \]