packages feed

SciBaseTypes-0.1.0.0: Statistics/Odds.hs

-- | Provides newtypes for odds, log-odds, and discretized versions.
--
-- TODO This is currently quite ad-hoc and needs better formalization. In
-- particular in terms of wrapping and usage of @Num@ and @Semiring@.

module Statistics.Odds where

import Control.DeepSeq (NFData(..))
import Data.Aeson (FromJSON,ToJSON)
import Data.Binary (Binary)
import Data.Hashable (Hashable)
import Data.Serialize (Serialize)
import Data.Vector.Unboxed.Deriving
import GHC.Generics (Generic)

import Algebra.Structure.Semiring
import Numeric.Discretized
import Numeric.Limits



-- | Odds.

newtype Odds = Odds { getOdds ∷ Double }
  deriving (Generic,Eq,Ord,Show,Read,Num)

deriving instance Semiring Odds



-- | Encodes log-odds that have been rounded or clamped to integral numbers.
-- One advantage this provides is more efficient "maximum/minimum" calculations
-- compared to using @Double@s.
--
-- Note that these are "explicit" log-odds. Each numeric operation uses the
-- underlying operation on @Int@. If you want automatic handling, choose @Log
-- Odds@.

newtype DiscLogOdds (t∷k) = DiscLogOdds { getDiscLogOdds ∷ Discretized t }
  deriving (Generic,Eq,Ord,Show,Read)

deriving instance (Num (Discretized (t∷k))) ⇒ Num (DiscLogOdds t)

deriving instance (Semiring (Discretized (t∷k))) ⇒ Semiring (DiscLogOdds t)

derivingUnbox "DiscretizedLogOdds"
  [t| forall t . DiscLogOdds t → Int |]  [| getDiscretized . getDiscLogOdds |]  [| DiscLogOdds . Discretized |]

instance Binary    (DiscLogOdds t)
instance Serialize (DiscLogOdds t)
instance FromJSON  (DiscLogOdds t)
instance ToJSON    (DiscLogOdds t)
instance Hashable  (DiscLogOdds t)

instance (NFData (Discretized t)) ⇒ NFData (DiscLogOdds t) where
  rnf (DiscLogOdds k) = rnf k
  {-# Inline rnf #-}

instance (NumericLimits (Discretized t)) ⇒ NumericLimits (DiscLogOdds t) where
  minFinite = DiscLogOdds minFinite
  {-# Inline minFinite #-}
  maxFinite = DiscLogOdds maxFinite
  {-# Inline maxFinite #-}