packages feed

pure-fft (empty) → 0.1.0

raw patch · 4 files changed

+166/−0 lines, 4 filesdep +basesetup-changed

Dependencies added: base

Files

+ LICENSE view
@@ -0,0 +1,26 @@+Copyright (c) Matt Morrow.+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.+3. The names of the author may not be used to endorse or promote+   products derived from this software without specific prior written+   permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,4 @@+> import Distribution.Simple+> main :: IO ()+> main = defaultMain+
+ pure-fft.cabal view
@@ -0,0 +1,21 @@+name:               pure-fft+version:            0.1.0+cabal-version:      >= 1.2+build-type:         Simple+license:            BSD3+license-file:       LICENSE+category:           Numeric, Math+author:             Matt Morrow+copyright:          Matt Morrow+maintainer:         Matt Morrow <mjm2002@gmail.com>+stability:          experimental+synopsis:           Fast Fourier Transform+description:        A pure-haskell implementation+                    of the radix-2 DIT version of+                    the Cooley-Tukey FFT algorithm.++library+  build-depends:    base+  ghc-options:      -O2+  hs-source-dirs:   src+  exposed-modules:  Numeric.FFT
+ src/Numeric/FFT.hs view
@@ -0,0 +1,115 @@+{-# OPTIONS_GHC -O2 #-}++{- |+  Module      :  Numeric.FFT+  Copyright   :  (c) Matt Morrow 2008+  License     :  BSD3+  Maintainer  :  Matt Morrow <mjm2002@gmail.com>+  Stability   :  experimental+  Portability :  portable+++  A radix-2 DIT version of+  the Cooley-Tukey FFT algorithm.+-}++module Numeric.FFT (+    fft, ifft+  , dft, idft+) where++import Data.List(foldl')+import Data.Complex(Complex(..))++-----------------------------------------------------------------------------++-- | /O(n lg n)/. A radix-2 DIT+--  (decimation-in-time) version of the+--  Cooley-Tukey FFT algorithm.+--  The length of the input list /must/+--  be a power of two, or only the prefix+--  of the list of length equal to the largest+--  power of two less than the length of the list+--  will be transformed.+fft :: [Complex Double] -> [Complex Double]+fft []    = []+fft [x,y] = dft [x,y]+fft xs    = fmap (go len ys zs) [0..len*2-1]+  where (ys,zs) = (fft***fft)+            . deinterleave $ xs+        len = length ys+        go len xs ys k+          | k <  len  = (xs!!k) + (ys!!k) * f k (len*2)+          | otherwise = let k' = k - len+              in (xs!!k') - (ys!!k') * f k' (len*2)+          where i = 0 :+ 1+                fi = fromIntegral+                f k n = exp (negate(2*pi*i*fi k)/fi n)+        (***) f g (x,y) = (f x, g y)+        deinterleave :: [a] -> ([a],[a])+        deinterleave = unzip . pairs+        pairs :: [a] -> [(a,a)]+        pairs []       = []+        pairs (x:y:zs) = (x,y) : pairs zs+        pairs _        = []+++ifft :: [Complex Double] -> [Complex Double]+ifft xs = let n = (fromIntegral . length) xs in fmap (/n) (fft xs)++-----------------------------------------------------------------------------++-- | /O(n^2)/. The Discrete Fourier Transform.+dft :: [Complex Double] -> [Complex Double]+dft xs = let len = length xs+          in zipWith (go len) [0..len-1] (repeat xs)+  where i = 0 :+ 1+        fi = fromIntegral+        go len k xs = foldl' (+) 0 . flip fmap [0..len-1]+          $ \n -> (xs!!n) * exp (negate(2*pi*i*fi n*fi k)/fi len)++idft :: [Complex Double] -> [Complex Double]+idft xs = let n = (fromIntegral . length) xs in fmap (/n) (dft xs)++-----------------------------------------------------------------------------++{-+"A radix-2 decimation-in-time (DIT) FFT is+the simplest and most common form of the+Cooley-Tukey algorithm, although highly+optimized Cooley-Tukey implementations+typically use other forms of the algorithm"++"Radix-2 DIT divides a DFT of size N into+two interleaved DFTs (hence the name "radix-2")+of size N/2 with each recursive stage."++<http://en.wikipedia.org/wiki/Cooley-Tukey_FFT_algorithm>+-}++-----------------------------------------------------------------------------++{-+[m@ganon SPHODRA]$ time ./test_fft+(-32767.999999213338) :+ (-6.835652750528328e8)++real    0m0.757s+user    0m0.729s+sys     0m0.019s+++[m@ganon SPHODRA]$ time ./test_dft+^C++real    0m21.221s+user    0m20.938s+sys     0m0.017s++import Math.FFT(fft)+main = print . last . fft . fmap fromIntegral $ [0..2^16-1]++import Math.FFT(dft)+main = print . last . dft . fmap fromIntegral $ [0..2^16-1]+-}++-----------------------------------------------------------------------------