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

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.