Aufgrund einer Shoutbox-Diskussion letzens mit Mars fiel auf, dass eine diskrete Fouriertransformation wohl noch nicht wirklich groß in AutoIt geschrieben wurde.
Also hab ich mich mal kurz rangesetzt.
Im Grunde ist es nichts aufregendes sondern einfach eine klassische DFT.
Vor allem ist es keine FFT. Daher keine Performancewunder erwarten.
Evtl. bastel ich da nochmal eine bei Gelegenheit dazu (ist bloß immer schwierig mit dem Nachdenken hierzu, da AutoIt keinen nativen Datentyp für komplexe Zahlen hat).
Ansonsten hier alles inkl. Beispiel:
AutoIt
#include <Array.au3>
Global $aInput[] = [0.672957, -0.453061, -0.835088, 0.980334, 0.972232, 0.640295, 0.791619, -0.042803, 0.282745, 0.153629, 0.939992, 0.588169, 0.189058, 0.461301, -0.667901, -0.314791]
$aDFT = _fourier_dft($aInput)
_ArrayDisplay($aDFT, "Ergebnis der DFT", "", 16+64, @TAB, "Realteil|Imaginärteil|Amplitude|Phase|Frequenz|Periodenlänge")
; #FUNCTION# ==========================================================================
; Name...........: _fourier_dft()
; Description ...: calculate the discrete fourier transformation for a given input vector
; Syntax.........: _fourier_dft(ByRef $aInput, Const $nFs = 1)
; Parameters ....: $aInput = 1D-Array with periodic discrete input values
; $nFs = sampling frequency - needed to calculate adjusted values for frequency and period
; Return values .: On Success: = Returns a 2D-Array [Ubound($aInput)/2+1][6] = [[real_1, img_1, amplitude_1, phase_1, freq_1, period_1], ...]
; On Failure: = Sets @Error and returns NULL
; @ERROR: = 0 = No error.
; 1 = $aInput != valid 1D-Array with values
; Author ........: AspirinJunkie
; Remarks .......: this is "only" a normal dft - not an fft. So don't expect much performance for big inputs
; Example .......: #include <Array.au3>
; Global $aInput[] = [0.672957, -0.453061, -0.835088, 0.980334, 0.972232, 0.640295, 0.791619, -0.042803, 0.282745, 0.153629, 0.939992, 0.588169, 0.189058, 0.461301, -0.667901, -0.314791]
; $aDFT = _fourier_dft($aInput)
; _ArrayDisplay($aDFT, "Ergebnis der DFT", "", 16+64, @TAB, "Realteil|Imaginärteil|Amplitude|Phase|Frequenz|Periodenlänge")
; ======================================================================================
Func _fourier_dft(ByRef $aInput, Const $nFs = 1)
Local Const $N = UBound($aInput)
If (UBound($aInput, 0) <> 1) OR ($N < 1) Then Return SetError(1, $N, NULL) ; e1: aInput != valid 1D-Array with values
Local Enum $eReal, $eImg, $eAmplitude, $ePhase, $eFrequency, $ePeriod
Local Const $Pi2N = (ACos(-1) * 2) / $N
Local $aRet[$N/2 + 1][6], $nFTemp
For $k = 0 To $N/2
For $i = 0 To $N - 1
$nFTemp = $i * $k * $Pi2N
$aRet[$k][$eReal] += $aInput[$i] * cos($nFTemp)
$aRet[$k][$eImg] -= $aInput[$i] * sin($nFTemp)
Next
$aRet[$k][$eAmplitude] = ($aRet[$k][$eReal]^2) + ($aRet[$k][$eImg]^2)
$aRet[$k][$ePhase] = atan2($aRet[$k][$eImg], $aRet[$k][$eReal])
$aRet[$k][$eFrequency] = $k * $nFs / $N
$aRet[$k][$ePeriod] = 1 / $aRet[$k][$eFrequency]
Next
Return $aRet
EndFunc
Func atan2($y, $x)
Return (2 * ATan($y / ($x + Sqrt($x * $x + $y * $y))))
EndFunc
Alles anzeigen