SciBaseTypes-0.1.0.0: Numeric/LogDomain.hs
-- | This module provides log-domain functionality. Ed Kmett provides, with
-- @log-domain@, a generic way to handle numbers in the log-domain, some which
-- is used under the hood here. We want some additional type safety and also
-- connect with the 'SemiRing' module.
module Numeric.LogDomain where
import Control.Monad.Except
import Numeric.Log
-- | Instances for @LogDomain x@ should be for specific types.
class LogDomain x where
-- | The type family to connect a type @x@ with the type @Ln x@ in the
-- log-domain.
type Ln x ∷ *
-- | Transport a value in @x@ into the log-domain. @logdom@ should throw an
-- exception if @log x@ is not valid.
logdom ∷ (MonadError String m) ⇒ x → m (Ln x)
-- | Unsafely transport x into the log-domain.
unsafelogdom ∷ x → Ln x
-- | Transport a value @Ln x@ back into the linear domain @x@.
lindom ∷ Ln x → x
instance LogDomain Double where
type Ln Double = Log Double
{-# Inline logdom #-}
logdom x
| x < 0 = throwError "log of negative number"
| otherwise = return $ unsafelogdom x
{-# Inline unsafelogdom #-}
unsafelogdom = Exp . log
{-# Inline lindom #-}
lindom = exp . ln