{-# LANGUAGE NoMonomorphismRestriction #-}
module Entropy.Features 
    ( features 
    , X
    )
where
import Prelude hiding (sum)
import ListZipper hiding (at)
import Data.List (foldl')
import qualified Data.Map as Map
import SparseVector (elems,scale)
import Data.Monoid (mappend)

at i (x:xs) | i > 1 = at (i-1) xs
            | i == 1 = Just x
at i []     = Nothing
    
type X = Map.Map Int (Map.Map String Double)

features :: ListZipper String -> X
features z = 
    let fs = [ 
               (0 , focus z )
             , (-2, at 2 . left $ z )
             , (-1, at 1 . left $ z )
             , (-12, mappend (at 2 . left $ z) (at 1 . left $ z ))
             , (12,  flip mappend (at 2 . right $ z) (at 1 . right $ z ))
             , (1,  at 1 . right $ z ) 
             , (2,  at 2 . right $ z ) 
             ]
    in --  unit 
       -- . weight . 
      Map.fromList 
       $ [ (k, Map.singleton v 1) | (k,Just v) <- fs ] 
 
sum = foldl' (+) 0

unit v = v `scale` (1 / (sum (elems v)))

gaussian x sigma mu =
    1 / ((sigma * (sqrt (2 *pi))) *  (exp (negate (x-mu)^2 / (2 * sigma^2))))

weight = Map.mapWithKey $ \ k x -> x `scale` gaussian (fromIntegral k) 1 0