| exports | kernelspec | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
#%config InlineBackend.figure_format = 'svg'
from pylab import *
A smooth function
where
is the continuous Fourier transform. Recall that
We can truncate the series
An approximation method which makes use of the function values at a discrete set of points only, will be more useful in computations.
For any even integer
which are uniformly spaced with spacing
:tags: remove-input
N = 9
h = 2*pi/N
x = h * arange(0,N)
figure(figsize=(8,2))
plot(x,0*x,'-o')
d = 0.005
text(0,d,"$x=0$",ha='center',va='bottom')
text(x[-1],d,"$x=2\\pi$",ha='center',va='bottom')
text(0,-d,"$x_0$",ha='center',va='top')
text(h,-d,"$x_1$",ha='center',va='top')
text(2*h,-d,"$x_2$",ha='center',va='top')
text(x[-3],-d,"$x_{N-2}$",ha='center',va='top')
text(x[-2],-d,"$x_{N-1}$",ha='center',va='top')
xticks([]), yticks([]);
Note that
In Python, we can generate the grid points like this.
h = 2 * pi / N
x = h * arange(0,N)The degree
We will determine the
This is a system of
First prove the orthogonality relation
Then computing
\begin{align} \sum_{j=0}^{N-1} u(x_j) \ee^{-\ii k x_j} &= \sum_{j=0}^{N-1} \clr{red}{I_N u(x_j)} \ee^{-\ii k x_j} \ &= \sum_{j=0}^{N-1} \clr{red}{\sum_{l=-N/2}^{N/2-1} \tilde u_l \ee^{\ii l x_j}} \ee^{-\ii k x_j} \ &= \sum_{l=-N/2}^{N/2-1} \tilde u_l \clr{blue}{\sum_{j=0}^{N-1} \ee^{\ii (l-k)x_j}} \ &= \sum_{l=-N/2}^{N/2-1} \tilde u_l \clr{blue}{N \delta_{lk}} \end{align}
we obtain the discrete Fourier coefficients
This is known as the discrete Fourier transform (DFT) of
The interpolation conditions
will be called the inverse DFT (IDFT) of
+++
:::{exercise} Prove the discrete orthogonality relation . This implies
$$ \frac{1}{N} \sum_{j=0}^{N-1} \ee^{\ii (l-k)x_j} = \delta_{lk}, \qquad - N/2 \le l, k \le N/2-1 $$ :::
+++
:::{prf:remark} If we apply the Trapeoidal rule of integration to using the uniformly spaced points, we obtain . :::
+++
We can derive a Lagrange form of the interpolation as follows.
where
The functions
:::{prf:remark}
Why did we not include the term corresponding to
take the same values at all the nodes
Let us define the set of trigonometric functions
:::{prf:lemma}
If
:::{prf:proof}
If
for some coefficients
Define the discrete inner product
and the usual continuous one
In fact, the discrete one can be obtained if we apply Trapezoidal rule to the continuous inner product.
:::{prf:lemma}
For any
$$ \ip{u,v}_N = \ip{u,v} $$ :::
:::{prf:proof} Let
Then
and
$$ \begin{aligned} \ip{u,v}N &= \frac{2\pi}{N} \sum{j=0}^{N-1} u(x_j) \conj{v(x_j)} \ &= \frac{2\pi}{N} \sum_{j=0}^{N-1} u(x_j) \sumf \conj{b_k} \ee^{-\ii k x_j} \ &= 2\pi \sumf \left( \frac{1}{N} \sum_{j=0}^{N-1} u(x_j) \ee^{-\ii k x_j} \right) \conj{b_k} \ &= 2\pi \sumf a_k \conj{b_k} \end{aligned} $$ :::
As a consequence,
:::{prf:lemma}
For any continuous function
:::
:::{prf:proof} A direct computation gives
$$ \begin{aligned} \ip{I_N u, v}N &= \frac{2\pi}{N} \sum{j=0}^{N-1} I_N u(x_j) \conj{v(x_j)} \ &= \frac{2\pi}{N} \sum_{j=0}^{N-1} u(x_j) \conj{v(x_j)} \ &= \ip{u,v}_N \end{aligned} $$ :::
Hence the interpolant satisfies
Thus
$I_N u$ is the orthogonal projection of$u$ onto$S_N$ with respect to the discrete inner product.The error
$u - I_N u$ is perpendicular to$S_N$ and$I_N u$ is the best approximation to$u$ in$S_N$ wrt the discrete norm$\norm{\cdot}_N$ .
This is also related to the property that
+++
:::{prf:lemma} Aliasing
:label: lem:falias
If the Fourier series
$$ \tilu_k = \hatu_k + \sum_{m=-\infty,m\ne 0}^\infty \hatu_{k + Nm}, \qquad k=-N/2, \ldots, N/2-1 $$ :::
:::{prf:proof}
Starting from the definition of
But by
Hence
$$ \tilu_k = \sum_{m=-\infty}^\infty \hatu_{k + Nm} = \hatu_k + \sum_{m=-\infty,m\ne 0}^\infty \hatu_{k + Nm} $$ :::
Define
which is a truncation of the Fourier series
:::{prf:lemma} Under the conditions of
$$ \norm{u - P_N u}_2 \le \norm{u - I_N u}_2 $$ :::
:::{prf:proof} Using , the interpolant can be written as
Hence
and
we get
which proves the desired result. :::
+++
The result of and decay properties of Fourier transform are key to showing the error estimate of trigonometric interpolation.
:::{prf:lemma}
:label: lem:trigerr
Let
\begin{align} \norm{u - P_N u}\infty \le \sumfr |\hatu_k| &= \order{\frac{1}{N^m}} \ \norm{u - I_N u}\infty \le 2 \sumfr |\hatu_k| &= \order{\frac{1}{N^m}} \end{align} :::
:::{prf:proof} From the smoothness of the function, we have
The first inequality is easy since
For the second, we use the decomposition
so that
But
and hence
The error is given by
The sum on the right can be bounded by an integral
$$
\begin{aligned}
\frac{1}{(N/2)^{m+1}} + \frac{1}{(N/2+1)^{m+1}} + \ldots
&< \int_0^\infty \frac{1}{(N/2 + x - 1)^{m+1}} \ud x \
&= \frac{1}{m(N/2-1)^{m}} \
&= \order{\frac{1}{N^{m}}} \quad \textrm{for } N \gg 1
\end{aligned}
$$
:::
:::{prf:remark} The error of trigonometric interpolation is at most twice the error in the truncated Fourier series. This shows that trigonometric interpolation at uniformly spaced points gives very accurate approximations provided the function is sufficiently smooth. :::
:::{prf:remark}
We can derive the error in
If the function
and
which is real, and
is also real. When we want to evaluate
the above expression is not real because of the last term. We can modify it as
\begin{align} I_N u(x) &= \tilu_0 + \sum_{k=1}^{N/2-1} \left( \tilu_k \phi_k(x) + \conj{\tilu_k \phi_k(x)} \right) \ & \qquad + \half \tilu_{-N/2} \phi_{-N/2}(x) + \half \tilu_{-N/2} \phi_{N/2}(x) \end{align}
i.e.,
and the prime denotes that the first and last terms must be multiplied by half. This ensures that the interpolation conditions are still satisfied and
However, in actual numerical computation, we may get an imaginary part of order machine precision, and then we have to take the real part. Then, we may as well compute it as before and take real part
Computing each
The matrix has special structure and using some tricks, the cost can be reduced to
Numpy has routines to compute the DFT using FFT, see numpy.fft. It takes the trigonometric polynomial in the form
which is different from our convention.
from numpy import pi,arange
import numpy.fft as fft
h = 2*pi/N
x = h*arange(0,N)
u = f(x)
u_hat = fft(u)The output u_hat gives the DFT in the following order
Scipy.fft also provides equivalent routines for FFT.
See more examples of using Fourier interpolation for approximation and differentiation here http://cpraveen.github.io/chebpy.
+++
The following function computes the trigonometric interpolant and plots it. It also computes error norm by using ne uniformly spaced points.
# Wave numbers are arranged as k=[0,1,...,N/2,-N/2+1,-N/2,...,-1]
def fourier_interp(N,f,ne=1000,fig=True):
if mod(N,2) != 0:
print("N must be even")
return
h = 2*pi/N; x = h*arange(0,N);
v = f(x);
v_hat = fft(v)
k = zeros(N)
n = N//2
k[0:n+1] = arange(0,n+1)
k[n+1:] = arange(-n+1,0,1)
xx = linspace(0.0,2*pi,ne)
vf = real(exp(1j*outer(xx,k)) @ v_hat) / N
ve = f(xx)
# Plot interpolant and exact function
if fig:
plot(x,v,'o',xx,vf,xx,ve)
legend(('Data','Fourier','Exact'))
xlabel('x'), ylabel('y'), title("N = "+str(N))
errori = abs(vf-ve).max()
error2 = sqrt(h*sum((vf-ve)**2))
print("Error (max,L2) = ",errori,error2)
return errori, error2
To measure rate of error convergence, we can compute error with
and estimate the rate
f1 = lambda x: exp(sin(x))
fourier_interp(24,f1);
g = lambda x: sin(x/2)
e1i,e12 = fourier_interp(24,g)
e2i,e22 = fourier_interp(48,g,fig=False)
print("Rate (max,L2) = ", log(e1i/e2i)/log(2), log(e12/e22)/log(2))
trihat = lambda x: (x >= 0.5*pi)*(x <= 1.5*pi)*(1 - 2*abs(x-pi)/pi)
e1i,e12 = fourier_interp(24,trihat)
e2i,e22 = fourier_interp(48,trihat,fig=False)
print("Rate (max,L2) = ", log(e1i/e2i)/log(2), log(e12/e22)/log(2))
does not apply in this case.
f2 = lambda x: (abs(x-pi) < 0.5*pi)
e1i,e12 = fourier_interp(24,f2)
e2i,e22 = fourier_interp(48,f2)
print("Rate (max,L2) = ", log(e1i/e2i)/log(2), log(e12/e22)/log(2))
We do not get convergence in maximum norm but we see convergence in 2-norm at a rate of
+++
:::{note} Uniformly spaced points were not a good choice for polynomial interpolation, since they lead to Runge phenomenon. We needed to use points clustered at the boundaries to get good approximations.
Uniformly spaced points are the best choice for trigonometric interpolation. They lead to discrete orthogonality and an explicit expression for the DFT. Moreover, the highly efficient FFT is also possible because of this property. :::
+++
:::{exercise}
With
Comment on the nature of these curves. :::
+++
:::{exercise}
To test convergence as
\begin{align} \norm{I_N u - u}\infty &\approx \max{j} |I_N u(x_j) - u(x_j)| \ \norm{I_N u - u}2 &\approx \left( \frac{2\pi}{m} \sum{j} [I_N u(x_j) - u(x_j)]^2 \right)^\half \end{align}
Plot error versus
+++
:::{attention} Approximating derivatives
If
We can thus compute derivatives at all points with almost
+++
:::{seealso} Here are some nice applications of DFT from [@Brunton2019], also see the book website https://databookuw.com.