{-# LANGUAGE FlexibleInstances #-} module HaskellWorks.Data.Excess.MinMaxExcess0 ( MinMaxExcess0(..) , MaxExcess , MinExcess ) where import Data.Word import HaskellWorks.Data.Bits.BitWise import HaskellWorks.Data.Bits.FixedBitSize import HaskellWorks.Data.Excess.Triplet import HaskellWorks.Data.Naive import qualified Data.Vector.Storable as DVS type MinExcess = Int type MaxExcess = Int class MinMaxExcess0 a where minMaxExcess0 :: a -> Triplet instance MinMaxExcess0 [Bool] where minMaxExcess0 = go 0 0 0 where go minE maxE allE (x:xs) = let ne = if x then allE - 1 else allE + 1 in go (minE `min` ne) (maxE `max` ne) ne xs go minE maxE allE _ = Triplet minE allE maxE {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (Naive Word8) where minMaxExcess0 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE - 1 else allE + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (Naive Word16) where minMaxExcess0 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE - 1 else allE + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (Naive Word32) where minMaxExcess0 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE - 1 else allE + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (Naive Word64) where minMaxExcess0 = go 0 0 0 0 . naive where go minE maxE allE n w | n < fixedBitSize w = let ne = if w .?. fromIntegral n then allE - 1 else allE + 1 in go (minE `min` ne) (maxE `max` ne) ne (n + 1) w go minE maxE allE _ _ = Triplet minE allE maxE {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word8 where minMaxExcess0 w = Triplet (word8Excess0Min DVS.! fromIntegral w) (word8Excess0 DVS.! fromIntegral w) (word8Excess0Max DVS.! fromIntegral w) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word16 where minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA)) (allExcessA + allExcessB) (maxExcessA `max` (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word8) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 8) :: Word8) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word32 where minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA)) (allExcessA + allExcessB) (maxExcessA `max` (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word16) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 16) :: Word16) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 Word64 where minMaxExcess0 w = Triplet (minExcessA `min` (minExcessB + allExcessA)) (allExcessA + allExcessB) (maxExcessA `max` (maxExcessB + allExcessA)) where Triplet minExcessA allExcessA maxExcessA = minMaxExcess0 (fromIntegral w :: Word32) Triplet minExcessB allExcessB maxExcessB = minMaxExcess0 (fromIntegral (w .>. 32) :: Word32) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word8) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word8 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in Triplet (minE `min` (wMinE + allE)) ( wAllE + allE ) (maxE `max` (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word16) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word16 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in Triplet (minE `min` (wMinE + allE)) ( wAllE + allE ) (maxE `max` (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word32) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word32 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in Triplet (minE `min` (wMinE + allE)) ( wAllE + allE ) (maxE `max` (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} instance MinMaxExcess0 (DVS.Vector Word64) where minMaxExcess0 = DVS.foldl' gen (Triplet 0 0 0) where gen :: Triplet -> Word64 -> Triplet gen (Triplet minE allE maxE) w = let Triplet wMinE wAllE wMaxE = minMaxExcess0 w in Triplet (minE `min` (wMinE + allE)) ( wAllE + allE ) (maxE `max` (wMaxE + allE)) {-# INLINE minMaxExcess0 #-} word8Excess0Min :: DVS.Vector Int word8Excess0Min = DVS.fromList [ 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5 , 0, -1, -1, -3, -1, -3, -3, -5, -1, -3, -3, -5, -3, -5, -5, -7 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, -1, -3, -1, -3, -3, -5 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 0, -1, 0, -2, 0, -1, -1, -3, 0, -1, 0, -2, 0, -2, -2, -4 , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 0, -1, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8 ] word8Excess0 :: DVS.Vector Int word8Excess0 = DVS.fromList [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 0, -2 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 4, 2, 2, 0, 2, 0, 0, -2, 2, 0, 0, -2, 0, -2, -2, -4 , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 2, 0, 0, -2, 0, -2, -2, -4, 0, -2, -2, -4, -2, -4, -4, -6 , 0, -2, -2, -4, -2, -4, -4, -6, -2, -4, -4, -6, -4, -6, -6, -8 ] word8Excess0Max :: DVS.Vector Int word8Excess0Max = DVS.fromList [ 8, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 2, 4, 2, 2, 0 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 7, 5, 5, 3, 5, 3, 3, 1, 5, 3, 3, 1, 3, 1, 1, 0 , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 6, 4, 4, 2, 4, 2, 2, 0, 4, 2, 2, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 5, 3, 3, 1, 3, 1, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 , 4, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 0, 2, 0, 1, 0 ]