Copyright | (c) Edward Kmett 2013 |
---|---|

License | BSD3 |

Maintainer | Edward Kmett <ekmett@gmail.com> |

Stability | experimental |

Portability | non-portable |

Safe Haskell | Trustworthy |

Language | Haskell98 |

# Documentation

`Log`

-domain `Float`

and `Double`

values.

class Floating a => Precise a where Source

This provides `log1p`

and `expm1`

for working more accurately with small numbers.

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.

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.

sum :: (RealFloat a, Ord 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]`

`>>>`

40001.3`Prelude.sum xs`

This sum gives a more accurate result,

`>>>`

40004.01`Numeric.Log.sum xs`

*NB:* This does require two passes over the data.