2016-05-17 7 views
-1

Ich versuche DFT und seine Inversion zu berechnen, für jetzt mit der einfachsten Methode möglich, aber es funktioniert nicht. Und was noch schlimmer ist, ich bin mir nicht sicher. Hier ist mein Code:Computing DFT per Definition mit C++

(realnum ist doppelt, freq_func und time_func sind Vektoren komplexer)

freq_func toFreq(const time_func & waveform) 
{ 
    freq_func res; 
    res.resize(waveform.size()); 

    const realnum N = spectrum.size(); 

    for (size_t k = 0; k < waveform.size(); k++) 
     for (size_t n = 0; n < waveform.size(); n++) 
      res[k] += waveform[n] * exp(complex(0, -2*PI*n*k/N)); 

    return res; 
} 


time_func toTime(const freq_func & spectrum) 
{ 

    freq_func res; 
    res.resize(spectrum.size()); 

    const realnum N = spectrum.size(); 

    for (size_t n = 0; n < spectrum.size(); n++) 
    { 
     for (size_t k = 0; k < spectrum.size(); k++) 
      res[n] += spectrum[k] * exp(complex(0, 2*PI*n*k/N)); 
     res[n] /= N; 
    } 

    return res; 
} 

Warum es nie ein = Totime (toFreq (a)) halten noch a = toFreq (Totime (ein))? Warum liefert toTime Ergebnisse mit beträchtlichen Imaginärteilen? Oder sollte es? Einige der Online-Rechner tun dies. Und warum behauptet Wikipedia, dass die Teilung durch N nach toFreq verschoben werden kann, oder sogar durch die Division durch 1/sqrt (N), sollte es nicht nur eine mögliche Definition geben?

+0

Wenn Sie ein komplexes Debugging-Problem haben, versuchen Sie, es in eine Reihe einfacherer Probleme zu bringen, bevor Sie es auf stackoverflow veröffentlichen. Versuchen Sie zum Beispiel, einige Komponententests zu schreiben, dass 'exp (complex (...))' wirklich tut, was Sie denken, dass es ist, Sie könnten überrascht sein. Wenn ja, dann hätten Sie ein viel einfacheres Problem mit Ihren Händen. Wenn nicht, fügen Sie solche Informationen in Ihre Frage ein. Ihr Codebeispiel sollte eigenständig sein - ich sollte es kopieren und einfügen und dann kompilieren können. Wenn nicht, wie wird es jemand anderes debuggen. –

+0

Wenn es sich bei Ihrer Frage wirklich um das Format der Fourier-Transformationsdefinition handelt, ist das eine mathematische Frage und höchstwahrscheinlich ein off-topic auf SO. –

Antwort

0

Der Ausdruck complex(0, 2*PI*n*k/N) erstellt und initialisiert eine Anzahl complex mit Realteil-Set zum 0 und Imaginärteil Satz 2*PI*n*k/N. Um die DFT zu implementieren, möchten Sie wirklich eine komplexe Zahl verwenden, deren Größe 1 ist, und Phase ist 2*PI*n*k/N. Sie können dies mit:

complex(polar(1,2*PI*n*k/N)) 

für die Vorwärtstransformation und

complex(polar(1,-2*PI*n*k/N)) 

für die inverse Transformation.

Soweit der Wikipedia-Anspruch betroffen ist, ist es einfach eine Frage der Definition der DFT. Unterschiedliche Implementierungen können unterschiedliche Definitionen und damit eine Skalierung nach verschiedenen Faktoren wählen. Normalisierte DFTs wählen die Vorwärts- und die Rücktransformation, so dass ein Umlauf die ursprüngliche Sequenz erzeugt (z. B. x == toTime (toFreq (x))). Andere nicht normalisierte DFTs können eine andere Skalierung wählen (z. B. um einige Skalierungsoperationen zu speichern, wenn die Skalierung für die vorliegende Anwendung nicht wichtig ist).