dsp-0.1: Numeric/Transform/Fourier/FFTUtils.hs
-----------------------------------------------------------------------------
-- |
-- Module : Numeric.Transform.Fourier.FFTUtils
-- Copyright : (c) Matthew Donadio 2003
-- License : GPL
--
-- Maintainer : m.p.donadio@ieee.org
-- Stability : experimental
-- Portability : portable
--
-- Utility functions based on the FFT
--
-----------------------------------------------------------------------------
module Numeric.Transform.Fourier.FFTUtils (fft_mag, fft_db, fft_phase, fft_grd, fft_info,
rfft_mag, rfft_db, rfft_phase, rfft_grd, rfft_info,
write_fft_info, write_rfft_info) where
import System.IO
import Data.Array
import Data.Complex
import Numeric.Transform.Fourier.FFT
import DSP.Unwrap
magsq (x:+y) = x*x + y*y
log10 0 = -1.0e9
log10 x = logBase 10 x
dot a b = realPart a * realPart b + imagPart a * imagPart b
eps = 1.0e-1 :: Double
-- General functions
fft_mag x = fmap magnitude $ fft $ x
fft_db x = fmap (10 *) $ fmap log10 $ fmap magsq $ fft $ x
fft_phase x = unwrap eps $ fmap phase $ fft $ x
fft_grd x = listArray (bounds x') [ dot (x'!i) (dx'!i) / magsq (x'!i) | i <- indices x' ]
where x' = fft x
dx' = fft $ listArray (bounds x) [ fromIntegral i * x!i | i <- indices x ]
fft_info x = (mag,db,arg,grd)
where x' = fft x
dx' = fft $ listArray (bounds x) [ fromIntegral i * x!i | i <- indices x ]
mag = fmap magnitude $ x'
db = fmap (10 *) $ fmap log10 $ fmap magsq $ x'
arg = unwrap eps $ fmap phase $ x'
grd = listArray (bounds x') [ dot (x'!i) (dx'!i) / magsq (x'!i) | i <- indices x' ]
rfft_mag x = fmap magnitude $ rfft $ x
rfft_db x = fmap (10 *) $ fmap log10 $ fmap magsq $ rfft $ x
rfft_phase x = unwrap eps $ fmap phase $ rfft $ x
rfft_grd x = listArray (bounds x') [ dot (x'!i) (dx'!i) / magsq (x'!i) | i <- indices x' ]
where x' = rfft x
dx' = rfft $ listArray (bounds x) [ fromIntegral i * x!i | i <- indices x ]
dot a b = realPart a * realPart b + imagPart a * imagPart b
-- I/O
rfft_info x = (mag,db,arg,grd)
where x' = rfft x
dx' = rfft $ listArray (bounds x) [ fromIntegral i * x!i | i <- indices x ]
mag = fmap magnitude $ x'
db = fmap (10 *) $ fmap log10 $ fmap magsq $ x'
arg = unwrap eps $ fmap phase $ x'
grd = listArray (bounds x') [ dot (x'!i) (dx'!i) / magsq (x'!i) | i <- indices x' ]
hPrintIndex h n (i,x) = do
hPutStr h $ show (fromIntegral i / fromIntegral n)
hPutStr h $ " "
hPutStrLn h $ show x
write_cvector f x = do
let n = (snd $ bounds x) + 1
h <- openFile f WriteMode
sequence $ map (hPrintIndex h n) $ assocs $ x
hClose h
write_fft_info b x = do
let (mag,db,arg,grd) = fft_info x
write_cvector (b ++ "_mag.out") mag
write_cvector (b ++ "_db.out") mag
write_cvector (b ++ "_arg.out") mag
write_cvector (b ++ "_grd.out") mag
write_rvector f x = do
let n = (snd $ bounds x) + 1
h <- openFile f WriteMode
sequence $ map (hPrintIndex h n) $ take (n `div` 2) $ assocs $ x
hClose h
write_rfft_info b x = do
let (mag,db,arg,grd) = rfft_info x
write_rvector (b ++ "_mag.out") mag
write_rvector (b ++ "_db.out") db
write_rvector (b ++ "_arg.out") arg
write_rvector (b ++ "_grd.out") grd