수학

푸리에 해석 : 리만-르베그 보조정리 파이썬코드

릿카。 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()

리만-르베그 보조정리
각 함수의 푸리에 부분합