-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Log-domain floating point numbers -- -- 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 probabilities as is done in Hidden Markov Models. It is also -- helpful for preventing overflow. @package logfloat @version 0.13.4 -- | 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 -DHUGS=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. -- -- This installation was compiled with the normal Prelude version. -- This should be correct. 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 -- more so. 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 -- | like compare cmp :: PartialOrd a => a -> a -> Maybe Ordering -- | like (>) gt :: PartialOrd a => a -> a -> Maybe Bool -- | like (>=) ge :: PartialOrd a => a -> a -> Maybe Bool -- | like (==) eq :: PartialOrd a => a -> a -> Maybe Bool -- | like (/=) ne :: PartialOrd a => a -> a -> Maybe Bool -- | like (<=) le :: PartialOrd a => a -> a -> Maybe Bool -- | like (<) lt :: PartialOrd a => a -> a -> Maybe Bool -- | like max. The default instance returns the left argument when -- they're equal. maxPO :: PartialOrd a => a -> a -> Maybe a -- | like min. The default instance returns the left argument when -- they're equal. minPO :: PartialOrd a => a -> a -> Maybe a infix 4 `gt` infix 4 `ge` infix 4 `eq` infix 4 `ne` infix 4 `le` infix 4 `lt` infix 4 `maxPO` infix 4 `minPO` -- | 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 GHC.Classes.Ord a => Data.Number.PartialOrd.PartialOrd a instance Data.Number.PartialOrd.PartialOrd GHC.Types.Float instance Data.Number.PartialOrd.PartialOrd GHC.Types.Double -- | 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: -- --
infinity + negativeInfinity
negativeInfinity + infinity
infinity - infinity
negativeInfinity - negativeInfinity
inf * 0
0 * inf
inf / inf
inf `div` inf
0 / 0
0 `div` 0
-- logFloat (p + q) == logFloat p + logFloat q -- logFloat (p * q) == logFloat p * logFloat q ---- -- (Do note, however, that subtraction can and negation will throw -- errors: since LogFloat can only represent the positive half -- of Double. Num is the wrong abstraction to put at the -- bottom of the numeric type-class hierarchy; but alas, we're stuck with -- it.) -- -- 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. -- Also note that, for precision, if you're doing more than a few -- multiplications in the log-domain, you should use product -- rather than using (*) repeatedly. -- -- Even more particularly, you should avoid addition whenever -- possible. Addition is provided because sometimes we need it, and the -- proper implementation is not immediately apparent. However, between -- two LogFloats addition requires crossing the exp/log boundary -- twice; with a LogFloat and a Double 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 -- normal-domain operations first, do it! -- --
-- logFloat p == logToLogFloat (log p) ---- -- If p is NaN or negative, then the two sides differ only in -- which error is thrown. logFloat :: Double -> LogFloat -- | Semantically convert our log-domain value back into the normal-domain. -- Beware of overflow/underflow. The following equivalence holds (without -- qualification): -- --
-- fromLogFloat == exp . logFromLogFloat --fromLogFloat :: LogFloat -> Double -- | Constructor which assumes the argument is already in the log-domain. -- Throws errors on notANumber inputs. logToLogFloat :: Double -> LogFloat -- | Return the log-domain value itself without conversion. logFromLogFloat :: LogFloat -> Double -- | O(n). Compute the sum of a finite list of LogFloats, -- being careful to avoid underflow issues. That is, the following -- equivalence holds (modulo underflow and all that): -- --
-- logFloat . sum == sum . map logFloat ---- -- N.B., this function requires two passes over the input. Thus, -- it is not amenable to list fusion, and hence will use a lot of memory -- when summing long lists. -- -- Since: 0.13 sum :: [LogFloat] -> LogFloat -- | O(n). Compute the product of a finite list of LogFloats, -- being careful to avoid numerical error due to loss of precision. That -- is, the following equivalence holds (modulo underflow and all that): -- --
-- logFloat . product == product . map logFloat ---- -- Since: 0.13 product :: [LogFloat] -> LogFloat -- | O(1). Compute powers in the log-domain; that is, the following -- equivalence holds (modulo underflow and all that): -- --
-- logFloat (p ** m) == logFloat p `pow` m ---- -- Since: 0.13 pow :: LogFloat -> Double -> LogFloat infixr 8 `pow` -- | Definition: log1p == log . (1+). Standard C libraries provide -- a special definition for log1p which is more accurate than -- doing the naive thing, especially for very small arguments. For -- example, the naive version underflows around 2 ** -53, -- whereas the specialized version underflows around 2 ** -1074. -- This function is used by (+) and (-) on -- LogFloat. -- -- N.B. The statistics:Statistics.Math module provides a pure -- Haskell implementation of log1p for those who are interested. -- We do not copy it here because it relies on the vector -- package which is non-portable. If there is sufficient interest, a -- portable variant of that implementation could be made. Contact the -- maintainer if the FFI and naive implementations are insufficient for -- your needs. -- -- This installation was compiled to use the FFI version. log1p :: Double -> Double -- | Definition: expm1 == subtract 1 . exp. Standard C libraries -- provide a special definition for expm1 which is more accurate -- than doing the naive thing, especially for very small arguments. This -- function isn't needed internally, but is provided for symmetry with -- log1p. -- -- This installation was compiled to use the FFI version. expm1 :: Double -> Double instance Foreign.Storable.Storable Data.Number.LogFloat.LogFloat instance GHC.Classes.Ord Data.Number.LogFloat.LogFloat instance GHC.Classes.Eq Data.Number.LogFloat.LogFloat instance Data.Array.Base.IArray Data.Array.Base.UArray Data.Number.LogFloat.LogFloat instance Data.Number.PartialOrd.PartialOrd Data.Number.LogFloat.LogFloat instance GHC.Read.Read Data.Number.LogFloat.LogFloat instance GHC.Show.Show Data.Number.LogFloat.LogFloat instance GHC.Num.Num Data.Number.LogFloat.LogFloat instance GHC.Real.Fractional Data.Number.LogFloat.LogFloat instance GHC.Real.Real Data.Number.LogFloat.LogFloat