-----------------------------------------------------------------------------
-- |
-- Module      :  DSP.Filter.FIR.Sharpen
-- Copyright   :  (c) Matthew Donadio 2003
-- License     :  GPL
--
-- Maintainer  :  m.p.donadio@ieee.org
-- Stability   :  experimental
-- Portability :  portable
--
-- Module to sharpen FIR filters
--
-- Reference: Hamming, Sect 6.6
--
-- @H'(z) = 3 * H(z)^2 - s * H(z)^3@
-- @      = H(z)^2 * (3 - 2 * H(z))@
--
-- Procedure:
--
-- (1)  Filter the signal once with H(z)
--
-- 2.  Double this
--
-- 3.  Subtract this from 3x
--
-- 4.  Filter this twice by H(z) or once by H(z)^2
--
-----------------------------------------------------------------------------

module DSP.Filter.FIR.Sharpen where

import Data.Array

import qualified DSP.Basic as Basic
import DSP.Filter.FIR.FIR

-- | Filter shaprening routine

sharpen :: (Num a, Eq a) => Array Int a -- ^ h[n]
	-> ([a] -> [a]) -- ^ function that implements the sharpened filter

sharpen :: forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
sharpen Array Int a
h [a]
x = [a]
step4
    where step1 :: [a]
step1 = forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
fir Array Int a
h [a]
x
	  step2 :: [a]
step2 = forall a b. (a -> b) -> [a] -> [b]
map (a
2forall a. Num a => a -> a -> a
*) [a]
step1
	  step3 :: [a]
step3 = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (-) (forall a b. (a -> b) -> [a] -> [b]
map (a
3forall a. Num a => a -> a -> a
*) (forall a. Num a => Int -> [a] -> [a]
Basic.delay Int
delay [a]
x)) [a]
step2
	  step4 :: [a]
step4 = forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
fir Array Int a
h forall a b. (a -> b) -> a -> b
$ forall a. (Num a, Eq a) => Array Int a -> [a] -> [a]
fir Array Int a
h forall a b. (a -> b) -> a -> b
$ [a]
step3
	  -- step4 = fir $ conv h h $ step3
	  m :: Int
m = forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall i e. Array i e -> (i, i)
bounds Array Int a
h
	  delay :: Int
delay = Int
m forall a. Integral a => a -> a -> a
`div` Int
2