logfloat 0.8.5 → 0.8.6
raw patch · 2 files changed
+73/−22 lines, 2 files
Files
- Data/Number/LogFloat.hs +69/−20
- logfloat.cabal +4/−2
Data/Number/LogFloat.hs view
@@ -10,12 +10,19 @@ -- http://www.haskell.org/ghc/docs/latest/html/users_guide/rewrite-rules.html -- http://www.randomhacks.net/articles/2007/02/10/map-fusion-and-haskell-performance --- {-# OPTIONS_GHC -ddump-simpl-stats #-}+-- {-# OPTIONS_GHC -ddump-rules -ddump-simpl-stats #-} -{-# OPTIONS_GHC -Wall -Werror #-}-{-# OPTIONS_GHC -O2 -fvia-C -optc-O3 #-}+{-# OPTIONS_GHC -Wall -Werror #-} +-- Unfortunately we need -fglasgow-exts in order to actually pick+-- up on the rules (see -ddump-rules). The -frewrite-rules flag+-- doesn't do what you want.+-- cf <http://hackage.haskell.org/trac/ghc/ticket/2213>+-- cf <http://www.mail-archive.com/glasgow-haskell-users@haskell.org/msg14313.html>+{-# OPTIONS_GHC -O2 -fvia-C -optc-O3 -fexcess-precision -fglasgow-exts #-}+ -- Version History+-- (v0.8.6) Removed buggy RULES -- (v0.8.5) Gave up and converted from lhs to hs so Hackage docs work -- (v0.8.4) Broke out Transfinite -- (v0.8.3) Documentation updates@@ -30,7 +37,7 @@ -- (v0.1) Initial version created for hw5 for NLP with Jason Eisner. -- ------------------------------------------------------------------- ~ 2008.08.16+-- ~ 2008.08.17 -- | -- Module : Data.Number.LogFloat -- Copyright : Copyright (c) 2007--2008 wren ng thornton@@ -78,11 +85,11 @@ ---------------------------------------------------------------- ----- Try to add in some optimizations. Why the first few need to be+-- Try to add in some optimizations. Why these need to be -- down here and localized to the module, I don't know. We don't -- do anything foolish like this, but our clients might, or they -- might be generated by other code transformations. Note that due--- to the fuzz, these equations are not actually true, even though+-- to the fuzz, these equations are not strictly true, even though -- they are mathematically correct. {-# RULES@@ -93,14 +100,19 @@ "exp.log" exp . log = id #-} --- These are general rule versions of our operators for 'LogFloat'.--- I had some issues inducing 'Ord' on @x@ and @y@, even though--- they're 'Num' so I can't do "(+)\/log" and "(-)\/log" so easily.--{-# RULES-"(*)/log" forall x y. log x * log y = log (x + y)-"(/)/log" forall x y. log x / log y = log (x - y)- #-}+-- We'd like to be able to take advantage of general rule versions+-- of our operators for 'LogFloat', with rules like @log x + log y+-- = log (x * y)@ and @log x - log y = log (x / y)@. However the+-- problem is that those equations could be driven in either direction+-- depending on whether we think time performance or non-underflow+-- performance is more important, and the answers may be different+-- at every call site.+--+-- Since we implore users to do normal-domain computations whenever+-- it would not degenerate accuracy, we should not rewrite their+-- decisions in any way. The log\/exp fusion strictly improves both+-- time and accuracy, so those are safe. But the buck stops with+-- them. ----------------------------------------------------------------@@ -140,23 +152,52 @@ -- into @Ratio@ types is error-prone and non-portable, as discussed -- in "Data.Number.Transfinite". +{-# INLINE [1] toFractional #-}+{-# SPECIALIZE toFractional :: (Real a) => a -> Float #-} {-# SPECIALIZE toFractional :: (Real a) => a -> Double #-} {-# SPECIALIZE toFractional :: (Fractional b) => Double -> b #-} toFractional :: (Real a, Fractional b) => a -> b toFractional = fromRational . toRational +-- The INLINE pragma is to /delay/ inlining, so the rules below can+-- have their way+ -- This should only fire when it's type-safe {-# RULES "toFractional/id" toFractional = id #-} --- This should happen already, but who knows--- TODO: see if it ever fires+-- These too should only fire when it's type-safe+-- This should already happen, but...+-- TODO: Check the logs to see if it ever fires+-- BUG: why does -ddump-rules call these two orphaned? {-# RULES-"toFractional/toFractional" forall x.- toFractional (toFractional x) = toFractional x-"toFractional.toFractional" toFractional . toFractional = toFractional+"toRational/fromRational" forall x. toRational (fromRational x) = x+"toRational.fromRational" toRational . fromRational = id #-} +-- 'toFractional' should be inlined and the above rules should+-- obviate this, but...+-- TODO: We should check the logs to see if it ever fires before+-- removing them+{-# RULES+"toFractional/toFractional" forall x.+ toFractional (toFractional x) = toFractional x+"toFractional.toFractional" toFractional . toFractional = toFractional+ #-} ++{- It looks like we need these for vast performance improvement.+ Is there some way to include them without resorting to CPP or+ other non-portability?+ <http://www.haskell.org/ghc/docs/latest/html/users_guide/rewrite-rules.html>++import GHC.Prim+{-# RULES "toFractional::Int->Double" toFractional = i2d #-}+i2d (I# i) = D# (int2Double# i)+{-# RULES "toFractional::Int->Float" toFractional = i2f #-}+i2f (I# i) = F# (int2Float# i)+-}++ ---------------------------------------------------------------- -- -- | Reduce the number of constant string literals we need to store.@@ -173,7 +214,7 @@ | otherwise = errorOutOfRange fun --- | It's unfortunate that notANumber is not equal to itself, but+-- | It's unfortunate that 'notANumber' is not equal to itself, but -- we can hack around that. GHC gives NaN for the log of negatives -- and so we could ideally take advantage of @log . guardNonNegative -- fun = guardIsANumber fun . log@ to simplify things, but Hugs@@ -255,6 +296,14 @@ -- These are our module-specific versions of "log\/exp" and "exp\/log"; -- They do the same things but also have a @LogFloat@ in between -- the logarithm and exponentiation.+--+-- In order to ensure these rules fire we may need to delay inlining+-- of the four con-\/destructors, like we do for 'toFractional'.+-- Unfortunately, I'm not entirely sure whether they will be inlined+-- already or not (and whether they are may be fragile) and I don't+-- want to inline them excessively and lead to code bloat in the+-- off chance that we could prune some of it away.+-- TODO: thoroughly investigate this. {-# RULES -- Out of log-domain and back in
logfloat.cabal view
@@ -1,6 +1,9 @@ ----------------------------------------------------------------+-- wren ng thornton <wren@community.haskell.org> ~ 2008.08.17+----------------------------------------------------------------+ Name: logfloat-Version: 0.8.5+Version: 0.8.6 Cabal-Version: >= 1.2 Build-Type: Simple Stability: stable@@ -22,7 +25,6 @@ Exposed-Modules: Data.Number.LogFloat , Data.Number.Transfinite Build-Depends: base- Ghc-Options: -O2 -fvia-C -optc-O3 ---------------------------------------------------------------- ----------------------------------------------------------- fin.