Files
fourier-series-example/fourier.py
BrokenVoodooDoll 1a2fa7a586 Add files via upload
2021-04-16 12:22:49 +03:00

91 lines
2.0 KiB
Python

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import quad
T = 2 # period
def f(x): # one period of the periodic function
if -1 <= x < 0:
return 2 * x + 2
elif 0 <= x < 0.5:
return -2
elif 0.5 <= x <= 1:
return 1
else:
return 0
x = np.linspace(-2, 2, 1000)
y = [f(xi) for xi in x]
plt.figure()
plt.plot(x, y)
plt.grid()
plt.xlabel("$x$")
plt.ylabel("$f(x)$")
plt.title("One period of the signal")
# Fourier coefficients
a_0 = 2 / T * quad(f, -T / 2, T / 2)[0]
def a(n):
return (4 * np.sin(np.pi * n / 2) ** 2 / (np.pi * n) -
2 * np.sin(np.pi * n / 2) +
np.sin(np.pi * n) - np.sin(np.pi * n / 2)) / (np.pi * n)
def b(n):
return (2 * (np.sin(np.pi * n) - np.pi * n) / (np.pi * n) -
np.cos(np.pi * n) + np.cos(np.pi * n / 2) +
4 * (np.cos(np.pi * n / 4) ** 2 - 1)) / (np.pi * n)
def amplitude(n):
if n == 0:
return a_0
return np.sqrt(a(n) ** 2 + b(n) ** 2)
def phase(n):
if n == 0:
return 0
return np.angle(a(n) - 1j*b(n))
def frequency(n):
return n / T
def harmonics(x, n):
return amplitude(n) * np.cos(2 * np.pi * frequency(n) * x + phase(n))
n = np.arange(-50, 50)
amp = [amplitude(ni) for ni in n]
ph = [phase(ni) for ni in n]
# spectrum of amplitudes
plt.figure()
plt.stem(n, amp)
plt.grid()
plt.xlabel("$n$")
plt.ylabel("$d(n)$")
# spectrum of [phases]
plt.figure()
plt.stem(n, ph)
plt.grid()
plt.xlabel("$n$")
plt.ylabel("$\\theta(n)$, rad")
def s(x, number=3):
result = 0
for ni in range(1, number + 1):
result += harmonics(x, ni)
return a_0 + result
x = np.linspace(-2 * T, 2 * T, 1000)
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
# Fourier approximations of the signal f(x)
for ax, n in zip((ax1, ax2, ax3, ax4), (3, 10, 20,100)):
ax.plot(x, s(x, n))
ax.set_title("$S_{{{}}}$".format(n))
ax.grid()
ax.set_xlabel("$x$")
plt.show()