-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Log-domain floating point numbers
--
-- This module presents a class for storing numbers in the log-domain.
-- The main reason for doing this is to prevent underflow when
-- multiplying many probabilities as is done in Hidden Markov Models. It
-- is also helpful for preventing overflow.
@package logfloat
@version 0.8.3
-- | This module presents a class for storing numbers in the log-domain.
-- 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 log-domain 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 non-negative
-- numbers for efficiency's sake, see the forthcoming
-- Data.Number.LogFloat.Signed for doing signed log-domain
-- calculations.
module Data.Number.LogFloat
infinity :: (Fractional a) => a
negativeInfinity :: (Fractional a) => a
notANumber :: (Fractional a) => a
-- | 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.
log :: (Floating a) => a -> a
-- | The most generic numeric converter I can come up with. All the
-- built-in numeric types are Real, though Int and
-- Integer aren't Fractional.
toFractional :: (Real a, Fractional b) => a -> b
-- | 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 normal-domain, and
-- so will underflow at that point. This behavior may change in the
-- future.
--
-- Performing operations in the log-domain is cheap, prevents underflow,
-- and is otherwise very nice for dealing with miniscule probabilities.
-- However, crossing into and out of the log-domain 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 normal-domain multiplication won't underflow,
-- because that way you enter the log-domain 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 log-domain first. This
-- makes addition incredibly slow. Again, if you can parenthesize to do
-- plain operations first, do it!
data LogFloat
-- | A constructor which does semantic conversion from normal-domain to
-- log-domain.
logFloat :: (Real a) => a -> LogFloat
-- | Constructor which assumes the argument is already in the log-domain.
logToLogFloat :: (Real a) => a -> LogFloat
-- | Return our log-domain value back into normal-domain. Beware of
-- overflow/underflow.
fromLogFloat :: (Floating a) => LogFloat -> a
-- | Return the log-domain value itself without costly conversion
logFromLogFloat :: (Floating a) => LogFloat -> a
instance Eq LogFloat
instance Ord LogFloat
instance Real LogFloat
instance Fractional LogFloat
instance Num LogFloat
instance Show LogFloat