-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Log-domain floating point numbers -- @package logfloat @version 0.13.1 -- | 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 where gt x y = case x `cmp` y of { Just GT -> Just True Just _ -> Just False Nothing -> Nothing } ge x y = case x `cmp` y of { Just LT -> Just False Just _ -> Just True Nothing -> Nothing } eq x y = case x `cmp` y of { Just EQ -> Just True Just _ -> Just False Nothing -> Nothing } ne x y = case x `cmp` y of { Just EQ -> Just False Just _ -> Just True Nothing -> Nothing } le x y = case x `cmp` y of { Just GT -> Just False Just _ -> Just True Nothing -> Nothing } lt x y = case x `cmp` y of { Just LT -> Just True Just _ -> Just False Nothing -> Nothing } maxPO x y = do { o <- x `cmp` y; case o of { GT -> Just x EQ -> Just x LT -> Just y } } minPO x y = do { o <- x `cmp` y; case o of { GT -> Just y EQ -> Just x LT -> Just x } } 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: -- --
-- 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 -- | 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 Eq LogFloat instance Ord LogFloat instance IArray UArray LogFloat instance Storable LogFloat instance Real LogFloat instance Fractional LogFloat instance Num LogFloat instance Show LogFloat instance PartialOrd LogFloat