|Maintainer||Edward Kmett <firstname.lastname@example.org>|
|(RealFloat a, Unbox a) => Vector Vector (Log a)|
|(RealFloat a, Unbox a) => MVector MVector (Log a)|
|(RealFloat a, Precise a, Enum a) => Enum (Log a)|
|Eq a => Eq (Log a)|
|(RealFloat a, Precise a) => Floating (Log a)|
|(Precise a, RealFloat a, Eq a) => Fractional (Log a)|
|Data a => Data (Log a)|
|(Precise a, RealFloat a) => Num (Log a)|
|Ord a => Ord (Log a)|
|(Floating a, Read a) => Read (Log a)|
|(Precise a, RealFloat a, Ord a) => Real (Log a)|
|(Floating a, Show a) => Show (Log a)|
|Generic (Log a)|
|(Precise a, RealFloat a) => Monoid (Log a)|
|Storable a => Storable (Log a)|
|Binary a => Binary (Log a)|
|Serial a => Serial (Log a)|
|Serialize a => Serialize (Log a)|
|NFData a => NFData (Log a)|
|Hashable a => Hashable (Log a)|
|SafeCopy a0 => SafeCopy (Log a0)|
|(RealFloat a, Unbox a) => Unbox (Log a)|
expm1 for working more accurately with small numbers.
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! + ...
x is small, the leading 1 consumes all of the available precision.
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.
Efficiently and accurately compute the sum of a set of log-domain numbers
While folding with
(+) accomplishes the same end, it requires an
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]
This sum gives a more accurate result,
NB: This does require two passes over the data.