aern2-mp 0.2.8.0 → 0.2.9.0
raw patch · 12 files changed
+180/−64 lines, 12 filesdep ~collect-errorsdep ~mixed-types-num
Dependency ranges changed: collect-errors, mixed-types-num
Files
- aern2-mp.cabal +6/−5
- changelog.md +4/−0
- src/AERN2/MP/Ball/Field.hs +13/−9
- src/AERN2/MP/Ball/Tests.hs +7/−0
- src/AERN2/MP/Ball/Type.hs +5/−5
- src/AERN2/MP/Dyadic.hs +1/−1
- src/AERN2/MP/Float.hs +1/−0
- src/AERN2/MP/Float/Arithmetic.hs +14/−14
- src/AERN2/MP/Float/Conversions.hs +20/−12
- src/AERN2/MP/Float/PreludeNum.hs +72/−0
- src/AERN2/MP/Float/Tests.hs +3/−3
- src/AERN2/MP/Float/Type.hs +34/−15
aern2-mp.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: aern2-mp-version: 0.2.8.0+version: 0.2.9.0 synopsis: Multi-precision ball (interval) arithmetic description: Please see the README on GitHub at <https://github.com/michalkonecny/aern2/#readme> category: Math@@ -48,6 +48,7 @@ AERN2.MP.Float.Auxi AERN2.MP.Float.Conversions AERN2.MP.Float.Operators+ AERN2.MP.Float.PreludeNum AERN2.MP.Float.Tests AERN2.MP.Float.Type AERN2.MP.Precision@@ -85,11 +86,11 @@ QuickCheck , base ==4.* , cdar-mBound >=0.1.0.0- , collect-errors >=0.1.3+ , collect-errors >=0.1.5 , deepseq , hspec , integer-logarithms- , mixed-types-num >=0.5.8+ , mixed-types-num >=0.5.9 , reflection , regex-tdfa , template-haskell@@ -125,11 +126,11 @@ , aern2-mp , base ==4.* , cdar-mBound >=0.1.0.0- , collect-errors >=0.1.3+ , collect-errors >=0.1.5 , deepseq , hspec , integer-logarithms- , mixed-types-num >=0.5.8+ , mixed-types-num >=0.5.9 , reflection , regex-tdfa , template-haskell
changelog.md view
@@ -1,5 +1,9 @@ # Change log for aern2-mp +* v 0.2.9 2022-07-13+ * testing basic ops produce valid MPBalls+ * more instances for CN Kleenean+ * Num MPFloat (unspecified rounding mode) * v 0.2.8 2021-08-04 * compatibility with ghc 9.0.1 * add limits for CN (WithCurrentPrec p (CN MPBall))
src/AERN2/MP/Ball/Field.hs view
@@ -34,7 +34,7 @@ import AERN2.MP.Ball.Type import AERN2.MP.Ball.Conversions ()-import AERN2.MP.Ball.Comparisons ()+import AERN2.MP.Ball.Comparisons (hullMPBall) {- addition -} @@ -136,10 +136,10 @@ (x12C, e12) = MPFloat.ceduCentreErr $ MPFloat.mulCEDU x1 x2 mulByEndpoints :: MPBall -> MPBall -> MPBall-mulByEndpoints b1 b2 = +mulByEndpoints b1 b2 = fromEndpoints l r where- (l,r) + (l,r) | 0 <= l1 && 0 <= l2 = (l1*.l2, r1*^r2) -- 0 <= l1 <= r1, 0 <= l2 <= r2 | r1 <= 0 && r2 <= 0 = (r1*.r2, l1*^l2) -- l1 <= r1 <= 0, l2 <= r2 <= 0 | 0 <= l1 && r2 <= 0 = (r1*.l2, l1*^r2) -- l2 <= r2 <= 0 <= l1 <= r1@@ -279,8 +279,8 @@ pow = powUsingMulRecipCutNeg (mpBall 1) powUsingMulRecipCutNeg :: _ => MPBall -> MPBall -> e -> MPBall-powUsingMulRecipCutNeg one x e - | even e = +powUsingMulRecipCutNeg one x e+ | even e = max 0 $ powUsingMulRecip one mulByEndpoints recip x e | otherwise = powUsingMulRecip one mulByEndpoints recip x e @@ -304,9 +304,13 @@ CanDivIMod MPBall MPBall where type DivIType MPBall MPBall = Integer- divIMod x m - | m !>! 0 = (d, xm)+ divIMod x m+ | m !>! 0 = (error "Integer division for MPBall undefined", xm') | otherwise = error $ "modulus not positive: " ++ show m where- d = floor $ centre $ (centreAsBall x) / (centreAsBall m)- xm = x - m*d+ (l, r) = endpoints $ x / m+ (dL, dR) = (floor l, floor r) + xmL = x - m*dL+ xmR = x - m*dR+ xm = hullMPBall xmL xmR+ xm' = min (max 0 xm) m
src/AERN2/MP/Ball/Tests.hs view
@@ -85,24 +85,31 @@ specHasOrder tInt tMPBall tRational describe "min/max/abs" $ do specCanNegNum tMPBall+ specResultIsValid1 abs "abs" tMPBall specCanAbs tMPBall+ specResultIsValid2 min "min" tMPBall tMPBall+ specResultIsValid2 max "max" tMPBall tMPBall specCanMinMaxNotMixed tMPBall specCanMinMax tMPBall tInteger tMPBall describe "ring" $ do+ specResultIsValid2 add "add" tMPBall tMPBall specCanAddNotMixed tMPBall specCanAddSameType tMPBall specCanAdd tInt tMPBall tRational specCanAdd tInteger tMPBall tInt+ specResultIsValid2 sub "sub" tMPBall tMPBall specCanSubNotMixed tMPBall specCanSub tMPBall tInteger specCanSub tInteger tMPBall specCanSub tMPBall tInt specCanSub tInt tMPBall+ specResultIsValid2 mul "mul" tMPBall tMPBall specCanMulNotMixed tMPBall specCanMulSameType tMPBall specCanMul tInt tMPBall tRational -- specCanPow tMPBall tInteger describe "field" $ do+ specResultIsValid2Pre (\_ y -> isCertainlyNonZero y) divide "divide" tMPBall tMPBall specCanDivNotMixed tMPBall specCanDiv tInteger tMPBall specCanDiv tMPBall tInt
src/AERN2/MP/Ball/Type.hs view
@@ -46,7 +46,7 @@ import AERN2.MP.Dyadic import qualified AERN2.MP.Float as MPFloat-import AERN2.MP.Float (MPFloat, mpFloat, showMPFloat)+import AERN2.MP.Float (MPFloat, mpFloat) import AERN2.MP.Float.Operators import AERN2.MP.Precision import AERN2.MP.Accuracy@@ -70,7 +70,7 @@ instance ShowWithAccuracy MPBall where showWithAccuracy displayAC b@(MPBall x e) = -- printf "[%s ± %s](prec=%s)" (show x) (showAC $ getAccuracy b) (show $ integer $ getPrecision b)- printf "[%s ± %s%s]" (dropSomeDigits $ showMPFloat x) eDS (showAC $ getAccuracy b)+ printf "[%s ± %s%s]" (dropSomeDigits $ show x) eDS (showAC $ getAccuracy b) -- "[" ++ show x ++ " ± " ++ show e ++ "](prec=" ++ (show $ integer $ getPrecision x) ++ ")" where eDS @@ -101,8 +101,8 @@ instance CanTestIsIntegerType MPBall -- False by default --- instance CanTestValid MPBall where--- isValid = isFinite+instance CanTestValid MPBall where+ isValid = isFinite instance CanTestNaN MPBall where isNaN = not . isFinite@@ -143,7 +143,7 @@ giveUpIfVeryInaccurate = (aux =<<) where aux b@(MPBall _ e)- | e > 1000 = CN.noValueNumErrorPotential $ numErrorVeryInaccurate "MPBall" ""+ | e > 1000000 = CN.noValueNumErrorPotential $ numErrorVeryInaccurate "MPBall" "" | otherwise = cn b {- ball construction/extraction functions -}
src/AERN2/MP/Dyadic.hs view
@@ -60,7 +60,7 @@ import AERN2.Norm import AERN2.MP.Precision import AERN2.MP.Accuracy-import AERN2.MP.Float+import AERN2.MP.Float hiding (lift1, lift2) {-| Exact dyadic type based on MPFloat. -} newtype Dyadic = Dyadic { dyadicMPFloat :: MPFloat }
src/AERN2/MP/Float.hs view
@@ -42,6 +42,7 @@ import AERN2.MP.Float.Conversions as Conversions import AERN2.MP.Float.Operators as Operators+import AERN2.MP.Float.PreludeNum () import AERN2.MP.Float.Tests as Tests -- | Computes an upper bound to the distance @|x - y|@ of @x@ and @y@.
src/AERN2/MP/Float/Arithmetic.hs view
@@ -36,48 +36,48 @@ {- common functions -} instance CanNeg MPFloat where- negate = P.negate+ negate = lift1 P.negate instance CanAbs MPFloat where- abs = P.abs+ abs = lift1 P.abs addCEDU :: MPFloat -> MPFloat -> BoundsCEDU MPFloat-addCEDU = binaryCEDU (P.+)+addCEDU = binaryCEDU $ lift2 (P.+) subCEDU :: MPFloat -> MPFloat -> BoundsCEDU MPFloat-subCEDU = binaryCEDU (P.-)+subCEDU = binaryCEDU $ lift2 (P.-) mulCEDU :: MPFloat -> MPFloat -> BoundsCEDU MPFloat-mulCEDU = binaryCEDU (P.*)+mulCEDU = binaryCEDU $ lift2 (P.*) divCEDU :: MPFloat -> MPFloat -> BoundsCEDU MPFloat divCEDU x y - | y P.== (P.fromInteger 0) = getBoundsCEDU MPLow.Bottom- | otherwise = binaryCEDU (P./) x y+ | unMPFloat y P.== (P.fromInteger 0) = getBoundsCEDU (MPFloat MPLow.Bottom)+ | otherwise = binaryCEDU (lift2 (P./)) x y recipCEDU :: MPFloat -> BoundsCEDU MPFloat-recipCEDU = unaryCEDU P.recip+recipCEDU = unaryCEDU $ lift1 P.recip {- special constants and functions -} piCEDU :: Precision -> BoundsCEDU MPFloat piCEDU pp = - getBoundsCEDU $ MPLow.piA (p2cdarPrec pp)+ getBoundsCEDU $ MPFloat (MPLow.piA (p2cdarPrec pp)) cosCEDU :: MPFloat -> BoundsCEDU MPFloat-cosCEDU = unaryCEDU MPLow.cosA+cosCEDU = unaryCEDU $ lift1 MPLow.cosA sinCEDU :: MPFloat -> BoundsCEDU MPFloat-sinCEDU = unaryCEDU MPLow.sinA+sinCEDU = unaryCEDU $ lift1 MPLow.sinA sqrtCEDU :: MPFloat -> BoundsCEDU MPFloat-sqrtCEDU = unaryCEDU MPLow.sqrtA+sqrtCEDU = unaryCEDU $ lift1 MPLow.sqrtA expCEDU :: MPFloat -> BoundsCEDU MPFloat-expCEDU = unaryCEDU MPLow.expA+expCEDU = unaryCEDU $ lift1 MPLow.expA logCEDU :: MPFloat -> BoundsCEDU MPFloat-logCEDU = unaryCEDU MPLow.logA+logCEDU = unaryCEDU $ lift1 MPLow.logA {- auxiliary functions to automatically determine result precision from operand precisions -}
src/AERN2/MP/Float/Conversions.hs view
@@ -49,23 +49,26 @@ instance ConvertibleExactly Integer MPFloat where safeConvertExactly =- Right . P.fromInteger+ Right . MPFloat . P.fromInteger instance ConvertibleExactly Int MPFloat where safeConvertExactly = safeConvertExactly . integer fromIntegerCEDU :: Precision -> Integer -> BoundsCEDU MPFloat fromIntegerCEDU pp =- setPrecisionCEDU pp . P.fromInteger+ setPrecisionCEDU pp . MPFloat . P.fromInteger fromRationalCEDU :: Precision -> Rational -> BoundsCEDU MPFloat fromRationalCEDU pp =- setPrecisionCEDU pp . (MPLow.toApproxMB (p2cdarPrec pp))+ setPrecisionCEDU pp . (MPFloat . MPLow.toApproxMB (p2cdarPrec pp)) {- conversions from MPFloat -} -instance ConvertibleExactly MPFloat Rational where+instance ConvertibleExactly MPLow.Approx Rational where safeConvertExactly = Right . P.toRational++instance ConvertibleExactly MPFloat Rational where+ safeConvertExactly = safeConvertExactly . unMPFloat toDouble :: MPFloat -> Double toDouble = P.fromRational . rational@@ -79,15 +82,17 @@ instance CanRound MPFloat where- properFraction x = (n,f)+ properFraction (MPFloat x) = (n,f) where r = rational x n = (numerator r) `P.quot` (denominator r)- f = ceduCentre $ x `subCEDU` (P.fromInteger n)+ f = ceduCentre $ (MPFloat x) `subCEDU` (MPFloat $ P.fromInteger n) {- comparisons -} -instance HasEqAsymmetric MPFloat MPFloat+instance HasEqAsymmetric MPLow.Approx MPLow.Approx+instance HasEqAsymmetric MPFloat MPFloat where+ equalTo = lift2R equalTo instance HasEqAsymmetric MPFloat Integer where equalTo = convertSecond equalTo instance HasEqAsymmetric Integer MPFloat where@@ -103,7 +108,10 @@ instance CanTestZero MPFloat -instance HasOrderAsymmetric MPFloat MPFloat+instance HasOrderAsymmetric MPLow.Approx MPLow.Approx+instance HasOrderAsymmetric MPFloat MPFloat where+ lessThan = lift2R lessThan+ leq = lift2R leq instance HasOrderAsymmetric MPFloat Integer where lessThan = convertSecond lessThan leq = convertSecond leq@@ -132,11 +140,11 @@ max x y | isNaN x = x | isNaN y = y- | otherwise = P.max x y+ | otherwise = lift2 P.max x y min x y | isNaN x = x | isNaN y = y- | otherwise = P.min x y+ | otherwise = lift2 P.min x y {- constants -} @@ -146,11 +154,11 @@ two = mpFloat 2 nan, infinity :: MPFloat-nan = MPLow.Bottom+nan = MPFloat MPLow.Bottom infinity = nan itisNaN :: MPFloat -> Bool-itisNaN MPLow.Bottom = True+itisNaN (MPFloat MPLow.Bottom) = True itisNaN _ = False instance CanTestFinite MPFloat where
+ src/AERN2/MP/Float/PreludeNum.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE StandaloneDeriving #-}+{-# OPTIONS_GHC -Wno-orphans #-}+{-|+ Module : AERN2.MP.Float.PreludeNum+ Description : Prelude numerical operators for MPFloat+ Copyright : (c) Michal Konecny+ License : BSD3++ Maintainer : mikkonecny@gmail.com+ Stability : experimental+ Portability : portable++ Instances for Prelude classes such as Num, Fractional, using an unspecified rounding.+-}++module AERN2.MP.Float.PreludeNum+(+)+where++import MixedTypesNumPrelude+import qualified Prelude as P++-- import AERN2.MP.Precision+import AERN2.MP.Float.Auxi++import AERN2.MP.Float.Type+import AERN2.MP.Float.Arithmetic++deriving instance P.Eq MPFloat+deriving instance P.Ord MPFloat++instance P.Num MPFloat where+ fromInteger = MPFloat . P.fromInteger -- default precision (mBound)!+ negate = lift1 P.negate+ abs = lift1 P.abs+ signum = lift1 P.signum+ (+) = c2 addCEDU+ (-) = c2 subCEDU+ (*) = c2 mulCEDU++instance P.Fractional MPFloat where+ fromRational = MPFloat . P.fromRational -- default precision (mBound)!+ (/) = c2 divCEDU++instance P.Floating MPFloat where+ sin = c1 sinCEDU+ cos = c1 cosCEDU+ exp = c1 expCEDU+ log = c1 logCEDU+ pi = error "Prelude.Floating MPFloat: pi not defined"+ asin = error "Prelude.Floating MPFloat: asin not defined yet"+ acos = error "Prelude.Floating MPFloat: acos not defined yet"+ atan = error "Prelude.Floating MPFloat: atan not defined yet"+ sinh = error "Prelude.Floating MPFloat: sinh not defined yet"+ cosh = error "Prelude.Floating MPFloat: cosh not defined yet"+ asinh = error "Prelude.Floating MPFloat: asinh not defined yet"+ acosh = error "Prelude.Floating MPFloat: acosh not defined yet"+ atanh = error "Prelude.Floating MPFloat: atanh not defined yet"++c1 :: + (t -> BoundsCEDU MPFloat) -> + (t -> MPFloat)+c1 op x = ceduCentre $ op x++c2 :: + (t1 -> t2 -> BoundsCEDU MPFloat) -> + (t1 -> t2 -> MPFloat)+c2 op x y = ceduCentre $ op x y++instance P.Real MPFloat where+ toRational (MPFloat a) = toRational a
src/AERN2/MP/Float/Tests.hs view
@@ -175,15 +175,15 @@ argsS = unlines [printf " %s = %s ~ %s bits (dR/d%s = %s ~ %s bits)" - argS (show arg) (show $ getErrorStepSizeLog arg) - argS (showMPFloat argD) (show $ getNormLog argD)+ argS (show arg) (show $ getErrorStepSizeLog $ unMPFloat arg) + argS (show argD) (show $ getNormLog argD) | (arg, argD, argS) <- argsLR ] argsLR = args ++ [(l, one, "L"), (r, one, "R"), (abs(r-.l), zero, "|R-L|")] e = 0 - maxStepLoss - precLoss maxStepLoss = sum $ map (max 1) $ (catMaybes $ map stepLoss argsLR) stepLoss (arg, argD, _argS) =- case (getNormLog argD, getErrorStepSizeLog arg) of+ case (getNormLog argD, getErrorStepSizeLog $ unMPFloat arg) of (NormBits dbits, Just stepBits) -> Just $ dbits + stepBits _ -> Nothing -- resNorm =
src/AERN2/MP/Float/Type.hs view
@@ -15,8 +15,8 @@ module AERN2.MP.Float.Type ( -- * MPFloat numbers and their basic operations- MPFloat- , showMPFloat+ MPFloat(..)+ , lift1, lift2, lift2R , getErrorStepSizeLog , setPrecisionCEDU , p2cdarPrec@@ -35,26 +35,44 @@ import AERN2.MP.Float.Auxi import qualified Data.CDAR as MPLow+import Control.DeepSeq (NFData)+import GHC.Generics (Generic) {-| Multiple-precision floating-point type based on CDAR.Approx with 0 radius. -}-type MPFloat = MPLow.Approx+newtype MPFloat = MPFloat { unMPFloat :: MPLow.Approx }+ deriving (Generic) -showMPFloat :: MPFloat -> String-showMPFloat x = MPLow.showA x+lift1 :: (MPLow.Approx -> MPLow.Approx) -> MPFloat -> MPFloat+lift1 f (MPFloat a) = MPFloat (f a) +lift2 :: + (MPLow.Approx -> MPLow.Approx -> MPLow.Approx) -> + (MPFloat -> MPFloat -> MPFloat)+lift2 f (MPFloat a1) (MPFloat a2) = MPFloat (f a1 a2)++lift2R :: + (MPLow.Approx -> MPLow.Approx -> t) -> + (MPFloat -> MPFloat -> t)+lift2R f (MPFloat a1) (MPFloat a2) = f a1 a2++instance Show MPFloat where+ show x = MPLow.showA $ unMPFloat x+ deriving instance (Typeable MPFloat)+instance NFData MPFloat p2cdarPrec :: Precision -> MPLow.Precision p2cdarPrec = P.fromInteger . integer getBoundsCEDU :: MPFloat -> BoundsCEDU MPFloat-getBoundsCEDU (MPLow.Approx mb m e s) = +getBoundsCEDU (MPFloat (MPLow.Approx mb m e s)) = BoundsCEDU - (MPLow.Approx mb m 0 s) (MPLow.approxMB eb_mb e 0 s)- (MPLow.Approx mb (m-e) 0 s) (MPLow.Approx mb (m+e) 0 s)-getBoundsCEDU MPLow.Bottom =+ (MPFloat $ MPLow.Approx mb m 0 s) (MPFloat $ MPLow.approxMB eb_mb e 0 s)+ (MPFloat $ MPLow.Approx mb (m-e) 0 s) (MPFloat $ MPLow.Approx mb (m+e) 0 s)+getBoundsCEDU (MPFloat MPLow.Bottom) = BoundsCEDU- MPLow.Bottom MPLow.Bottom MPLow.Bottom MPLow.Bottom+ (MPFloat MPLow.Bottom) (MPFloat MPLow.Bottom) + (MPFloat MPLow.Bottom) (MPFloat MPLow.Bottom) {-| The bit-size bound for the error bound in CEDU -} eb_prec :: Precision@@ -65,18 +83,19 @@ eb_mb = int $ integer eb_prec instance HasPrecision MPFloat where- getPrecision (MPLow.Approx mb _ _ _) = prec (P.toInteger $ mb)- getPrecision MPLow.Bottom = error "illegal MPFloat (Bottom)"+ getPrecision (MPFloat (MPLow.Approx mb _ _ _)) = prec (P.toInteger $ mb)+ getPrecision (MPFloat MPLow.Bottom) = error "illegal MPFloat (Bottom)" instance CanSetPrecision MPFloat where setPrecision p = ceduCentre . setPrecisionCEDU p setPrecisionCEDU :: Precision -> MPFloat -> BoundsCEDU MPFloat-setPrecisionCEDU pp = getBoundsCEDU . MPLow.enforceMB . MPLow.setMB (p2cdarPrec pp)+setPrecisionCEDU pp = + getBoundsCEDU . lift1 MPLow.enforceMB . lift1 (MPLow.setMB (p2cdarPrec pp)) instance HasNorm MPFloat where- getNormLog (MPLow.Approx _ m _ s) = (getNormLog m) + (integer s)- getNormLog MPLow.Bottom = error "getNormLog undefined for Bottom"+ getNormLog (MPFloat (MPLow.Approx _ m _ s)) = (getNormLog m) + (integer s)+ getNormLog (MPFloat MPLow.Bottom) = error "getNormLog undefined for Bottom" {-| Returns @s@ such that @2^s@ is the distance to the nearest other number with the same precision.