packages feed

dsp-0.1: DSP/Correlation.hs

-----------------------------------------------------------------------------
-- |
-- Module      :  DSP.Correlation
-- Copyright   :  (c) Matthew Donadio 2003
-- License     :  GPL
--
-- Maintainer  :  m.p.donadio@ieee.org
-- Stability   :  experimental
-- Portability :  portable
--
-- This module contains routines to perform cross- and auto-correlation.
-- These formulas can be found in most DSP textbooks.
-- 
-- In the following routines, x and y are assumed to be of the same
-- length.
--
-----------------------------------------------------------------------------

module DSP.Correlation (rxy, rxy_b, rxy_u, rxx, rxx_b, rxx_u) where

import Data.Array
import Data.Complex

-- * Functions

-- TODO: fix these routines to handle the case were x and y are different
-- lengths.

-- | raw cross-correllation

rxy :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                 -> Array a (Complex b) -- ^ y
                                 -> a                   -- ^ k
                                 -> Complex b           -- ^ R_xy[k]

rxy x y k | k >= 0 = sum [ x!(i+k) * (conjugate (y!i)) | i <- [0..(n-1-k)] ]
          | k < 0  = conjugate (rxy y x (-k))
    where n = snd (bounds x) + 1

-- | biased cross-correllation

rxy_b :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                   -> Array a (Complex b) -- ^ y
                                   -> a                   -- ^ k
                                   -> Complex b           -- ^ R_xy[k] \/ N

rxy_b x y k = (rxy x y k) / (fromIntegral n)
    where n = snd (bounds x) + 1

-- | unbiased cross-correllation

rxy_u :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                   -> Array a (Complex b) -- ^ y
                                   -> a                   -- ^ k
                                   -> Complex b           -- ^ R_xy[k] \/ (N-k)

rxy_u x y k = (rxy x y k) / (fromIntegral (n-(abs k)))
    where n = snd (bounds x) + 1

-- autocorrellation

-- We define autocorrelation in terms of the cross correlation routines.

-- | raw auto-correllation

rxx :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                 -> a                   -- ^ k
                                 -> Complex b           -- ^ R_xx[k]

rxx   x k = rxy   x x k

-- | biased auto-correllation

rxx_b :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                   -> a                   -- ^ k
                                   -> Complex b           -- ^ R_xx[k] \/ N

rxx_b x k = rxy_b x x k

-- | unbiased auto-correllation

rxx_u :: (Ix a, Integral a, RealFloat b) => Array a (Complex b) -- ^ x
                                   -> a                   -- ^ k
                                   -> Complex b           -- ^ R_xx[k] \/ (N-k)

rxx_u x k = rxy_u x x k

----------------------------------------------------------------------------
-- test routines
----------------------------------------------------------------------------

x = array (0,4) [ (0, 1 :+ 0), 
		  (1, 0 :+ 1), 
		  (2, (-1) :+  0), 
		  (3, 0 :+ (-1)), 
		  (4, 1 :+ 0) ]

y = array (0,4) [ (0, 1 :+ 0), 
		  (1, (-1) :+ 0), 
		  (2, 1 :+ 0), 
		  (3, (-1) :+ 0), 
		  (4, 1 :+ 0) ]

r = map (rxy_b x y) [ 0, 1, 2 ]

verify = r == [ (0.2 :+ 0.0), (0.0 :+ 0.0), (0.0 :+ 0.2) ]