-- 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.10.0 -- | Hugs (September 2006) has buggy definitions for isNaN and -- isInfinite on Float and Double. If this module is run through -- CPP with the macro __HUGS__ set to a value no larger than -- 200609, then correct definitions are used. Otherwise the Prelude -- definitions are used (which should be correct for other compilers). -- For example, run Hugs with -- --
--   hugs -F'cpp -P -D__HUGS__=200609' Hugs/RealFloat.hs
--   
-- -- N.B. The corrected definitions have only been tested to work for -- Float and Double. These definitions should probably not -- be used for other RealFloat types. module Hugs.RealFloat isInfinite :: (RealFloat a) => a -> Bool isNaN :: (RealFloat a) => a -> Bool -- | The Prelude's Ord class for dealing with ordered types is often -- onerous to use because it requires Eq as well as a total -- ordering. While such total orderings are common, partial orderings are -- moreso. This module presents a class for partially ordered types. module Data.Number.PartialOrd -- | This class defines a partially ordered type. The method names were -- chosen so as not to conflict with Ord and Eq. We use -- Maybe instead of defining new types PartialOrdering -- and FuzzyBool because this way should make the class easier -- to use. -- -- Minimum complete definition: cmp class PartialOrd a cmp :: (PartialOrd a) => a -> a -> Maybe Ordering gt :: (PartialOrd a) => a -> a -> Maybe Bool ge :: (PartialOrd a) => a -> a -> Maybe Bool eq :: (PartialOrd a) => a -> a -> Maybe Bool ne :: (PartialOrd a) => a -> a -> Maybe Bool le :: (PartialOrd a) => a -> a -> Maybe Bool lt :: (PartialOrd a) => a -> a -> Maybe Bool maxPO :: (PartialOrd a) => a -> a -> Maybe a minPO :: (PartialOrd a) => a -> a -> Maybe a -- | Like Data.Ord.comparing. Helpful in conjunction with the -- xxxBy family of functions from Data.List comparingPO :: (PartialOrd b) => (a -> b) -> a -> a -> Maybe Ordering instance [overlap ok] PartialOrd Double instance [overlap ok] PartialOrd Float instance [overlap ok] (Ord a) => PartialOrd a -- | This module presents a type class for numbers which have -- representations for transfinite values. The idea originated from the -- IEEE-754 floating-point special values, used by -- Data.Number.LogFloat. However not all Fractional types -- necessarily support transfinite values. In particular, Ratio -- types including Rational do not have portable representations. -- -- For the Glasgow compiler (GHC 6.8.2), GHC.Real defines -- 1%0 and 0%0 as representations for infinity -- and notANumber, but most operations on them will raise -- exceptions. If toRational is used on an infinite floating -- value, the result is a rational with a numerator sufficiently large -- that it will overflow when converted back to a Double. If -- used on NaN, the result would buggily convert back as -- negativeInfinity. For more discussion on why this approach is -- problematic, see: -- -- -- -- Hugs (September 2006) stays closer to the haskell98 spec and offers no -- way of constructing those values, raising arithmetic overflow errors -- if attempted. module Data.Number.Transfinite -- | Many numbers are not Bounded yet, even though they can -- represent arbitrarily large values, they are not necessarily able to -- represent transfinite values such as infinity itself. This class is -- for types which are capable of representing such values. Notably, this -- class does not require the type to be Fractional nor -- Floating since integral types could also have representations -- for transfinite values. By popular demand the Num restriction -- has been lifted as well, due to complications of defining Show -- or Eq for some types. -- -- In particular, this class extends the ordered projection to have a -- maximum value infinity and a minimum value -- negativeInfinity, as well as an exceptional value -- notANumber. All the natural laws regarding infinity -- and negativeInfinity should pertain. (Some of these are -- discussed below.) -- -- Hugs (September 2006) has buggy Prelude definitions for isNaN -- and isInfinite on Float and Double. This module provides -- correct definitions, so long as Hugs.RealFloat is compiled -- correctly. class (PartialOrd a) => Transfinite a infinity :: (Transfinite a) => a negativeInfinity :: (Transfinite a) => a notANumber :: (Transfinite a) => a isInfinite :: (Transfinite a) => a -> Bool isNaN :: (Transfinite a) => a -> Bool -- | 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. log :: (Floating a, Transfinite a) => a -> a -- | The realToFrac function is defined to pivot through a -- Rational according to the haskell98 spec. This is non-portable -- and problematic as discussed above. Since there is some resistance to -- breaking from the spec, this class defines a reasonable variant which -- deals with transfinite values appropriately. -- -- N.B. The generic instance for transfinite types uses expensive checks -- to ensure correctness. On GHC there are specialized versions which use -- primitive converters instead. These instances are hidden from other -- compilers by the CPP. Be warned that the instances are overlapped, so -- you'll need to give type signatures if the arguments to -- realToFrac are polymorphic. -- -- If any of these restrictions (CPP, GHC-only optimizations, -- OverlappingInstances) are onerous to you, contact the maintainer (we -- like patches). Note that this does work for Hugs with suitable -- options (e.g. hugs -98 +o -F'cpp -P'). class (Real a, Fractional b) => RealToFrac a b realToFrac :: (RealToFrac a b) => a -> b instance [overlap ok] RealToFrac Double Float instance [overlap ok] RealToFrac Float Double instance [overlap ok] RealToFrac Integer Double instance [overlap ok] RealToFrac Integer Float instance [overlap ok] RealToFrac Int Double instance [overlap ok] RealToFrac Int Float instance [overlap ok] (Real a, Transfinite a, Fractional b, Transfinite b) => RealToFrac a b instance [overlap ok] (Real a, Fractional a) => RealToFrac a a instance [overlap ok] Transfinite Float instance [overlap ok] Transfinite Double -- | This module presents a type 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 -- | 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, RealToFrac a Double) => a -> LogFloat -- | Constructor which assumes the argument is already in the log-domain. logToLogFloat :: (Real a, RealToFrac a Double) => a -> LogFloat -- | Return our log-domain value back into normal-domain. Beware of -- overflow/underflow. fromLogFloat :: (Fractional a, Transfinite a, RealToFrac Double a) => LogFloat -> a -- | Return the log-domain value itself without costly conversion logFromLogFloat :: (Fractional a, Transfinite a, RealToFrac Double a) => LogFloat -> a instance Eq LogFloat instance Ord LogFloat instance Real LogFloat instance Fractional LogFloat instance Num LogFloat instance Show LogFloat instance PartialOrd LogFloat