Một số khác biệt giữa DFT và FFT làm cho FFT nhanh như vậy là gì?


16

Tôi đang cố gắng để hiểu FFT, đây là những gì tôi có cho đến nay:

Để tìm độ lớn của tần số trong dạng sóng, người ta phải thăm dò chúng bằng cách nhân sóng với tần số mà chúng đang tìm kiếm, trong hai pha khác nhau (sin và cos) và trung bình mỗi pha. Pha được tìm thấy bởi mối quan hệ của nó với hai và mã cho nó là như thế này:

//simple pseudocode
var wave = [...];                //an array of floats representing amplitude of wave
var numSamples = wave.length;
var spectrum = [1,2,3,4,5,6...]  //all frequencies being tested for.  

function getMagnitudesOfSpectrum() {
   var magnitudesOut = [];
   var phasesOut = [];

   for(freq in spectrum) {
       var magnitudeSin = 0;
       var magnitudeCos = 0;

       for(sample in numSamples) {
          magnitudeSin += amplitudeSinAt(sample, freq) * wave[sample];
          magnitudeCos += amplitudeCosAt(sample, freq) * wave[sample];
       }

       magnitudesOut[freq] = (magnitudeSin + magnitudeCos)/numSamples;
       phasesOut[freq] = //based off magnitudeSin and magnitudeCos
   }

   return magnitudesOut and phasesOut;
}

Để thực hiện việc này cho rất nhiều tần số rất nhanh, các FFT sử dụng nhiều thủ thuật.

Một số thủ thuật được sử dụng để làm cho FFT nhanh hơn nhiều so với DFT là gì?

PS Tôi đã thử xem xét các thuật toán FFT đã hoàn thành trên web, nhưng tất cả các thủ thuật có xu hướng được cô đọng thành một đoạn mã đẹp mà không cần giải thích nhiều. Điều tôi cần trước tiên, trước khi tôi có thể hiểu toàn bộ, là một số giới thiệu về từng thay đổi hiệu quả này dưới dạng khái niệm.

Cảm ơn bạn.


7
"DFT" không đề cập đến một thuật toán: nó đề cập đến một hoạt động toán học. "FFT" dùng để chỉ một lớp phương thức tính toán hoạt động đó.

1
Chỉ muốn chỉ ra rằng việc sử dụng sudotrong ví dụ mã của bạn có thể gây nhầm lẫn, vì đó là một lệnh nổi tiếng trong thế giới máy tính. Bạn có thể có nghĩa là psuedocode.
rwfeather

1
@nwfeather Có lẽ anh ấy có nghĩa là 'mã giả'.
dùng207421

Câu trả lời:


20

Việc triển khai ngây thơ của DFT điểm về cơ bản là nhân với ma trậnĐiều này dẫn đến sự phức tạp của .N × N O ( N 2 )NN×NO(N2)

Một trong những phổ biến nhất Fast Fourier Transform (FFT) thuật toán là radix-2 Cooley-Tukey decimation-in-Time thuật toán FFT. Đây là một cách tiếp cận phân chia và chinh phục cơ bản.

Trước tiên, hãy xác định "hệ số twiddle" là: trong đó là đơn vị tưởng tượng, sau đó là DFT của được cho bởi Nếu chẵn (và là số nguyên), thì tổng có thể được chia thành hai tổng như sau trong đó phép tính tổng đầu tiên xử lý các mẫu chẵn của và mẫu thứ hai với các mẫu lẻ của và sử dụng thực tế là j

WNej2πN
X[k]x[n]X[k]= N - 1 n = 0 x[n]j1X[k]x[n]N N
X[k]=n=0N1x[n]WNkn.
N X[k]= N / 2 - 1 n=0x[2n]W 2 k n N + N / 2 - 1 n=0x[2n+1]W k ( 2 n + 1 ) N x[n]x[n]xeN2
X[k]=n=0N/21x[2n]WN2kn+n=0N/21x[2n+1]WNk(2n+1)
x[n]x[n] . Xác định vàx o [ n ] x [ 2 n + 1 ]xe[n]x[2n]xo[n]x[2n+1]
  1. WNk(2n+1)=WN2knWNk
  2. WN2kn=WN/2kn ,

điều này có thể được viết lại thành trong đó và là các biến đổi DFT của các mẫu chẵn và lẻ của . Vì vậy, chúng tôi chỉ chuyển đổi một DFT điểm đơn thành hai DFT nhỏ hơn . Điều này giúp giảm chi phí tính toán vì khi .

X[k]=n=0N/21xe[n]WN/2kn+WNkn=0N/21xo[n]WN/2kn=Xe[k]+WNkXo[k]
Xe[k]Xo[k]N2x[n]NN2
2(N2)2+N<N2
N>2

Sau đó chúng ta có thể lặp lại quy trình tương tự trên hai DFT nhỏ hơn đó. Cách tiếp cận phân chia và chinh phục này cho phép đạt được độ phức tạp của , tốt hơn so với mà chúng ta đã thực hiện với việc triển khai DFT ngây thơ (như là minh họa rất nhiều bằng câu trả lời của leftaroundabout ).O(NlogN)O(N2)


bạn có sẵn sàng liệt kê ra từng biến là gì không? Tôi khá mới mẻ này, vì vậy W, j, X(), Nkchưa có định nghĩa đối với tôi.
Seph Reed

W đã được xác định trong câu trả lời của tôi. Tôi đã cố gắng để xác định tốt hơn một số ký hiệu khác. biểu thị chỉ số trong miền tần số và chỉ số trong miền thời gian. kn
anpar

19

http://nbviewer.jupyter.org/gist/leftaroundabout/83df89a7d3bdc24373ea470fb50be629

DFT, cỡ 16

Sơ đồ các hoạt động trong một DFT kích thước 16 ngây thơ

FFT, cỡ 16

Sơ đồ các hoạt động trong một kích thước-16 radix-2 FFT

Sự khác biệt về độ phức tạp khá rõ ràng từ đó, phải không?


Đây là cách tôi hiểu FFT.

Trước hết, tôi luôn nghĩ về biến đổi Fourier trước hết là biến đổi của các hàm liên tục , tức là ánh xạ phỏng đoán . Trong ánh sáng đó, rõ ràng là không cần thiết phải đi đến cấp độ sâu nhất của Lv và vòng lặp qua các yếu tố riêng lẻ , bởi vì các yếu tố riêng lẻ của Wap là các điểm duy nhất trên dòng thực, trong đó có vô số vô hạn .FT:L2(R)L2(R)

Vì vậy, làm thế nào đến sự chuyển đổi này vẫn được xác định rõ? Chà, điều quan trọng là nó hoạt động không phải trên không gian chức năng chung mà chỉ trên không gian của các hàm có thể tích hợp (Lebesgue-, vuông-) . Bây giờ, tính tích hợp này không phải là một tài sản rất mạnh (yếu hơn nhiều so với tính khác biệt, v.v.), nhưng nó đòi hỏi chức năng này trở thành bản ghi chép cục bộ với thông tin có thể đếm được. Sự mô tả như vậy được đưa ra bởi các hệ số của Biến đổi Fourier thời gian ngắnRC . Trường hợp đơn giản nhất là chức năng của bạn liên tục và bạn chia nó thành các vùng nhỏ đến mức cơ bản là không đổi trong mỗi vùng. Sau đó, mỗi STFT có thuật ngữ zeroth mạnh nhất. Nếu bạn bỏ qua các hệ số khác (dù sao phân rã) thì mỗi miền chỉ là một điểm dữ liệu duy nhất. Trong tất cả các hệ số giới hạn giới hạn thời gian ngắn này, bạn có thể thực hiện một biến đổi Fourier riêng biệt. Trên thực tế, đó chính xác là những gì bạn làm khi thực hiện bất kỳ FT nào trên dữ liệu trong thế giới thực được đo!

Tuy nhiên, dữ liệu đo không nhất thiết phải tương ứng với một đại lượng vật lý cơ bản. Chẳng hạn, khi bạn đo một số cường độ ánh sáng , bạn thực sự chỉ đang đo biên độ của sóng điện từ có tần số quá cao để được lấy mẫu bằng ADC. Nhưng rõ ràng bạn cũng có thể tính toán DFT của tín hiệu cường độ ánh sáng được lấy mẫu, và với giá rẻ như vậy, bất chấp tần số điên cuồng của sóng ánh sáng.

Điều này có thể được hiểu là lý do quan trọng nhất FFT là giá rẻ:

Đừng bận tâm cố gắng xem các chu kỳ dao động riêng lẻ từ mức cao nhất. Thay vào đó, chỉ chuyển đổi một số thông tin cấp cao đã được xử lý trước tại địa phương.

Đó không phải là tất cả để có nó, mặc dù. Điều tuyệt vời về FFT là vẫn cung cấp cho bạn tất cả thông tin mà một DFT hoàn chỉnh sẽ cung cấp . Tức là tất cả thông tin bạn cũng sẽ nhận được khi lấy mẫu sóng điện từ chính xác của chùm sáng. Điều này có thể được thực hiện bằng cách chuyển đổi tín hiệu photodiode? - bạn có thể đo tần số ánh sáng chính xác từ đó không?

Vâng, câu trả lời là không bạn không thể. Đó là, trừ khi bạn áp dụng các thủ thuật thêm.
Trước hết, bạn cần ít nhất phải đo khoảng tần số trong các khối thời gian ngắn. Vâng, điều đó là có thể với máy quang phổ. Nhưng nó chỉ có thể lên đến một độ chính xác của , một mối quan hệ không chắc chắn tiêu biểu .Δν=1/Δt

Bằng cách có một khoảng thời gian tổng thể dài hơn, chúng ta cũng có thể thu hẹp độ không đảm bảo tần số. Và điều này thực sự có thể, nếu bạn đo cục bộ không chỉ tần số thô mà cả pha của sóng. Bạn biết rằng tín hiệu 1000 Hz sẽ có cùng pha chính xác nếu bạn nhìn vào nó một giây sau. Trong khi tín hiệu 1000,5 Hz, trong khi không thể phân biệt được ở quy mô ngắn, sẽ có pha đảo ngược một giây sau đó.

May mắn thay, thông tin pha đó rất có thể được lưu trữ trong một số phức duy nhất. Và đó là cách FFT hoạt động! Nó bắt đầu với rất nhiều biến đổi nhỏ, cục bộ. Đây là giá rẻ - vì một điều rõ ràng là vì họ chỉ sử dụng một lượng nhỏ dữ liệu, nhưng thứ hai là vì họ biết rằng, do khoảng thời gian ngắn, dù sao họ cũng không thể giải quyết tần số chính xác - vì vậy nó vẫn có giá cả phải chăng mặc dù bạn làm rất nhiều biến đổi như vậy.

Tuy nhiên, những điều này cũng ghi lại pha và từ đó bạn có thể làm cho độ phân giải tần số chính xác hơn ở cấp cao nhất. Việc chuyển đổi được yêu cầu lại rẻ, bởi vì bản thân nó không bận tâm với bất kỳ dao động tần số cao nào mà chỉ với dữ liệu tần số thấp được xử lý trước.


Yup, lập luận của tôi là một chút tròn vào thời điểm này. Chúng ta hãy gọi nó là đệ quy và chúng ta ổn ...

mối quan hệ này là không cơ học lượng tử, nhưng bất định Heisenberg có thực sự là lý do cơ bản giống nhau.


2
miêu tả hình ảnh tốt đẹp của vấn đề. :-)
robert bristow-johnson

2
Bạn không thích sơ đồ được lặp đi lặp lại ở mọi nơi và không bao giờ thực sự giải thích ở bất cứ đâu :)
Mehrdad

1
Tôi hiểu bức tranh sau khi vừa đọc câu trả lời của anpar.
JDługosz

15

Dưới đây là hình ảnh để thêm vào câu trả lời hay của Robert thể hiện "tái sử dụng" các hoạt động, trong trường hợp này là cho DFT 8 điểm. "Các yếu tố Twiddle" được biểu diễn trong sơ đồ bằng cách sử dụng ký hiệu bằng với e j 2 π n kWNnkej2πnkN

Lưu ý đường dẫn được hiển thị và phương trình bên dưới hiển thị kết quả cho tần số bin X (1), như được đưa ra bởi phương trình của Robert.

Các đường đứt nét không khác gì các đường liền nét chỉ để làm rõ vị trí của phép nối tổng.

Triển khai FFT


8

về cơ bản, trong tính toán DFT ngây thơ trực tiếp từ tổng kết:

X[k]=n=0N1x[n]ej2πnkN

Nej2πnkNNN1X[k]kX[k+1]

  1. vì vậy FFT giữ một số dữ liệu trung gian.
  2. FFT cũng sẽ sử dụng bao thanh toán cho yếu tố twiddle một chút để có thể sử dụng cùng một yếu tố cho sự kết hợp dữ liệu trung gian.

4

Tôi là một người trực quan. Tôi thích tưởng tượng FFT là một thủ thuật ma trận hơn là một thủ thuật tổng kết.

Để giải thích ở mức cao:

Một DFT ngây thơ tính toán từng mẫu đầu ra một cách độc lập và sử dụng mọi mẫu đầu vào trong mỗi tính toán (thuật toán N² cổ điển).

Một FFT phổ biến sử dụng các đối xứng và các mẫu trong định nghĩa DFT để thực hiện tính toán theo "lớp" (các lớp N log), mỗi lớp có yêu cầu thời gian không đổi trên mỗi mẫu tạo ra thuật toán N log N.

Cụ thể hơn:

Một cách để hình dung các đối xứng này là xem DFT dưới dạng đầu vào ma trận 1 × N nhân với ma trận NxN của tất cả các số mũ phức tạp của bạn. Hãy bắt đầu với trường hợp "cơ số 2". Chúng ta sẽ phân tách các hàng chẵn và lẻ của ma trận (tương ứng với các mẫu đầu vào chẵn và lẻ) và coi chúng là hai phép nhân ma trận riêng biệt cộng lại để có cùng kết quả cuối cùng.

Bây giờ hãy nhìn vào các ma trận này: trong nửa đầu, nửa bên trái giống hệt với nửa bên phải. Mặt khác, nửa bên phải là nửa bên trái x −1. Điều này có nghĩa là chúng ta chỉ thực sự phải sử dụng nửa bên trái của các ma trận này để nhân và tạo một nửa bên phải với giá rẻ bằng cách nhân với 1 hoặc −1. Tiếp theo, hãy quan sát rằng ma trận thứ hai khác với ma trận thứ nhất bởi các yếu tố giống nhau trong mỗi cột, vì vậy chúng ta có thể nhân ra và nhân nó vào đầu vào để bây giờ cả hai mẫu chẵn và lẻ đều sử dụng cùng một ma trận, nhưng yêu cầu một số nhân Đầu tiên. Và bước cuối cùng là quan sát rằng ma trận N / 2 × N / 2 kết quả này giống hệt với ma trận DFT N / 2 và chúng ta có thể làm điều này nhiều lần cho đến khi chúng ta đạt được ma trận 1 × 1 trong đó DFT là một hàm nhận dạng.

Để khái quát hóa ngoài cơ số 2, bạn có thể nhìn vào việc tách mỗi hàng thứ ba và nhìn vào ba khối cột hoặc mỗi thứ 4, v.v.

Trong trường hợp đầu vào có kích thước nguyên tố, tồn tại một phương thức để zero-pad, FFT và cắt ngắn đúng, nhưng điều đó nằm ngoài phạm vi của câu trả lời này.

Xem: http://whoiskylefinn.com/MatrixFFT.html


FFT chính , FFT khác nhau . Sử dụng zero-pad không phải là lựa chọn duy nhất. Xin lỗi, tôi chỉ tìm thấy không sử dụng đệm quá mức. Một câu hỏi nhỏ, tôi không hiểu ý của bạn là gì bởi "mỗi lớp với yêu cầu thời gian không đổi trên mỗi mẫu", nếu bạn có thể giải thích, nó sẽ rất tuyệt.
Ác

1
Xin lỗi tôi không có ý nói không đệm là cách, chỉ muốn chỉ để đọc thêm. Và "lớp" có nghĩa là đệ quy hoặc dịch từ N DFT sang 2 N / 2 DFT, với thời gian không đổi trên mỗi mẫu có nghĩa là bước này là O (N).
kylefinn

Cho đến nay, trong tất cả các mô tả, điều này có vẻ gần nhất để làm cho một vấn đề phức tạp trở nên đơn giản. Tuy nhiên, điều lớn mà nó thiếu là một ví dụ về các ma trận này. Bạn sẽ có một cái?
Seph Reed

Đã tải lên này, sẽ giúp: whoiskylefinn.com/MatrixFFT.html
kylefinn

1

DFT thực hiện nhân ma trận N ^ 2 ma trận.

Các FFT thực hiện các thủ thuật thông minh, khai thác các thuộc tính của ma trận (làm suy giảm ma trận nhân lên) để giảm chi phí tính toán.

Trước tiên chúng ta hãy xem một DFT nhỏ:

W = fft (mắt (4));

x = rand (4,1) + 1j * rand (4,1);

X numf = fft (x);

X = W * x;

khẳng định (tối đa (abs (X-X numf)) <1e-7)

Thật tuyệt vời vì vậy chúng tôi có thể thay thế các cuộc gọi MATLAB đến thư viện FFTW bằng cách nhân ma trận nhỏ (phức tạp) 4 x 4 bằng cách điền vào một ma trận từ hàm FFT. Vậy ma trận này trông như thế nào?

N = 4,

Wn = exp (-1j * 2 * pi / N),

f = ((0: N-1) '* (0: N-1))

f =

 0     0     0     0
 0     1     2     3
 0     2     4     6
 0     3     6     9

W = Wn. ^ F

W =

1 1 1 1

1 -i -1 tôi

1 -1 1 -1

1 i -1 -i

Mỗi phần tử là +1, -1, + 1j hoặc -1j. Rõ ràng, điều này có nghĩa là chúng ta có thể tránh các phép nhân phức tạp đầy đủ. Hơn nữa, cột đầu tiên giống hệt nhau, có nghĩa là chúng ta đang nhân phần tử đầu tiên của x nhiều lần với cùng một yếu tố.

Nó chỉ ra rằng các sản phẩm tenxơ Kronecker, "các yếu tố twiddle" và ma trận hoán vị trong đó chỉ số được thay đổi theo lật lại nhị phân vừa được thu gọn vừa đưa ra một viễn cảnh thay thế về cách các FFT được tính như một tập hợp các hoạt động ma trận thưa thớt.

Các dòng dưới đây là một số thập phân đơn giản về tần số (DIF) radix 2 FFT chuyển tiếp. Mặc dù các bước có vẻ rườm rà, nhưng lại thuận tiện khi sử dụng lại FFT chuyển tiếp / nghịch đảo, radix4 / split-radix hoặc decimation-in-time, trong khi là một đại diện công bằng về cách các FFT tại chỗ có xu hướng được triển khai trong thế giới thực, Tôi tin.

N = 4;

x = randn (N, 1) + 1j * randn (N, 1);

T1 = exp (-1j * 2 * pi * ([số không (1, N / 2), 0: (N / 2-1)]). '/ N),

M0 = kron (mắt (2), fft (mắt (2))),

M1 = kron (fft (mắt (2)), mắt (2)),

X = bitrevorder (x. '* M1 * diag (T1) * M0),

X numf = fft (x)

khẳng định (tối đa (abs (X (:) - X numf (:))) <1e-6)

CF Van Loan có một cuốn sách tuyệt vời về chủ đề này.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.