{-# OPTIONS_GHC -Wno-orphans #-}
{-|
    Module      :  AERN2.MP.Float.Tests
    Description :  Tests for operations on arbitrary precision floats
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mikkonecny@gmail.com
    Stability   :  experimental
    Portability :  portable

    Tests for operations on arbitrary precision floats.

    To run the tests using stack, execute:

    @
    stack test aern2-mp --test-arguments "-a 1000"
    @

    Or to run only MPFloat tests, execute:

    @
    stack test aern2-mp --test-arguments "-a 1000 -m MPFloat"
    @
-}
module AERN2.MP.Float.Tests
  (
    specMPFloat, tMPFloat
    , enforceRangeMP
    , approxEqual, approxEqualWithArgs
    , frequencyElements
  )
where

import MixedTypesNumPrelude
-- import qualified Prelude as P
-- import Data.Ratio
import Text.Printf
import Data.Maybe ( catMaybes )

import Test.Hspec
import Test.QuickCheck
-- import qualified Test.Hspec.SmallCheck as SC

-- import qualified Numeric.CollectErrors as CN

import AERN2.Norm
import AERN2.MP.Precision
import AERN2.MP.Float.Auxi

import AERN2.MP.Float.Type
import AERN2.MP.Float.Arithmetic
import AERN2.MP.Float.Conversions

import AERN2.MP.Float.Operators

instance Arbitrary MPFloat where
  arbitrary :: Gen MPFloat
arbitrary =
    do
    Bool
giveSpecialValue <- forall t a. ConvertibleExactly t Int => [(t, a)] -> Gen a
frequencyElements [(Integer
9, Bool
False),(Integer
1, Bool
True)]
    Bool -> Gen MPFloat
aux Bool
giveSpecialValue
    where
      aux :: Bool -> Gen MPFloat
aux Bool
giveSpecialValue
        | Bool
giveSpecialValue =
            forall a. [a] -> Gen a
elements [MPFloat
nan, MPFloat
infinity, -MPFloat
infinity, MPFloat
zero, MPFloat
one, -MPFloat
one]
        | Bool
otherwise =
          do
          (Precision
p :: Precision) <- forall a. Arbitrary a => Gen a
arbitrary
          (Integer
s :: Integer) <- forall a. Arbitrary a => Gen a
arbitrary
          Integer
ex <- forall a. Random a => (a, a) -> Gen a
choose (-Integer
20,Integer
10)
          let resultR :: MulType Integer Rational
resultR = Integer
s forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
* (Rational
10.0forall t1 t2. CanPow t1 t2 => t1 -> t2 -> PowType t1 t2
^Integer
ex)
          let result :: MPFloat
result = forall a. BoundsCEDU a -> a
ceduCentre forall a b. (a -> b) -> a -> b
$ Precision -> Rational -> BoundsCEDU MPFloat
fromRationalCEDU Precision
p MulType Integer Rational
resultR
          forall (m :: * -> *) a. Monad m => a -> m a
return MPFloat
result

frequencyElements :: ConvertibleExactly t Int => [(t, a)] -> Gen a
frequencyElements :: forall t a. ConvertibleExactly t Int => [(t, a)] -> Gen a
frequencyElements [(t, a)]
elems = forall a. [(Int, Gen a)] -> Gen a
frequency [(forall t. CanBeInt t => t -> Int
int t
n, forall (m :: * -> *) a. Monad m => a -> m a
return a
e) | (t
n,a
e) <- [(t, a)]
elems]

{-| 
    @enforceRange (Just l, Just u) a@ where @l < u@ returns an arbitrary value @b@ with @u < b < l@.
    Moreover, the returned values are distributed roughly evenly if the input values @a@ are distributed 
    roughly evenly in a large neighbourhood of the interval @[l,r]@.
    In most cases, when @l<a<u@, then @b=a@.
-}
enforceRangeMP ::
    (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP :: (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (Maybe Integer, Maybe Integer)
_ MPFloat
a
    | forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
a = MPFloat
a -- pass NaN unchanged
enforceRangeMP (Just Integer
l_, Just Integer
u_) MPFloat
a
    | forall t. CanNeg t => t -> NegType t
not (MPFloat
l forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u) = forall a. HasCallStack => String -> a
error String
"enforceRange: inconsistent range"
    | forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = (MPFloat
u MPFloat -> MPFloat -> MPFloat
-^ MPFloat
l)MPFloat -> MPFloat -> MPFloat
/^MPFloat
two
    | MPFloat
l forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
a forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat
a forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u = MPFloat
a
    | MPFloat
l forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
b forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat
b forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u = MPFloat
b
    | Bool
otherwise = (MPFloat
u MPFloat -> MPFloat -> MPFloat
-^ MPFloat
l)MPFloat -> MPFloat -> MPFloat
/^MPFloat
two
    where
    l :: MPFloat
l = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
l_
    u :: MPFloat
u = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
u_
    b :: MPFloat
b = MPFloat
l MPFloat -> MPFloat -> MPFloat
+^ ((forall t. CanAbs t => t -> AbsType t
abs MPFloat
a) forall t1 t2. CanDivIMod t1 t2 => t1 -> t2 -> ModType t1 t2
`mod` (MPFloat
uMPFloat -> MPFloat -> MPFloat
-^MPFloat
l))
enforceRangeMP (Just Integer
l_, Maybe Integer
_) MPFloat
a
    | forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = forall t. CanAbs t => t -> AbsType t
abs MPFloat
a
    | MPFloat
l forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
a = MPFloat
a
    | MPFloat
l forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== MPFloat
a = MPFloat
a MPFloat -> MPFloat -> MPFloat
+^ MPFloat
one
    | Bool
otherwise = (MPFloat
twoMPFloat -> MPFloat -> MPFloat
*^MPFloat
l MPFloat -> MPFloat -> MPFloat
-^ MPFloat
a)
    where
    l :: MPFloat
l = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
l_
enforceRangeMP (Maybe Integer
_, Just Integer
u_) MPFloat
a
    | forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = - (forall t. CanAbs t => t -> AbsType t
abs MPFloat
a)
    | MPFloat
a forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u = MPFloat
a
    | MPFloat
a forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== MPFloat
u = MPFloat
a MPFloat -> MPFloat -> MPFloat
-. MPFloat
one
    | Bool
otherwise = (MPFloat
twoMPFloat -> MPFloat -> MPFloat
*.MPFloat
u MPFloat -> MPFloat -> MPFloat
-. MPFloat
a)
    where
    u :: MPFloat
u = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
u_
enforceRangeMP (Maybe Integer, Maybe Integer)
_ MPFloat
a = MPFloat
a

instance CanDivIMod MPFloat MPFloat where
  type DivIType MPFloat MPFloat = Integer
  divIMod :: MPFloat
-> MPFloat -> (DivIType MPFloat MPFloat, ModType MPFloat MPFloat)
divIMod MPFloat
x MPFloat
m
    | (forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
m)) = ((RoundType MPFloat
d :: Integer), MPFloat
xm)
    | (forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
x)) = ((RoundType MPFloat
d :: Integer), MPFloat
xm)
    | MPFloat
m forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> MPFloat
zero = (RoundType MPFloat
d, MPFloat
xm)
    | Bool
otherwise = ((RoundType MPFloat
d :: Integer), MPFloat
xm)
    where
    d :: RoundType MPFloat
d = forall t. CanRound t => t -> RoundType t
floor (MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
m)
    xm :: MPFloat
xm = MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat RoundType MPFloat
d)MPFloat -> MPFloat -> MPFloat
*^MPFloat
m
    -- errM :: (CanEnsureCN t) => t -> EnsureCN t
    -- errM s = CN.noValueNumErrorCertain $ CN.OutOfDomain $ "modulus not finite and positive: " ++ show m
    -- errX :: (CanEnsureCN t) => t -> EnsureCN t
    -- errX s = CN.noValueNumErrorCertain$ CN.OutOfDomain $ "modulus input not finite: " ++ show x


{- approximate comparison -}

-- infix 4 =~=

-- (=~=) :: MPFloat -> MPFloat -> Property
-- l =~= r =
--   approxEqualWithArgs 1 [(l, "L"),(r, "R")] l r

{-|
  Assert equality of two MPFloat's with tolerance @1/2^p@.
-}
approxEqual ::
  Integer {-^ @p@ precision to guide tolerance -} ->
  MPFloat {-^ LHS of equation-} ->
  MPFloat {-^ RHS of equation -}->
  Bool
approxEqual :: Integer -> MPFloat -> MPFloat -> Bool
approxEqual Integer
e MPFloat
x MPFloat
y
  | forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
True
  | forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y = Bool
True
  | forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
True
  | forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
False
  | forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y = MPFloat
x forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== MPFloat
y
  | Bool
otherwise =
      forall t. CanAbs t => t -> AbsType t
abs (MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y) forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
<= Rational
0.5forall t1 t2. CanPow t1 t2 => t1 -> t2 -> PowType t1 t2
^Integer
e

{-|
  Assert equality of two MPFloat's with tolerance derived from the given list of input and intermediate values
  and their differentials (ie the derivative of the result wrt this value).
  The difference in the left and right results is expected to share at least as many significant digits
  as the worst error step among the input and intermediate numbers shifted by the slope of the differential
  minus the given precision loss parameter.

  When the assertion fails, report the given values using the given names.
-}
approxEqualWithArgs ::
  Integer {-^ bits of extra precision loss allowed -} ->
  [(MPFloat, MPFloat, String)] {-^ intermediate values from which to determine tolerance, their names to report when the equality fails -} ->
  MPFloat {-^ LHS of equation-} ->
  MPFloat {-^ RHS of equation -}->
  Property
approxEqualWithArgs :: Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
precLoss [(MPFloat, MPFloat, String)]
args MPFloat
l MPFloat
r =
  forall prop. Testable prop => String -> prop -> Property
counterexample String
description forall a b. (a -> b) -> a -> b
$ Integer -> MPFloat -> MPFloat -> Bool
approxEqual SubType Integer Integer
e MPFloat
l MPFloat
r
  where
  description :: String
description =
    forall r. PrintfType r => String -> r
printf String
"args:\n%s tolerance: <= 2^(%d)" String
argsS (-SubType Integer Integer
e)
  argsS :: String
argsS =
    [String] -> String
unlines
      [forall r. PrintfType r => String -> r
printf String
"    %s = %s ~ %s bits (dR/d%s = %s ~ %s bits)" 
                String
argS (forall a. Show a => a -> String
show MPFloat
arg) (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ Approx -> Maybe Int
getErrorStepSizeLog forall a b. (a -> b) -> a -> b
$ MPFloat -> Approx
unMPFloat MPFloat
arg) 
                                      String
argS (forall a. Show a => a -> String
show MPFloat
argD) (forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall a. HasNorm a => a -> NormLog
getNormLog MPFloat
argD)
      | (MPFloat
arg, MPFloat
argD, String
argS) <- [(MPFloat, MPFloat, String)]
argsLR
      ]
  argsLR :: [(MPFloat, MPFloat, String)]
argsLR = [(MPFloat, MPFloat, String)]
args forall a. [a] -> [a] -> [a]
++ [(MPFloat
l, MPFloat
one, String
"L"), (MPFloat
r, MPFloat
one, String
"R"), (forall t. CanAbs t => t -> AbsType t
abs(MPFloat
rMPFloat -> MPFloat -> MPFloat
-.MPFloat
l), MPFloat
zero, String
"|R-L|")]
  e :: SubType Integer Integer
e = Integer
0 forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
- Integer
maxStepLoss forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
- Integer
precLoss
  maxStepLoss :: Integer
maxStepLoss = forall t.
(CanAddSameType t, ConvertibleExactly Integer t) =>
[t] -> t
sum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max Integer
1) forall a b. (a -> b) -> a -> b
$ (forall a. [Maybe a] -> [a]
catMaybes forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall {a} {c}. HasNorm a => (MPFloat, a, c) -> Maybe Integer
stepLoss [(MPFloat, MPFloat, String)]
argsLR)
  stepLoss :: (MPFloat, a, c) -> Maybe Integer
stepLoss (MPFloat
arg, a
argD, c
_argS) =
    case (forall a. HasNorm a => a -> NormLog
getNormLog a
argD, Approx -> Maybe Int
getErrorStepSizeLog forall a b. (a -> b) -> a -> b
$ MPFloat -> Approx
unMPFloat MPFloat
arg) of
      (NormBits Integer
dbits, Just Int
stepBits) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Integer
dbits forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ Int
stepBits
      (NormLog, Maybe Int)
_ -> forall a. Maybe a
Nothing
  -- resNorm =
  --   case (getNormLog l, getNormLog r) of
  --    (NormBits nl, NormBits nr) -> nl `max` nr; 
  --    (NormBits nl, _) -> nl
  --    (_, NormBits nr) -> nr
  --    _ -> 0
  -- p = foldl max 2 $ map (integer . getPrecision . fst) args

{-|
  A runtime representative of type @MPFloat@.
  Used for specialising polymorphic tests to concrete types.
-}
tMPFloat :: T MPFloat
tMPFloat :: T MPFloat
tMPFloat = forall t. String -> T t
T String
"MPFloat"

trueForNotFinite :: 
  (CanTestFinite t1, CanTestFinite t2) => 
  (t1 -> t2 -> Bool) -> 
  (t1 -> t2 -> Bool)
trueForNotFinite :: forall t1 t2.
(CanTestFinite t1, CanTestFinite t2) =>
(t1 -> t2 -> Bool) -> t1 -> t2 -> Bool
trueForNotFinite t1 -> t2 -> Bool
rel t1
a t2
b 
  | forall t. CanTestFinite t => t -> Bool
isFinite t1
a forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanTestFinite t => t -> Bool
isFinite t2
b = t1 -> t2 -> Bool
rel t1
a t2
b
  | Bool
otherwise = Bool
True

specMPFloat :: Spec
specMPFloat :: Spec
specMPFloat =
  let
    infix 4 <=%, >=%, ==%
    (<=%), (>=%) :: 
      (CanTestFinite t1, CanTestFinite t2, 
       HasOrderAsymmetric t1 t2, OrderCompareType t1 t2 ~ Bool) => 
      t1 -> t2 -> Bool
    (==%) :: 
      (CanTestFinite t1, CanTestFinite t2, 
       HasEqAsymmetric t1 t2, EqCompareType t1 t2 ~ Bool) => 
      t1 -> t2 -> Bool
    <=% :: forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
(<=%) = forall t1 t2.
(CanTestFinite t1, CanTestFinite t2) =>
(t1 -> t2 -> Bool) -> t1 -> t2 -> Bool
trueForNotFinite forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
(<=)
    >=% :: forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
(>=%) = forall t1 t2.
(CanTestFinite t1, CanTestFinite t2) =>
(t1 -> t2 -> Bool) -> t1 -> t2 -> Bool
trueForNotFinite forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
(>=) 
    ==% :: forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasEqAsymmetric t1 t2,
 EqCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
(==%) = forall t1 t2.
(CanTestFinite t1, CanTestFinite t2) =>
(t1 -> t2 -> Bool) -> t1 -> t2 -> Bool
trueForNotFinite forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
(==) 
  in
  forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe (String
"MPFloat") forall a b. (a -> b) -> a -> b
$ do
    forall t prop.
(HasPrecision t, CanSetPrecision t, CanTestFinite t, Arbitrary t,
 Show t, Testable prop) =>
T t -> (t -> t -> prop) -> Spec
specCanSetPrecision T MPFloat
tMPFloat 
      (forall prop a b.
(Testable prop, Show a, Show b) =>
String -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 String
"=~=" (\MPFloat
xPrec MPFloat
x -> Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
1 [(MPFloat
xPrec, MPFloat
one, String
"xPrec")] MPFloat
x MPFloat
xPrec))
    forall t.
(Arbitrary t, CanTestFinite t, Show t, Show (RoundType t),
 CanRound t, CanSub (RoundType t) (RoundType t),
 HasOrderAsymmetric t (RoundType t),
 HasOrderAsymmetric (SubType (RoundType t) (RoundType t)) Integer,
 HasOrderAsymmetric (RoundType t) t,
 HasOrderAsymmetric (RoundType t) (RoundType t),
 HasOrderAsymmetric Integer (SubType (RoundType t) (RoundType t)),
 HasEqAsymmetric (RoundType t) (RoundType t),
 CanTestCertainly (OrderCompareType t (RoundType t)),
 CanTestCertainly
   (OrderCompareType (SubType (RoundType t) (RoundType t)) Integer),
 CanTestCertainly (OrderCompareType (RoundType t) t),
 CanTestCertainly (OrderCompareType (RoundType t) (RoundType t)),
 CanTestCertainly
   (OrderCompareType Integer (SubType (RoundType t) (RoundType t))),
 CanTestCertainly (EqCompareType (RoundType t) (RoundType t)),
 ConvertibleExactly Integer t) =>
T t -> Spec
specCanRound T MPFloat
tMPFloat
    forall t.
(Arbitrary t, Show t, Show (NegType (NegType t)),
 HasEqAsymmetric t t, HasEqAsymmetric (NegType t) t,
 HasEqAsymmetric (NegType (NegType t)) t,
 CanTestCertainly (EqCompareType t t),
 CanTestCertainly (EqCompareType (NegType t) t),
 CanTestCertainly (EqCompareType (NegType (NegType t)) t),
 CanTestFinite t, CanTestPosNeg t, CanTestPosNeg (NegType t),
 ConvertibleExactly Integer t, CanNeg t, CanNeg (NegType t)) =>
T t -> Spec
specCanNegNum T MPFloat
tMPFloat
    forall t.
(Arbitrary t, CanAbs t, CanAbs (AbsType t), CanTestFinite t,
 HasEqAsymmetric t t, HasEqAsymmetric t (AbsType t),
 HasEqAsymmetric (AbsType (AbsType t)) (AbsType t),
 HasEqAsymmetric (NegType t) (AbsType t),
 CanTestCertainly (EqCompareType t t),
 CanTestCertainly (EqCompareType t (AbsType t)),
 CanTestCertainly (EqCompareType (AbsType (AbsType t)) (AbsType t)),
 CanTestCertainly (EqCompareType (NegType t) (AbsType t)), Show t,
 Show (AbsType t), Show (AbsType (AbsType t)), Show (NegType t),
 CanTestPosNeg t, CanTestPosNeg (AbsType t), CanNeg t) =>
T t -> Spec
specCanAbs T MPFloat
tMPFloat
    forall t.
(HasOrderAsymmetric (MinMaxType t t) t, Arbitrary t,
 CanTestFinite t, HasEqAsymmetric (MinMaxType t t) t,
 HasEqAsymmetric (MinMaxType t t) (MinMaxType t t),
 HasEqAsymmetric
   (MinMaxType t (MinMaxType t t)) (MinMaxType (MinMaxType t t) t),
 CanTestCertainly (OrderCompareType (MinMaxType t t) t),
 CanTestCertainly (EqCompareType (MinMaxType t t) t),
 CanTestCertainly (EqCompareType (MinMaxType t t) (MinMaxType t t)),
 CanTestCertainly
   (EqCompareType
      (MinMaxType t (MinMaxType t t)) (MinMaxType (MinMaxType t t) t)),
 Show t, Show (MinMaxType t t),
 Show (MinMaxType t (MinMaxType t t)),
 Show (MinMaxType (MinMaxType t t) t), CanMinMaxAsymmetric t t,
 CanMinMaxAsymmetric t (MinMaxType t t),
 CanMinMaxAsymmetric (MinMaxType t t) t) =>
T t -> Spec
specCanMinMaxNotMixed T MPFloat
tMPFloat
    -- specCanMinMax tMPFloat tInteger tMPFloat
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"special values" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"0 * infinity = NaN" forall a b. (a -> b) -> a -> b
$ do
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
zero MPFloat -> MPFloat -> MPFloat
*^ MPFloat
infinity)
        forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
zero MPFloat -> MPFloat -> MPFloat
*. MPFloat
infinity)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"infinity / infinity = NaN" forall a b. (a -> b) -> a -> b
$ do
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
infinity MPFloat -> MPFloat -> MPFloat
/^ MPFloat
infinity)
        forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
infinity MPFloat -> MPFloat -> MPFloat
/. MPFloat
infinity)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"infinity - infinity = NaN" forall a b. (a -> b) -> a -> b
$ do
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
infinity MPFloat -> MPFloat -> MPFloat
-^ MPFloat
infinity)
        forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
        forall t. CanTestNaN t => t -> Bool
isNaN (MPFloat
infinity MPFloat -> MPFloat -> MPFloat
-. MPFloat
infinity)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate addition" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"up ~ down" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          let
            =~~= :: MPFloat -> MPFloat -> Property
(=~~=) = Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
1 [(MPFloat
x,MPFloat
one,String
"x"), (MPFloat
y,MPFloat
one,String
"y")]
            infix 4 =~~=
          in
          MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y MPFloat -> MPFloat -> Property
=~~= MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"absorbs 0" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) ->
          forall t. CanNeg t => t -> NegType t
not (forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x) forall prop. Testable prop => Bool -> prop -> Property
==>
            MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
zero forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"approximately commutative" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
y MPFloat -> MPFloat -> MPFloat
+^ MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
y MPFloat -> MPFloat -> MPFloat
+. MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"approximately associative" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) (MPFloat
z :: MPFloat) ->
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y) MPFloat -> MPFloat -> MPFloat
+. MPFloat
z forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ (MPFloat
y MPFloat -> MPFloat -> MPFloat
+^ MPFloat
z)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y) MPFloat -> MPFloat -> MPFloat
+^ MPFloat
z forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x MPFloat -> MPFloat -> MPFloat
+. (MPFloat
y MPFloat -> MPFloat -> MPFloat
+. MPFloat
z)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate subtraction" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"up ~ down" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          let
            =~~= :: MPFloat -> MPFloat -> Property
(=~~=) = Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
1 [(MPFloat
x,MPFloat
one,String
"x"), (MPFloat
y,MPFloat
one,String
"y")]
            infix 4 =~~=
          in
          MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y MPFloat -> MPFloat -> Property
=~~= MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"same as negate and add" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ (-MPFloat
y)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x MPFloat -> MPFloat -> MPFloat
+. (-MPFloat
y)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate multiplication" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"up ~ down" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          let
            =~~= :: MPFloat -> MPFloat -> Property
(=~~=) = Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
1 [(MPFloat
x,MPFloat
y,String
"x"), (MPFloat
y,MPFloat
x,String
"y")]
            infix 4 =~~=
          in
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y MPFloat -> MPFloat -> Property
=~~= MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"absorbs 1" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) ->
            MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
one forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasEqAsymmetric t1 t2,
 EqCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
==% MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"approximately commutative" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
y MPFloat -> MPFloat -> MPFloat
*^ MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
y MPFloat -> MPFloat -> MPFloat
*. MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"approximately associative" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) (MPFloat
y_ :: MPFloat) (MPFloat
z_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          let y :: MPFloat
y = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
y_ in
          let z :: MPFloat
z = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
z_ in
          (forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
z)) forall prop. Testable prop => Bool -> prop -> Property
==>
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y) MPFloat -> MPFloat -> MPFloat
*. MPFloat
z forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ (MPFloat
y MPFloat -> MPFloat -> MPFloat
*^ MPFloat
z)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y) MPFloat -> MPFloat -> MPFloat
*^ MPFloat
z forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x MPFloat -> MPFloat -> MPFloat
*. (MPFloat
y MPFloat -> MPFloat -> MPFloat
*. MPFloat
z)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"approximately distributes over addition" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) (MPFloat
y_ :: MPFloat) (MPFloat
z_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          let y :: MPFloat
y = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
y_ in
          let z :: MPFloat
z = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
z_ in
          (forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
z)) forall prop. Testable prop => Bool -> prop -> Property
==>
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*. (MPFloat
y MPFloat -> MPFloat -> MPFloat
+. MPFloat
z) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% (MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y) MPFloat -> MPFloat -> MPFloat
+^ (MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
z)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ (MPFloat
y MPFloat -> MPFloat -> MPFloat
+^ MPFloat
z) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% (MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y) MPFloat -> MPFloat -> MPFloat
+. (MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
z)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate division" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          MPFloat
x MPFloat -> MPFloat -> MPFloat
/. MPFloat
y forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"up ~ down" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) (MPFloat
y :: MPFloat) ->
          let
            =~~= :: MPFloat -> MPFloat -> Property
(=~~=) = Integer
-> [(MPFloat, MPFloat, String)] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
10 [(MPFloat
x,MPFloat
oneMPFloat -> MPFloat -> MPFloat
/^MPFloat
y,String
"x"), (MPFloat
y,-(MPFloat
xMPFloat -> MPFloat -> MPFloat
/^MPFloat
y)MPFloat -> MPFloat -> MPFloat
/^MPFloat
y,String
"y")]
            infix 4 =~~=
          in
          forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
y forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat
y forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
/= Integer
0
          forall prop. Testable prop => Bool -> prop -> Property
==>
          MPFloat
x MPFloat -> MPFloat -> MPFloat
/. MPFloat
y MPFloat -> MPFloat -> Property
=~~= MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
y
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"recip(recip x) = x" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) ->
          (forall t. CanNeg t => t -> NegType t
not (forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
x) forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| MPFloat
x forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> Integer
0 forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| MPFloat
x forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< Integer
0) forall prop. Testable prop => Bool -> prop -> Property
==>
          MPFloat
one MPFloat -> MPFloat -> MPFloat
/. (MPFloat
one MPFloat -> MPFloat -> MPFloat
/^ MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
one MPFloat -> MPFloat -> MPFloat
/^ (MPFloat
one MPFloat -> MPFloat -> MPFloat
/. MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"x/1 = x" forall a b. (a -> b) -> a -> b
$ do 
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) ->
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
/. MPFloat
one) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
one) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"x/x = 1" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x :: MPFloat) ->
          -- (isCertainlyNonZero x && (not $ isNaN $ x /. x)) ==>
            (MPFloat
x MPFloat -> MPFloat -> MPFloat
/. MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
one
            forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
            (MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
one
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"x/y = x*(1/y)" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) (MPFloat
y_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          let y :: MPFloat
y = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
y_ in
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
/. MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ (MPFloat
one MPFloat -> MPFloat -> MPFloat
/^ MPFloat
y)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x MPFloat -> MPFloat -> MPFloat
*. (MPFloat
one MPFloat -> MPFloat -> MPFloat
/. MPFloat
y)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate sqrt" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          MPFloat -> MPFloat
sqrtDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
sqrtUp MPFloat
x
      -- it "up ~ down" $ do
      --   property $ \ (x_ :: MPFloat) ->
      --     let 
      --       x = enforceRangeMP (Just 0, Nothing) x_ 
      --       (=~~=) = approxEqualWithArgs 7 [(x,(one/^(sqrtUp x))/^two,"x")]
      --       infix 4 =~~=
      --     in
      --     sqrtDown x =~~= sqrtUp x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"sqrt(x) >= 0" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          MPFloat -> MPFloat
sqrtUp MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% Integer
0
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"sqrt(x)^2 ~ x" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max MPFloat
zero forall a b. (a -> b) -> a -> b
$ MPFloat -> MPFloat
sqrtDown MPFloat
x) MPFloat -> MPFloat -> MPFloat
*. (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max MPFloat
zero forall a b. (a -> b) -> a -> b
$ MPFloat -> MPFloat
sqrtDown MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MPFloat -> MPFloat
sqrtUp MPFloat
x) MPFloat -> MPFloat -> MPFloat
*^ (MPFloat -> MPFloat
sqrtUp MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate exp" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat -> MPFloat
expDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
expUp MPFloat
x
      -- it "up ~ down" $ do
      --   property $ \ (x_ :: MPFloat) ->
      --     let x = enforceRangeMP (Just (-1000000), Just 1000000) x_ in
      --     let
      --       (=~~=) = approxEqualWithArgs 4 [(x,expUp x,"x")]
      --       infix 4 =~~=
      --     in
      --     expDown x =~~= expUp x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"exp(-x) == 1/(exp x)" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat
one MPFloat -> MPFloat -> MPFloat
/. (MPFloat -> MPFloat
expUp MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
expUp (-MPFloat
x)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat
one MPFloat -> MPFloat -> MPFloat
/^ (MPFloat -> MPFloat
expDown MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat -> MPFloat
expDown (-MPFloat
x)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"exp(x+y) = exp(x)*exp(y)" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) (MPFloat
y_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          let y :: MPFloat
y = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
y_ in
          MPFloat -> MPFloat
expDown (MPFloat
x MPFloat -> MPFloat -> MPFloat
+. MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% (MPFloat -> MPFloat
expUp MPFloat
x) MPFloat -> MPFloat -> MPFloat
*^ (MPFloat -> MPFloat
expUp MPFloat
y)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
expUp (MPFloat
x MPFloat -> MPFloat -> MPFloat
+^ MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% (MPFloat -> MPFloat
expDown MPFloat
x) MPFloat -> MPFloat -> MPFloat
*. (MPFloat -> MPFloat
expDown MPFloat
y)
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate log" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          MPFloat -> MPFloat
logDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
logUp MPFloat
x
      -- it "up ~ down" $ do
      --   property $ \ (x_ :: MPFloat) ->
      --     let x = enforceRangeMP (Just 0, Nothing) x_ in
      --     let
      --       (=~~=) = approxEqualWithArgs 4 [(x,one/^x,"x")]
      --       infix 4 =~~=
      --     in
      --     logDown x =~~= logUp x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"log(1/x) == -(log x)" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          MPFloat -> MPFloat
logDown (MPFloat
one MPFloat -> MPFloat -> MPFloat
/. MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% -(MPFloat -> MPFloat
logDown MPFloat
x)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
logUp (MPFloat
one MPFloat -> MPFloat -> MPFloat
/^ MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% -(MPFloat -> MPFloat
logUp MPFloat
x)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"log(x*y) = log(x)+log(y)" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) (MPFloat
y_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
x_ in
          let y :: MPFloat
y = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just Integer
0, forall a. Maybe a
Nothing) MPFloat
y_ in
          MPFloat -> MPFloat
logDown (MPFloat
x MPFloat -> MPFloat -> MPFloat
*. MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% (MPFloat -> MPFloat
logUp MPFloat
x) MPFloat -> MPFloat -> MPFloat
+^ (MPFloat -> MPFloat
logUp MPFloat
y)
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
logUp (MPFloat
x MPFloat -> MPFloat -> MPFloat
*^ MPFloat
y) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% (MPFloat -> MPFloat
logDown MPFloat
x) MPFloat -> MPFloat -> MPFloat
+. (MPFloat -> MPFloat
logDown MPFloat
y)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"log(exp x) == x" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000), forall a. a -> Maybe a
Just Integer
10000) MPFloat
x_ in
          MPFloat -> MPFloat
logDown (MPFloat -> MPFloat
expDown MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat
x
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
logUp (MPFloat -> MPFloat
expUp MPFloat
x) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% MPFloat
x
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate sine" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat -> MPFloat
sinDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
sinUp MPFloat
x
      -- TODO: fix accuracy of CDAR mBounds sine
      -- it "up ~ down" $ do
      --   property $ \ (x_ :: MPFloat) ->
      --     let x = enforceRangeMP (Just (-1000000), Just 1000000) x_ in
      --     let
      --       (=~~=) = approxEqualWithArgs 2 [(x,cosUp x,"x")]
      --       infix 4 =~~=
      --     in
      --     sinDown x =~~= sinUp x
      -- it "sin(pi/2) ~ 1" $ do
      --   property $ \ (p :: Precision) ->
      --     let
      --       piA = ceduCentre $ piCEDU p
      --       (=~~=) = approxEqualWithArgs 2 []
      --       infix 4 =~~=
      --     in
      --     sinUp(piA/.(setPrecision (p+10) $ mpFloat 2)) =~~= one
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"in [-1,1]" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat -> MPFloat
sinDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% Integer
1
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
sinUp MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% -Integer
1
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
describe String
"approximate cosine" forall a b. (a -> b) -> a -> b
$ do
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"down <= up" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat -> MPFloat
cosDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% MPFloat -> MPFloat
cosUp MPFloat
x
      -- it "up ~ down" $ do
      --   property $ \ (x_ :: MPFloat) ->
      --     let x = enforceRangeMP (Just (-1000000), Just 1000000) x_ in
      --     let
      --       (=~~=) = approxEqualWithArgs 2 [(x,-(sinUp x),"x")]
      --       infix 4 =~~=
      --     in
      --     cosDown x =~~= cosUp x
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"in [-1,1]" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          MPFloat -> MPFloat
cosDown MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% Integer
1
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          MPFloat -> MPFloat
cosUp MPFloat
x forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% -Integer
1
      -- it "cos(pi)=-1" $ do
      --   property $ \ (p :: Precision) ->
      --     let
      --       piA = ceduCentre $ piCEDU p
      --       (=~~=) = approxEqualWithArgs 2 []
      --       infix 4 =~~=
      --     in
      --     cosUp(piA) =~~= (-one)
      forall a.
(HasCallStack, Example a) =>
String -> a -> SpecWith (Arg a)
it String
"cos(x)^2 + sin(x)^2 = 1" forall a b. (a -> b) -> a -> b
$ do
        forall prop. Testable prop => prop -> Property
property forall a b. (a -> b) -> a -> b
$ \ (MPFloat
x_ :: MPFloat) ->
          let x :: MPFloat
x = (Maybe Integer, Maybe Integer) -> MPFloat -> MPFloat
enforceRangeMP (forall a. a -> Maybe a
Just (-Integer
1000000), forall a. a -> Maybe a
Just Integer
1000000) MPFloat
x_ in
          let
            cosxU :: MPFloat
cosxU = MPFloat -> MPFloat
cosUp MPFloat
x
            cosxD :: MPFloat
cosxD = MPFloat -> MPFloat
cosDown MPFloat
x
            cosx2U :: MinMaxType MPFloat MPFloat
cosx2U = (MPFloat
cosxU MPFloat -> MPFloat -> MPFloat
*^ MPFloat
cosxU) forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` (MPFloat
cosxD MPFloat -> MPFloat -> MPFloat
*^ MPFloat
cosxD)
            cosx2D :: MPFloat
cosx2D
              | MPFloat
cosxD forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> Integer
0 = MPFloat
cosxD MPFloat -> MPFloat -> MPFloat
*. MPFloat
cosxD
              | MPFloat
cosxU forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< Integer
0 = MPFloat
cosxU MPFloat -> MPFloat -> MPFloat
*. MPFloat
cosxU
              | Bool
otherwise = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
0
            sinxU :: MPFloat
sinxU = MPFloat -> MPFloat
sinUp MPFloat
x
            sinxD :: MPFloat
sinxD = MPFloat -> MPFloat
sinDown MPFloat
x
            sinx2U :: MinMaxType MPFloat MPFloat
sinx2U = (MPFloat
sinxU MPFloat -> MPFloat -> MPFloat
*^ MPFloat
sinxU) forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
`max` (MPFloat
sinxD MPFloat -> MPFloat -> MPFloat
*^ MPFloat
sinxD)
            sinx2D :: MPFloat
sinx2D
              | MPFloat
sinxD forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> Integer
0 = MPFloat
sinxD MPFloat -> MPFloat -> MPFloat
*. MPFloat
sinxD
              | MPFloat
sinxU forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< Integer
0 = MPFloat
sinxU MPFloat -> MPFloat -> MPFloat
*. MPFloat
sinxU
              | Bool
otherwise = forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
0
          in
          (forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
x ) forall prop. Testable prop => Bool -> prop -> Property
==>
          (MPFloat
cosx2D MPFloat -> MPFloat -> MPFloat
+. MPFloat
sinx2D) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
<=% Integer
1
          forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&&
          (MinMaxType MPFloat MPFloat
cosx2U MPFloat -> MPFloat -> MPFloat
+^ MinMaxType MPFloat MPFloat
sinx2U) forall t1 t2.
(CanTestFinite t1, CanTestFinite t2, HasOrderAsymmetric t1 t2,
 OrderCompareType t1 t2 ~ Bool) =>
t1 -> t2 -> Bool
>=% Integer
1