수학
푸리에 해석 : 리만-르베그 보조정리 파이썬코드
릿카。
2023. 4. 9. 19:11
리만-르베그 보조정리(Riemann-Lebesgue lemma)는 적분 가능한 함수의 푸리에 계수가, N이 무한대로 가면서 0이 되는 경향이 있다고 말합니다. 즉, 푸리에 계수는 순서가 증가함에 따라 작아집니다. 5개 함수에 대해 진행합니다 :
1. Sawtooth function
2. Square function
3. Triangle function
4. Gaissian function
5. Absolute sine function
import numpy as np
import matplotlib.pyplot as plt
# Define the function for which you want to calculate the Fourier coefficients
def f(x):
return np.sin(x)
# Sawtooth wave:
def sawtooth(x):
return (x % (2 * np.pi)) - np.pi
# Square wave:
def square(x):
return np.where((x % (2 * np.pi)) < np.pi, 1, -1)
# Triangle wave:
def triangle(x):
x_mod = x % (2 * np.pi)
return np.where(x_mod < np.pi, 2 * x_mod / np.pi - 1, 3 - 2 * x_mod / np.pi)
# Gaussian function:
def gaussian(x):
sigma = 1
mu = 0
return (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-(x - mu)**2 / (2 * sigma**2))
# Absolute sine function:
def absine(x):
return np.abs(np.sin(x))
functions = [
("Sawtooth wave", sawtooth),
("Square wave", square),
("Triangle wave", triangle),
("Gaussian function", gaussian),
("Absolute sine function", absine),
]
# Calculate the Fourier coefficients for a given function
def fourier_coefficients(func, n, N):
x = np.linspace(-np.pi, np.pi, N)
y = func(x)
delta_x = 2 * np.pi / N
# Calculate the coefficients a_n and b_n
a_n = (1 / np.pi) * sum(y * np.cos(n * x) * delta_x)
b_n = (1 / np.pi) * sum(y * np.sin(n * x) * delta_x)
return a_n, b_n
# Calculate the magnitude of the Fourier coefficients
def magnitude(a_n, b_n):
return np.sqrt(a_n**2 + b_n**2)
# Visualize the Riemann-Lebesgue lemma
def visualize_riemann_lebesgue(N, num_coefficients):
plt.figure(figsize=(15, 10))
for i, (name, func) in enumerate(functions, 1):
a_coeffs = []
b_coeffs = []
magnitudes = []
for n in range(num_coefficients + 1):
a_n, b_n = fourier_coefficients(func, n, N)
a_coeffs.append(a_n)
b_coeffs.append(b_n)
magnitudes.append(magnitude(a_n, b_n))
x, y = plot_truncated_fourier_series(func, N, num_terms)
plt.subplot(3, 2, i)
plt.plot(range(num_coefficients + 1), magnitudes, marker='o', label=f"{name} (Riemann-Lebesgue)", markersize=2)
plt.legend()
plt.xlabel('n')
plt.ylabel('a_n')
plt.show()
def plot_truncated_fourier_series(func, N, num_terms):
x = np.linspace(-1 * np.pi, 1 * np.pi, 1000)
y = np.zeros_like(x)
for n in range(1, num_terms + 1):
a_n, b_n = fourier_coefficients(func, n, N)
y += a_n * np.cos(n * x) + b_n * np.sin(n * x)
return x, y
N = 1000
num_coefficients = 50
visualize_riemann_lebesgue(N, num_coefficients)
# 푸리에 변환 plot
plt.figure(figsize=(15, 10))
num_terms = 50
for i, (name, func) in enumerate(functions, 1):
x, y = plot_truncated_fourier_series(func, N, num_terms)
plt.subplot(3, 2, i)
plt.plot(x, y, label=f"{name} (truncated Fourier series)")
plt.plot(x, func(x), '--', label=f"{name} (original)", color='black')
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.tight_layout()
plt.show()