
Data.Number.LogFloat  Portability  portable  Stability  stable  Maintainer  wren@community.haskell.org 





Description 
This module presents a type for storing numbers in the logdomain.
The main reason for doing this is to prevent underflow when
multiplying many small probabilities as is done in Hidden Markov
Models and other statistical models often used for natural
language processing. The logdomain also helps prevent overflow
when multiplying many large numbers. In rare cases it can speed
up numerical computation (since addition is faster than
multiplication, though logarithms are exceptionally slow), but
the primary goal is to improve accuracy of results. A secondary
goal has been to maximize efficiency since these computations
are frequently done within a O(n^3) loop.
The LogFloat of this module is restricted to nonnegative
numbers for efficiency's sake, see the forthcoming
Data.Number.LogFloat.Signed for doing signed logdomain
calculations.


Synopsis 




Basic functions



Since the normal log throws an error on zero, we
have to redefine it in order for things to work right. Arguing
from limits we can see that log 0 == negativeInfinity. Newer
versions of GHC have this behavior already, but older versions
and Hugs do not.
This function will raise an error when taking the log of negative
numbers, rather than returning notANumber as the newer GHC
implementation does. The reason being that typically this is a
logical error, and notANumber allows the error to propegate
silently.
In order to improve portability, the Transfinite class is
required to indicate that the Floating type does in fact have
a representation for negative infinity. Both native floating
types (Double and Float) are supported. If you define your
own instance of Transfinite, verify the above equation holds
for your 0 and negativeInfinity. If it doesn't, then you
should avoid importing our log and will probably want converters
to handle the discrepancy when dealing with LogFloats.



The most generic numeric converter I can come up with. All the
builtin numeric types are Real, though Int and Integer
aren't Fractional. Beware that converting transfinite values
into Ratio types is errorprone and nonportable, as discussed
in Data.Number.Transfinite.


LogFloat data type and conversion functions



A LogFloat is just a Double with a special interpretation.
The logFloat function is presented instead of the constructor,
in order to ensure semantic conversion. At present the Show
instance will convert back to the normaldomain, and so will
underflow at that point. This behavior may change in the future.
Performing operations in the logdomain is cheap, prevents
underflow, and is otherwise very nice for dealing with miniscule
probabilities. However, crossing into and out of the logdomain
is expensive and should be avoided as much as possible. In
particular, if you're doing a series of multiplications as in
lp * logFloat q * logFloat r it's faster to do lp * logFloat
(q * r) if you're reasonably sure the normaldomain multiplication
won't underflow, because that way you enter the logdomain only
once, instead of twice.
Even more particularly, you should avoid addition whenever
possible. Addition is provided because it's necessary at times
and the proper implementation is not immediately transparent.
However, between two LogFloats addition requires crossing the
exp/log boundary twice; with a LogFloat and a regular number
it's three times since the regular number needs to enter the
logdomain first. This makes addition incredibly slow. Again,
if you can parenthesize to do plain operations first, do it!
 Instances  



A constructor which does semantic conversion from normaldomain
to logdomain.



Constructor which assumes the argument is already in the
logdomain.



Return our logdomain value back into normaldomain. Beware
of overflow/underflow.



Return the logdomain value itself without costly conversion


Exceptional numeric values


module Data.Number.Transfinite 

Produced by Haddock version 2.7.2 