Copyright | (c) Edward Kmett 2013-2015 |
---|---|
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, 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.