packages feed

histogram-fill 0.6.2.0 → 0.7.0.0

raw patch · 7 files changed

+434/−96 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Data.Histogram.ST: fillMonoid :: (PrimMonad m, Monoid a, MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> (BinValue bin, a) -> m ()
- Data.Histogram.ST: fillOne :: (PrimMonad m, Num a, MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> BinValue bin -> m ()
- Data.Histogram.ST: fillOneW :: (PrimMonad m, Num a, MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> (BinValue bin, a) -> m ()
+ Data.Histogram: First :: HistIndex b
+ Data.Histogram: Last :: HistIndex b
+ Data.Histogram: at :: (Bin bin, Unbox a) => Histogram bin a -> HistIndex bin -> a
+ Data.Histogram: maximum :: (Bin bin, Unbox a, Ord a) => Histogram bin a -> a
+ Data.Histogram: minimum :: (Bin bin, Unbox a, Ord a) => Histogram bin a -> a
+ Data.Histogram: sum :: (Bin bin, Unbox a, Num a) => Histogram bin a -> a
+ Data.Histogram.Fill: mkFoldBuilder :: (Bin bin, Unbox val) => bin -> val -> (val -> a -> val) -> HBuilder (BinValue bin, a) (Histogram bin val)
+ Data.Histogram.Fill: mkFoldBuilderG :: (Bin bin, Vector v val) => bin -> val -> (val -> a -> val) -> HBuilder (BinValue bin, a) (Histogram v bin val)
+ Data.Histogram.Generic: First :: HistIndex b
+ Data.Histogram.Generic: Last :: HistIndex b
+ Data.Histogram.Generic: at :: (Bin bin, Vector v a) => Histogram v bin a -> HistIndex bin -> a
+ Data.Histogram.Generic: maximum :: (Bin bin, Vector v a, Ord a) => Histogram v bin a -> a
+ Data.Histogram.Generic: minimum :: (Bin bin, Vector v a, Ord a) => Histogram v bin a -> a
+ Data.Histogram.Generic: sum :: (Bin bin, Vector v a, Num a) => Histogram v bin a -> a
+ Data.Histogram.ST: fill :: (PrimMonad m, MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> BinValue bin -> (a -> b -> a) -> b -> m ()

Files

Data/Histogram.hs view
@@ -12,14 +12,17 @@ -- 'Data.Histogram.Generic' but specialzed to unboxed vectors. Refer -- aforementioned module for documentation. module Data.Histogram ( -- * Immutable histogram-    -- * Data type+    -- * Immutable histograms     Histogram   , module Data.Histogram.Bin+    -- ** Constructors   , histogram   , histogramUO-  , HistIndex(..) -  , histIndex-    -- * Read histograms from string+    -- ** Conversion to other data types+  , asList+  , asVector+    -- * Serialization to strings+    -- $serialization   , readHistogram   , readFileHistogram     -- * Accessors@@ -28,10 +31,11 @@   , underflows   , overflows   , outOfRange-    -- ** Convert to other data types-  , asList-  , asVector-     -- * Modification+    -- ** Indexing+  , HistIndex(..) +  , histIndex+  , at+    -- * Transformations   , map   , bmap   , mapData@@ -42,6 +46,9 @@     -- * Folding   , foldl   , bfoldl+  , sum+  , minimum+  , maximum     -- * Slicing & rebinning   , slice   , rebin@@ -67,7 +74,7 @@ import Data.Histogram.Generic (HistIndex(..),histIndex) import Data.Histogram.Bin -import Prelude hiding (map,zip,foldl)+import Prelude hiding (map,zip,foldl,sum,maximum,minimum)   @@ -119,6 +126,9 @@          => Histogram bin a -> Vector (BinValue bin, a)  asVector = H.asVector +at :: (Bin bin, Unbox a) => Histogram bin a -> HistIndex bin -> a+at = H.at+ ---------------------------------------------------------------- -- Modify histograms ----------------------------------------------------------------@@ -148,7 +158,6 @@ convertBinning = H.convertBinning  - ---------------------------------------------------------------- -- Folding ----------------------------------------------------------------@@ -159,6 +168,14 @@ bfoldl :: (Bin bin, Unbox a) => (b -> BinValue bin -> a -> b) -> b -> Histogram bin a -> b bfoldl = H.bfoldl +sum :: (Bin bin, Unbox a, Num a) => Histogram bin a -> a+sum = foldl (+) 0++minimum :: (Bin bin, Unbox a, Ord a) => Histogram bin a -> a+minimum = H.minimum++maximum :: (Bin bin, Unbox a, Ord a) => Histogram bin a -> a+maximum = H.maximum   ----------------------------------------------------------------
Data/Histogram/Fill.hs view
@@ -32,15 +32,19 @@   , joinHBuilder   , treeHBuilder     -- * Histogram constructors+    -- ** Using unboxed vectors   , module Data.Histogram.Bin   , mkSimple   , mkWeighted   , mkMonoidal-  , mkFolder-    -- ** Generic versions+  , mkFoldBuilder+    -- ** Using generic vectors   , mkSimpleG   , mkWeightedG   , mkMonoidalG+  , mkFoldBuilderG+    -- ** Pure fold+  , mkFolder     -- * Fill histograms   , fillBuilder   , fillBuilderVec@@ -323,13 +327,24 @@ mkMonoidal = mkMonoidalG {-# INLINE mkMonoidal #-} +-- | Create most generic histogram builder.+mkFoldBuilder :: (Bin bin, Unbox val)+              => bin               -- ^ Binning algorithm+              -> val               -- ^ Initial value+              -> (val -> a -> val) -- ^ Folding function+              -> HBuilder (BinValue bin, a) (Histogram bin val)+{-# INLINE mkFoldBuilder #-}+mkFoldBuilder = mkFoldBuilderG+++ -- | Create builder. Bin content will be incremented by 1 for each --   item put into histogram mkSimpleG :: (Bin bin, G.Vector v val, Num val             ) => bin -> HBuilder (BinValue bin) (H.Histogram v bin val) mkSimpleG bin = HBuilder $ do   acc <- newMHistogram 0 bin-  return HBuilderM { hbInput  = fillOne    acc+  return HBuilderM { hbInput  = \x -> fill acc x (+) 1                    , hbOutput = freezeHist acc                    } {-# INLINE mkSimpleG #-}@@ -338,24 +353,30 @@ --   for each item put into histogram mkWeightedG :: (Bin bin, G.Vector v val, Num val               ) => bin -> HBuilder (BinValue bin,val) (H.Histogram v bin val)-mkWeightedG bin = HBuilder $ do-  acc <- newMHistogram 0 bin-  return HBuilderM { hbInput  = fillOneW acc-                   , hbOutput = freezeHist acc-                   }+mkWeightedG bin = mkFoldBuilderG bin 0 (+) {-# INLINE mkWeightedG #-}  -- | Create builder. New value wil be mappended to current content of --   a bin for each item put into histogram mkMonoidalG :: (Bin bin, G.Vector v val, Monoid val               ) => bin -> HBuilder (BinValue bin,val) (H.Histogram v bin val)-mkMonoidalG bin = HBuilder $ do-  acc <- newMHistogram mempty bin-  return HBuilderM { hbInput  = fillMonoid acc+mkMonoidalG bin = mkFoldBuilderG bin mempty mappend+{-# INLINE mkMonoidalG #-}++-- | Create most generic histogram builder.+mkFoldBuilderG :: (Bin bin, G.Vector v val)+               => bin               -- ^ Binning algorithm+               -> val               -- ^ Initial value+               -> (val -> a -> val) -- ^ Folding function+               -> HBuilder (BinValue bin, a) (H.Histogram v bin val)+{-# INLINE mkFoldBuilderG #-}+mkFoldBuilderG bin x0 f = HBuilder $ do+  acc <- newMHistogram x0 bin+  return HBuilderM { hbInput  = \(!x,!w) -> fill acc x f w                    , hbOutput = freezeHist acc                    }-{-# INLINE mkMonoidalG #-} + -- | Create histogram builder which just does ordinary pure fold. It -- is intended for use when some fold should be performed together -- with histogram filling@@ -370,13 +391,6 @@ {-# INLINE mkFolder #-}  --- mkMonoidalAcc :: (Bin bin, Unbox val, StatMonoid val a---                  ) => bin -> HBuilder (BinValue bin,a) (Histogram bin val)--- mkMonoidalAcc bin = HBuilder $ do acc <- newMHistogram mempty bin---                                   return $ HBuilderM { hbInput  = fillMonoidAccum acc---                                                      , hbOutput = freezeHist acc---                                                      }--- {-# INLINE mkMonoidalAcc #-}  ---------------------------------------------------------------- -- Actual filling of histograms
Data/Histogram/Generic.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE FlexibleContexts   #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP #-} -- | -- Module     : Data.Histogram -- Copyright  : Copyright (c) 2009, Alexey Khudyakov <alexey.skladnoy@gmail.com>@@ -9,14 +10,17 @@ --  -- Generic immutable histograms.  module Data.Histogram.Generic ( -    -- * Data type+    -- * Immutable histograms     Histogram   , module Data.Histogram.Bin+    -- ** Constructors   , histogram   , histogramUO-  , HistIndex(..) -  , histIndex-   -- * Read histograms from string+    -- ** Conversion to other data types+  , asList+  , asVector+    -- * Serialization to strings+    -- $serialization   , readHistogram   , readFileHistogram     -- * Accessors@@ -25,10 +29,11 @@   , underflows   , overflows   , outOfRange-    -- ** Convert to other data types-  , asList-  , asVector-    -- * Modification+    -- ** Indexing+  , HistIndex(..) +  , histIndex+  , at+    -- * Transformations   , map   , bmap   , mapData@@ -40,11 +45,15 @@     -- * Folding   , foldl   , bfoldl+  , sum+  , minimum+  , maximum     -- * Slicing & rebinning   , slice   , rebin   , rebinFold     -- * 2D histograms+    -- $hist2D     -- ** Slicing   , sliceAlongX   , sliceAlongY@@ -65,36 +74,33 @@  import qualified Data.Vector.Generic         as G import Data.Maybe           (fromMaybe)-import Data.Typeable        -- (Typeable(..),Typeable1(..),Typeable2(..),mkTyConApp,mkTyCon)+import Data.Typeable import Data.Vector.Generic  (Vector,(!)) import Text.Read-import Prelude       hiding (map,zip,foldl)+import Prelude       hiding (map,zip,foldl,sum,maximum,minimum) import qualified Prelude    (zip)  import Data.Histogram.Bin import Data.Histogram.Bin.Read ++ ------------------------------------------------------------------- Data type and smart constructors+-- Data type & smart constructors & conversion ----------------------------------------------------------------  -- | Immutable histogram. Histogram consists of binning algorithm,---   optional number of under and overflows, and data. +--   optional number of under and overflows, and data. Type parameter+--   have following meaning:+--+--   [@v@] type of vector used to store bin content.+--+--   [@bin@] binning. It should be instance of 'Bin'. Check that type class description for details.+--+--   [@a@] type of bin content. data Histogram v bin a = Histogram bin (Maybe (a,a)) (v a)                          deriving (Eq) --- | Point inside histogram's domain. It could be either bin index or---   bin value.-data HistIndex b-  = Index Int          -- ^ Index for a bin-  | Value (BinValue b) -- ^ Value-  deriving (Typeable)---- | Convert 'HistIndex' to actual index-histIndex :: Bin b => b -> HistIndex b -> Int-histIndex _ (Index i) = i-histIndex b (Value x) = toIndex b x- -- | Create histogram from binning algorithm and vector with -- data. Overflows are set to Nothing.  --@@ -110,11 +116,51 @@   | nBins b == G.length v = Histogram b uo v   | otherwise             = error "Data.Histogram.Generic.histogramUO: number of bins and vector size doesn't match" +-- | Convert histogram data to list.+asList :: (Vector v a, Bin bin) => Histogram v bin a -> [(BinValue bin, a)]+asList (Histogram bin _ arr) = +  Prelude.zip (fromIndex bin <$> [0..]) (G.toList arr) +-- | Convert histogram data to vector+asVector :: (Bin bin, Vector v a, Vector v (BinValue bin,a))+         => Histogram v bin a -> v (BinValue bin, a)+asVector (Histogram bin _ arr) =+  G.generate (nBins bin) $ \i -> (fromIndex bin i, arr ! i)+++ ---------------------------------------------------------------- -- Instances & reading histograms from strings  ---------------------------------------------------------------- +-- $serialization+--+-- 'Show' instance is abused for serialization and produces human+-- readable data like that: +--+-- > # Histogram+-- > # Underflows = 0+-- > # Overflows  = 88+-- > # BinI+-- > # Low  = 0+-- > # High = 9+-- > 0       99+-- > 1       91+-- > 2       95+-- > 3       81+-- > 4       92+-- > 5       105+-- > 6       90+-- > 7       79+-- > 8       91+-- > 9       89+--+-- It could be deserialize using 'readHistogram' function. 'Read'+-- instance coulde provided as well but it turned out to be+-- impractically slow.+--+-- Serialization with cereal package is provided by histogram-fill-cereal+ instance (Show a, Show (BinValue bin), Show bin, Bin bin, Vector v a) => Show (Histogram v bin a) where     show h@(Histogram bin uo _) = "# Histogram\n" ++ showUO uo ++ show bin ++                                   unlines (fmap showT $ asList h)@@ -125,9 +171,19 @@           showUO Nothing      = "# Underflows = \n" ++                                 "# Overflows  = \n" ++histTyCon :: String -> String -> TyCon+#if MIN_VERSION_base(4,4,0)+histTyCon = mkTyCon3 "histogram-fill"+#else+histTyCon m s = mkTyCon $ m ++ "." ++ s+#endif+ instance Typeable1 v => Typeable2 (Histogram v) where-  typeOf2 h = mkTyConApp (mkTyCon "Data.Histogram.Generic.Histogram") [typeOf1 (histData h)]+  typeOf2 h = mkTyConApp (histTyCon "Data.Histogram.Generic" "Histogram") [typeOf1 $ histData h] ++ -- | Vector do not supply 'NFData' instance so let just 'seq' it and --   hope it's enough. Should be enough for unboxed vectors. instance (NFData a, NFData bin) => NFData (Histogram v bin a) where@@ -165,7 +221,7 @@   ------------------------------------------------------------------- Accessors & conversion+-- Accessors ----------------------------------------------------------------  -- | Histogram bins@@ -178,31 +234,42 @@  -- | Number of underflows underflows :: Histogram v bin a -> Maybe a-underflows (Histogram _ uo _) = fst <$> uo+underflows h = fst <$> outOfRange  h  -- | Number of overflows overflows :: Histogram v bin a -> Maybe a-overflows (Histogram _ uo _) = snd <$> uo+overflows h = snd <$> outOfRange h  -- | Underflows and overflows outOfRange :: Histogram v bin a -> Maybe (a,a) outOfRange (Histogram _ uo _) = uo --- | Convert histogram data to list.-asList :: (Vector v a, Bin bin) => Histogram v bin a -> [(BinValue bin, a)]-asList (Histogram bin _ arr) = -  Prelude.zip (fromIndex bin <$> [0..]) (G.toList arr) --- | Convert histogram data to vector-asVector :: (Bin bin, Vector v a, Vector v (BinValue bin,a))-         => Histogram v bin a -> v (BinValue bin, a)-asVector (Histogram bin _ arr) =-  G.generate (nBins bin) $ \i -> (fromIndex bin i, arr G.! i)  +-- | Point inside histogram's domain. It could be either bin index or+--   bin value. 'First' and 'Last' constructors are useful for+--   histogram slicing.+data HistIndex b+  = Index Int          -- ^ Index for a bin+  | Value (BinValue b) -- ^ Value+  | First              -- ^ Bin with index 0+  | Last               -- ^ Bin maximum index.+  deriving (Typeable) +-- | Convert 'HistIndex' to actual index+histIndex :: Bin b => b -> HistIndex b -> Int+histIndex _ (Index i) = i+histIndex b (Value x) = toIndex b x+histIndex _ First     = 0+histIndex b Last      = nBins b - 1++-- | Index histogtam.+at :: (Bin bin, Vector v a) => Histogram v bin a -> HistIndex bin -> a+at (Histogram bin _ v) i = v ! histIndex bin i+ ------------------------------------------------------------------- Modify histograms+-- Transformation ----------------------------------------------------------------  -- | fmap lookalike. It's not possible to create Functor instance@@ -271,15 +338,29 @@ bfoldl f x0 (Histogram bin _ vec) =   G.ifoldl' (\acc -> f acc . fromIndex bin) x0 vec +-- | Sum contents of all bins+sum :: (Bin bin, Vector v a, Num a) => Histogram v bin a -> a+sum = foldl (+) 0 +-- | Maximal bin value+minimum :: (Bin bin, Vector v a, Ord a) => Histogram v bin a -> a+minimum = G.minimum . histData +-- | Maximal bin value+maximum :: (Bin bin, Vector v a, Ord a) => Histogram v bin a -> a+maximum = G.maximum . histData+++ ---------------------------------------------------------------- -- Slicing and reducing histograms ----------------------------------------------------------------  -- | Slice histogram. Values/indices specify inclusive --   variant. Under/overflows are discarded. If requested value falls---   out of histogram range it will be truncated.+--   out of histogram range it will be truncated. Use 'First' or+--   'Last' constructor if you need slice from first or to last bin+--   correspondingly. slice :: (SliceableBin bin, Vector v a)       => HistIndex bin          -- ^ Lower inclusive bound       -> HistIndex bin          -- ^ Upper inclusive bound@@ -330,9 +411,26 @@     off  = case dir of CutLower  -> G.length vec - n * k                        CutHigher -> 0 ++ ---------------------------------------------------------------- -- 2D histograms ----------------------------------------------------------------++-- $hist2D+--+-- Data in 2D histograms is stored in row major order. This in fact+-- dictated by implementation of 'Bin2D'. So indices of bin are+-- arranged in following pattern:+-- +-- >  0  1  2  3+-- >  4  5  6  7+-- >  8  9 10 11+--+-- Function from @AlongX@ family work with histogram slices along X+-- axis (as name suggest) which are contigous and therefor are+-- generally faster than @AlongY@ family.+  -- | Get slice of 2D histogram along X axis. This function is faster --   than 'sliceAlongY' since no array reallocations is required
Data/Histogram/ST.hs view
@@ -11,9 +11,7 @@ module Data.Histogram.ST ( -- * Mutable histograms                            MHistogram                          , newMHistogram-                         , fillOne-                         , fillOneW-                         , fillMonoid+                         , fill                          -- , fillMonoidAccum                          , unsafeFreezeHist                          , freezeHist@@ -21,7 +19,6 @@  import Control.Monad.Primitive -import Data.Monoid import qualified Data.Vector.Generic         as G import qualified Data.Vector.Generic.Mutable as M @@ -49,30 +46,23 @@   return $ MHistogram n bin a {-# INLINE newMHistogram #-} --- Generic fill-fill :: (PrimMonad m, M.MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> BinValue bin -> (a -> a) -> m ()-fill (MHistogram n bin arr) !x f-  | i <  0    = M.unsafeWrite arr  n    . f =<< M.unsafeRead arr n-  | i >= n    = M.unsafeWrite arr (n+1) . f =<< M.unsafeRead arr (n+1)-  | otherwise = M.unsafeWrite arr  i    . f =<< M.unsafeRead arr i+-- | Generic fill. It could be seen as left fold with multiple+--   accumulators where accumulator is chosen by @BinValue bin@.+fill :: (PrimMonad m, M.MVector v a, Bin bin)+     => MHistogram (PrimState m) v bin a -- ^ Mutable histogram to put value to+     -> BinValue bin                     -- ^ Value being binned+     -> (a -> b -> a)                    -- ^ Fold function+     -> b                                -- ^ Value being put into histogram+     -> m ()+fill (MHistogram n bin arr) !x f val = do+  a <- M.unsafeRead arr ix+  M.unsafeWrite arr ix $! f a val   where-    i = toIndex bin x+    i  = toIndex bin x+    ix | i <  0    = n+       | i >= n    = n+1+       | otherwise = i {-# INLINE fill #-}---- | Put one value into histogram-fillOne :: (PrimMonad m, Num a, M.MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> BinValue bin -> m ()-fillOne h !x = fill h x (+1)-{-# INLINE fillOne #-}---- | Put one value into histogram with weight-fillOneW :: (PrimMonad m, Num a, M.MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> (BinValue bin, a) -> m ()-fillOneW h (!x,!w) = fill h x (+w)-{-# INLINE fillOneW #-} ---- | Put one monoidal element-fillMonoid :: (PrimMonad m, Monoid a, M.MVector v a, Bin bin) => MHistogram (PrimState m) v bin a -> (BinValue bin, a) -> m ()-fillMonoid h (!x,!m) = fill h x (`mappend` m)-{-# INLINE fillMonoid #-}   -- | Create immutable histogram from mutable one. This operation is
histogram-fill.cabal view
@@ -1,10 +1,23 @@ Name:           histogram-fill-Version:        0.6.2.0+Version:        0.7.0.0 Synopsis:       Library for histograms creation. Description:       This is library for histograms filling. Its aim to provide   convenient way to create and fill histograms.    .+  Changes in 0.7.0.0+  .+  * mkFoldBuilder is added to @Data.Histogram.Fill@+  .+  * fill functions in @Data.Histogram.ST@ are replaced with generic+    variant.+  .+  * Indexing for immutable histograms is added and special constructor+    for first and last bin are added to @HistIndex@ data type.+  .+  * Functions to calculate sum, minimum and maximum of immutable+    histogram are added.+  .   Changes in 0.6.2.0   .   * MaybeBin added.@@ -51,7 +64,6 @@                         deepseq,                         primitive,                         vector >= 0.7---                        monoid-statistics == 0.1.*   Exposed-modules:      Data.Histogram                         Data.Histogram.Generic                         Data.Histogram.Fill
+ test/QC.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE FlexibleContexts  #-}+import Data.Typeable++import Test.QuickCheck+import Test.Framework                       (Test,testGroup,defaultMain)+import Test.Framework.Providers.QuickCheck2 (testProperty)++import Data.Histogram+import Data.Histogram.Bin.MaybeBin+import QC.Instances ()++++----------------------------------------------------------------+--+----------------------------------------------------------------+tests :: [Test]+tests =+  [ testGroup "Bins"+    [ testsBin (T :: T BinI)+    , testsBin (T :: T BinInt) +    , testsBin (T :: T (BinF Float)) +    , testsBin (T :: T (BinF Float))+    , testsBin (T :: T BinD)+    , testsBin (T :: T (BinEnum Char))+    , testsBin (T :: T LogBinD)+    , testsBin (T :: T (MaybeBin BinI))+    , testsBin (T :: T (Bin2D BinI BinI))+    ]+  , testGroup "fromIndex . toIndex == is" +    [ testProperty "BinI"    $ prop_FromTo (T :: T BinI)+    , testProperty "BinEnum" $ prop_FromTo (T :: T (BinEnum Char))+    , testProperty "Bin2D"   $ prop_FromTo (T :: T (Bin2D BinI BinI))+    ]+  , testGroup "Sliceable bins"+    [ testSliceBin (T :: T BinI)+    , testSliceBin (T :: T BinInt) +    , testSliceBin (T :: T (BinF Float)) +    , testSliceBin (T :: T (BinF Float))+    , testSliceBin (T :: T BinD)+    , testSliceBin (T :: T (BinEnum Char))+    , testSliceBin (T :: T LogBinD)+    ]      +  , testGroup "Histogram"+    [ testProperty "read . show"  (isIdentity (readHistogram . show) :: Histogram BinI Int -> Bool)+    ]+  ]++testsBin :: ( Read a, Show a, Show (BinValue a), Eq a, Typeable a+            , Bin a+            , Arbitrary a, Arbitrary (BinValue a)+            ) => T a -> Test+testsBin t+  = testGroup ("Bin test for " ++ show (typeOfT t))+  [ testProperty "read . show = id"         $ prop_ReadShow t+  , testProperty "toIndex . fromIndex = id" $ prop_ToFrom   t+  , testProperty "inRange"                  $ prop_InRange  t+  ]++testSliceBin :: ( Show b, Typeable b, SliceableBin b, Arbitrary b+                ) => T b -> Test+testSliceBin t +  = testGroup ("Slice tests for" ++ show (typeOfT t))+  [ testProperty "N of bins"  $ prop_sliceBin t+  ]+++----------------------------------------------------------------+-- Bin tests+----------------------------------------------------------------++-- > read . show == id+prop_ReadShow :: (Read a, Show a, Eq a) => T a -> a -> Bool+prop_ReadShow _ = isIdentity (read . show)++-- > toIndex . fromIndex == id+prop_ToFrom :: Bin bin => T bin -> Int -> bin -> Property+prop_ToFrom _ i bin =+  i >= 0 && i < nBins bin  ==>  isIdentity (toIndex bin . fromIndex bin) i++-- > fromIndex . toIndex == id+-- Hold only for integral bins+prop_FromTo :: (Bin bin, Eq (BinValue bin)) => T bin -> BinValue bin -> bin -> Property+prop_FromTo _ x bin =+  inRange bin x  ==>  isIdentity (fromIndex bin . toIndex bin) x++-- > inRange b x == indexInRange b x+prop_InRange :: (Bin bin) => T bin -> bin -> BinValue bin -> Bool+prop_InRange _ b x +  = inRange b x == indexInRange (toIndex b x)+  where+    indexInRange i = i >= 0  &&  i < nBins b++-- Sliced bin have correct number of bins+prop_sliceBin :: (SliceableBin b) => T b -> b -> Gen Bool+prop_sliceBin _ bin = do+  let n = nBins bin+  i <- choose (0, n-1)+  j <- choose (i, n-1)+  return $ nBins (sliceBin i j bin) == (j - i + 1)++++----------------------------------------------------------------+-- Helpers+----------------------------------------------------------------++isIdentity :: Eq a => (a -> a) -> a -> Bool+isIdentity f x = x == f x++data T a = T++paramOfT :: T a -> a+paramOfT _ = undefined++typeOfT :: Typeable a => T a -> TypeRep+typeOfT = typeOf . paramOfT++----------------------------------------------------------------+-- Main+----------------------------------------------------------------++main :: IO ()+main =+  defaultMain tests
+ test/QC/Instances.hs view
@@ -0,0 +1,82 @@+-- Yes I DO want orphans here+{-# OPTIONS_GHC -fno-warn-orphans #-}++{-# LANGUAGE FlexibleInstances #-}+module QC.Instances() where++import Control.Applicative+import Test.QuickCheck+import qualified Data.Vector.Unboxed as U++import Data.Histogram+import Data.Histogram.Bin.MaybeBin++++----------------------------------------------------------------+-- Bin instances+----------------------------------------------------------------++instance Arbitrary BinI where+  arbitrary = do+    let maxI = 100+    lo <- choose (-maxI , maxI)+    hi <- choose (lo    , maxI)+    return $ binI lo hi++instance Arbitrary BinInt where+  arbitrary = do+    let maxI = 100+    base <- choose (-maxI,maxI)+    step <- choose (1,10)+    n    <- choose (1,10^3)+    return $ BinInt base step n++instance (Arbitrary a, Ord a, Enum a) => Arbitrary (BinEnum a) where+  arbitrary = do+    l <- arbitrary+    h <- suchThat arbitrary (>= l)+    return $ binEnum l h++instance Arbitrary (BinF Float) where+  arbitrary = do+    lo <- choose (-1.0e+3-1 , 1.0e+3)+    n  <- choose (1, 10^3)+    hi <- choose (lo , 1.0e+3+1)+    return $ binF lo n hi++instance Arbitrary (BinF Double) where+  arbitrary = do+    lo <- choose (-1.0e+6-1 , 1.0e+6)+    n  <- choose (1, 10^6)+    hi <- choose (lo , 1.0e+6+1)+    return $ binF lo n hi++instance Arbitrary BinD where+  arbitrary = do+    lo <- choose (-1.0e+6-1 , 1.0e+6)+    n  <- choose (1, 10^6)+    hi <- choose (lo , 1.0e+6+1)+    return $ binD lo n hi++instance Arbitrary LogBinD where+  arbitrary = do+    lo <- choose (1.0e-6 , 1.0e+6)+    n  <- choose (1, 10^6)+    hi <- choose (lo , 1.0e+6+1)+    return $ logBinD lo n hi++instance Arbitrary bin => Arbitrary (MaybeBin bin) where+  arbitrary = MaybeBin <$> arbitrary++instance (Arbitrary bx, Arbitrary by) => Arbitrary (Bin2D bx by) where+    arbitrary = Bin2D <$> arbitrary <*> arbitrary++----------------------------------------------------------------+-- Histogram instance+----------------------------------------------------------------++instance (Bin bin, U.Unbox a, Arbitrary bin, Arbitrary a) => Arbitrary (Histogram bin a) where+    arbitrary = do+      bin <- suchThat arbitrary ((<333) . nBins)+      histogramUO bin <$> arbitrary <*> (U.fromList <$> vectorOf (nBins bin) arbitrary)