【机器学习笔记31】傅里叶变换

【参考资料】
【1】《复变函数与积分变换》
【2】《数字信号处理》

1. 傅里叶级数

定义: 设fT(t)f_T(t)是以T为周期的实值函数,且在[T2,T2][-\dfrac{T}{2}, \dfrac{T}{2}]上满足狄利克雷条件,即:
1)连续或只有有限个第一类间断点;
备注:第一类间断点包括:
可去间断点:左右极限存在且相等,但不等于该点的值,或该点无定义;
跳跃间断点:左右极限存在但不相等

2)只有有限个极值点

那么fT(t)f_T(t)在连续点处有

傅里叶级数的三角形式

fT(t)=a02+n=1+(ancosnω0t+bnsinnω0t)f_T(t)=\dfrac{a_0}{2} + \sum\limits_{n=1}^{+\infty}(a_n \cos n \omega_0 t + b_n \sin n \omega_0 t)
w0=2πTw_0 = \dfrac{2 \pi}{T}

an=2TT/2T/2fT(t)cosnω0tdta_n = \dfrac{2}{T}\int_{-T/2}^{T/2} f_T(t) \cos n \omega_0 tdt其中n=0,1,2,n = 0, 1, 2, \dots

bn=2TT/2T/2fT(t)sinnω0tdtb_n = \dfrac{2}{T}\int_{-T/2}^{T/2} f_T(t) \sin n \omega_0 tdt其中n=0,1,2,n = 0, 1, 2, \dots

傅里叶级数的复指数形式

fT(t)=+cnejnω0tf_T(t) = \sum\limits_{-\infty}^{+\infty} c_n e^{jn \omega_0 t}
cn=1TT/2T/2fT(t)ejnω0tdtc_n = \dfrac{1}{T} \int_{-T/2}^{T/2} f_T(t) e^{-jn \omega_0 t}dt

【机器学习笔记31】傅里叶变换


2. 傅里叶变换

周期函数可以展开为傅里叶级数。从物理上将周期为T的函数可以由一系列ω0=2πT\omega_0 = \dfrac{2\pi}{T}为间隔的离散频率所形成的简谐波合成。当T越来越大时,取得频率间隔越来越小,当T变成无穷大时,周期函数就变成了非周期函数,此时傅里叶级数就转变称了傅里叶变换。

推导如下:

f(t)=limT+fT(t)f(t)=\lim\limits_{T \to +\infty}f_T(t)
=limT+n=n=+[1TT/2T/2fT(τ)ejnω0τdτ]ejnω0t=\lim\limits_{T \to +\infty} \sum\limits_{n=-\infty}^{n=+\infty} [ \dfrac{1}{T} \int_{-T/2}^{T/2} f_T(\tau) e^{-jn \omega_0 \tau} d \tau ] e^{jn \omega_0 t}

在周期函数下时域信号被分解为频率ω0=2πT\omega_0 = \dfrac{2 \pi}{T}的简谐波,此时T区域无穷。

因此有越来越小的ω0\omega_0记作Δω\Delta \omega,而nω0n \omega_0记作ωn\omega_n, 并且T=2πΔωT=\dfrac{2 \pi}{\Delta \omega}
于是有:

f(t)=12πlimΔω0n=n=+[π/Δωπ/ΔωfT(τ)ejωnτdτ.ejωnt]Δωf(t)=\dfrac{1}{2\pi} \lim\limits_{\Delta \omega \to 0} \sum\limits_{n=-\infty}^{n=+\infty} [ \int_{-\pi/\Delta \omega}^{\pi/\Delta \omega}f_T(\tau)e^{-j\omega_n \tau}d\tau . e^{j \omega_n t}] \Delta \omega

f(t)=12π+[+f(τ)ejωτdτ]ejωtdωf(t)=\dfrac{1}{2\pi} \int\limits_{-\infty}^{+\infty}[\int\limits_{-\infty}^{+\infty} f(\tau) e^{-j\omega \tau}d\tau] e^{j\omega t}d\omega

因此得到定理如下(傅里叶变换):
F(ω)=+f(t)ejωtdtF(\omega)=\int\limits_{-\infty}^{+\infty} f(t) e^{-j\omega t} dt
f(t)=12π+F(ω)ejωtdωf(t)=\dfrac{1}{2\pi}\int\limits_{-\infty}^{+\infty} F(\omega)e^{j\omega t}d \omega

3. 单位冲击函数

单位冲击函数定义:
1)当t0t \ne 0时,ξ(t)=0\xi(t)=0
2)+ξ(t)dt=1\int_{-\infty}^{+\infty} \xi(t) dt = 1

主要性质:
1 当实数域有界函数f(t),在t=0点连续,则+ξ(t)f(t)dt=f(0)\int_{-\infty}^{+\infty} \xi(t) f(t) dt = f(0)
2 当实数域有界函数f(t),在t=t0t = t_0点连续,则+ξ(tt0)f(t)dt=f(t0)\int_{-\infty}^{+\infty} \xi(t - t_0) f(t) dt = f(t_0)
3 ξ(t)\xi(t)是偶函数,有ξ(t)=ξ(t)\xi(t) = \xi(-t)
4 ξ(t)\xi(t)是单位阶跃函数μ(t)\mu (t)的导数
μ(t)={1,t>00,t<0\mu(t) = \begin{cases} 1, & t > 0 \\ 0, & t < 0 \end{cases}

5 ξ(t)\xi(t)函数的傅里叶变换

公式1:F(ω)=F[xi(t)]=+ξ(t)ejωtdt=ejwtt=0=1F(\omega)=F[xi(t)] =\int_{-\infty}^{+\infty}\xi(t)e^{-j\omega t}dt = e^{-jwt}|_{t=0} = 1
公式2:F1[1]=12π+ejωtdω=ξ(t)F^{-1}[1] = \dfrac{1}{2\pi} \int_{-\infty}^{+\infty} e^{-j \omega t} d \omega = \xi(t) //根据逆变换可知
根据上面两个公式,我们可以作出如下推导:
f(t)=1f(t)=1,其傅里叶变换(由公式2) F(ω)=+ejωtdt=2πξ(t)F(\omega)=\int_{-\infty}^{+\infty} e^{-j \omega t} dt = 2\pi \xi(t)
f(t)=ejω0tf(t)=e^{j \omega_0 t}
F(ω)=+ejω0tejωtdt=2πξ(ω0ω)F(\omega) = \int_{-\infty}^{+\infty} e^{j \omega_0 t} e^{-j \omega t} dt = 2 \pi \xi(\omega_0 - \omega)
f(t)=cosω0t=1/2+(ejω0t+ejω0t)ejωtdt=π[ξ(ωω0)+ξ(ω+ω0)]f(t)=cos \omega_0 t = 1/2 \int_{-\infty}^{+\infty}(e^{j \omega_0 t} + e^{-j \omega_0 t}) e^{-j \omega t} dt = \pi[\xi(\omega - \omega_0) + \xi(\omega + \omega_0)]

因此在广义的傅里叶变换下周期函数仍然可以以傅里叶变换展开

4. 离散傅里叶变换

设x(n)是一个长度为M的有限长序列,则定义x(n)的N点离散傅里叶变换为:
X(k)=DFT[x(n)]=n=0N1WNknk=0,1,2,,N1X(k) = DFT[x(n)]=\sum\limits_{n=0}^{N-1}W_{N}^{kn} \quad k = 0,1,2,\dots, N-1

X(k)的傅里叶逆变换为:
x(n)=IDFT[X(k)]=1Nn=0N1X(k)WNknn=0,1,2,,N1x(n) = IDFT[X(k)] = \dfrac{1}{N}\sum\limits_{n=0}^{N-1}X(k)W_{N}^{-kn} \quad n = 0,1,2,\dots, N-1
其中WN=ej2πNW_N=e^{-j \dfrac{2\pi}{N}},N是DFT变换区间长度,NMN \ge M

5. 代码实现(numpy和纯python)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import matplotlib.ticker as tik
import pandas as pd
import numpy as np
import math


def _fft_code():

    plt.figure(figsize=(8, 4))

    df = pd.read_csv('./data/test.csv', sep=',')

    data = df['std_value'].astype(float)

    ax1 = plt.subplot(1,2,1)
    ax1.set_title('time series')
    plt.gca().yaxis.set_major_formatter(tik.FormatStrFormatter('%1.2f'))

    plt.plot(data,'r')

    list_len = len(data)

    y = data

    m = np.floor(list_len) #DFT中的N,要求N >= M,这里字节用序列长度

    a = np.zeros(int(m))
    b = np.zeros(int(m))
    c = np.zeros(int(m))

    N = int(list_len - 1)

    for i in range(0, int(m)- 1):
       for t in range(0, N - 1):

           a[i + 1] = a[i + 1] + y[t + 1] * np.cos(2 * np.pi * i * t/N)
           b[i + 1] = b[i + 1] + y[t + 1] * np.sin(2 * np.pi * i * t/N)

       c[i + 1] = a[i + 1] + b[i + 1]

    ax2 = plt.subplot(1,2,2)
    ax2.set_title('Fourier Result')
    plt.plot(c,'b')
    plt.show()


def _fft_np():

    df = pd.read_csv('./data/test.csv', sep=',')

    data = df['std_value']

    fig = plt.figure(figsize=(8, 4))

    

    ax1 = plt.subplot(1,2,1)
    ax1.set_title('time series')
    plt.gca().yaxis.set_major_formatter(tik.FormatStrFormatter('%1.2f'))


    plt.plot(data,'r')

    transformed = np.fft.fft(data)

    d = abs(transformed) 
    x = np.arange(len(d))

    ax2 = plt.subplot(1,2,2)
    ax2.set_title('Fourier Result')
    plt.plot(d,'b')

    plt.show()

"""
说明:

傅里叶变换代码实现,对应的笔记《傅里叶变换》

作者:fredric

日期:2018-11-18

_fft_np: 采用numpy自带傅里叶变换函数

_fft_code: 纯python代码,依据基本的DFT推导,未采用FFT


"""

if __name__ == '__main__':

    _fft_code()

    _fft_np()



【机器学习笔记31】傅里叶变换