From 95a28111e90f15e21e55a924275a51895cb4086d Mon Sep 17 00:00:00 2001 From: Jie Date: Tue, 30 Oct 2018 15:36:50 +0900 Subject: [PATCH] Added DFT and re-wrote FFT (#397) --- contents/cooley_tukey/code/haskell/fft.hs | 40 ++++++++++++++--------- contents/cooley_tukey/cooley_tukey.md | 4 +-- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/contents/cooley_tukey/code/haskell/fft.hs b/contents/cooley_tukey/code/haskell/fft.hs index 2c3eb11ba..579e56e6d 100644 --- a/contents/cooley_tukey/code/haskell/fft.hs +++ b/contents/cooley_tukey/code/haskell/fft.hs @@ -1,22 +1,32 @@ import Data.Complex -import Data.Array -import Data.Ratio +import Data.List (partition) +import Data.Map ((!)) import qualified Data.Map as M +import Data.Ratio + +dft :: [Complex Double] -> [Complex Double] +dft x = matMult dftMat x + where + n = length x + w = exp $ (-2) * pi * (0 :+ 1) / fromIntegral n + dftMat = [[w ^ (j * k) | j <- [0 .. n - 1]] | k <- [0 .. n - 1]] + matMult m x = map (sum . zipWith (*) x) m fft :: [Complex Double] -> [Complex Double] -fft x = let n = length x - i = 0 :+ 1 - w = M.fromList [(k%n, exp ((-2)*pi*i*(fromIntegral k)/(fromIntegral n)) ) | k<-[0..n-1]] - arr = fft' n w (listArray (0,n-1) x) - in [arr!k | k<-[0..n-1]] +fft x = fft' x where - fft' 1 _ x = x - fft' n w x = let n2 = div n 2 - e = fft' n2 w (listArray (0, n2-1) [x!k | k<-[0,2..n-1]]) - o = fft' n2 w (listArray (0, n2-1) [x!k | k<-[1,3..n-1]]) - in array (0, n-1) $ concat [[(k, e!k + o!k * w M.!(k%n)), - (k + n2, e!k - o!k * w M.!(k%n))] - | k <- [0..n2-1]] + n = length x + w0 = exp ((-2) * pi * (0 :+ 1) / fromIntegral n) + w = M.fromList [(k % n, w0 ^ k) | k <- [0 .. n - 1]] + fft' [x] = [x] + fft' x = + let (evens, odds) = partition (even . fst) $ zip [0 ..] x + e = fft' $ map snd evens + o = fft' $ map snd odds + x1 = zipWith3 (\e o k -> e + o * w ! (k %n)) e o [0 ..] + x2 = zipWith3 (\e o k -> e - o * w ! (k %n)) e o [0 ..] + in x1 ++ x2 main = do - print $ fft [0,1,2,3] + print $ dft [0, 1, 2, 3] + print $ fft [0, 1, 2, 3] diff --git a/contents/cooley_tukey/cooley_tukey.md b/contents/cooley_tukey/cooley_tukey.md index 4710bf052..c2a7434ab 100644 --- a/contents/cooley_tukey/cooley_tukey.md +++ b/contents/cooley_tukey/cooley_tukey.md @@ -78,7 +78,7 @@ For some reason, though, putting code to this transformation really helped me fi {% sample lang="cpp" %} [import:23-33, lang:"c_cpp"](code/c++/fft.cpp) {% sample lang="hs" %} -[import:4-13, lang:"julia"](code/julia/fft.jl) +[import:7-13, lang:"haskell"](code/haskell/fft.hs) {% sample lang="py" %} [import:5-11, lang:"python"](code/python/fft.py) {% sample lang="scratch" %} @@ -125,7 +125,7 @@ In the end, the code looks like: {% sample lang="cpp" %} [import:36-66, lang:"c_cpp"](code/c++/fft.cpp) {% sample lang="hs" %} -[import:6-19, lang:"haskell"](code/haskell/fft.hs) +[import:15-28, lang:"haskell"](code/haskell/fft.hs) {% sample lang="py" %} [import:13-24, lang:"python"](code/python/fft.py) {% sample lang="scratch" %}