module Data.Histogram.Fill (
HistBuilder(..)
, HBuilderST
, feedOne
, freezeHBuilderST
, joinHBuilderST
, joinHBuilderSTList
, treeHBuilderST
, HBuilderIO
, feedOneIO
, freezeHBuilderIO
, joinHBuilderIO
, joinHBuilderIOList
, treeHBuilderIO
, HBuilder
, joinHBuilder
, joinHBuilderList
, treeHBuilder
, toBuilderST
, toBuilderIO
, builderSTtoIO
, fillBuilder
, module Data.Histogram.Bin
, mkHist1
, mkHist
, mkHistMaybe
, mkHistWgh1
, mkHistWgh
, mkHistWghMaybe
, mkHistMonoid1
, mkHistMonoid
, mkHistMonoidMaybe
, forceInt
, forceDouble
, forceFloat
) where
import Control.Applicative ((<$>))
import Control.Monad (when)
import Control.Monad.ST
import Data.Monoid (Monoid, mempty)
import Data.Vector.Unboxed (Unbox)
import Data.Histogram
import Data.Histogram.Bin
import Data.Histogram.ST
class HistBuilder h where
modifyIn :: (a' -> a) -> h a b -> h a' b
modifyMaybe :: h a b -> h (Maybe a) b
addCut :: (a -> Bool) -> h a b -> h a b
modifyOut :: (b -> b') -> h a b -> h a b'
data HBuilderST s a b = HBuilderST { hbInput :: a -> ST s ()
, hbOutput :: ST s b
}
instance HistBuilder (HBuilderST s) where
modifyIn f h = h { hbInput = hbInput h . f }
addCut f h = h { hbInput = \x -> when (f x) (hbInput h x) }
modifyMaybe h = h { hbInput = modified }
where modified (Just x) = hbInput h x
modified Nothing = return ()
modifyOut f h = h { hbOutput = f `fmap` hbOutput h }
instance Functor (HBuilderST s a) where
fmap = modifyOut
feedOne :: HBuilderST s a b -> a -> ST s ()
feedOne = hbInput
freezeHBuilderST :: HBuilderST s a b -> ST s b
freezeHBuilderST = hbOutput
joinHBuilderST :: [HBuilderST s a b] -> HBuilderST s a [b]
joinHBuilderST hs = HBuilderST { hbInput = \x -> mapM_ (flip hbInput x) hs
, hbOutput = mapM hbOutput hs
}
joinHBuilderSTList :: [HBuilderST s a [b]] -> HBuilderST s a [b]
joinHBuilderSTList = fmap concat . joinHBuilderST
treeHBuilderST :: [HBuilderST s a b -> HBuilderST s a' b'] -> HBuilderST s a b -> HBuilderST s a' [b']
treeHBuilderST fs h = joinHBuilderST $ map ($ h) fs
data HBuilderIO a b = HBuilderIO { hbInputIO :: a -> IO ()
, hbOutputIO :: IO b
}
instance HistBuilder (HBuilderIO) where
modifyIn f h = h { hbInputIO = hbInputIO h . f }
addCut f h = h { hbInputIO = \x -> when (f x) (hbInputIO h x) }
modifyMaybe h = h { hbInputIO = modified }
where modified (Just x) = hbInputIO h x
modified Nothing = return ()
modifyOut f h = h { hbOutputIO = f `fmap` hbOutputIO h }
instance Functor (HBuilderIO a) where
fmap = modifyOut
feedOneIO :: HBuilderIO a b -> a -> IO ()
feedOneIO = hbInputIO
freezeHBuilderIO :: HBuilderIO a b -> IO b
freezeHBuilderIO = hbOutputIO
joinHBuilderIO :: [HBuilderIO a b] -> HBuilderIO a [b]
joinHBuilderIO hs = HBuilderIO { hbInputIO = \x -> mapM_ (flip hbInputIO x) hs
, hbOutputIO = mapM hbOutputIO hs
}
joinHBuilderIOList :: [HBuilderIO a [b]] -> HBuilderIO a [b]
joinHBuilderIOList = fmap concat . joinHBuilderIO
treeHBuilderIO :: [HBuilderIO a b -> HBuilderIO a' b'] -> HBuilderIO a b -> HBuilderIO a' [b']
treeHBuilderIO fs h = joinHBuilderIO $ map ($ h) fs
newtype HBuilder a b = HBuilder { toBuilderST :: (forall s . ST s (HBuilderST s a b)) }
instance HistBuilder (HBuilder) where
modifyIn f (HBuilder h) = HBuilder (modifyIn f <$> h)
addCut f (HBuilder h) = HBuilder (addCut f <$> h)
modifyMaybe (HBuilder h) = HBuilder (modifyMaybe <$> h)
modifyOut f (HBuilder h) = HBuilder (modifyOut f <$> h)
instance Functor (HBuilder a) where
fmap = modifyOut
joinHBuilder :: [HBuilder a b] -> HBuilder a [b]
joinHBuilder hs = HBuilder (joinHBuilderST <$> mapM toBuilderST hs)
joinHBuilderList :: [HBuilder a [b]] -> HBuilder a [b]
joinHBuilderList = modifyOut concat . joinHBuilder
treeHBuilder :: [HBuilder a b -> HBuilder a' b'] -> HBuilder a b -> HBuilder a' [b']
treeHBuilder fs h = joinHBuilder $ map ($ h) fs
builderSTtoIO :: HBuilderST RealWorld a b -> HBuilderIO a b
builderSTtoIO (HBuilderST i o) = HBuilderIO (stToIO . i) (stToIO o)
toBuilderIO :: HBuilder a b -> IO (HBuilderIO a b)
toBuilderIO h = builderSTtoIO `fmap` stToIO (toBuilderST h)
fillBuilder :: HBuilder a b -> [a] -> b
fillBuilder hb xs =
runST $ do h <- toBuilderST hb
mapM_ (feedOne h) xs
freezeHBuilderST h
mkHist1 :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> BinValue bin)
-> HBuilder a b
mkHist1 bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = fillOne acc . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHist :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> [BinValue bin])
-> HBuilder a b
mkHist bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = mapM_ (fillOne acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistMaybe :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> Maybe (BinValue bin))
-> HBuilder a b
mkHistMaybe bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = maybe (return ()) (fillOne acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistWgh1 :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> (BinValue bin, val))
-> HBuilder a b
mkHistWgh1 bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = fillOneW acc . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistWgh :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> [(BinValue bin, val)])
-> HBuilder a b
mkHistWgh bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = mapM_ (fillOneW acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistWghMaybe :: (Bin bin, Unbox val, Num val) =>
bin
-> (Histogram bin val -> b)
-> (a -> Maybe (BinValue bin, val))
-> HBuilder a b
mkHistWghMaybe bin out inp = HBuilder $ do
acc <- newMHistogram 0 bin
return $ HBuilderST { hbInput = maybe (return ()) (fillOneW acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistMonoid1 :: (Bin bin, Unbox val, Monoid val) =>
bin
-> (Histogram bin val -> b)
-> (a -> (BinValue bin, val))
-> HBuilder a b
mkHistMonoid1 bin out inp = HBuilder $ do
acc <- newMHistogram mempty bin
return $ HBuilderST { hbInput = fillMonoid acc . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistMonoid :: (Bin bin, Unbox val, Monoid val) =>
bin
-> (Histogram bin val -> b)
-> (a -> [(BinValue bin, val)])
-> HBuilder a b
mkHistMonoid bin out inp = HBuilder $ do
acc <- newMHistogram mempty bin
return $ HBuilderST { hbInput = mapM_ (fillMonoid acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
mkHistMonoidMaybe :: (Bin bin, Unbox val, Monoid val) =>
bin
-> (Histogram bin val -> b)
-> (a -> Maybe (BinValue bin, val))
-> HBuilder a b
mkHistMonoidMaybe bin out inp = HBuilder $ do
acc <- newMHistogram mempty bin
return $ HBuilderST { hbInput = maybe (return ()) (fillMonoid acc) . inp
, hbOutput = fmap out (freezeHist acc)
}
forceInt :: Histogram bin Int -> Histogram bin Int
forceInt = id
forceDouble :: Histogram bin Double -> Histogram bin Double
forceDouble = id
forceFloat :: Histogram bin Float -> Histogram bin Float
forceFloat = id