Skip to content

Commit 5f51503

Browse files
committed
Added Read instance
Ignore-this: 11d988e1fd9b68089a0f81cfef20b1e3 darcs-hash:c1d1b4eac92f2ccda99e3215354d74529ac7def7
1 parent 9a1644c commit 5f51503

File tree

3 files changed

+64
-43
lines changed

3 files changed

+64
-43
lines changed

CHANGELOG

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
0.13.4 (2017-06-18):
2+
- Added Read LogFloat instance. (h/t Rob Zinkov)
13
0.13.3.2 (2015-08-06):
24
- Fixed the buggy Show LogFloat instance
35
0.13.3.1 (2015-05-30):
@@ -15,7 +17,9 @@
1517
- removed support for older versions of GHC, in order to clean things up
1618

1719
0.12.1 (2010-03-19):
18-
- Fixed some NaN injection bugs in the Num instance. These would only have been triggered by non-probabilistic uses of LogFloat (i.e., if you used @logFloat infinity@)
20+
- Fixed some NaN injection bugs in the Num instance. These would
21+
only have been triggered by non-probabilistic uses of LogFloat
22+
(i.e., if you used @logFloat infinity@)
1923
0.12.0.3 (2009-04-03):
2024
- Added notes to INSTALL about Windows compatibility
2125
0.12.0.2 (2009-04-03):
@@ -24,9 +28,10 @@
2428
- Disabled -fvia-C so the FFI can be used in GHC 6.10
2529
0.12 (2009-03-10):
2630
- Added log1p.
27-
- Added Storable instance (for GHC only)
28-
- removed orphaned toRational/fromRational rules. The RealToFrac module obviates those optimizations.
29-
- Adjusted Real LogFloat instance to throw errors on transfinite values
31+
- Added Storable instance (for GHC only)
32+
- removed orphaned toRational/fromRational rules. The
33+
RealToFrac module obviates those optimizations.
34+
- Adjusted Real LogFloat instance to throw errors on transfinite values
3035

3136
0.11.2 (2009-03-09):
3237
- Moved log/exp rules from LogFloat into Transfinite
@@ -35,26 +40,36 @@
3540
0.11.1 (2009-03-08):
3641
- Added IArray UArray LogFloat instance (thanks to Felipe Lessa).
3742
0.11 (2009-01-29):
38-
- Moved the RealToFrac class from Data.Number.Transfinite to Data.Number.RealToFrac. This breaks backwards compatibility if you depended directly on that module for the class. If you imported the class from Data.Number.LogFloat then you're still fine.
39-
- Cabal build fail due to missing new module (Fixed in 0.11.0.1).
43+
- Moved the RealToFrac class from Data.Number.Transfinite to
44+
Data.Number.RealToFrac. This breaks backwards compatibility if
45+
you depended directly on that module for the class. If you
46+
imported the class from Data.Number.LogFloat then you're still
47+
fine.
48+
- Cabal build fail due to missing new module (Fixed in 0.11.0.1).
4049

4150
0.10 (2009-01-29):
42-
- Hugs' Prelude definitions of isInfinite and isNaN for Float and Double are buggy. The new Hugs.RealFloat module provides correct implementations (defaulting to the Prelude definition for non-Hugs compilers).
43-
- The PartialOrd and Transfinite instances for Double and Float have been updated to use these corrected functions.
44-
- Added maxPO and minPO to PartialOrd and added comparingPO to Data.Number.PartialOrd.
45-
- Minor changes to circumvent bugs in Hackage's new version of Haddock. You should be able to see all the documentation now.
51+
- Hugs' Prelude definitions of isInfinite and isNaN for Float
52+
and Double are buggy. The new Hugs.RealFloat module provides
53+
correct implementations (defaulting to the Prelude definition
54+
for non-Hugs compilers).
55+
- The PartialOrd and Transfinite instances for Double and Float
56+
have been updated to use these corrected functions.
57+
- Added maxPO and minPO to PartialOrd and added comparingPO to
58+
Data.Number.PartialOrd.
59+
- Minor changes to circumvent bugs in Hackage's new version of
60+
Haddock. You should be able to see all the documentation now.
4661

4762
0.9.1 (2008-08-30):
4863
- Fixed some PartialOrd stuff and sanitized documentation
49-
- Build fail on GHC 6.10 due to GHC.Prim (Fixed in 0.9.1.1).
64+
- Build fail on GHC 6.10 due to GHC.Prim (Fixed in 0.9.1.1).
5065
0.9.0 (2008-08-30):
5166
- s/toFractional/realToFrac/g.
5267
- Also moved realToFrac and log to Transfinite
53-
- Build fail on GHC 6.10 due to GHC.Prim
68+
- Build fail on GHC 6.10 due to GHC.Prim
5469

5570
0.8.6 (2008-08-17):
5671
- Removed buggy RULES
57-
- Build fail on GHC 6.10 due to -Werror and removal of -fno-warn-orphans
72+
- Build fail on GHC 6.10 due to -Werror and removal of -fno-warn-orphans
5873
0.8.5 (2008-08-17):
5974
- Gave up and converted from lhs to hs so Hackage docs work
6075
0.8.4 (2008-08-17):

logfloat.cabal

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
----------------------------------------------------------------
2-
-- wren gayle romano <[email protected]> ~ 2015.10.02
2+
-- wren gayle romano <[email protected]> ~ 2017.06.18
33
----------------------------------------------------------------
44

55
-- By and large Cabal >=1.2 is fine; but
@@ -10,12 +10,12 @@ Cabal-Version: >= 1.9.2
1010
Build-Type: Simple
1111

1212
Name: logfloat
13-
Version: 0.13.3.3
13+
Version: 0.13.4
1414
Stability: experimental
1515
Homepage: http://code.haskell.org/~wren/
1616
Author: wren gayle romano
1717
Maintainer: [email protected]
18-
Copyright: Copyright (c) 2007--2015 wren gayle romano
18+
Copyright: Copyright (c) 2007--2017 wren gayle romano
1919
License: BSD3
2020
License-File: LICENSE
2121

@@ -31,7 +31,7 @@ Description:
3131
Extra-source-files:
3232
README.md, CHANGELOG
3333

34-
-- Cf., <https://travis-ci.org/wrengr/bytestring-lexing>
34+
-- Cf., <https://travis-ci.org/wrengr/logfloat>
3535
Tested-With:
3636
GHC ==7.6.1, GHC ==7.6.2, GHC ==7.6.3,
3737
GHC ==7.8.1, GHC ==7.8.2, GHC ==7.8.3, GHC ==7.8.4,

src/Data/Number/LogFloat.hs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
{-# OPTIONS_GHC -O2 -fexcess-precision -fenable-rewrite-rules #-}
1515

1616
----------------------------------------------------------------
17-
-- ~ 2015.08.06
17+
-- ~ 2017.06.18
1818
-- |
1919
-- Module : Data.Number.LogFloat
20-
-- Copyright : Copyright (c) 2007--2015 wren gayle romano
20+
-- Copyright : Copyright (c) 2007--2017 wren gayle romano
2121
-- License : BSD3
2222
-- Maintainer : [email protected]
2323
-- Stability : stable
@@ -44,7 +44,7 @@ module Data.Number.LogFloat
4444
(
4545
-- * Exceptional numeric values
4646
module Data.Number.Transfinite
47-
47+
4848
-- * @LogFloat@ data type
4949
, LogFloat()
5050
-- ** Isomorphism to normal-domain
@@ -56,7 +56,7 @@ module Data.Number.LogFloat
5656
-- ** Additional operations
5757
, sum, product
5858
, pow
59-
59+
6060
-- * Accurate versions of logarithm\/exponentiation
6161
, log1p, expm1
6262
) where
@@ -80,7 +80,7 @@ import Hugs.IOExts (unsafeCoerce)
8080
#elif __NHC__
8181
import NonStdUnsafeCoerce (unsafeCoerce)
8282
#elif __GLASGOW_HASKELL__ >= 710
83-
-- For when the *heap* representations are the same
83+
-- For when the *heap* representations are the same
8484
--import Data.Coerce (coerce)
8585
-- For when the *unboxed array* storage representations are the same
8686
import Unsafe.Coerce (unsafeCoerce)
@@ -98,6 +98,9 @@ import Foreign.Storable (Storable)
9898
-- in order to ensure semantic conversion. At present the 'Show'
9999
-- instance will convert back to the normal-domain, and hence will
100100
-- underflow at that point. This behavior may change in the future.
101+
-- At present, the 'Read' instance parses things in the normal-domain
102+
-- and then converts them to the log-domain. Again, this behavior
103+
-- may change in the future.
101104
--
102105
-- Because 'logFloat' performs the semantic conversion, we can use
103106
-- operators which say what we *mean* rather than saying what we're
@@ -165,27 +168,27 @@ instance IArray UArray LogFloat where
165168
{-# INLINE bounds #-}
166169
bounds :: forall i. Ix i => UArray i LogFloat -> (i, i)
167170
bounds = unsafeCoerce (bounds :: UArray i Double -> (i, i))
168-
171+
169172
{-# INLINE numElements #-}
170173
numElements :: forall i. Ix i => UArray i LogFloat -> Int
171174
numElements = unsafeCoerce (numElements :: UArray i Double -> Int)
172-
175+
173176
{-# INLINE unsafeArray #-}
174177
unsafeArray :: forall i. Ix i => (i,i) -> [(Int,LogFloat)] -> UArray i LogFloat
175178
unsafeArray = unsafeCoerce (unsafeArray :: (i,i) -> [(Int,Double)] -> UArray i Double)
176-
179+
177180
{-# INLINE unsafeAt #-}
178181
unsafeAt :: forall i. Ix i => UArray i LogFloat -> Int -> LogFloat
179182
unsafeAt = unsafeCoerce (unsafeAt :: UArray i Double -> Int -> Double)
180-
183+
181184
{-# INLINE unsafeReplace #-}
182185
unsafeReplace :: forall i. Ix i => UArray i LogFloat -> [(Int,LogFloat)] -> UArray i LogFloat
183186
unsafeReplace = unsafeCoerce (unsafeReplace :: UArray i Double -> [(Int,Double)] -> UArray i Double)
184-
187+
185188
{-# INLINE unsafeAccum #-}
186189
unsafeAccum :: forall i e. Ix i => (LogFloat -> e -> LogFloat) -> UArray i LogFloat -> [(Int,e)] -> UArray i LogFloat
187190
unsafeAccum = unsafeCoerce (unsafeAccum :: (Double -> e -> Double) -> UArray i Double -> [(Int,e)] -> UArray i Double)
188-
191+
189192
{-# INLINE unsafeAccumArray #-}
190193
unsafeAccumArray :: forall i e. Ix i => (LogFloat -> e -> LogFloat) -> LogFloat -> (i,i) -> [(Int,e)] -> UArray i LogFloat
191194
unsafeAccumArray = unsafeCoerce (unsafeAccumArray :: (Double -> e -> Double) -> Double -> (i,i) -> [(Int,e)] -> UArray i Double)
@@ -241,30 +244,30 @@ unsafeLogToLogFloat = LogFloat
241244
instance IArray UArray LogFloat where
242245
{-# INLINE bounds #-}
243246
bounds = bounds . logFromLFUArray
244-
247+
245248
-- Apparently this method was added in base-2.0/GHC-6.6 but Hugs
246249
-- (Sept 2006) doesn't have it. Not sure about NHC's base
247250
#if (!(defined(__HUGS__))) || (__HUGS__ > 200609)
248251
{-# INLINE numElements #-}
249252
numElements = numElements . logFromLFUArray
250253
#endif
251-
254+
252255
{-# INLINE unsafeArray #-}
253256
unsafeArray =
254257
unsafeArray $:: id ~> logFromLFAssocs ~> unsafeLogToLFUArray
255-
258+
256259
{-# INLINE unsafeAt #-}
257260
unsafeAt =
258261
unsafeAt $:: logFromLFUArray ~> id ~> unsafeLogToLogFloat
259-
262+
260263
{-# INLINE unsafeReplace #-}
261264
unsafeReplace =
262265
unsafeReplace $:: logFromLFUArray ~> logFromLFAssocs ~> unsafeLogToLFUArray
263-
266+
264267
{-# INLINE unsafeAccum #-}
265268
unsafeAccum =
266269
unsafeAccum $:: unsafeLogToLFFunc ~> logFromLFUArray ~> id ~> unsafeLogToLFUArray
267-
270+
268271
{-# INLINE unsafeAccumArray #-}
269272
unsafeAccumArray =
270273
unsafeAccumArray $:: unsafeLogToLFFunc ~> logFromLogFloat ~> id ~> id ~> unsafeLogToLFUArray
@@ -278,6 +281,9 @@ instance PartialOrd LogFloat where
278281
| isNaN x || isNaN y = Nothing
279282
| otherwise = Just $! x `compare` y
280283

284+
instance Read LogFloat where
285+
readsPrec p s =
286+
[(LogFloat (log x), r) | (x, r) <- readsPrec p s, not (isNaN x), x >= 0]
281287

282288
----------------------------------------------------------------
283289
-- | Reduce the number of constant string literals we need to store.
@@ -458,20 +464,20 @@ instance Num LogFloat where
458464
-- either isNaN. This does not constitute a bug since we
459465
-- maintain the invariant that values wrapped by 'LogFloat'
460466
-- are not NaN.
461-
467+
462468
(*) (LogFloat x) (LogFloat y)
463469
| isInfinite x
464470
&& isInfinite y
465471
&& x == negate y = LogFloat negativeInfinity -- @0*infinity == 0@
466472
| otherwise = LogFloat (x+y)
467-
473+
468474
(+) (LogFloat x) (LogFloat y)
469475
| x == y
470476
&& isInfinite x
471477
&& isInfinite y = LogFloat x -- @0+0 == 0@, @infinity+infinity == infinity@
472478
| x >= y = LogFloat (x + log1p (exp (y - x)))
473479
| otherwise = LogFloat (y + log1p (exp (x - y)))
474-
480+
475481
(-) (LogFloat x) (LogFloat y)
476482
| x == negativeInfinity
477483
&& y == negativeInfinity = LogFloat negativeInfinity -- @0-0 == 0@
@@ -480,7 +486,7 @@ instance Num LogFloat where
480486
-- TODO: flip @x@ and @y@ when @y > x@.
481487
-- Also, will throw error if (x,y) is (infinity,infinity)
482488
LogFloat (guardIsANumber "(-)" (x + log1p (negate (exp (y - x)))))
483-
489+
484490
signum (LogFloat x)
485491
| x == negativeInfinity = 0
486492
| x > negativeInfinity = 1
@@ -489,11 +495,11 @@ instance Num LogFloat where
489495
-- broke the invariant. That shouldn't be possible and
490496
-- so noone else bothers to check, but we check here just
491497
-- in case.
492-
498+
493499
negate _ = errorOutOfRange "negate"
494-
500+
495501
abs = id
496-
502+
497503
fromInteger = LogFloat . log
498504
. guardNonNegative "fromInteger" . fromInteger
499505

@@ -507,7 +513,7 @@ instance Fractional LogFloat where
507513
&& isInfinite y = errorOutOfRange "(/)"
508514
| x == negativeInfinity = LogFloat negativeInfinity -- @0/infinity == 0@
509515
| otherwise = LogFloat (x-y)
510-
516+
511517
fromRational = LogFloat . log
512518
. guardNonNegative "fromRational" . fromRational
513519

@@ -577,7 +583,7 @@ sum :: [LogFloat] -> LogFloat
577583
sum xs = LogFloat (theMax + log theSum)
578584
where
579585
LogFloat theMax = maximum xs
580-
586+
581587
-- compute @\log \sum_{x \in xs} \exp(x - theMax)@
582588
theSum = foldl' (\ acc (LogFloat x) -> acc + exp (x - theMax)) 0 xs
583589

0 commit comments

Comments
 (0)