module Numeric.Signal.Internal (
Convolvable(..),
Filterable(..),
freqz,
pwelch,
hilbert,
) where
import Data.Packed.Development(createVector,vec,app1,app2,app3,app4)
import Numeric.LinearAlgebra
import qualified Numeric.GSL.Fourier as F
import Foreign
import Foreign.C.Types
import Prelude hiding(filter)
type PD = Ptr Double
type PC = Ptr (Complex Double)
type PF = Ptr Float
class Convolvable a where
convolve :: a -> a -> a
class (Storable a, Container Vector a, Num (Vector a)
, Convert a, Floating (Vector a), RealElement a
, Num a)
=> Filterable a where
fromDouble :: Vector Double -> Vector a
filter_ :: Vector a
-> Vector a
-> Vector a
-> Vector a
hamming_ :: Int
-> Vector a
complex_power_ :: Vector (Complex Double)
-> Vector a
downsample_ :: Int -> Vector a -> Vector a
deriv_ :: Vector a -> Vector a
unwrap_ :: Vector a -> Vector a
polyEval_ :: Vector a
-> Vector (Complex Double)
-> Vector (Complex Double)
instance Convolvable (Vector Double) where
convolve x y = fst $ fromComplex $ F.ifft $ (F.fft (complex x) * F.fft (complex y))
convolve_vector_double c a = unsafePerformIO $ do
r <- createVector (dim a)
app3 signal_vector_double_convolve vec c vec a vec r "signalDoubleConvolve"
return r
foreign import ccall "signal-aux.h vector_double_convolve" signal_vector_double_convolve :: CInt -> PD -> CInt -> PD -> CInt -> PD -> IO CInt
instance Convolvable (Vector Float) where
convolve x y = single $ fst $ fromComplex $ F.ifft $ (F.fft (complex $ double x) * F.fft (complex $ double y))
convolve_vector_float c a = unsafePerformIO $ do
r <- createVector (dim a)
app3 signal_vector_float_convolve vec c vec a vec r "signalFloatConvolve"
return r
foreign import ccall "signal-aux.h vector_float_convolve" signal_vector_float_convolve :: CInt -> PF -> CInt -> PF -> CInt -> PF -> IO CInt
instance Convolvable (Vector (Complex Double)) where
convolve x y = F.ifft $ (F.fft x * F.fft y)
convolve_vector_complex c a = unsafePerformIO $ do
r <- createVector (dim a)
app3 signal_vector_complex_convolve vec c vec a vec r "signalComplexConvolve"
return r
foreign import ccall "signal-aux.h vector_complex_convolve" signal_vector_complex_convolve :: CInt -> PC -> CInt -> PC -> CInt -> PC -> IO CInt
instance Filterable Double where
fromDouble = id
filter_ = filterD
hamming_ = hammingD
complex_power_ = complex_powerD
downsample_ = downsampleD
deriv_ = derivD
unwrap_ = unwrapD
polyEval_ = polyEval
instance Filterable Float where
fromDouble = single
filter_ = filterF
hamming_ = hammingF
complex_power_ = complex_powerF
downsample_ = downsampleF
deriv_ = derivF
unwrap_ = unwrapF
polyEval_ c = polyEval (double c)
filterD :: Vector Double
-> Vector Double
-> Vector Double
-> Vector Double
filterD l k v = unsafePerformIO $ do
r <- createVector (dim v)
app4 signal_filter_double vec l vec k vec v vec r "signalFilter"
return r
foreign import ccall "signal-aux.h filter_double" signal_filter_double :: CInt -> PD -> CInt -> PD -> CInt -> PD -> CInt -> PD -> IO CInt
filterF :: Vector Float
-> Vector Float
-> Vector Float
-> Vector Float
filterF l k v = unsafePerformIO $ do
r <- createVector (dim v)
app4 signal_filter_float vec l vec k vec v vec r "signalFilter"
return r
foreign import ccall "signal-aux.h filter_float" signal_filter_float :: CInt -> PF -> CInt -> PF -> CInt -> PF -> CInt -> PF -> IO CInt
hilbert :: Vector Double -> Vector (Complex Double)
hilbert v = unsafePerformIO $ do
let r = complex v
app1 signal_hilbert vec r "hilbert"
return r
foreign import ccall "signal-aux.h hilbert" signal_hilbert :: CInt -> PC -> IO CInt
pwelch :: Int
-> Vector Double
-> Vector Double
pwelch w v = unsafePerformIO $ do
let r = constant 0.0 ((w `div` 2) + 1)
app2 (signal_pwelch $ fromIntegral w) vec (complex v) vec r "pwelch"
return r
foreign import ccall "signal-aux.h pwelch" signal_pwelch :: CInt -> CInt -> PC -> CInt -> PD -> IO CInt
hammingD :: Int
-> Vector Double
hammingD l
| l == 1 = constant 1.0 1
| otherwise = unsafePerformIO $ do
r <- createVector l
app1 signal_hamming_double vec r "Hamming"
return r
foreign import ccall "signal-aux.h hamming_double" signal_hamming_double :: CInt -> PD -> IO CInt
hammingF :: Int
-> Vector Float
hammingF l
| l == 1 = constant 1.0 1
| otherwise = unsafePerformIO $ do
r <- createVector l
app1 signal_hamming_float vec r "Hamming"
return r
foreign import ccall "signal-aux.h hamming_float" signal_hamming_float :: CInt -> PF -> IO CInt
freqz :: (Filterable a, Complex Double ~ ComplexOf (DoubleOf a)
,Filterable (DoubleOf a)) =>
Vector a
-> Vector a
-> Vector a
-> Vector a
freqz b a w = let k = max (dim b) (dim a)
hb = polyEval_ (postpad b k) (exp (scale (0 :+ 1) ((complex $ double w))))
ha = polyEval_ (postpad a k) (exp (scale (0 :+ 1) ((complex $ double w))))
in complex_power_ (hb / ha)
postpad v n = let d = dim v
in if d < n then join [v,(constant 0.0 (nd))]
else v
polyEval :: Vector Double
-> Vector (Complex Double)
-> Vector (Complex Double)
polyEval c z = unsafePerformIO $ do
r <- createVector (dim z)
app3 signal_real_poly_complex_eval vec c vec z vec r "polyEval"
return r
foreign import ccall "signal-aux.h real_poly_complex_eval" signal_real_poly_complex_eval :: CInt -> PD -> CInt -> PC -> CInt -> PC -> IO CInt
complex_powerD :: Vector (Complex Double)
-> Vector Double
complex_powerD v = unsafePerformIO $ do
r <- createVector (dim v)
app2 signal_complex_power_double vec v vec r "complex_power"
return r
foreign import ccall "signal-aux.h complex_power_double" signal_complex_power_double :: CInt -> PC -> CInt -> PD -> IO CInt
complex_powerF :: Vector (Complex Double)
-> Vector Float
complex_powerF v = unsafePerformIO $ do
r <- createVector (dim v)
app2 signal_complex_power_float vec v vec r "complex_power"
return r
foreign import ccall "signal-aux.h complex_power_float" signal_complex_power_float :: CInt -> PC -> CInt -> PF -> IO CInt
downsampleD :: Int -> Vector Double -> Vector Double
downsampleD n v = unsafePerformIO $ do
r <- createVector (dim v `div` n)
app2 (signal_downsample_double $ fromIntegral n) vec v vec r "downsample"
return r
foreign import ccall "signal-aux.h downsample_double" signal_downsample_double :: CInt -> CInt -> PD -> CInt -> PD -> IO CInt
downsampleF :: Int -> Vector Float -> Vector Float
downsampleF n v = unsafePerformIO $ do
r <- createVector (dim v `div` n)
app2 (signal_downsample_float $ fromIntegral n) vec v vec r "downsample"
return r
foreign import ccall "signal-aux.h downsample_float" signal_downsample_float :: CInt -> CInt -> PF -> CInt -> PF -> IO CInt
derivD :: Vector Double -> Vector Double
derivD v = unsafePerformIO $ do
r <- createVector (dim v 1)
app2 (signal_diff_double) vec v vec r "diff"
return r
foreign import ccall "signal-aux.h vector_diff_double" signal_diff_double :: CInt -> PD -> CInt -> PD -> IO CInt
derivF :: Vector Float -> Vector Float
derivF v = unsafePerformIO $ do
r <- createVector (dim v 1)
app2 (signal_diff_float) vec v vec r "diff"
return r
foreign import ccall "signal-aux.h vector_diff_float" signal_diff_float :: CInt -> PF -> CInt -> PF -> IO CInt
unwrapD :: Vector Double -> Vector Double
unwrapD v = unsafePerformIO $ do
r <- createVector $ dim v
app2 signal_unwrap_double vec v vec r "unwrap"
return r
foreign import ccall "signal-aux.h unwrap_double" signal_unwrap_double :: CInt -> PD -> CInt -> PD -> IO CInt
unwrapF :: Vector Float -> Vector Float
unwrapF v = unsafePerformIO $ do
r <- createVector $ dim v
app2 signal_unwrap_float vec v vec r "unwrap"
return r
foreign import ccall "signal-aux.h unwrap_float" signal_unwrap_float :: CInt -> PF -> CInt -> PF -> IO CInt