FFT'yi bu kadar hızlı yapan DFT ve FFT arasındaki bazı farklar nelerdir?


16

FFT'leri anlamaya çalışıyorum, işte şu ana kadar olan şey:

Bir dalga formundaki frekansların büyüklüğünü bulmak için, dalgayı aradıkları frekansla iki farklı fazda (sin ve cos) çarparak ve her birinin ortalamasını alarak bunları araştırmak gerekir. Faz, ikisiyle olan ilişkisi ile bulunur ve bunun kodu şuna benzer:

//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;
}

Bunu birçok frekansta çok hızlı bir şekilde yapmak için, FFT'ler birçok numara kullanır.

FFT'leri DFT'den çok daha hızlı hale getirmek için kullanılan bazı püf noktaları nelerdir?

PS Web'de tamamlanmış FFT algoritmalarına bakmayı denedim, ancak tüm hileler çok fazla açıklama yapmadan tek bir güzel kod parçasına yoğunlaşma eğilimindedir. Her şeyi anlayabilmem için önce ihtiyacım olan şey, bu etkili değişikliklerin her birine kavram olarak giriş niteliğindedir.

Teşekkür ederim.


7
"DFT" bir algoritmayı ifade etmez: bir matematiksel işlemi ifade eder. "FFT", bu işlemi hesaplamak için bir yöntem sınıfını ifade eder.

1
Sadece sudokod örnekte kullanımının kafa karıştırıcı olabileceğini belirtmek istedim , çünkü bu bilgisayar dünyasında iyi bilinen bir komuttur. Muhtemelen psuedocode demek istediniz.
rwfeather

1
@nwfeather Muhtemelen 'sahte kod' anlamına geliyordu.
user207421

Yanıtlar:


20

Bir noktası DFT'nin saf uygulaması temel olarak bir N × N matrisi ile çarpmadır. Bir karmaşıklık Bu sonuçlar , O ( K 2 ) .N-N-xN-Ö(N-2)

En yaygın Hızlı Fourier Dönüşümü (FFT) algoritmalarından biri radix-2 Cooley-Tukey Zamanında Decimation FFT algoritmasıdır. Bu temel bir bölünme ve fethetme yaklaşımıdır.

Önce "twiddle faktörü" nü şu şekilde tanımlayın : buradaj

WN-e-j2πN-
, sonra DFT hayali birimidir,X,[k]vex[n]ile verilir , X[k]= N - 1j-1X[k]x[n]
X[k]=Σn=0N--1x[n]WN-kn.
Eğer (ve hatta olan KN- bir tamsayıdır), toplam daha sonra aşağıdaki gibi iki toplama bölünebilir X[k]= N / 2 - 1 n=0x[2n]W 2 k n N + N / 2 - 1 n=0x[2n+1]G k ( 2 n + 1 ) KN-2
X[k]=Σn=0N-/2-1x[2n]WN-2kn+Σn=0N-/2-1x[2n+1]WN-k(2n+1)
burada bile örnekleri ile, ilk toplama fiyatları x [ 2 , n + 1 ] ve aslında bu kullanarakx[n]ikincisi nin tek örnekleriyle . Tanımlama x E [ n ] X O [ n ] x[n] vexe[n]x[2n]xÖ[n]x[2n+1]
  1. veWN-k(2n+1)=WN-2knWN-k
  2. WN-2kn=WN-/2kn

bu olarak yeniden yazılabilir

X[k]=Σn=0N-/2-1xe[n]WN-/2kn+WN-kΣn=0N-/2-1xÖ[n]WN-/2kn=Xe[k]+WN-kXÖ[k]
Xe[k]XÖ[k]N-2x[n]N-N-2
2(N-2)2+N-<N-2
N->2

Ö(N-günlükN-)Ö(N-2)


değişkenlerin her birinin ne anlama geldiğini listelemek ister misiniz? Bu oldukça yeni böylece W, j, X(), Nve khenüz bana tanımlarını yok.
Seph Reed

Wkn

19

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

DFT, boyut 16

Bir boyut-16 naif DFT'deki operasyonların şeması

FFT, boyut 16

Boyut-16 taban-2 FFT'deki operasyonların şeması

Karmaşıklıktaki fark bundan oldukça belirgindir, değil mi?


FFT'yi şu şekilde anlıyorum.

FT:L2(R,)L2(R,)

Peki bu dönüşüm nasıl hala iyi tanımlanmış? Peki, genel fonksiyon alanı üzerinde çalışmaması çok önemlidir.R,C sadece (Lebesgue-, kare-) bütünleştirilebilir fonksiyonların . Şimdi, bu bütünlük çok güçlü bir özellik değildir (farklılaşabilirlikten çok daha zayıftır), ancak işlevin “yerel olarak sayılabilir bilgilerle ayırt edilebilir hale gelmesini” talep eder. Böyle bir açıklama, kısa süreli Fourier Dönüşümünün katsayıları tarafından verilir . En basit durum, işlevinizin sürekli olması ve onu o kadar küçük bölgelere bölmenizdir ki, her birinde temel olarak sabittir. Sonra STFT'lerin her biri en güçlü şekilde sıfırıncı terime sahiptir. Diğer katsayıları (zaten azalıyorsa) yoksayarsanız, her etki alanı yalnızca tek bir veri noktasıdır. Tüm bu kısa süreli LF sınır katsayılarından, ayrık bir Fourier dönüşümü alabilirsiniz. Aslında, ölçülen gerçek dünya verileri üzerinde herhangi bir FT gerçekleştirirken tam olarak bunu yaparsınız!

Ölçülen verilerin mutlaka temel bir fiziksel miktara karşılık gelmesi gerekmez. Örneğin, bazı ışık yoğunluğunu ölçtüğünüzde, frekansı bir ADC ile örneklenemeyecek kadar yüksek olan bir elektromanyetik dalganın genliğini . Ancak, ışık dalgasının deli frekansına rağmen, örneklenmiş bir ışık yoğunluğu sinyalinin DFT'sini de hesaplayabilirsiniz.

Bu, FFT'nin ucuz olmasının en önemli nedeni olarak anlaşılabilir:

Bireysel salınım döngülerini görmeye çalışmakla uğraşmayın en yüksek seviyeden . Bunun yerine, önceden yerel olarak önceden işlenmiş olan biraz yüksek düzeydeki bilgileri dönüştürün.

Yine de hepsi bu kadar değil. FFT ile ilgili en güzel şey şudur: , size tam bir DFT'nin vereceği tüm bilgileri hala vermesidir. . Yani bir ışık huzmesinin tam elektromanyetik dalgasını örneklerken alacağınız tüm bilgiler. Bu bir fotodiyot sinyali dönüştürülerek yapılabilir mi? - Bundan kesin ışık frekansını ölçebilir misiniz?

Cevap hayır olamaz. Fazladan hileler uygulamadığınız sürece.
Her şeyden önce, kısa zaman bloklarındaki frekansı en azından kabaca ölçmeniz gerekir . Bu bir spektrografla mümkün. Ancak sadece hassasiyete kadar mümkündürΔν=1/Δt , tipik bir belirsizlik ilişkisi .

Genel olarak daha uzun bir zaman aralığına sahip olarak, frekans belirsizliğini daraltabilmeliyiz. Ve yerel olarak sadece kaba frekansı değil, aynı zamanda dalganın fazını da ölçerseniz, bu gerçekten mümkündür . Bir saniye sonra bakarsanız 1000 Hz'lik bir sinyalin aynı faza sahip olacağını biliyorsunuz. Oysa 1000,5 Hz'lik bir sinyal kısa ölçekte ayırt edilemezken, bir saniye sonra fazı tersine çevirecektir.

Neyse ki, bu faz bilgisi tek bir karmaşık sayı içinde çok iyi saklanabilir. Ve FFT böyle çalışır! Çok sayıda küçük, yerel dönüşümle başlar. Bunlar ucuzdur - bir şey için açıkçası, sadece az miktarda veri kullandıkları için, ancak ikincisi, kısa zaman aralığı nedeniyle, frekansı zaten çok kesin bir şekilde çözemediklerini bildikleri için - bu tür dönüşümleri bir sürü yapın.

Ancak bunlar fazı da kaydeder ve bundan sonra frekans çözünürlüğünü en üst düzeyde daha kesin hale getirebilirsiniz. Gerekli dönüşüm yine ucuzdur, çünkü herhangi bir yüksek frekanslı salınımla uğraşmaz, sadece önceden işlenmiş düşük frekanslı verilerle uğraşmaz.


Evet, bu noktada argümanlarım biraz dairesel. Sadece özyinelemeli diyelim ve iyiyiz ...

Bu ilişki olduğunu değil mekanik kuantum ama Heisenberg belirsizlik aslında aynı temel nedeni vardır.


2
konunun güzel resimli tasviri. :-)
robert bristow-johnson

2
Her yerde tekrarlanan ve aslında hiçbir yerde açıklanmayan diyagramları sevmiyor musunuz :)
user541686

1
Anpar'ın cevabını okuduktan sonra resmi anladım.
JDługosz

15

İşte Robert'ın operasyonların "yeniden kullanımını" gösteren iyi cevabını eklemek için bir resim, bu durumda 8 noktalı bir DFT için. "Twiddle Faktörleri", gösterimi kullanılarak şemada gösterilmiştir.WN-nkej2πnkN-

Gösterilen yolun ve altındaki denklemin, Robert denklemi tarafından verildiği gibi frekans bölmesi X (1) için sonucu gösterdiğini unutmayın.

Kesikli çizgiler yalnızca toplama birleşimlerinin nerede olduğunu netleştirmek için düz çizgilerden farklı değildir.

FFT uygulaması


8

esasen, saf DFT'yi doğrudan toplamdan hesaplarken:

X[k]=Σn=0N--1x[n]ej2πnkN-

N-ej2πnkN-N- karmaşık çarpmalar ve N--1eklemeler. ve bu sadeceX[k] ve bir örneği k. sonra saf DFT tüm ara verileri atar veX[k+1].

  1. böylece FFT bazı ara verilere dayanır.
  2. FFT, aynı faktörün bir ara veri kombinasyonu için kullanılabilmesi için, döndürme faktörünü biraz çarpanlarına ayırmayı da kullanacaktır.

4

Ben görsel bir insanım. FFT'yi bir toplama hilesi yerine bir matris hilesi olarak hayal etmeyi tercih ediyorum.

Üst düzeyde açıklamak için:

Saf bir DFT, her çıktı örneğini bağımsız olarak hesaplar ve her hesaplamadaki her girdi örneğini (klasik N² algoritması) kullanır.

Ortak bir FFT, "katmanlar" (log N katmanları) içindeki hesaplamayı yapmak için DFT tanımındaki simetrileri ve desenleri kullanır, her katman bir N log N algoritması oluşturan örnek başına sabit zaman gereksinimine sahiptir.

Daha fazla özellik:

Bu simetrileri görselleştirmenin bir yolu, DFT'ye , tüm karmaşık üslerinizin bir NxN matrisi ile çarpılan 1 × N matris girişi olarak bakmaktır . "Radix 2" kasası ile başlayalım. Matrisin çift ve tek satırlarını (çift ve tek giriş örneklerine karşılık gelir) ayıracağız ve aynı nihai sonucu elde etmek için bir araya getiren iki ayrı matris çarpımı olarak düşüneceğiz.

Şimdi bu matrislere bakın: ilkinde sol yarısı sağ yarısı ile aynıdır. Diğerinde, sağ yarısı sol yarısı x left1'dir. Bu, bu matrislerin sol yarısını çarpma için gerçekten kullanmamız ve sağ yarıyı 1 veya −1 ile çarparak ucuza yaratmamız gerektiği anlamına gelir. Daha sonra, ikinci matrisin ilk matristen her sütunda aynı olan faktörlerle farklı olduğunu gözlemleyin, bu yüzden bunu hesaplayabilir ve girişe çarparız, böylece hem çift hem de tek örnekler aynı matrisi kullanır, ancak bir çarpan gerektirir ilk. Ve son adım, ortaya çıkan bu N / 2 × N / 2 matrisinin bir N / 2 DFT matrisiyle aynı olduğunu ve DFT'nin bir kimlik fonksiyonu olduğu 1 × 1 matrise ulaşana kadar bunu tekrar tekrar yapabiliriz.

Yarıçap 2'nin ötesinde genelleme yapmak için, her üç sırayı bölmeye ve üç sütun parçasına veya her 4'e vb. Bakabilirsiniz.

Asal boyutlu girişler durumunda, düzgün sıfırlama, FFT ve kesme için bir yöntem vardır, ancak bu, bu cevabın kapsamı dışındadır.

Bkz. Http://whoiskylefinn.com/MatrixFFT.html


ana FFT , çeşitli FFT . Sıfır pedi kullanmak tek seçenek değildir. Üzgünüm, sadece sıfır dolguyu aşırı kullanıyorum. Küçük bir soru, "örnek başına sabit zaman gereksinimi olan her katman" ile ne demek istediğinizi anlamıyorum, açıklayabilirseniz, harika olurdu.
Evil

1
Üzgünüm sıfır dolgu demek olduğunu kastetmedim, sadece daha fazla okumaya işaret etmek istedim. Ve "tabaka", bir özyineleme anlamına gelir veya bir N DFT'den 2 N / 2 DFT'ye bir çeviri anlamına gelir; örnek başına sabit zaman, bu adımın O (N) olduğu anlamına gelir.
kylefinn

Şimdiye kadar, tüm açıklamalardan, bu karmaşık bir konuyu basitleştirmeye en yakın görünüyor. Ancak eksik olan en büyük şey bu matrislere bir örnektir. Bir tane olur mu?
Seph Reed


1

DFT kaba kuvvet N ^ 2 matrisini çarpar.

FFT'ler, hesaplama maliyetini azaltmak için matrisin özelliklerinden (matrisin çoğalmasını deforme ederek) akıllıca hileler yapar.

Önce küçük bir DFT'ye bakalım:

W = FFT (göz (4));

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

X_ref = fft (x);

X = G * x;

onaylama (maks. (abs (X-X_ref)) <1e-7)

Harika, bu nedenle, FFT işlevinden bir matrisi doldurarak küçük bir 4x4 (karmaşık) matris çarpımı ile FFTW kütüphanesine çağrı yapan MATLAB'ların yerine geçebiliyoruz. Peki bu matris neye benziyor?

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 i

1 -1 1 -1

1 i -1 -i

Her eleman ya +1, -1, + 1j ya da -1j'dir. Açıkçası, bu tam karmaşık çarpmalardan kaçınabileceğimiz anlamına gelir. Ayrıca, ilk sütun aynıdır, yani x'in ilk elemanını tekrar tekrar aynı faktörle çarpıyoruz.

Kronecker tensör ürünlerinin, "twiddle faktörlerinin" ve endeksin ters çevrilmiş ikili temsile göre değiştirildiği permütasyon matrisinin hem kompakt olduğu hem de FFT'lerin bir dizi seyrek matris işlemi olarak nasıl hesaplandığına alternatif bir bakış açısı sağladığı ortaya çıkıyor.

Aşağıdaki satırlar, Frekans (DIF) yarıçapı 2 ileri FFT'de basit bir Decimation'dur. Adımlar hantal gibi görünse de, yerinde FFT'lerin gerçek dünyada nasıl uygulandığının adil bir temsili iken, ileri / ters FFT, radix4 / split-radix veya zaman içinde decimation için yeniden kullanmak uygundur, İnanıyorum.

N = 4;

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

T1 = exp (-1j * 2 * pi * ([sıfırlar (1, N / 2), 0: (N / 2-1)]). '/ N),

M0 = kron (göz (2), fft (göz (2))),

M1 = kron (fft (göz (2)), göz (2)),

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

X_ref = FFT (x)

Assert (maks (abs (X () - X_ref (:))) <1e-6)

CF Van Loan'ın bu konuda harika bir kitabı var.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.