-- 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