Skip to content

Haskell: added FFT method for convolution #396

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion contents/convolutions/code/haskell/convolution.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
import Data.Array.CArray
import Data.Complex
import Data.List (tails)
import Math.FFT (dft, idft)

convolution :: (Num a) => [a] -> [a] -> [a]
convolution x = map (sum . zipWith (*) (reverse x)) . spread
where spread = init . tails . (replicate (length x - 1) 0 ++)
where
spread = init . tails . (replicate (length x - 1) 0 ++)

convolutionFFT :: [Complex Double] -> [Complex Double] -> [Complex Double]
convolutionFFT x y = elems $ idft $ liftArray2 (*) (fft x) (fft y)
where
fft a = dft $ listArray (1, length a) a

main :: IO ()
main = do
let x = [1, 2, 1, 2, 1]
y = [2, 1, 2, 1, 2]
print $ convolution x y
print $ convolutionFFT x y
5 changes: 2 additions & 3 deletions contents/convolutions/convolutions.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ In code, this looks something like:
{% sample lang="jl" %}
[import:1-17, lang:"julia"](code/julia/conv.jl)
{% sample lang="hs" %}
[import:1-5, lang:"haskell"](code/haskell/convolution.hs)
[import:6-9, lang:"haskell"](code/haskell/convolution.hs)
{% sample lang="c"%}
[import:5-18, lang:"c_cpp"](code/c/convolutions.c)
{% sample lang="cpp"%}
Expand Down Expand Up @@ -86,8 +86,7 @@ That said, Julia has an in-built fft routine, so the code for this method could
[import:19-22, lang:"julia"](code/julia/conv.jl)
Where the `.*` operator is an element-wise multiplication.
{% sample lang="hs" %}
The FFT-based convolution in Haskell is complicated, so here is some simple julia code:
[import:19-22, lang:"julia"](code/julia/conv.jl)
[import:11-14, lang:"haskell"](code/haskell/convolution.hs)
Where the `.*` operator is an element-wise multiplication.
{% sample lang="c"%}
[import:20-30, lang:"c_cpp"](code/c/convolutions.c)
Expand Down