log-domain-0.12: Log-domain arithmetic

Copyright (c) Edward Kmett 2013-2015 BSD3 Edward Kmett experimental non-portable Trustworthy Haskell98

Numeric.Log

Description

Synopsis

# Documentation

newtype Log a Source #

Log-domain Float and Double values.

Constructors

 Exp Fieldsln :: a

Instances

 Source # Methods(>>=) :: Log a -> (a -> Log b) -> Log b #(>>) :: Log a -> Log b -> Log b #return :: a -> Log a #fail :: String -> Log a # Source # Methodsfmap :: (a -> b) -> Log a -> Log b #(<\$) :: a -> Log b -> Log a # Source # Methodspure :: a -> Log a #(<*>) :: Log (a -> b) -> Log a -> Log b #(*>) :: Log a -> Log b -> Log b #(<*) :: Log a -> Log b -> Log a # Source # Methodsfold :: Monoid m => Log m -> m #foldMap :: Monoid m => (a -> m) -> Log a -> m #foldr :: (a -> b -> b) -> b -> Log a -> b #foldr' :: (a -> b -> b) -> b -> Log a -> b #foldl :: (b -> a -> b) -> b -> Log a -> b #foldl' :: (b -> a -> b) -> b -> Log a -> b #foldr1 :: (a -> a -> a) -> Log a -> a #foldl1 :: (a -> a -> a) -> Log a -> a #toList :: Log a -> [a] #null :: Log a -> Bool #length :: Log a -> Int #elem :: Eq a => a -> Log a -> Bool #maximum :: Ord a => Log a -> a #minimum :: Ord a => Log a -> a #sum :: Num a => Log a -> a #product :: Num a => Log a -> a # Source # Methodstraverse :: Applicative f => (a -> f b) -> Log a -> f (Log b) #sequenceA :: Applicative f => Log (f a) -> f (Log a) #mapM :: Monad m => (a -> m b) -> Log a -> m (Log b) #sequence :: Monad m => Log (m a) -> m (Log a) # Source # MethodsserializeWith :: MonadPut m => (a -> m ()) -> Log a -> m () #deserializeWith :: MonadGet m => m a -> m (Log a) # Source # Methodsextract :: Log a -> a #duplicate :: Log a -> Log (Log a) #extend :: (Log a -> b) -> Log a -> Log b # Source # Methods(<@>) :: Log (a -> b) -> Log a -> Log b #(@>) :: Log a -> Log b -> Log b #(<@) :: Log a -> Log b -> Log a # Source # Methodsdistribute :: Functor f => f (Log a) -> Log (f a) #collect :: Functor f => (a -> Log b) -> f a -> Log (f b) #distributeM :: Monad m => m (Log a) -> Log (m a) #collectM :: Monad m => (a -> Log b) -> m a -> Log (m b) # Source # MethodsliftHashWithSalt :: (Int -> a -> Int) -> Int -> Log a -> Int # Source # Methodstraverse1 :: Apply f => (a -> f b) -> Log a -> f (Log b) #sequence1 :: Apply f => Log (f b) -> f (Log b) # Source # Methods(<.>) :: Log (a -> b) -> Log a -> Log b #(.>) :: Log a -> Log b -> Log b #(<.) :: Log a -> Log b -> Log a # Source # Methods(>>-) :: Log a -> (a -> Log b) -> Log b #join :: Log (Log a) -> Log a # Source # Methodsduplicated :: Log a -> Log (Log a) #extended :: (Log a -> b) -> Log a -> Log b # Source # Methodsfold1 :: Semigroup m => Log m -> m #foldMap1 :: Semigroup m => (a -> m) -> Log a -> m #toNonEmpty :: Log a -> NonEmpty a # (RealFloat a, Unbox a) => Vector Vector (Log a) Source # MethodsbasicUnsafeFreeze :: PrimMonad m => Mutable Vector (PrimState m) (Log a) -> m (Vector (Log a)) #basicUnsafeThaw :: PrimMonad m => Vector (Log a) -> m (Mutable Vector (PrimState m) (Log a)) #basicLength :: Vector (Log a) -> Int #basicUnsafeSlice :: Int -> Int -> Vector (Log a) -> Vector (Log a) #basicUnsafeIndexM :: Monad m => Vector (Log a) -> Int -> m (Log a) #basicUnsafeCopy :: PrimMonad m => Mutable Vector (PrimState m) (Log a) -> Vector (Log a) -> m () #elemseq :: Vector (Log a) -> Log a -> b -> b # Unbox a => MVector MVector (Log a) Source # MethodsbasicLength :: MVector s (Log a) -> Int #basicUnsafeSlice :: Int -> Int -> MVector s (Log a) -> MVector s (Log a) #basicOverlaps :: MVector s (Log a) -> MVector s (Log a) -> Bool #basicUnsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) (Log a)) #basicInitialize :: PrimMonad m => MVector (PrimState m) (Log a) -> m () #basicUnsafeReplicate :: PrimMonad m => Int -> Log a -> m (MVector (PrimState m) (Log a)) #basicUnsafeRead :: PrimMonad m => MVector (PrimState m) (Log a) -> Int -> m (Log a) #basicUnsafeWrite :: PrimMonad m => MVector (PrimState m) (Log a) -> Int -> Log a -> m () #basicClear :: PrimMonad m => MVector (PrimState m) (Log a) -> m () #basicSet :: PrimMonad m => MVector (PrimState m) (Log a) -> Log a -> m () #basicUnsafeCopy :: PrimMonad m => MVector (PrimState m) (Log a) -> MVector (PrimState m) (Log a) -> m () #basicUnsafeMove :: PrimMonad m => MVector (PrimState m) (Log a) -> MVector (PrimState m) (Log a) -> m () #basicUnsafeGrow :: PrimMonad m => MVector (PrimState m) (Log a) -> Int -> m (MVector (PrimState m) (Log a)) # (RealFloat a, Precise a, Enum a) => Enum (Log a) Source # Methodssucc :: Log a -> Log a #pred :: Log a -> Log a #toEnum :: Int -> Log a #fromEnum :: Log a -> Int #enumFrom :: Log a -> [Log a] #enumFromThen :: Log a -> Log a -> [Log a] #enumFromTo :: Log a -> Log a -> [Log a] #enumFromThenTo :: Log a -> Log a -> Log a -> [Log a] # Eq a => Eq (Log a) Source # Methods(==) :: Log a -> Log a -> Bool #(/=) :: Log a -> Log a -> Bool # (RealFloat a, Precise a) => Floating (Log a) Source # Methodspi :: Log a #exp :: Log a -> Log a #log :: Log a -> Log a #sqrt :: Log a -> Log a #(**) :: Log a -> Log a -> Log a #logBase :: Log a -> Log a -> Log a #sin :: Log a -> Log a #cos :: Log a -> Log a #tan :: Log a -> Log a #asin :: Log a -> Log a #acos :: Log a -> Log a #atan :: Log a -> Log a #sinh :: Log a -> Log a #cosh :: Log a -> Log a #tanh :: Log a -> Log a #asinh :: Log a -> Log a #acosh :: Log a -> Log a #atanh :: Log a -> Log a #log1p :: Log a -> Log a #expm1 :: Log a -> Log a #log1pexp :: Log a -> Log a #log1mexp :: Log a -> Log a # (Precise a, RealFloat a) => Fractional (Log a) Source # Methods(/) :: Log a -> Log a -> Log a #recip :: Log a -> Log a # Data a => Data (Log a) Source # Methodsgfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Log a -> c (Log a) #gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Log a) #toConstr :: Log a -> Constr #dataTypeOf :: Log a -> DataType #dataCast1 :: Typeable (* -> *) t => (forall d. Data d => c (t d)) -> Maybe (c (Log a)) #dataCast2 :: Typeable (* -> * -> *) t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Log a)) #gmapT :: (forall b. Data b => b -> b) -> Log a -> Log a #gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Log a -> r #gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Log a -> r #gmapQ :: (forall d. Data d => d -> u) -> Log a -> [u] #gmapQi :: Int -> (forall d. Data d => d -> u) -> Log a -> u #gmapM :: Monad m => (forall d. Data d => d -> m d) -> Log a -> m (Log a) #gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Log a -> m (Log a) #gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Log a -> m (Log a) # (Precise a, RealFloat a) => Num (Log a) Source # Methods(+) :: Log a -> Log a -> Log a #(-) :: Log a -> Log a -> Log a #(*) :: Log a -> Log a -> Log a #negate :: Log a -> Log a #abs :: Log a -> Log a #signum :: Log a -> Log a # Ord a => Ord (Log a) Source # Methodscompare :: Log a -> Log a -> Ordering #(<) :: Log a -> Log a -> Bool #(<=) :: Log a -> Log a -> Bool #(>) :: Log a -> Log a -> Bool #(>=) :: Log a -> Log a -> Bool #max :: Log a -> Log a -> Log a #min :: Log a -> Log a -> Log a # (Floating a, Read a) => Read (Log a) Source # MethodsreadsPrec :: Int -> ReadS (Log a) #readList :: ReadS [Log a] #readPrec :: ReadPrec (Log a) # (Precise a, RealFloat a, Ord a) => Real (Log a) Source # MethodstoRational :: Log a -> Rational # (Precise a, RealFloat a) => RealFrac (Log a) Source # MethodsproperFraction :: Integral b => Log a -> (b, Log a) #truncate :: Integral b => Log a -> b #round :: Integral b => Log a -> b #ceiling :: Integral b => Log a -> b #floor :: Integral b => Log a -> b # (Floating a, Show a) => Show (Log a) Source # MethodsshowsPrec :: Int -> Log a -> ShowS #show :: Log a -> String #showList :: [Log a] -> ShowS # Generic (Log a) Source # Associated Typestype Rep (Log a) :: * -> * # Methodsfrom :: Log a -> Rep (Log a) x #to :: Rep (Log a) x -> Log a # (Precise a, RealFloat a) => Semigroup (Log a) Source # Methods(<>) :: Log a -> Log a -> Log a #sconcat :: NonEmpty (Log a) -> Log a #stimes :: Integral b => b -> Log a -> Log a # (Precise a, RealFloat a) => Monoid (Log a) Source # Methodsmempty :: Log a #mappend :: Log a -> Log a -> Log a #mconcat :: [Log a] -> Log a # Storable a => Storable (Log a) Source # MethodssizeOf :: Log a -> Int #alignment :: Log a -> Int #peekElemOff :: Ptr (Log a) -> Int -> IO (Log a) #pokeElemOff :: Ptr (Log a) -> Int -> Log a -> IO () #peekByteOff :: Ptr b -> Int -> IO (Log a) #pokeByteOff :: Ptr b -> Int -> Log a -> IO () #peek :: Ptr (Log a) -> IO (Log a) #poke :: Ptr (Log a) -> Log a -> IO () # Binary a => Binary (Log a) Source # Methodsput :: Log a -> Put #get :: Get (Log a) #putList :: [Log a] -> Put # Serial a => Serial (Log a) Source # Methodsserialize :: MonadPut m => Log a -> m () #deserialize :: MonadGet m => m (Log a) # Serialize a => Serialize (Log a) Source # Methodsput :: Putter (Log a) #get :: Get (Log a) # NFData a => NFData (Log a) Source # Methodsrnf :: Log a -> () # Hashable a => Hashable (Log a) Source # MethodshashWithSalt :: Int -> Log a -> Int #hash :: Log a -> Int # (RealFloat a, Unbox a) => Unbox (Log a) Source # data MVector s (Log a) Source # data MVector s (Log a) = MV_Log (MVector s a) type Rep (Log a) Source # type Rep (Log a) = D1 (MetaData "Log" "Numeric.Log" "log-domain-0.12-CNdmMpWc5WJDIs53Nv8ljO" True) (C1 (MetaCons "Exp" PrefixI True) (S1 (MetaSel (Just Symbol "ln") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a))) data Vector (Log a) Source # data Vector (Log a) = V_Log (Vector a)

class Floating a => Precise a where Source #

This provides log1p and expm1 for working more accurately with small numbers.

Minimal complete definition

Methods

log1p :: a -> a Source #

Computes log(1 + x)

This is far enough from 0 that the Taylor series is defined.

This can provide much more accurate answers for logarithms of numbers close to 1 (x near 0).

These arise when working wth log-scale probabilities a lot.

expm1 :: a -> a Source #

The Taylor series for exp(x) is given by

exp(x) = 1 + x + x^2/2! + ...

When x is small, the leading 1 consumes all of the available precision.

This computes:

exp(x) - 1 = x + x^2/2! + ..

which can afford you a great deal of additional precision if you move things around algebraically to provide the 1 by other means.

log1pexp :: a -> a Source #

log1mexp :: a -> a Source #

Instances

 Source # Methods Source # Methods (RealFloat a, Precise a) => Precise (Complex a) Source # Methodslog1p :: Complex a -> Complex a Source #expm1 :: Complex a -> Complex a Source #

sum :: (RealFloat a, Precise a, Foldable f) => f (Log a) -> Log a Source #

Efficiently and accurately compute the sum of a set of log-domain numbers

While folding with (+) accomplishes the same end, it requires an additional n-2 logarithms to sum n terms. In addition, here we introduce fewer opportunities for round-off error.

While for small quantities the naive sum accumulates error,

>>> let xs = Prelude.replicate 40000 (Exp 1e-4) :: [Log Float]
>>> Prelude.sum xs ~= 4.00e4
True


This sum gives a more accurate result,

>>> Numeric.Log.sum xs ~= 4.00e4
True


NB: This does require two passes over the data.