View in NBViewer Open in binder Download notebook View source


11.2. Transformada discreta de Fourier

using LinearAlgebra
using Plots
using FFTW
using Random

Transformada discreta de Fourier

\[ X_k = \sum_{n=0}^{N-1} x_n e^{\frac{-2\pi i kn}{N}} = \sum_{n=0}^{N-1} x_n \left(\cos\left(\frac{2\pi kn}{N} \right) - i \sin\left(\frac{2\pi kn}{N}\right) \right). \] \[ x_n = \frac{1}{N}\sum_{k=0}^{N-1} X_k e^{\frac{2\pi i nk}{N}}. \]

Simetria no caso real

\[ \begin{align*} X_{N-k} & = \sum_{n=0}^{N-1} x_n e^{\frac{-2\pi i (N-k)n}{N}} = \sum_{n=0}^{N-1} x_n e^{-2\pi i n}e^{\frac{2\pi i kn}{N}} = \sum_{n=0}^{N-1} x_n e^{\frac{2\pi i kn}{N}} \\ & = \sum_{n=0}^{N-1} \overline{x_n e^{\frac{-2\pi i kn}{N}}} = \overline{\sum_{n=0}^{N-1} x_n e^{\frac{-2\pi i k n}{N}}} = \overline{X_k}. \end{align*} \]

Comparação com a série de Fourier

\[ x(t) = \sum_{k\in \mathbb{Z}} c_k e^{\frac{i 2k\pi t}{T}}. \] \[ c_k = \frac{1}{T}\int_{0}^{T} x(t)e^{-\frac{i 2k\pi t}{T}}\;\mathrm{d}t. \] \[ c_k \approx \frac{1}{T} \sum_{n=0}^{N-1} x(t_n) e^{\frac{- 2k\pi i t_n}{T}} \Delta t = \frac{1}{N} \sum_{n=0}^{N-1} x_n e^{\frac{-2k\pi i n}{N}} = \frac{X_k}{N}. \]

Comparação com a transformada inversa

\[ x_n = \frac{1}{N}\sum_{k=0}^{N-1} X_k e^{\frac{2\pi i nk}{N}} = \frac{1}{N}\sum_{k=0}^{[N/2]} X_k e^{\frac{2\pi i nk}{N}} + \frac{1}{N}\sum_{k=[N/2]+1}^{N-1} X_k e^{\frac{2\pi i nk}{N}}. \] \[ [N/2] = [2M/2 + 1/2] = M = (N-1)/2, \]

o que nos dá

\[j = N - [N/2] - 1 = 2M+1 - M - 1 = M = (N-1)/2 = [N-1/2]. \] \[ [N/2] = M = N/2, \quad \text{e} \quad [(N-1)/2] = [ (2M - 1)/2] = [M - 1/2] = M - 1, \]

o que nos dá

\[j = N - [N/2] - 1 = 2M - M - 1 = M - 1 = [(N-1)/2].\]

Continuando

\[ \begin{align*} x_n & = \frac{1}{N}\sum_{k=0}^{[N/2]} X_k e^{\frac{2\pi i nk}{N}} + \frac{1}{N}\sum_{j=1}^{[(N-1)/2]} X_{N-j} e^{\frac{2\pi i n(N-j)}{N}} \\ & = \frac{1}{N}\sum_{k=0}^{[N/2]} X_k e^{\frac{2\pi i nk}{N}} + \frac{1}{N}\sum_{j=1}^{[(N-1)/2]} \overline{X_j}e^{\frac{-2\pi j nk}{N}} \\ & = \frac{1}{N}\sum_{k=0}^{[N/2]} X_k e^{\frac{2\pi i nk}{N}} + \frac{1}{N}\sum_{k=-1}^{-[(N-1)/2]}\overline{X_{-k}}e^{\frac{2\pi i nk}{N}} \end{align*} \] \[ \begin{align*} x_n & \approx \sum_{k=0}^{[N/2]} c_k e^{\frac{2\pi i nk}{N}} + \sum_{k=-1}^{-[(N-1)/2]}\overline{c_{-k}}e^{\frac{2\pi i nk}{N}} \\ & = \sum_{k=0}^{[N/2]} c_k e^{\frac{2\pi i nk}{N}} + \sum_{k=-1}^{-[(N-1)/2]} c_k e^{\frac{2\pi i nk}{N}} = \sum_{k=-[(N-1)/2]}^{[N/2]} c_k e^{\frac{2\pi i nk}{N}}. \end{align*} \] \[ x(t_n) = \sum_{k=-[(N-1)/2]}^{[N/2]} c_k e^{\frac{2\pi i nk}{N}} \approx \sum_{k=-[(N-1)/2]}^{[N/2]} \frac{X_k}{N} e^{\frac{2\pi i nk}{N}} = x_n. \] \[ x(t_n) = \sum_{k=-N/2+1}^{N/2} c_k e^{\frac{2\pi i nk}{N}} \approx \sum_{k=-N/2+1}^{N/2} \frac{X_k}{N} e^{\frac{2\pi i nk}{N}} = x_n. \] \[ x(t_n) = \sum_{k=-(N-1)/2}^{(N-1)/2} c_k e^{\frac{2\pi i nk}{N}} \approx \sum_{k=-(N-1)/2}^{(N-1)/2} \frac{X_k}{N} e^{\frac{2\pi i nk}{N}} = x_n. \]

Indexamento no Julia

\[ Z = \left(\frac{|X_0|}{N}, \frac{2|X_1|}{N}, \ldots, \frac{2|X_{N/2-1}|}{N}\right) \]

Transformada rápida de Fourier

Exemplos

Exemplo de sinal constante

fs = 440
Tf = 1.0
tempos = 0.0:inv(fs):Tf
N = length(tempos) # N = fs + 1 se T == 1
freqs = 0:div(N,2)/Tf
nothing
k = 0 # número de onda
ν = k/Tf # frequência
A = 0
B = 4
x = A*sin.(2π*ν*tempos) + B*cos.(2π*ν*tempos) # onda senoidal pura, de frequência ν
W = √(A^2 + B^2) # amplitude da onda
nothing
plot(tempos, x, xlabel = "tempo (s)", ylabel="amplitude", label=nothing, ylims=(-1.1W,1.1W),
    title="Onda senoidal com frequência ν = $ν Hz", titlefont = 10)
X = fft(x)
Xr = rfft(x)
maximum(abs.(X[1:length(Xr)] - Xr))
5.409610308782961e-14
Z = [abs(Xr[1])/N; 2abs.(Xr[2:end])/N]

println("Amplitude dada diretamente no espaço físico: W = $W")
println("Amplitude calculada via FFT: |X_k|/N = $(Z[1+k])")
Amplitude dada diretamente no espaço físico: W = 4.0
Amplitude calculada via FFT: |X_k|/N = 4.0
scatter(abs.(X), markersize=2, label=nothing, xlabel="índice", ylabel="amplitude",
    title="Amplitude dos coeficientes da transformada discreta complexa de Fourier", titlefont=10)
scatter(freqs, Z, markersize=2, legend=nothing, xlabel="frequência (Hz)", ylabel="amplitude",
    title="Espectro de amplitude", titlefont=10)
scatter(freqs[1:6], Z[1:6], markersize=6, legend=nothing, xlabel="frequência (Hz)", ylabel="amplitude",
    title="Parte inicial do espectro de amplitude", titlefont=10)

Exemplo de onda senoidal pura

k = 3 # número de onda
ν = k/Tf # frequência
A = 3
B = 4
x = A*sin.(2π*ν*tempos) + B*cos.(2π*ν*tempos) # onda senoidal pura, de frequência ν
W = √(A^2 + B^2) # amplitude da onda
plot(tempos, x, xlabel = "tempo (s)", ylabel="amplitude", label=nothing, ylims=(-1.1W,1.1W),
    title="Onda senoidal com frequência ν = $ν Hz", titlefont = 10)
X = fft(x)
Xr = rfft(x)
maximum(abs.(X[1:length(Xr)] - Xr))
9.018901711841947e-14
Z = [abs(Xr[1])/N; 2abs.(Xr[2:end]/N)]

println("Amplitude dada diretamente no espaço físico: W = $W")
println("Amplitude calcula via FFT: |X_k|/N = $(Z[1+k])")
Amplitude dada diretamente no espaço físico: W = 5.0
Amplitude calcula via FFT: |X_k|/N = 5.001210101433121
scatter(abs.(X), markersize=2, label=nothing, xlabel="índice", ylabel="amplitude",
    title="Amplitude dos coeficientes da transformada discreta complexa de Fourier", titlefont=10)
scatter(freqs[1:6], Z[1:6], markersize=6, legend=nothing, xlabel="frequência (Hz)", ylabel="amplitude",
    title="Parte inicial do espectro de amplitude", titlefont=10)

Exemplo de combinação de frequências

ks = (3, 5, 8, 16, 17) # número de onda
νs = ks./Tf # frequências
As = rand(MersenneTwister(358),length(ks))
Bs = rand(length(ks))
x = sum([A * sin.(2π*ν*tempos) + B*cos.(2π*ν*tempos) for (A,B,ν) in zip(As, Bs, νs)]) 
Ws = sqrt.(As.^2 .+ Bs.^2)
plot(tempos, x, xlabel = "tempo (s)", ylabel="amplitude", label=nothing, ylims=(-1.1W,1.1W),
    title="Onda senoidal com frequência ν = $ν Hz", titlefont = 10)
X = fft(x)
Xr = rfft(x)
maximum(abs.(X[1:length(Xr)] - Xr))
3.1776437161565096e-14
Z = [abs(Xr[1])/N; 2abs.(Xr[2:end]/N)]

println("Amplitudes dadas diretamente no espaço físico: W = $Ws")
println("Amplitudes calculadas via FFT: |X_k|/N = $([Z[i+1] for i in ks])")
Amplitudes dadas diretamente no espaço físico: W = [0.8283940081422632, 0.9
543363785738578, 0.6945005986909628, 0.9967345166751823, 0.3857676993077362
4]
Amplitudes calculadas via FFT: |X_k|/N = [0.8397719183213538, 0.95904303663
7107, 0.6937572061402019, 1.0021378307416826, 0.35341120582108815]
scatter(abs.(X), markersize=2, label=nothing, xlabel="índice", ylabel="amplitude",
    title="Amplitude dos coeficientes da transformada discreta complexa de Fourier", titlefont=10)
scatter(freqs[1:20], Z[1:20], xticks=freqs[1:20], markersize=6, legend=nothing, xlabel="frequência (Hz)", ylabel="amplitude",
    title="Parte inicial do espectro de amplitude", titlefont=10)
@show length(freqs)
@show length(Xr)
@show length(Z)
length(freqs) = 221
length(Xr) = 221
length(Z) = 221
221
div(N,2)+1
221

Exercícios

  1. Verifique a afirmação de que \(x_n \approx f(t_n)\) no caso em que \(N\) é par, indicado acima.

  2. Mostre que a transformada inversa é, de fato, a inversa da transformada discreta de Fourier, i.e.

\[ \frac{1}{N}\sum_{k=0}^{N-1} \sum_{j=0}^{N-1} x_j e^{\frac{-2\pi i kj}{N}} e^{\frac{2\pi i nk}{N}} = x_n, \qquad n=0, \ldots, N-1. \]