{-# 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 <- [(Integer, Bool)] -> Gen Bool
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 =
            [MPFloat] -> Gen MPFloat
forall a. [a] -> Gen a
elements [MPFloat
nan, MPFloat
infinity, -MPFloat
infinity, MPFloat
zero, MPFloat
one, -MPFloat
one]
        | Bool
otherwise =
          do
          (Precision
p :: Precision) <- Gen Precision
forall a. Arbitrary a => Gen a
arbitrary
          (Integer
s :: Integer) <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
          Integer
ex <- (Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
choose (-Integer
20,Integer
10)
          let resultR :: MulType Integer Rational
resultR = Integer
s Integer -> Rational -> MulType Integer Rational
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
* (Rational
10.0Rational -> Integer -> PowType Rational Integer
forall t1 t2. CanPow t1 t2 => t1 -> t2 -> PowType t1 t2
^Integer
ex)
          let result :: MPFloat
result = BoundsCEDU MPFloat -> MPFloat
forall a. BoundsCEDU a -> a
ceduCentre (BoundsCEDU MPFloat -> MPFloat) -> BoundsCEDU MPFloat -> MPFloat
forall a b. (a -> b) -> a -> b
$ Precision -> Rational -> BoundsCEDU MPFloat
fromRationalCEDU Precision
p Rational
MulType Integer Rational
resultR
          MPFloat -> Gen MPFloat
forall (m :: * -> *) a. Monad m => a -> m a
return MPFloat
result

frequencyElements :: ConvertibleExactly t Int => [(t, a)] -> Gen a
frequencyElements :: [(t, a)] -> Gen a
frequencyElements [(t, a)]
elems = [(Int, Gen a)] -> Gen a
forall a. [(Int, Gen a)] -> Gen a
frequency [(t -> Int
forall t. CanBeInt t => t -> Int
int t
n, a -> Gen a
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
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
a = MPFloat
a -- pass NaN unchanged
enforceRangeMP (Just Integer
l_, Just Integer
u_) MPFloat
a
    | Bool -> NegType Bool
forall t. CanNeg t => t -> NegType t
not (MPFloat
l MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u) = [Char] -> MPFloat
forall a. HasCallStack => [Char] -> a
error [Char]
"enforceRange: inconsistent range"
    | MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = (MPFloat
u MPFloat -> MPFloat -> MPFloat
-^ MPFloat
l)MPFloat -> MPFloat -> MPFloat
/^MPFloat
two
    | MPFloat
l MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
a Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat
a MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u = MPFloat
a
    | MPFloat
l MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
b Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat
b MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
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 = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
l_
    u :: MPFloat
u = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
u_
    b :: MPFloat
b = MPFloat
l MPFloat -> MPFloat -> MPFloat
+^ ((MPFloat -> AbsType MPFloat
forall t. CanAbs t => t -> AbsType t
abs MPFloat
a) MPFloat -> MPFloat -> ModType MPFloat MPFloat
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
    | MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = MPFloat -> AbsType MPFloat
forall t. CanAbs t => t -> AbsType t
abs MPFloat
a
    | MPFloat
l MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
a = MPFloat
a
    | MPFloat
l MPFloat -> MPFloat -> EqCompareType MPFloat MPFloat
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 = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
l_
enforceRangeMP (Maybe Integer
_, Just Integer
u_) MPFloat
a
    | MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
a = - (MPFloat -> AbsType MPFloat
forall t. CanAbs t => t -> AbsType t
abs MPFloat
a)
    | MPFloat
a MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< MPFloat
u = MPFloat
a
    | MPFloat
a MPFloat -> MPFloat -> EqCompareType MPFloat MPFloat
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 = Integer -> MPFloat
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
    | (Bool -> NegType Bool
forall t. CanNeg t => t -> NegType t
not (MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
m)) = ((Integer
RoundType MPFloat
d :: Integer), ModType MPFloat MPFloat
MPFloat
xm)
    | (Bool -> NegType Bool
forall t. CanNeg t => t -> NegType t
not (MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isFinite MPFloat
x)) = ((Integer
RoundType MPFloat
d :: Integer), ModType MPFloat MPFloat
MPFloat
xm)
    | MPFloat
m MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> MPFloat
zero = (RoundType MPFloat
DivIType MPFloat MPFloat
d, ModType MPFloat MPFloat
MPFloat
xm)
    | Bool
otherwise = ((Integer
RoundType MPFloat
d :: Integer), ModType MPFloat MPFloat
MPFloat
xm)
    where
    d :: RoundType MPFloat
d = MPFloat -> RoundType MPFloat
forall t. CanRound t => t -> RoundType t
floor (MPFloat
x MPFloat -> MPFloat -> MPFloat
/^ MPFloat
m)
    xm :: MPFloat
xm = MPFloat
x MPFloat -> MPFloat -> MPFloat
-^ (Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
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
  | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
True
  | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y = Bool
True
  | MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
True
  | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = Bool
False
  | MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
|| MPFloat -> Bool
forall t. CanTestFinite t => t -> Bool
isInfinite MPFloat
y = MPFloat
x MPFloat -> MPFloat -> EqCompareType MPFloat MPFloat
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== MPFloat
y
  | Bool
otherwise =
      MPFloat -> AbsType MPFloat
forall t. CanAbs t => t -> AbsType t
abs (MPFloat
x MPFloat -> MPFloat -> MPFloat
-. MPFloat
y) MPFloat -> Rational -> OrderCompareType MPFloat Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
<= Rational
0.5Rational -> Integer -> PowType Rational Integer
forall 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, [Char])] -> MPFloat -> MPFloat -> Property
approxEqualWithArgs Integer
precLoss [(MPFloat, MPFloat, [Char])]
args MPFloat
l MPFloat
r =
  [Char] -> Bool -> Property
forall prop. Testable prop => [Char] -> prop -> Property
counterexample [Char]
description (Bool -> Property) -> Bool -> Property
forall a b. (a -> b) -> a -> b
$ Integer -> MPFloat -> MPFloat -> Bool
approxEqual Integer
SubType Integer Integer
e MPFloat
l MPFloat
r
  where
  description :: [Char]
description =
    [Char] -> [Char] -> Integer -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"args:\n%s tolerance: <= 2^(%d)" [Char]
argsS (-Integer
SubType Integer Integer
e)
  argsS :: [Char]
argsS =
    [[Char]] -> [Char]
unlines
      [[Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
-> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"    %s = %s ~ %s bits (dR/d%s = %s ~ %s bits)" 
                [Char]
argS (MPFloat -> [Char]
forall a. Show a => a -> [Char]
show MPFloat
arg) (Maybe Int -> [Char]
forall a. Show a => a -> [Char]
show (Maybe Int -> [Char]) -> Maybe Int -> [Char]
forall a b. (a -> b) -> a -> b
$ Approx -> Maybe Int
getErrorStepSizeLog (Approx -> Maybe Int) -> Approx -> Maybe Int
forall a b. (a -> b) -> a -> b
$ MPFloat -> Approx
unMPFloat MPFloat
arg) 
                                      [Char]
argS (MPFloat -> [Char]
forall a. Show a => a -> [Char]
show MPFloat
argD) (NormLog -> [Char]
forall a. Show a => a -> [Char]
show (NormLog -> [Char]) -> NormLog -> [Char]
forall a b. (a -> b) -> a -> b
$ MPFloat -> NormLog
forall a. HasNorm a => a -> NormLog
getNormLog MPFloat
argD)
      | (MPFloat
arg, MPFloat
argD, [Char]
argS) <- [(MPFloat, MPFloat, [Char])]
argsLR
      ]
  argsLR :: [(MPFloat, MPFloat, [Char])]
argsLR = [(MPFloat, MPFloat, [Char])]
args [(MPFloat, MPFloat, [Char])]
-> [(MPFloat, MPFloat, [Char])] -> [(MPFloat, MPFloat, [Char])]
forall a. [a] -> [a] -> [a]
++ [(MPFloat
l, MPFloat
one, [Char]
"L"), (MPFloat
r, MPFloat
one, [Char]
"R"), (MPFloat -> AbsType MPFloat
forall t. CanAbs t => t -> AbsType t
abs(MPFloat
rMPFloat -> MPFloat -> MPFloat
-.MPFloat
l), MPFloat
zero, [Char]
"|R-L|")]
  e :: SubType Integer Integer
e = Integer
0 Integer -> Integer -> SubType Integer Integer
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
- Integer
maxStepLoss Integer -> Integer -> SubType Integer Integer
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
- Integer
precLoss
  maxStepLoss :: Integer
maxStepLoss = [Integer] -> Integer
forall t.
(CanAddSameType t, ConvertibleExactly Integer t) =>
[t] -> t
sum ([Integer] -> Integer) -> [Integer] -> Integer
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer) -> [Integer] -> [Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Integer -> Integer -> MinMaxType Integer Integer
forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max Integer
1) ([Integer] -> [Integer]) -> [Integer] -> [Integer]
forall a b. (a -> b) -> a -> b
$ ([Maybe Integer] -> [Integer]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Integer] -> [Integer]) -> [Maybe Integer] -> [Integer]
forall a b. (a -> b) -> a -> b
$ ((MPFloat, MPFloat, [Char]) -> Maybe Integer)
-> [(MPFloat, MPFloat, [Char])] -> [Maybe Integer]
forall a b. (a -> b) -> [a] -> [b]
map (MPFloat, MPFloat, [Char]) -> Maybe Integer
forall a c. HasNorm a => (MPFloat, a, c) -> Maybe Integer
stepLoss [(MPFloat, MPFloat, [Char])]
argsLR)
  stepLoss :: (MPFloat, a, c) -> Maybe Integer
stepLoss (MPFloat
arg, a
argD, c
_argS) =
    case (a -> NormLog
forall a. HasNorm a => a -> NormLog
getNormLog a
argD, Approx -> Maybe Int
getErrorStepSizeLog (Approx -> Maybe Int) -> Approx -> Maybe Int
forall a b. (a -> b) -> a -> b
$ MPFloat -> Approx
unMPFloat MPFloat
arg) of
      (NormBits Integer
dbits, Just Int
stepBits) -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ Integer
dbits Integer -> Int -> AddType Integer Int
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ Int
stepBits
      (NormLog, Maybe Int)
_ -> Maybe Integer
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 = [Char] -> T MPFloat
forall t. [Char] -> T t
T [Char]
"MPFloat"

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