packages feed

aern2-real 0.2.1.0 → 0.2.4.0

raw patch · 9 files changed

+830/−158 lines, 9 filesdep +aern2-realdep ~collect-errorsdep ~mixed-types-numPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: aern2-real

Dependency ranges changed: collect-errors, mixed-types-num

API changes (from Hackage documentation)

- AERN2.Real.CKleenean: instance AERN2.Real.CKleenean.CanSelect (Numeric.CollectErrors.Type.CN Numeric.MixedTypes.Kleenean.Kleenean)
- AERN2.Real.CKleenean: instance AERN2.Real.CKleenean.CanSelect Numeric.MixedTypes.Kleenean.Kleenean
- AERN2.Real.CKleenean: instance Numeric.MixedTypes.Literals.ConvertibleExactly t Numeric.MixedTypes.Kleenean.Kleenean => Numeric.MixedTypes.Literals.ConvertibleExactly t AERN2.Real.CKleenean.CKleenean
- AERN2.Real.Type: crealFromWithCurrentPrec :: (forall p. KnownNat p => WithCurrentPrec (CN MPBall) p) -> CReal
+ AERN2.Real.CKleenean: instance AERN2.Real.CKleenean.CanSelect (Numeric.CollectErrors.Type.CN AERN2.Kleenean.Kleenean)
+ AERN2.Real.CKleenean: instance AERN2.Real.CKleenean.CanSelect AERN2.Kleenean.Kleenean
+ AERN2.Real.CKleenean: instance Numeric.MixedTypes.Literals.ConvertibleExactly t AERN2.Kleenean.Kleenean => Numeric.MixedTypes.Literals.ConvertibleExactly t AERN2.Real.CKleenean.CKleenean
+ AERN2.Real.Examples.ClosestPairDist: average :: (HasIntegers t, CanAddSameType t, CanDivBy t Integer) => [t] -> t
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_naive :: _ => [t] -> t
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_run :: _ => ([t] -> t) -> Integer -> t
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_runTests1 :: IO ()
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_runTests2 :: IO ()
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_run_naive :: Integer -> R
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_run_split :: Integer -> R
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_spec :: (Show t, Show b, HasEqAsymmetric t b, CanTestCertainly (EqCompareType t b), CanSub b b, CanMinMaxAsymmetric b b, CanAbs b, ConvertibleExactly b r, SubType b b ~ b, AbsType b ~ b, MinMaxType b b ~ b) => ([r] -> r) -> (r -> t) -> [b] -> Property
+ AERN2.Real.Examples.ClosestPairDist: closestPairDist_split :: _ => (t -> t -> Bool) -> [t] -> t
+ AERN2.Real.Examples.ClosestPairDist: compMPBall :: MPBall -> MPBall -> Bool
+ AERN2.Real.Examples.ClosestPairDist: compRApprox :: R -> R -> Bool
+ AERN2.Real.Examples.ClosestPairDist: distance :: (CanSubSameType t, CanAbsSameType t) => (t, t) -> t
+ AERN2.Real.Examples.ClosestPairDist: distinctPairs :: [t] -> [(t, t)]
+ AERN2.Real.Examples.ClosestPairDist: largest :: CanMinMaxSameType t => [t] -> t
+ AERN2.Real.Examples.ClosestPairDist: sample_integers :: IO ()
+ AERN2.Real.Examples.ClosestPairDist: sample_rationals :: IO ()
+ AERN2.Real.Examples.ClosestPairDist: smallest :: CanMinMaxSameType t => [t] -> t
+ AERN2.Real.Examples.ClosestPairDist: tails1 :: [t] -> [[t]]
+ AERN2.Real.Examples.ClosestPairDist: type R = CReal
+ AERN2.Real.Examples.Introduction: a_third :: CReal
+ AERN2.Real.Examples.Introduction: absQ :: Rational -> Rational
+ AERN2.Real.Examples.Introduction: absR1 :: CReal -> CReal
+ AERN2.Real.Examples.Introduction: absR2 :: CReal -> CReal
+ AERN2.Real.Examples.Introduction: absR2_approx :: (HasIfThenElse (SelectType (OrderCompareType t Rational)) t, CanSelect (OrderCompareType t Rational), HasOrderAsymmetric t Rational, CanNeg t, NegType t ~ t) => t -> Rational -> IfThenElseType (SelectType (OrderCompareType t Rational)) t
+ AERN2.Real.Examples.Introduction: compare_run1 :: CN Kleenean
+ AERN2.Real.Examples.Introduction: compare_run2 :: CN Kleenean
+ AERN2.Real.Examples.Introduction: compare_run3 :: CKleenean
+ AERN2.Real.Examples.Introduction: compare_run4 :: CSequence Kleenean
+ AERN2.Real.Examples.Introduction: compare_run5 :: CN Kleenean
+ AERN2.Real.Examples.Introduction: compare_run6 :: CSequence Kleenean
+ AERN2.Real.Examples.Introduction: compare_run7 :: CN Kleenean
+ AERN2.Real.Examples.Introduction: detectCN :: CanTestErrorsPresent a => a -> Maybe a
+ AERN2.Real.Examples.Introduction: e_sum :: Integer -> CReal
+ AERN2.Real.Examples.Introduction: e_sum2 :: Integer -> CReal
+ AERN2.Real.Examples.Introduction: fact :: Integer -> CReal
+ AERN2.Real.Examples.Introduction: logistic1 :: _ => Rational -> Integer -> t -> t
+ AERN2.Real.Examples.Introduction: logistic1_CReal_run :: Integer -> CReal
+ AERN2.Real.Examples.Introduction: my_e :: CReal
+ AERN2.Real.Examples.Introduction: my_e2 :: CReal
+ AERN2.Real.Examples.Introduction: partialfn_bad1 :: CReal
+ AERN2.Real.Examples.Introduction: partialfn_bad2 :: CSequence MPBall
+ AERN2.Real.Examples.Introduction: partialfn_bad3 :: CSequence MPBall
+ AERN2.Real.Examples.Introduction: partialfn_bad6 :: CReal
+ AERN2.Real.Examples.Introduction: partialfn_bad7 :: CReal
+ AERN2.Real.Examples.Introduction: partialfn_ok4 :: CReal
+ AERN2.Real.Examples.Introduction: partialfn_ok5 :: CReal
+ AERN2.Real.Examples.Introduction: pi100 :: CN MPBall
+ AERN2.Real.Examples.Introduction: pif_run1 :: CReal
+ AERN2.Real.Examples.Introduction: select_run1 :: CReal
+ AERN2.Real.Examples.Introduction: sine1 :: CReal
+ AERN2.Real.Examples.Introduction: sine1_run1 :: CN MPBall
+ AERN2.Real.Examples.Introduction: sine1_run2 :: CN MPBall
+ AERN2.Real.Examples.Introduction: sumSines1 :: Integer -> CReal
+ AERN2.Real.Examples.Introduction: sumSines1_run1 :: CN MPBall
+ AERN2.Real.Examples.Introduction: sumSines1_run2 :: CN MPBall
+ AERN2.Real.Tests: specCReal :: Spec
+ AERN2.Real.Tests: tCReal :: T CReal
+ AERN2.Real.Type: instance Control.CollectErrors.Type.CanTakeErrors Numeric.CollectErrors.Type.NumErrors (AERN2.Real.Type.CSequence t)
+ AERN2.Real.Type: instance Numeric.CollectErrors.Type.CanClearPotentialErrors (AERN2.Real.Type.CSequence t)

Files

README.md view
@@ -2,13 +2,15 @@  Exact real arithmetic -API documentation available on the [Hackage page](https://hackage.haskell.org/package/aern2-real).+API documentation is available on the [Hackage page](https://hackage.haskell.org/package/aern2-real). +The remainder of this text is an introductory tutorial.  The code for the examples contained here is also available in file [Introduction.hs](src/AERN2/Real/Introduction.hs).+ ## Table of contents <!-- omit in toc --> -- [1. Numeric data types](#1-numeric-data-types)-- [2. Basic usage with Prelude](#2-basic-usage-with-prelude)-- [3. Basic usage with MixedTypesNumPrelude](#3-basic-usage-with-mixedtypesnumprelude)+- [1. Data types](#1-data-types)+- [2. Usage with Prelude](#2-usage-with-prelude)+- [3. Usage with MixedTypesNumPrelude](#3-usage-with-mixedtypesnumprelude) - [4. Partial functions and error handling](#4-partial-functions-and-error-handling) - [5. Limits](#5-limits) - [6. Multivalued selection](#6-multivalued-selection)@@ -16,7 +18,7 @@   - [6.2. Multi-valued selection](#62-multi-valued-selection) - [7. Specification and tests](#7-specification-and-tests) -## 1. Numeric data types+## 1. Data types  This package provides the following two data types: @@ -27,52 +29,83 @@ The type `CReal` has instances of both [mixed-types-num](https://hackage.haskell.org/package/mixed-types-num) type classes such as `CanAdd`, `CanSqrt` as well as with traditional Prelude type classes such as `Ord`, `Num` and `Floating`. The type `CKleenean` supports the usual Boolean operations. -## 2. Basic usage with Prelude+Real numbers are represented by converging sequences of dyadic intervals: +```Haskell+type CReal = CSequence MPBall+```++A `CSequence` is a list of approximations computed with increasing *precision*.+Precision here does *not* guarantee a certain *accuracy*.+Precision roughly corresponds to the number of *significant digits* used+in all intermediate computations.+With increasing precision the intervals eventually converge to exact values.++The elements of a `CSequence` use the `CN` error-collecting wrapper.+A convergent sequence must be error-free from some point onwards.+A sequence is allowed not to converge, but only if all its elements contain the same error.  +Such a sequence can be thought of as converging to this error.+++## 2. Usage with Prelude+ First, let us load the package with **Prelude** operations:  ```Text-$ stack ghci aern2-real:lib --no-load --ghci-options AERN2.Real-*AERN2.MP> import Prelude hiding (pi)-*AERN2.MP Prelude>+$ stack ghci aern2-real:lib --no-load --ghci-options "AERN2.Real -Wno-type-defaults"+*AERN2.Real> import Prelude hiding (pi)+*AERN2.Real Prelude> ``` -We can obtain approximations of a real number with any **requested accuracies**:+We can obtain approximations of a real number with a chosen *precision*:  ```Text-...> pi ? (bits 1000)-[3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117... ± ~0.0000 ~2^(-1230)]+...> (sin 1 ::CReal) ? (prec 120)+[0.84147098480789650665250232... ± ~4.6644e-35 ~2^(-114)] -...> pi ? (bits 1000000)-[3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117... ± ~0.0000 ~2^(-1028468)]-(4.12 secs, 270,972,152 bytes)+...> (sin 1 ::CReal) ? (prec 10000)+[0.84147098480789650665250232... ± ~0.0000 ~2^(-13530)] ``` -Instead of accuracy, we can request that the computation is performed with a certain **precision**, which roughly corresponds to the number of significant bits.  This usually trades speed with guaranteed accuracy:+Notice that sometimes the accuracy of the interval is lower than the working precision.  Instead of precision, we can request that the computation is performed with a certain *guaranteed accuracy*:  ```Text-...> (sin pi) ? (bits 10000) -- guaranteed accuracy at least 10000-[-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000... ± ~0.0000 ~2^(-13539)]-(0.27 secs, 196,580,192 bytes)+...> (sin 1 ::CReal) ? (bits 120)+[0.84147098480789650665250232... ± ~2.2431e-55 ~2^(-181)] -...> (sin pi) ? (prec 10000) -- no guaranteed accuracy-[-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000... ± ~0.0000 ~2^(-13539)]-(0.21 secs, 107,844,784 bytes)+Nevertheless, this sometimes comes with a performance penalty, since internally the computation may need to be restarted with a higher accuracy:++...> sumSines n = sum [sin (creal i) | i <- [1..n::Integer]]++...> sumSines 100 ? (prec 120)+[-0.12717101366042011543675217... ± ~2.8393e-33 ~2^(-108)]+(0.03 secs, 26,203,776 bytes)++...> sumSines 100 ? (bits 120)+[-0.12717101366042011543675217... ± ~1.2220e-53 ~2^(-175)]+(0.05 secs, 60,537,128 bytes) ``` -When formatting a real number, a **default precision** is used:+Which can be obtained faster if directly guessing that we need precision at least 130:  ```Text+...> (sumSines1 100) ? (prec 130)+[-0.12717101366042011543675217... ± ~1.2220e-53 ~2^(-175)]+(0.03 secs, 35,209,088 bytes)+```++When formatting a real number, a *default precision* is used:++```Text ...> pi-{?(prec 36): [3.141592653584666550159454345703125 ± ~1.4552e-11 ~2^(-36)]}+{?(prec 36): [3.14159265358466655015945434... ± ~1.4552e-11 ~2^(-36)]} ``` -The Prelude power operator works only for integral types:+The **Prelude** power operator works only for integral types:  ```Text ...> pi ^ 2-[9.8696044010893586188344909998725639610631902560... ± ~8.1120e-30 ~2^(-96)]-{?(prec 36): [9.8696044009993784129619598388671875 ± ~1.4964e-10 ~2^(-32)]}+{?(prec 36): [9.86960440099937841296195983... ± ~1.4964e-10 ~2^(-32)]}  ...> pi ^ pi <interactive>:18:1: error:@@ -99,32 +132,54 @@ *** Exception: Failed to decide equality of Sequences.  If you switch to MixedTypesNumPrelude instead of Prelude, comparison of Sequences returns CSequence Kleenean or similar instead of Bool. ``` -## 3. Basic usage with MixedTypesNumPrelude+## 3. Usage with MixedTypesNumPrelude -We see that some things do not work with Prelude. Let us use **MixedTypesNumPrelude** operations instead:+We see that some things do not work with Prelude. Let us use [MixedTypesNumPrelude](https://hackage.haskell.org/package/mixed-types-num) operations instead:  ```Text $ stack ghci aern2-real:lib --no-load --ghci-options AERN2.Real-*AERN2.MP> import MixedTypesNumPrelude-*AERN2.MP MixedTypesNumPrelude>+*AERN2.Real> import MixedTypesNumPrelude+*AERN2.Real MixedTypesNumPrelude> ``` -We get a more general power operator:+First, our Prelude expressions +- `(sin 1 :: CReal)`+- `sum [sin (creal i) | i <- [1..n::Integer]]`++can now be simplified as follows:+ ```Text+...> :t sin 1+sin 1 :: CReal++...> sumSines n = sum [sin i | i <- [1..n]]+...> :t sumSines+sumSines :: Integer -> CReal+```++Moreover, we get a more general power operator:++```Text ...> 2^0.5-{?(prec 36): [1.414213562371930730340852514178195642186126256312482171419747717302107387071785637999710161238908... ± ~1.0305e-11 ~2^(-36)]}+{?(prec 36): [1.41421356237193073034085251... ± ~1.0305e-11 ~2^(-36)]}  ...> pi ^ pi-{?(prec 36): [36.462159605538498632520418490483602438877178488347481362195878876490337527904728176508797332644462... ± ~2.7112e-9 ~2^(-28)]}+{?(prec 36): [36.46215960553849863252041849... ± ~2.7112e-9 ~2^(-28)]}  ...> (pi ^ pi) ? (bits 10000)-[36.462159607207911770990826022692123666365508402228818738709335922934074368881699904620079875706774... ± ~0.0000 ~2^(-13532)]-(0.90 secs, 631,865,912 bytes)+[36.46215960720791177099082602... ± ~0.0000 ~2^(-13532)]+(0.83 secs, 631,232,904 bytes) ``` -Real comparison now returns a `CKleenean` instead of `Bool`, supporting undecided comparisons and comparisons with a specified precision:+Real comparison now returns a `CKleenean` instead of `Bool`, where +```Haskell+type CKleenean = CSequence Kleenean+```++As a three-value truth type, `Kleenean` supports undecided comparisons.  Being a sequence, `CKleenean` supports comparisons with a specified precision:+ ```Text ...> pi > 0 {?(prec 36): CertainTrue}@@ -139,34 +194,101 @@ CertainFalse ``` +When the numbers are known exactly, an equality test succeeds:++```Test+...> (creal 0) == 0+{?(prec 36): CertainTrue}+```+ ## 4. Partial functions and error handling -Since comparisons can be only semi-decided, also errors such as division by zero or logarithm of a negative number can be only semi-detected.-Therefore, an invalid input leads to a normal `CReal` value, and the error is demonstrated only when we extract an approximation, and sometimes an error cannot be determined with certainty:+Normally in Haskell, computation such as `1/0` or `sqrt (-1)` result in **NaN** or run-time exceptions.+Since `CReal` uses the [CN wrapper](https://hackage.haskell.org/package/collect-errors), for `CReal` these expressions instead return special values that describe the error. +Since comparisons can be only semi-decided, also such errors can be only semi-detected.+Therefore, an invalid input leads to a normal `CReal` value, and the error is demonstrated only when we extract an approximation:+ ```Text-...> bad1 = pi/0+...> bad1 = sqrt (-1) ...> bad1 ? (prec 100)-{{ERROR: division by 0}}}+{{ERROR: out of domain: negative sqrt argument}}+```+ +and sometimes an error cannot be determined with certainty: -...> bad2 = 1/(pi-pi)+```Text+...> a_third = creal (1/3)++...> bad2 = 1/(a_third-a_third) ...> bad2 ? (prec 100) {{POTENTIAL ERROR: division by 0}}++...> bad2 ? (bits 100)+{{POTENTIAL ERROR: numeric error: failed to find an approximation with sufficient accuracy}} ``` +A query for guaranteed precision may take a long time because before it fails, the computation is attempted iteratively for higher and higher precisions, up to precision around 5,000,000 bits:++```Text+...> bad3 = 1/(pi-pi)+...> bad3 ? (prec 100)+{{POTENTIAL ERROR: division by 0}}++...> bad3 ? (bits 100)+-- TAKES A VERY LONG TIME+```+ When we are sure that potential errors are harmless, we can clear them:  ```Text-...> ok3 = sqrt (pi-pi)-...> ok3 ? (prec 10)-[0.022097086912079610143710452219156792352805496193468570709228515625 ± ~2.2097e-2 ~2^(-5)]{{POTENTIAL ERROR: out of domain: negative sqrt argument}}-...> clearPotentialErrors $ ok3 ? (prec 10)-[0.022097086912079610143710452219156792352805496193468570709228515625 ± ~2.2097e-2 ~2^(-5)]+...> ok4 = sqrt (pi-pi)+...> ok4 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)]{{POTENTIAL ERROR: out of domain: negative sqrt argument}}}++...> ok5 = clearPotentialErrors $ sqrt (pi-pi)+...> ok5 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)] ``` +Attempting to clear a certain error is harmless:++```Text+...> bad6 = clearPotentialErrors (sqrt (pi-pi-1))+...> bad6 ? (prec 100)+{{ERROR: out of domain: negative sqrt argument}}+```++But clearing a potential error which is a real error is unsound:++```Text+...> bad7 = clearPotentialErrors (sqrt (pi-pi-2^(-1000)))+...> bad7 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)]+...> bad7 ? (prec 1000)+{{ERROR: out of domain: negative sqrt argument}}+```++Errors can be investigated, eg as follows:++```Text+...> detectCN r = if not (CN.hasError r) then Just r else Nothing++...> detectCN (sqrt (-1) ? (prec 100))+Nothing++...> detectCN (sqrt 0 ? (prec 100))+Just [0 ± 0]+```++There is also `CN.hasCertainError` which ignores potential errors.+ ## 5. Limits  Computing a limit of a fast converging sequence of numbers or functions is one of the most fundamental operations for real numbers.+A sequence `a_n` is fast converging if each+`a_n` is no more than `0.5^n` distant from the limit.+ For example, we can compute `e` as the limit of the partial sums of terms `1/n!` for `n` ranging from `0` onwards:  ```Text@@ -174,8 +296,18 @@ ... MixedTypesNumPrelude> e_sum n = sum $ map (recip . fact) [0..n] ``` -TODO+The difference between `e` and `e_sum n` is no more than `3/(fact (n+1))` which is less than `0.5^(n-2)`.+Thus the sequence `\n -> e_sum (n+2)` is fast converging and the following limit is valid: +```Text+...> my_e = limit $ \(n :: Integer) -> e_sum (n+2)++...> my_e ? (prec 1000)+[2.71828182845904523536028747... ± ~0.0000 ~2^(-1217)]+```++The type declaration for `n` is required because `limit` is generic and works also for sequences indexed by `Int` or even positive rational numbers.+ ## 6. Multivalued selection  When a comparison is needed for branching, its semi-decidability becomes a challenge.  As an example, consider the task of defining the `abs` function by cases.@@ -184,8 +316,9 @@ ### 6.1. Parallel branching  ```Text-... MixedTypesNumPrelude> abs1 x = if x < 0 then -x else x-... MixedTypesNumPrelude> abs1 (pi - pi)+...> absR1 x = if x < 0 then -x else x++...> absR1 (pi - pi) {?(prec 36): [0 ± ~2.9104e-11 ~2^(-35)]} ``` @@ -193,8 +326,21 @@  ### 6.2. Multi-valued selection -TODO+A more general mechanism for dealing with branching based on semi-decidable conditions such as real-number comparisons is non-deterministic `select`. If given two lazy Kleeneans, `select` will enquire them concurrently with increasing precisions until one of them becomes `CertainTrue`.  By convention `select` returns a `Bool` which is `True` if the first branch succeeds and `False` if the second branch succeeds.   +Here we use `select` to implement a *soft* sign test with some tolerance `eps` and define `absR2` to be the limit of a sequence of approximate implementations of `abs` with different `eps`:++```Text+...> absR2_approx x (q :: Rational) = if select (x > -q) (x < q) then x else -x++...> absR2 x = limit $ absR2_approx x++...> absR2 (pi - pi)+{?(prec 36): [0 ± ~4.3656e-11 ~2^(-34)]}+```+ ## 7. Specification and tests -The approximations obtained using `? (bits n)` or `? (prec p)` are intervals of type `CN MPBall` from package [aern2-mp](../aern2-mp/README.md).  This type is also used internally for all `CReal` arithmetic.  The `MPBall` arithmetic is tested against a fairly complete hspec/QuickCheck specification of algebraic properties.+Most `CReal` operations are simply lifts of the corresponding `CN MPBall` operations, which are tested in package [aern2-mp](../aern2-mp/README.md) against a fairly complete hspec/QuickCheck specification of algebraic properties.++TODO: limit and select tests
aern2-real.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack ----- hash: 2eeae9f84732bd487f03a8ca2f34af6a8da594cc92af23524cd6e594a530ad03+-- hash: dcd52485dd451831f9e0d0903913a199f2dd7764f22b7fc61f3a3b292ba85676  name:           aern2-real-version:        0.2.1.0+version:        0.2.4.0 synopsis:       Real numbers as sequences of MPBalls description:    Please see the README on GitHub at <https://github.com/michalkonecny/aern2/#readme> category:       Math@@ -38,19 +38,66 @@       AERN2.Real.Limit       AERN2.Real.Tests       AERN2.Real.Type+      AERN2.Real.Examples.ClosestPairDist+      AERN2.Real.Examples.Introduction   other-modules:       Paths_aern2_real   hs-source-dirs:       src-  default-extensions: RebindableSyntax, ScopedTypeVariables, TypeFamilies, TypeOperators, ConstraintKinds, DefaultSignatures, MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, UndecidableInstances-  other-extensions: TemplateHaskell+      examples+  default-extensions:+      RebindableSyntax,+      ScopedTypeVariables,+      TypeFamilies,+      TypeOperators,+      ConstraintKinds,+      DefaultSignatures,+      MultiParamTypeClasses,+      FlexibleContexts,+      FlexibleInstances,+      UndecidableInstances+  other-extensions:+      TemplateHaskell   ghc-options: -Wall   build-depends:       QuickCheck     , aern2-mp >=0.2.1     , base ==4.*-    , collect-errors >=0.1+    , collect-errors >=0.1.5     , hspec     , integer-logarithms-    , mixed-types-num >=0.5.1+    , mixed-types-num >=0.5.3+  default-language: Haskell2010++test-suite aern2-real-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      AERN2.RealSpec+      Paths_aern2_real+  hs-source-dirs:+      test+  default-extensions:+      RebindableSyntax,+      ScopedTypeVariables,+      TypeFamilies,+      TypeOperators,+      ConstraintKinds,+      DefaultSignatures,+      MultiParamTypeClasses,+      FlexibleContexts,+      FlexibleInstances,+      UndecidableInstances+  other-extensions:+      TemplateHaskell+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+  build-depends:+      QuickCheck+    , aern2-mp >=0.2.1+    , aern2-real+    , base ==4.*+    , collect-errors >=0.1.5+    , hspec+    , integer-logarithms+    , mixed-types-num >=0.5.3   default-language: Haskell2010
changelog.md view
@@ -1,5 +1,11 @@ # Change log for aern2-real +* v 0.2.4 2021-05-26+  * overhaul README and examples+  * stop "very inaccurate" errors breaking ? (bits n) queries+  * optimisation: ? (bits n) queries start from precision n+  * add tests for accuracy queries, limit and select+  * fix div by 0 during low-accuracy integer powers * v 0.2.1 2021-05-18   * add conversion from WithAnyPrec * v 0.2.0 2021-05-17
+ examples/AERN2/Real/Examples/ClosestPairDist.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE PartialTypeSignatures #-}+{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}+{-|+    Module      :  AERN2.Real.Introduction+    Description :  aern2-real introductory examples+    Copyright   :  (c) Michal Konecny+    License     :  BSD3++    Maintainer  :  mikkonecny@gmail.com+    Stability   :  experimental+    Portability :  portable++    You can run the examples in this file in ghci.+    If you installed AERN2 using the official instructions,+    you can start ghci using the following command in the base+    folder:++    @+    stack repl aern2-real/examples/AERN2/Real/Examples/ClosestPairDist.hs+    @+-}+module AERN2.Real.Examples.ClosestPairDist where++import MixedTypesNumPrelude+-- import qualified Prelude as P+-- import Text.Printf++import Test.QuickCheck+import qualified Data.List as List++import AERN2.MP+import AERN2.Real++-- import Debug.Trace++-- define a short name for the type of real numbers:+type R = CReal++----------------------------------+-- Finding the smallest distance within a set of real numbers+----------------------------------++closestPairDist_naive ::+  _ => [t] -> t+closestPairDist_naive pts+  | length pts < 2 = error "closestPairDist_naive: too few points"+  | otherwise =+      (foldl1 min (map distance (distinctPairs pts)))++distance :: (CanSubSameType t, CanAbsSameType t) => (t, t) -> t+distance (a,b) = abs (a-b)++closestPairDist_run ::+  _ =>+  ([t] -> t) ->+  Integer -> t+closestPairDist_run (closestPairDist :: [t] -> t) n =+  closestPairDist [sin (convertExactly i :: t) | i <- [1..n]]++closestPairDist_run_naive :: Integer -> R+closestPairDist_run_naive =+  closestPairDist_run closestPairDist_naive ++closestPairDist_run_split :: Integer -> R+closestPairDist_run_split =+  closestPairDist_run $ closestPairDist_split compRApprox++{- Example runs:++*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_naive 1000 ? (prec 1000)+[0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]+(13.80 secs, 12,017,593,904 bytes)++*AERN2.Real.Examples.ClosestPairDist> closestPairDist_run_split 1000 ? (prec 1000)+[0.00000013295546744391165086... ± ~0.0000 ~2^(-1221)]+(4.95 secs, 9,979,768,504 bytes)++-}++{- specification and randomised tests -}++closestPairDist_spec closestPairDist (getFinite :: r -> t) numbers =+  (length numbers) < 2+  .||.+  (getFinite (closestPairDist numbersR)) ?==?$ (closestPairDist_naive numbers)+  where+  numbersR = map convertExactly numbers :: [r]+  a ?==?$ b = printArgsIfFails2 "?==?" (?==?) a b++closestPairDist_runTests1 =+  quickCheck (closestPairDist_spec (closestPairDist_split compRApprox) (?bits 100) :: [Integer] -> Property)+closestPairDist_runTests2 =+  quickCheck (closestPairDist_spec (closestPairDist_split compMPBall) id :: [Integer] -> Property)++sample_integers = sample' (arbitrary :: Gen [Integer]) >>= mapM_ print+sample_rationals = sample' (arbitrary :: Gen [Rational]) >>= mapM_ print++{- a version that splits, recurses and merges the results -}+closestPairDist_split ::+  _ => (t -> t -> Bool) -> [t] -> t+closestPairDist_split (.<) pts+  | length ptsL < 2 || length ptsR < 2 =+      closestPairDist_naive pts+  | otherwise =+      recurseAndMerge+  where+  (ptsL,ptsR) = List.partition isCertainlyLeft pts+    where+    isCertainlyLeft x = x .< average pts+  recurseAndMerge =+    foldl1 min [dL, dLR, dR]+    where+    dL = closestPairDist_split (.<) ptsL+    dLR = distance (largest ptsL, smallest ptsR)+    dR = closestPairDist_split (.<) ptsR++compRApprox :: R -> R -> Bool+compRApprox a b = (a?ac) !<! (b?ac)+  where+  ac = bits 100++compMPBall :: MPBall -> MPBall -> Bool+compMPBall = (!<!)++{- auxiliary functions -}++-- hull :: MPBall -> MPBall -> MPBall+-- hull = hullMPBall++average :: (HasIntegers t, CanAddSameType t, CanDivBy t Integer) => [t] -> t+average xs = (sum xs) / (length xs)++largest :: (CanMinMaxSameType t) => [t] -> t+largest pts = foldl1 max pts++smallest :: (CanMinMaxSameType t) => [t] -> t+smallest pts = foldl1 min pts++distinctPairs :: [t] -> [(t,t)]+distinctPairs xs = [(x,y) | (x:rest) <- tails1 xs, y <- rest]++{-| non-empty tails -}+tails1 :: [t] -> [[t]]+tails1 list =+  take (length list - 1) $ List.tails list
+ examples/AERN2/Real/Examples/Introduction.hs view
@@ -0,0 +1,294 @@+{-# LANGUAGE PartialTypeSignatures #-}+{-# OPTIONS_GHC -Wno-missing-signatures #-}+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}+{-|+    Module      :  AERN2.Real.Examples.Introduction+    Description :  aern2-real introductory examples+    Copyright   :  (c) Michal Konecny+    License     :  BSD3++    Maintainer  :  mikkonecny@gmail.com+    Stability   :  experimental+    Portability :  portable++    Introductory examples for packages aern2-mp and aern2-real.++    Please see aern2-real/README.md for explanations.++    You can run the following examples in ghci.+    If you installed AERN2 using the official instructions,+    you can start ghci using the following command in the base+    folder:++    @+    stack repl aern2-real/examples/AERN2/Real/Examples/Introduction.hs+    @+-}+module AERN2.Real.Examples.Introduction where++import MixedTypesNumPrelude++import qualified Numeric.CollectErrors as CN++import AERN2.MP+import AERN2.Real++-- import Debug.Trace++------------------------------+-- real numbers+------------------------------++-- Start with a simple real number:++sine1 = sin 1++sine1_run1 = sine1 ? (prec 120)+-- result: [0.84147098480789650665250232... ± ~4.6644e-35 ~2^(-114)]+sine1_run2 = sine1 ? (bits 120)+-- result: [0.84147098480789650665250232... ± ~2.2431e-55 ~2^(-181)]++-- Next, do a bit more work:++sumSines1 :: Integer -> CReal+sumSines1 n = sum [sin i | i <- [1..n]]++-- Request the above expression with n = 100 using roughly 100 significant binary digits:+sumSines1_run1 :: CN MPBall+sumSines1_run1 = (sumSines1 100) ? (prec 120)+{- ghci log:++*AERN2.Real.Introduction> sumSines1_run1+[-0.12717101366042011543675217... ± ~2.8393e-33 ~2^(-108)]+(0.03 secs, 26,203,776 bytes)+-}++-- Same as above but request guaranteed 100 bits of accuracy:+sumSines1_run2 = (sumSines1 100) ? (bits 100)+{- ghci log:++*AERN2.Real.Introduction> sumSines1_run2+[-0.12717101366042011543675217... ± ~2.8393e-33 ~2^(-108)]+(0.19 secs, 319,789,600 bytes)++This is considetably slower because there is some backtracking when target accuracy is not reached.  +-}++------------------------------+-- real number comparisons+------------------------------++{-+  First consider comparisons of real number approximations.+  These may be decided or undecided, using a 'Kleenean'.+-}++pi100 :: CN MPBall+pi100 = pi?(bits 100)++compare_run1 :: CN Kleenean+compare_run1 = pi100 > 0+-- returns: CertainTrue++compare_run2 :: CN Kleenean+compare_run2 = pi100 == pi100+-- returns: TrueOrFalse++compare_run3 :: CKleenean+compare_run3 = pi > 0+-- in ghci prints: {?(prec 36): CertainTrue}+-- (evaluated using default precision 36)++compare_run4 = pi == pi + 2^(-100)+-- in ghci prints: {?(prec 36): TrueOrFalse}++compare_run5 = (pi == pi + 2^(-100)) ? (prec 1000)+-- returns: CertainFalse++compare_run6 = (creal 0) == 0+-- in ghci prints: {?(prec 36): CertainTrue}+-- this is decided in finite time because 0 is represented exactly++compare_run7 = pi == pi ? (prec 10000)+-- returns: TrueOrFalse+-- (cannot confirm pi=pi in finite time)++------------------------------+-- checking partial functions+------------------------------++partialfn_bad1 = sqrt (-1)+{- ghci log:++*AERN2.Real.Introduction> partialfn_bad1 ? (bits 100)+{{ERROR: out of domain: negative sqrt argument}}++-}++a_third = creal (1/3)++partialfn_bad2 = 1/(a_third-a_third)+{- ghci log:++*AERN2.Real.Introduction> partialfn_bad2 ? (prec 100)+{{POTENTIAL ERROR: division by 0}}++*AERN2.Real.Introduction> partialfn_bad2 ? (bits 100)+{{POTENTIAL ERROR: numeric error: failed to find an approximation with sufficient accuracy}}++-}++partialfn_bad3 = 1/(pi-pi)+{- ghci log:++*AERN2.Real.Introduction> partialfn_bad3 ? (prec 100)+{{POTENTIAL ERROR: division by 0}}++*AERN2.Real.Introduction> partialfn_bad3 ? (bits 100)+-- TAKES A VERY LONG TIME++-}++{-+ When computing on approximations which do not have enough information+ to check whether an error occurs, we get a *potential* error:+-}++partialfn_ok4 = sqrt (pi-pi)+{- ghci log:++*AERN2.Real.Introduction> partialfn_ok4 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)]{{POTENTIAL ERROR: out of domain: negative sqrt argument}}+-}++partialfn_ok5 = clearPotentialErrors (sqrt (pi-pi))+{- ghci log:++*AERN2.Real.Introduction> partialfn_ok5 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)]++-}++partialfn_bad6 = clearPotentialErrors (sqrt (pi-pi-1))+{- ghci log:++*AERN2.Real.Introduction> partialfn_bad6 ? (prec 100) +{{ERROR: out of domain: negative sqrt argument}}++-}++partialfn_bad7 = clearPotentialErrors (sqrt (pi-pi-2^(-1000)))+{- ghci log:++*AERN2.Real.Introduction> partialfn_bad7 ? (prec 100)+[0.00000000000000000061331736... ± ~6.1332e-19 ~2^(-60)]++*AERN2.Real.Introduction> partialfn_bad7 ? (prec 1000)+{{ERROR: out of domain: negative sqrt argument}}++-}++detectCN :: CN.CanTestErrorsPresent a => a -> Maybe a+detectCN r = if not (CN.hasError r) then Just r else Nothing+{- ghci log:++*AERN2.Real.Introduction> detectCN (sqrt (-1) ? (prec 100))+Nothing++*AERN2.Real.Introduction> detectCN (sqrt 0 ? (prec 100))+Just [0 ± 0]++-}++---------------------------------+-- Computing limits+--------------------------------++fact :: Integer -> CReal+fact n = creal $ product [1..n]++e_sum :: Integer -> CReal+e_sum n = sum $ map (recip . fact) [0..n]++my_e :: CReal+my_e = limit $ \(n :: Integer) -> e_sum (n+2)++{- ghci log:++*AERN2.Real.Introduction> my_e ? (prec 1000)+[2.71828182845904523536028747... ± ~0.0000 ~2^(-1217)]++-}++-- a faster version:++e_sum2 :: Integer -> CReal+e_sum2 n = foldl aux (creal 1) $ reverse [1..n]+  where aux x m = 1 + x / m++my_e2 :: CReal+my_e2 = limit $ \(n :: Integer) -> e_sum2 (n+2)++---------------------------------+-- "parallel" branching for real numbers+--------------------------------++absQ :: Rational -> Rational+absQ x = if x < 0 then -x else x++absR1 :: CReal -> CReal+absR1 x = if x < 0 then -x else x+++pif_run1 = absR1 (pi-pi)+{- ghci log:++*AERN2.Real.Introduction> pif_run1+{?(prec 36): [0 ± ~2.9104e-11 ~2^(-35)]}++-}++-- pif_run2 = foldl1 (.) (replicate 100 (absR1 . (100*))) (pi-pi)++absR2_approx x (q :: Rational) = if select (x > -q) (x < q) then x else -x++absR2 :: CReal -> CReal+absR2 x = limit $ absR2_approx x++select_run1 = absR2 (pi-pi)+{- ghci log:++*AERN2.Real.Introduction> select_run1+{?(prec 36): [0 ± ~4.3656e-11 ~2^(-34)]}++-}++-----------------------------------------+-- Cauchy reals vs iRRAM style execution+-----------------------------------------++logistic1 :: _ => Rational -> Integer -> t -> t+logistic1 c n x0 =+  (foldl1 (.) (replicate n lg)) x0+  where+  lg x = c * x * (1-x)++logistic1_CReal_run :: Integer -> CReal+logistic1_CReal_run n = logistic1 3.82 n (creal 0.5)++-- TODO: define logistic1_iter++{-  Example uses:++*AERN2.Real.Examples.Introduction> logistic1_CReal_run 100 ? (bits 100)+[0.95087585116480286419338875... ± ~2.9792e-32 ~2^(-104)]+  +*AERN2.Real.Examples.Introduction> logistic1_CReal_run 10000 ? (bits 100)+[0.20775682944252359241450861... ± ~0.0000 ~2^(-2566)]+(2.06 secs, 2,970,188,704 bytes)++-}++{-+  Recommended further reading:  ClosestPairDist.hs+-}
src/AERN2/Real/Tests.hs view
@@ -14,12 +14,12 @@     To run the tests using stack, execute:      @-    stack test aern2-real --test-arguments "-a 1000 -m Real"+    stack test aern2-real --test-arguments "-a 1000 -m CReal"     @ -} module AERN2.Real.Tests   (-    -- specCauchyReal, tCReal+    specCReal, tCReal   ) where @@ -40,8 +40,12 @@ import AERN2.MP import AERN2.MP.Dyadic +import AERN2.Limit import AERN2.Real.Type+import AERN2.Real.CKleenean import AERN2.Real.Field ()+import AERN2.Real.Elementary ()+import AERN2.Real.Limit ()  instance Arbitrary CReal where   arbitrary =@@ -75,12 +79,12 @@         nextBit _ _ = error "in Arbitrary CReal"  arbitrarySmall :: (Arbitrary a, HasOrderCertainly a Integer) => Integer -> Gen a-arbitrarySmall limit = aux+arbitrarySmall bound = aux   where   aux =     do     x <- arbitrary-    if -limit !<=! x && x !<=! limit+    if -bound !<=! x && x !<=! bound       then return x       else aux @@ -92,9 +96,6 @@ tCReal :: T CReal tCReal = T "CReal" --- tCauchyRealAtAccuracy :: T CauchyRealAtAccuracy--- tCauchyRealAtAccuracy = T "CReal(ac)"- specCRrespectsAccuracy1 ::   String ->   (CReal -> CReal) ->@@ -109,6 +110,21 @@           Right v -> getAccuracy v >=$ ac           _ -> property True +specCRrespectsAccuracy2 ::+  String ->+  (CReal -> CReal -> CReal) ->+  (CReal -> Accuracy -> Bool) ->+  (CReal -> Accuracy -> Bool) ->+  Spec+specCRrespectsAccuracy2 opName op precond1 precond2 =+  it (opName ++ " respects accuracy requests") $ do+    property $+      \ (x :: CReal) (y :: CReal) (ac :: Accuracy) ->+        ac < (bits 1000) && precond1 x ac && precond2 y ac ==>+        case CN.toEither ((op x y) ? ac) of+          Right v -> getAccuracy v >=$ ac+          _ -> property True+ (>=$) :: Accuracy -> Accuracy -> Property (>=$) = printArgsIfFails2 ">=" (>=) @@ -137,50 +153,22 @@ -- specCRrespectsAccuracy2 opName op = --   specCRrespectsAccuracy2CN opName (\ a b -> cn (op a b)) --- specCRrespectsAccuracy2CN ::---   String ->---   (CReal -> CReal -> CauchyRealCN) ->---   (CReal -> Accuracy -> Bool) ->---   (CReal -> Accuracy -> Bool) ->---   Spec--- specCRrespectsAccuracy2CN opName op precond1 precond2 =---   it (opName ++ " respects accuracy requests") $ do---     property $---       \ (x :: CReal) (y :: CReal) (ac :: Accuracy) ->---         let acSG = accuracySG ac in---         ac < (bits 1000) && precond1 x acSG && precond2 y acSG  ==>---         case getMaybeValueCN ((op x y) ? acSG) of---           Just v -> getAccuracy v >=$ ac-          -- _ -> property True---- specCRrespectsAccuracy2T ::---   (Arbitrary t, Show t) =>---   T t ->---   String ->---   (CReal -> t -> CReal) ->---   (CReal -> Accuracy -> Bool) ->---   (t -> Bool) ->---   Spec--- specCRrespectsAccuracy2T tt opName op =---   specCRrespectsAccuracy2TCN tt opName (\ a b -> cn (op a b))---- specCRrespectsAccuracy2TCN ::---   (Arbitrary t, Show t) =>---   T t ->---   String ->---   (CReal -> t -> CauchyRealCN) ->---   (CReal -> Accuracy -> Bool) ->---   (t -> Bool) ->---   Spec--- specCRrespectsAccuracy2TCN (T tName :: T t) opName op precond1 precond2 =---   it (opName ++ " with " ++ tName ++ " respects accuracy requests") $ do---     property $---       \ (x :: CReal) (t :: t) (ac :: Accuracy) ->---         let acSG = accuracySG ac in---         ac < (bits 1000) && precond1 x acSG && precond2 t  ==>---         case getMaybeValueCN ((op x t) ? acSG) of---           Just v -> getAccuracy v >=$ ac---           _ -> property True+specCRrespectsAccuracy2T ::+  (Arbitrary t, Show t) =>+  T t ->+  String ->+  (CReal -> t -> CReal) ->+  (CReal -> Accuracy -> Bool) ->+  (t -> Bool) ->+  Spec+specCRrespectsAccuracy2T  (T tName :: T t) opName op precond1 precond2 =+  it (opName ++ " with " ++ tName ++ " respects accuracy requests") $ do+    property $+      \ (x :: CReal) (t :: t) (ac :: Accuracy) ->+        ac < (bits 1000) && precond1 x ac && precond2 t ==>+        case CN.toEither ((op x t) ? ac) of+          Right v -> getAccuracy v >=$ ac+          _ -> property True  precondAnyT :: t -> Bool precondAnyT _t = True@@ -191,46 +179,58 @@ precondSmallT :: (HasOrderCertainly t Integer) => t -> Bool precondSmallT t = -1000 !<=! t && t !<=! 1000 --- specCauchyReal :: Spec--- specCauchyReal =---   describe ("CReal") $ do---     -- specConversion tInteger tCauchyReal real (fst . integerBounds)---     describe "order" $ do---       specHasEqNotMixed tCReal---       -- specHasEq tInt tCReal tRational---       -- specCanPickNonZero tCReal---       specHasOrderNotMixed tCReal---       -- specHasOrder tInt tCReal tRational-    -- describe "min/max/abs" $ do-    --   specCRrespectsAccuracy1 "abs" abs precondAnyReal-    --   specCRrespectsAccuracy2 "max" max precondAnyReal precondAnyReal-    --   specCRrespectsAccuracy2 "min" min precondAnyReal precondAnyReal-    -- describe "ring" $ do-    --   specCRrespectsAccuracy1 "negate" negate precondAnyReal-    --   specCRrespectsAccuracy2 "+" add precondAnyReal precondAnyReal-    --   specCRrespectsAccuracy2T tInteger "+" add precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tRational "+" add precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tDyadic "+" add precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2 "a-b" sub precondAnyReal precondAnyReal-    --   specCRrespectsAccuracy2T tInteger "a-b" sub precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tRational "a-b" sub precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tDyadic "a-b" sub precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2 "*" mul precondAnyReal precondAnyReal-    --   specCRrespectsAccuracy2T tInteger "*" mul precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tRational "*" mul precondAnyReal precondAnyT-    --   specCRrespectsAccuracy2T tDyadic "*" mul precondAnyReal precondAnyT-    -- describe "field" $ do-    --   specCRrespectsAccuracy2CN "/" divide precondAnyReal precondNonZeroReal-    --   specCRrespectsAccuracy2TCN tInteger "/" divide precondAnyReal precondNonZeroT-    --   specCRrespectsAccuracy2TCN tRational "/" divide precondAnyReal precondNonZeroT-    --   specCRrespectsAccuracy2TCN tDyadic "/" divide precondAnyReal precondNonZeroT-    -- describe "elementary" $ do-    --   specCRrespectsAccuracy1CN "sqrt" sqrt precondPositiveReal-    --   specCRrespectsAccuracy1 "exp" exp precondSmallReal-    --   specCRrespectsAccuracy1CN "log" log precondPositiveSmallReal-    --   specCRrespectsAccuracy2CN "pow" pow precondPositiveSmallReal precondSmallReal-    --   specCRrespectsAccuracy2TCN tInteger "pow" pow precondNonZeroReal precondSmallT-    --   specCRrespectsAccuracy2TCN tRational "pow" pow precondPositiveSmallReal precondSmallT-    --   specCRrespectsAccuracy2TCN tDyadic "pow" pow precondPositiveSmallReal precondSmallT-    --   specCRrespectsAccuracy1 "cos" cos precondAnyReal-    --   specCRrespectsAccuracy1 "sine" sin precondAnyReal+specCReal :: Spec+specCReal =+  describe ("CReal") $ do+    -- specConversion tInteger tCReal creal (fst . integerBounds)+    -- describe "order" $ do+    --   specHasEqNotMixed tCReal+    --   specHasEq tInt tCReal tRational+    --   specCanPickNonZero tCReal+    --   specHasOrderNotMixed tCReal+    --   specHasOrder tInt tCReal tRational+    describe "min/max/abs" $ do+      specCRrespectsAccuracy1 "abs" abs precondAnyReal+      specCRrespectsAccuracy2 "max" max precondAnyReal precondAnyReal+      specCRrespectsAccuracy2 "min" min precondAnyReal precondAnyReal+    describe "ring" $ do+      specCRrespectsAccuracy1 "negate" negate precondAnyReal+      specCRrespectsAccuracy2 "+" add precondAnyReal precondAnyReal+      specCRrespectsAccuracy2T tInteger "+" add precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tRational "+" add precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tDyadic "+" add precondAnyReal precondAnyT+      specCRrespectsAccuracy2 "a-b" sub precondAnyReal precondAnyReal+      specCRrespectsAccuracy2T tInteger "a-b" sub precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tRational "a-b" sub precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tDyadic "a-b" sub precondAnyReal precondAnyT+      specCRrespectsAccuracy2 "*" mul precondAnyReal precondAnyReal+      specCRrespectsAccuracy2T tInteger "*" mul precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tRational "*" mul precondAnyReal precondAnyT+      specCRrespectsAccuracy2T tDyadic "*" mul precondAnyReal precondAnyT+    describe "field" $ do+      specCRrespectsAccuracy2 "/" divide precondAnyReal precondNonZeroReal+      specCRrespectsAccuracy2T tInteger "/" divide precondAnyReal precondNonZeroT+      specCRrespectsAccuracy2T tRational "/" divide precondAnyReal precondNonZeroT+      specCRrespectsAccuracy2T tDyadic "/" divide precondAnyReal precondNonZeroT+    describe "elementary" $ do+      specCRrespectsAccuracy1 "sqrt" sqrt precondPositiveReal+      specCRrespectsAccuracy1 "exp" exp precondSmallReal+      specCRrespectsAccuracy1 "log" log precondPositiveSmallReal+      specCRrespectsAccuracy2 "pow" pow precondPositiveSmallReal precondSmallReal+      specCRrespectsAccuracy2T tInteger "pow" pow precondNonZeroReal precondSmallT+      specCRrespectsAccuracy2T tRational "pow" pow precondPositiveSmallReal precondSmallT+      -- specCRrespectsAccuracy2T tDyadic "pow" pow precondPositiveSmallReal precondSmallT+      specCRrespectsAccuracy1 "cos" cos precondAnyReal+      specCRrespectsAccuracy1 "sine" sin precondAnyReal+    describe "select" $ do+      it "soft abs via select" $ do+        property $ \ (x :: CReal) (p :: Precision) (q :: Rational) ->+          (1 < q) ==>+          let eps = 1/q in+          (abs (abs x - (if select (x > -eps) (x < eps) then x else -x)) ? p) ?<? 2*eps+    describe "limit" $ do+      it "computing e as a limit of Taylor series" $ do+        property $ \ (p :: Precision) ->+          ((exp (mpBallP p 1.0)) ?==?) $+            (limit $ \(n :: Integer) -> sum $ map (recip . creal) $ take (n+3) $ scanl (*) 1 [1..(n)]) ? p+
src/AERN2/Real/Type.hs view
@@ -75,9 +75,15 @@   where   withP p = runWithPrec p withCurrentP :: CN b -crealFromWithCurrentPrec :: (forall p. (KnownNat p) => WithCurrentPrec (CN MPBall) p) -> CReal-crealFromWithCurrentPrec = cseqFromWithCurrentPrec+{- Error handling -} +instance CN.CanTakeErrors CN.NumErrors (CSequence t) where+  takeErrors es (CSequence s) = CSequence $ map (CN.takeErrors es) s+  takeErrorsNoValue es = CSequence $ repeat (CN.takeErrorsNoValue es)++instance CN.CanClearPotentialErrors (CSequence t) where+  clearPotentialErrors (CSequence s) = CSequence $ map clearPotentialErrors s+ {- Cauchy real numbers -}  type CReal = CSequence MPBall@@ -106,8 +112,14 @@  instance (HasAccuracy t) => CanExtractApproximation (CSequence t) Accuracy where   type ExtractedApproximation (CSequence t) Accuracy = CN t-  extractApproximation (CSequence s) ac = aux s-    where+  extractApproximation (CSequence s) ac = +    aux $ drop (cseqIndexForPrecision p - 1) s+    where    +    p = +      case ac of +        Exact -> defaultPrecision+        NoInformation -> prec 2+        _ -> ac2prec ac     aux (bCN : rest)        | CN.hasCertainError bCN = bCN       | getAccuracy bCN >= ac = bCN@@ -147,7 +159,7 @@   safeConvertExactly = safeConvertExactly . rational  instance ConvertibleExactly (WithAnyPrec (CN MPBall)) CReal where-  safeConvertExactly (WithAnyPrec wcp) = Right $ crealFromWithCurrentPrec wcp+  safeConvertExactly (WithAnyPrec wcp) = Right $ cseqFromWithCurrentPrec wcp  _example1 :: CReal _example1 = creal 1.0
+ test/AERN2/RealSpec.hs view
@@ -0,0 +1,20 @@+{-|+    Module      :  AERN2.RealSpec+    Description :  hspec tests for CauchyReal+    Copyright   :  (c) Michal Konecny+    License     :  BSD3++    Maintainer  :  mikkonecny@gmail.com+    Stability   :  experimental+    Portability :  portable+-}++module AERN2.RealSpec (spec) where++-- import MixedTypesNumPrelude+import AERN2.Real.Tests++import Test.Hspec++spec :: Spec+spec = specCReal
+ test/Spec.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}