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





Description 
This module presents a class 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 




Documentation Note


If you see no module description above, then the lhs2hs
script was not run correctly. Please rebuild the documentation
or see:
http://code.haskell.org/~wren/logfloat/dist/doc/html/logfloat/


IEEE floatingpoint special values


GHC.Real defines infinity and notANumber as
Rational. We export variants which are polymorphic because
that can be more helpful at times.
BUG: At present these constants are broken for Ratio
types including Rational, since Ratio types do not
typically permit a zero denominator. In GHC (6.8.2) the
result for infinity is a rational with a numerator
sufficiently large that fromRational will yield infinity
for Float and Double. In Hugs (September 2006) it
yields an arithmetic overflow error. For GHC, our notANumber
yields 0%1 rather than 0%0 as GHC.Real does.








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 it's obvious that log 0 == negativeInfinity.
If you're using some Floating type that's not built in, verify
this 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 discrepency.



The most generic numeric converter I can come up with. All the
builtin numeric types are Real, though Int and Integer aren't
Fractional.


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


Produced by Haddock version 2.4.2 