SciBaseTypes-0.1.1.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 Data.Info
import Algebra.Structure.Semiring
import Numeric.Discretized
import Numeric.Limits
-- | Odds.
newtype Odds = Odds { getOdds ∷ Double }
deriving (Generic,Eq,Ord,Show,Read,Num)
instance NFData Odds
deriving newtype 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 newtype instance (Num (Discretized (t∷k))) ⇒ Num (DiscLogOdds t)
deriving newtype instance (Semiring (Discretized (t∷k))) ⇒ Semiring (DiscLogOdds t)
deriving newtype instance (Fractional (Discretized (t∷k))) ⇒ Fractional (DiscLogOdds t)
deriving newtype instance (Real (Discretized (t∷k))) ⇒ Real (DiscLogOdds (t::k))
derivingUnbox "DiscretizedLogOdds"
[t| forall t . DiscLogOdds t → Int |] [| getDiscretized . getDiscLogOdds |] [| DiscLogOdds . Discretized |]
instance Binary (DiscLogOdds t)
instance Serialize (DiscLogOdds t)
instance Hashable (DiscLogOdds t)
instance ToJSON (Discretized t) ⇒ ToJSON (DiscLogOdds t) where
toJSON = toJSON . getDiscLogOdds
instance FromJSON (Discretized t) ⇒ FromJSON (DiscLogOdds t) where
parseJSON = fmap DiscLogOdds . parseJSON
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 #-}
instance Info (DiscLogOdds t) where
info = info . getDiscLogOdds