In [1]:
# Import modules
import math
import cmath
import numpy as np
import scipy
import matplotlib.pyplot as plt
In [2]:
np.set_printoptions(precision=3)
x = np.array([1, 0, -1, 0]).T
w = complex(math.cos(math.pi * 2 / x.size), -math.sin(math.pi * 2 / x.size))
F = np.empty((x.size, x.size), dtype=complex) # Fourier matrix
for i in range(x.size):
for j in range(x.size):
F[i, j] = pow(w,(i * j))
y = (1 / math.sqrt(x.size)) * np.matmul(F, x)
print(np.round(y)) # [0, 1, 0, 1]
In [3]:
# Or use numpy fft (fast fourier transform)
print(np.fft.fft(x) / np.sqrt(x.size))
For an even integer n, let $t_j = c + j(d - c)/n$ for $j = 0,\cdots,n - 1$, and let $x = (x_0,\cdots,x_{n-1})$ denote a vector of n real numbers. Define $\overrightarrow{a} + \overrightarrow{b}i = F_nx$, where $F_n$ is the Discrete Fourier Transform. Then the function
satisfies $P_n(t_j) = x_j$ for $j = 0,\cdots,n-1$
In [4]:
def even_trigonometric_interpolant(t, a, b, c, d):
return a[0] / np.sqrt(a.size) + 2 / np.sqrt(a.size) * \
np.sum([a[k] * np.cos(2 * k * np.pi * (t - c) / (d - c)) - \
b[k] * np.sin(2 * k * np.pi * (t - c) / (d - c)) for k in range(1, int(a.size / 2))]) + \
a[int(a.size / 2)] / np.sqrt(a.size) * np.cos(a.size * np.pi * (t - c) / (d - c))
In [5]:
c, d = 0, 1
x = np.array([1, 0, -1, 0]).T
y = np.fft.fft(x) / np.sqrt(x.size)
a = np.array(y.real)
b = np.array(y.imag)
f = lambda t, a, b, c, d : a[0] / np.sqrt(a.size) + 2 / np.sqrt(a.size) * \
np.sum([a[k] * np.cos(2 * k * np.pi * (t - c) / (d - c)) - \
b[k] * np.sin(2 * k * np.pi * (t - c) / (d - c)) for k in range(1, int(a.size / 2))]) + \
a[int(a.size / 2)] / np.sqrt(a.size) * np.cos(a.size * np.pi * (t - c) / (d - c))
t = np.linspace(c, d, 40)
xt = np.linspace(0, 1, 4, False)
data = [f(i, a, b, c, d) for i in t]
plt.plot(t, data)
plt.plot(xt, x, 'o', color='k')
plt.show()
In [6]:
c, d = 0, 1
xt = np.linspace(c, d, 8, False)
x = np.array([-2.2, -2.8, -6.1, -3.9, 0, 1.1, -0.6, -1.1])
y = np.fft.fft(x) / np.sqrt(x.size)
a = np.array(y.real)
b = np.array(y.imag)
t = np.linspace(c, d, 40)
data = [even_trigonometric_interpolant(i, a, b, c, d) for i in t]
plt.plot(t, data)
plt.plot(xt, x, 'o', color='k')
plt.show()
Let f0(t),\cdots,\f{n-1}(t) be functions of t and $t_0,\cdots,t_{n-1}$ be real numbers. Assume that the $n \times n$ matrix
$
is a real $n \times n$ otrhogonal matrix. If $y = Ax$, the function
interpolates $(t_0, x_0), \cdots, (t_{n-1}, x_{n-1})$, that is $F(t_j) = x_j$ for $j = 0,\cdots,n-1$
Let $n \ge 1$ and k, l be integers. Then
n & \text{if both (k-l)/n and (k+l)/n are integers} \ \frac{n}{2} & \text{if exactly one of (k-l)/n and (k+l)/n is an integer} \ 0 & \text{if neither is an integer} \end{matrix}\right.$
0 & \text{if both (k-l)/n and (k+l)/n are integers} \ \frac{n}{2} & \text{if (k-l)/n is an integer and (k+l)/n is not} \ -\frac{n}{2} & \text{if (k-l)/n is not and (k+l)/n is an integer} \ 0 & \text{if neither is an integer} \end{matrix}\right.$
Let $m \le n$ be integers, and assume that data $(t_0,x_0),\cdots,(t_{n-1},x_{n-1})$ are given. Set $y = Ax$, where A is an orthogonal matrix of form like Orthogonal Function Interpolation Theorem show. Then the interpolating polynomial for basis functions $f_0(t),\cdots,f_{n-1}(t)$ is
and the best least squares approximation, using only the functions $f_0,\cdots,f_{m-1}$, is
Let $[c,d]$ be an interval, let $m < n$ be even positive integers, $x = (x_0,\cdots,x_{n-1})$ a vector of n real numbers, and let $t_j = c + j(d - c)/n$ for $j=0,\cdots,n-1$. Let ${a_0,a_1,b_1,a_2,b_2,\cdots,a_{n/2-1},b_{n/2-1},a_{n/2}} = F_nx$ be the interpolating coefficients for x so that
for $j = 0,\cdots,n-1$. Then
is the best least squares fit of order m to the data $(t_j,x_j)$ for $j = 0,\cdots,n - 1$
In [7]:
def least_squares_even_trigonmetric(m, t, a, b, c, d):
return a[0] / np.sqrt(a.size) + 2 / np.sqrt(a.size) * \
np.sum([a[k] * np.cos(2 * k * np.pi * (t - c) / (d - c)) - \
b[k] * np.sin(2 * k * np.pi * (t - c) / (d - c)) for k in range(1, int(m / 2))]) + \
a[int(m / 2)] / np.sqrt(a.size) * np.cos(a.size * np.pi * (t - c) / (d - c))
In [8]:
m1, m2, m3 = 4, 6, 8
c, d = 0, 1
xt = np.linspace(c, d, 8, False)
x = np.array([-2.2, -2.8, -6.1, -3.9, 0, 1.1, -0.6, -1.1])
y = np.fft.fft(x) / np.sqrt(x.size)
a = np.array(y.real)
b = np.array(y.imag)
t = np.linspace(c, d, 40)
data1 = [least_squares_even_trigonmetric(m1, i, a, b, c, d) for i in t]
data2 = [least_squares_even_trigonmetric(m2, i, a, b, c, d) for i in t]
data3 = [least_squares_even_trigonmetric(m3, i, a, b, c, d) for i in t]
plt.xticks(xt, ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'])
plt.plot(t, data1, label='order 4')
plt.plot(t, data2, label='order 6')
plt.plot(t, data3, label='order 8')
plt.plot(xt, x, 'o', color='k')
plt.legend()
plt.grid(True)
plt.show()