variable-precision 0.3.1 → 0.4
raw patch · 4 files changed
+56/−11 lines, 4 files
Files
- CHANGES +2/−0
- Numeric/VariablePrecision/Algorithms.hs +43/−1
- Numeric/VariablePrecision/Float.hs +7/−7
- variable-precision.cabal +4/−3
CHANGES view
@@ -1,3 +1,5 @@+v0.4 better sin, cos, tan+v0.3.1 use complex-generic v0.2.1 fixed point v0.2 generic IEEE-ish v0.1.1 fixed for ghc-7.0.4
Numeric/VariablePrecision/Algorithms.hs view
@@ -44,6 +44,7 @@ , genericLog2 , genericLog'' , genericPi+ , genericSin , genericPositiveZero , genericNegativeZero , genericPositiveInfinity@@ -53,7 +54,7 @@ ) where import Data.Bits (bit, shiftR)-+import Data.List (foldl') -- | Special values implemented using basic RealFloat functionality. genericPositiveZero, genericNegativeZero, genericPositiveInfinity, genericNegativeInfinity, genericNotANumber :: RealFloat a => a@@ -291,6 +292,47 @@ k' = k + 1 p' = scaleFloat (-2) (sqr (a + b) / t) ++-- | Compute 'sin' using the method described in section 3 of+-- /Efficient multiple-precision evaluation of elementary functions/+-- David M Smith, 1989,+-- <http://digitalcommons.lmu.edu/math_fac/1/>+--+-- Requires a value for pi.+--+-- Uses basic RealFloat functionality, '(/)', and sqrt.+genericSin :: RealFloat a => Int {-^ accuracy -} -> a {-^ pi -} -> a {-^ x -} -> a+genericSin accuracy pi x0 = reduced taylor x0+ where+ sqr y = y * y+ t :: Double+ t = fromIntegral (floatDigits x0 - accuracy)+ k :: Int+ k = round (t / 3)+ three = 3 ^ k+ up 0 !y = y+ up n !y = up (n - 1) (y * (3 - scaleFloat 2 (sqr y)))+ reduced f y+ | y == 0 = y+ | y < 0 = (negate . reduced f . negate) y+ | y <= pi / 4 = (up k . f . (/ three)) y+ | y <= pi / 2 = (sqrt . (1 -) . sqr . reduced f . (pi / 2 -)) y+ | y <= pi = (reduced f . (pi -)) y+ | y <= pi * 2 = (negate . reduced f . (pi * 2 -)) y+ | otherwise = (reduced f . subtract (pi * 2)) y+ taylor y = (sum' . reverse . takeWhile ((> threshold) . abs) . go 1) y+ where+ threshold = scaleFloat (negate (floatDigits y * 2)) y+ x2 = sqr y+ go !n !xnf = xnf : go n' xnf'+ where+ n' = n + 1+ xnf' = negate (x2 * xnf / fromInt (2 * n + 1))+ fromInt :: Num a => Int -> a+ fromInt = fromIntegral++sum' :: Num a => [a] -> a+sum' = foldl' (+) 0 -- | Lift a function from Double to generic 'RealFloat' types. viaDouble :: (RealFloat a, RealFloat b) => (Double -> Double) -> a -> b
Numeric/VariablePrecision/Float.hs view
@@ -62,13 +62,13 @@ -- -- * 'exp', ----- * 'log'.+-- * 'log', --+-- * 'sin', 'cos', 'tan'.+-- -- These 'Floating' methods transit via 'Double' and so have limited -- precision: ----- * 'sin', 'cos', 'tan',--- -- * 'asin', 'acos', 'atan', -- -- * 'sinh', 'cosh', 'tanh',@@ -344,7 +344,7 @@ | otherwise = (fromInteger n', f') where n = m `shiftR` (negate e)- d = checkVFloat "properFraction" $ F (n `shiftL` (negate e)) e+ d = encodeVFloat (asTypeIn self) (n `shiftL` (negate e)) e f = me - d (n', f') | (m >= 0) == (f >= 0) = (n, f)@@ -440,11 +440,11 @@ -- 'logBase' uses default implementation in Floating - sin = viaDouble sin -- FIXME+ sin = genericSin 2 pi - cos = viaDouble cos -- FIXME+ cos x = sin (x + pi/2) - tan = viaDouble tan -- FIXME+ tan x = sin x / cos x sinh = viaDouble sinh -- FIXME
variable-precision.cabal view
@@ -1,10 +1,11 @@ Name: variable-precision-Version: 0.3.1+Version: 0.4 Synopsis: variable-precision floating point Description: Software floating point with type-tagged variable mantissa precision, implemented using a strict pair of 'Integer' and 'Int' scaled alike- to 'decodeFloat'. Version 0.2.1 added a fixed point number type.+ to 'decodeFloat'. Version 0.4 adds more number-type-agnostic numerical+ algorithms ('sin', 'cos', 'tan'). . Instances of the usual numeric type classes are provided, along with additional operators (with carefully chosen fixities) to coerce,@@ -72,4 +73,4 @@ source-repository this type: git location: git://gitorious.org/variable-precision/variable-precision.git- tag: v0.3.1+ tag: v0.4