{-# LANGUAGE DeriveDataTypeable #-}
{-|
    Module      :  AERN2.MP.ErrorBound
    Description :  Fixed precision non-negative up-rounded floating-point numbers
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

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

    Fixed precision non-negative up-rounded floating-point numbers.

    Currently using a fixed-precision MPFloat.
-}
module AERN2.MP.ErrorBound
    (ErrorBound, CanBeErrorBound, errorBound,
     absMP, subMP)
where

import MixedTypesNumPrelude
import qualified Prelude as P

import Data.Typeable
import GHC.Generics (Generic)
import Control.DeepSeq

import Test.QuickCheck

-- import Data.Convertible

import Data.Ratio (numerator)

import Math.NumberTheory.Logarithms (integerLog2)

import AERN2.MP.Precision
import AERN2.MP.Accuracy
import qualified AERN2.MP.Float as MPFloat
import AERN2.MP.Float (MPFloat, mpFloat, frequencyElements, one, ceduUp)
import AERN2.MP.Float.Operators
import AERN2.MP.Dyadic

{- example -}

_example1 :: ErrorBound
_example1 :: ErrorBound
_example1 = Integer
2Integer -> ErrorBound -> MulType Integer ErrorBound
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
*((Rational -> ErrorBound
forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Rational
0.01) ErrorBound -> ErrorBound -> AddType ErrorBound ErrorBound
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ Rational
0.1Rational -> ErrorBound -> MulType Rational ErrorBound
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
*(Rational -> ErrorBound
forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Rational
0.01)ErrorBound -> Integer -> DivType ErrorBound Integer
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
/Integer
3)

{- type -}

{-| A non-negative Double value to serve as an error bound. Arithmetic is rounded towards +infinity. -}
newtype ErrorBound = ErrorBound { ErrorBound -> MPFloat
er2mp :: MPFloat }
  deriving (ErrorBound -> ErrorBound -> Bool
(ErrorBound -> ErrorBound -> Bool)
-> (ErrorBound -> ErrorBound -> Bool) -> Eq ErrorBound
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrorBound -> ErrorBound -> Bool
$c/= :: ErrorBound -> ErrorBound -> Bool
== :: ErrorBound -> ErrorBound -> Bool
$c== :: ErrorBound -> ErrorBound -> Bool
P.Eq, Eq ErrorBound
Eq ErrorBound
-> (ErrorBound -> ErrorBound -> Ordering)
-> (ErrorBound -> ErrorBound -> Bool)
-> (ErrorBound -> ErrorBound -> Bool)
-> (ErrorBound -> ErrorBound -> Bool)
-> (ErrorBound -> ErrorBound -> Bool)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> Ord ErrorBound
ErrorBound -> ErrorBound -> Bool
ErrorBound -> ErrorBound -> Ordering
ErrorBound -> ErrorBound -> ErrorBound
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ErrorBound -> ErrorBound -> ErrorBound
$cmin :: ErrorBound -> ErrorBound -> ErrorBound
max :: ErrorBound -> ErrorBound -> ErrorBound
$cmax :: ErrorBound -> ErrorBound -> ErrorBound
>= :: ErrorBound -> ErrorBound -> Bool
$c>= :: ErrorBound -> ErrorBound -> Bool
> :: ErrorBound -> ErrorBound -> Bool
$c> :: ErrorBound -> ErrorBound -> Bool
<= :: ErrorBound -> ErrorBound -> Bool
$c<= :: ErrorBound -> ErrorBound -> Bool
< :: ErrorBound -> ErrorBound -> Bool
$c< :: ErrorBound -> ErrorBound -> Bool
compare :: ErrorBound -> ErrorBound -> Ordering
$ccompare :: ErrorBound -> ErrorBound -> Ordering
$cp1Ord :: Eq ErrorBound
P.Ord, Typeable, (forall x. ErrorBound -> Rep ErrorBound x)
-> (forall x. Rep ErrorBound x -> ErrorBound) -> Generic ErrorBound
forall x. Rep ErrorBound x -> ErrorBound
forall x. ErrorBound -> Rep ErrorBound x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ErrorBound x -> ErrorBound
$cfrom :: forall x. ErrorBound -> Rep ErrorBound x
Generic)

instance NFData ErrorBound

instance Show ErrorBound where
    show :: ErrorBound -> String
show (ErrorBound MPFloat
d) = MPFloat -> String
forall a. Show a => a -> String
show MPFloat
d

errorBoundPrecision :: Precision
errorBoundPrecision :: Precision
errorBoundPrecision = Integer -> Precision
prec Integer
53

instance HasAccuracy ErrorBound where
  getAccuracy :: ErrorBound -> Accuracy
getAccuracy (ErrorBound MPFloat
e)
      | Integer
RoundType Rational
eN Integer -> Integer -> OrderCompareType Integer Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> Integer
0 =
          Int -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits (Int -> Accuracy) -> Int -> Accuracy
forall a b. (a -> b) -> a -> b
$ Int -> NegType Int
forall t. CanNeg t => t -> NegType t
negate (Int -> NegType Int) -> Int -> NegType Int
forall a b. (a -> b) -> a -> b
$ Integer -> Int
integerLog2 Integer
RoundType Rational
eN
      | MPFloat
e 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
&& Integer
RoundType Rational
eRecipN Integer -> Integer -> OrderCompareType Integer Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> Integer
0 =
          Int -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits (Int -> Accuracy) -> Int -> Accuracy
forall a b. (a -> b) -> a -> b
$ Integer -> Int
integerLog2 Integer
RoundType Rational
eRecipN
      | MPFloat
e MPFloat -> Integer -> EqCompareType MPFloat Integer
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== Integer
0 = Accuracy
Exact
      | Bool
otherwise = Accuracy
NoInformation
      where
      eN :: RoundType Rational
eN = Rational -> RoundType Rational
forall t. CanRound t => t -> RoundType t
floor (Rational -> RoundType Rational) -> Rational -> RoundType Rational
forall a b. (a -> b) -> a -> b
$ MPFloat -> Rational
forall t. CanBeRational t => t -> Rational
rational MPFloat
e
      eRecipN :: RoundType Rational
eRecipN = Rational -> RoundType Rational
forall t. CanRound t => t -> RoundType t
ceiling (Rational -> RoundType Rational) -> Rational -> RoundType Rational
forall a b. (a -> b) -> a -> b
$ MPFloat -> Rational
forall t. CanBeRational t => t -> Rational
rational (MPFloat -> Rational) -> MPFloat -> Rational
forall a b. (a -> b) -> a -> b
$ MPFloat
one MPFloat -> MPFloat -> MPFloat
/. MPFloat
e
  getFiniteAccuracy :: ErrorBound -> Accuracy
getFiniteAccuracy eb :: ErrorBound
eb@(ErrorBound MPFloat
e) 
    | MPFloat
e MPFloat -> Integer -> EqCompareType MPFloat Integer
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
== Integer
0 = Precision -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits Precision
errorBoundPrecision
    | Bool
otherwise = ErrorBound -> Accuracy
forall a. HasAccuracy a => a -> Accuracy
getAccuracy ErrorBound
eb


{- conversions -}

instance ConvertibleExactly ErrorBound ErrorBound where
  safeConvertExactly :: ErrorBound -> ConvertResult ErrorBound
safeConvertExactly = ErrorBound -> ConvertResult ErrorBound
forall a b. b -> Either a b
Right

instance ConvertibleExactly ErrorBound MPFloat where
  safeConvertExactly :: ErrorBound -> ConvertResult MPFloat
safeConvertExactly = MPFloat -> ConvertResult MPFloat
forall a b. b -> Either a b
Right (MPFloat -> ConvertResult MPFloat)
-> (ErrorBound -> MPFloat) -> ErrorBound -> ConvertResult MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErrorBound -> MPFloat
er2mp

instance ConvertibleExactly ErrorBound Dyadic where
  safeConvertExactly :: ErrorBound -> ConvertResult Dyadic
safeConvertExactly = Dyadic -> ConvertResult Dyadic
forall a b. b -> Either a b
Right (Dyadic -> ConvertResult Dyadic)
-> (ErrorBound -> Dyadic) -> ErrorBound -> ConvertResult Dyadic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic (MPFloat -> Dyadic)
-> (ErrorBound -> MPFloat) -> ErrorBound -> Dyadic
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErrorBound -> MPFloat
er2mp

instance ConvertibleExactly ErrorBound Rational where
  safeConvertExactly :: ErrorBound -> ConvertResult Rational
safeConvertExactly = Rational -> ConvertResult Rational
forall a b. b -> Either a b
Right (Rational -> ConvertResult Rational)
-> (ErrorBound -> Rational) -> ErrorBound -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Rational
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> t2
convertExactly (MPFloat -> Rational)
-> (ErrorBound -> MPFloat) -> ErrorBound -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ErrorBound -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat

type CanBeErrorBound t = Convertible t ErrorBound
errorBound :: (CanBeErrorBound t) => t -> ErrorBound
errorBound :: t -> ErrorBound
errorBound = t -> ErrorBound
forall a b. Convertible a b => a -> b
convert

instance Convertible Rational ErrorBound where
  safeConvert :: Rational -> ConvertResult ErrorBound
safeConvert Rational
x
    | Rational
x Rational -> Integer -> OrderCompareType Rational Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Integer
0 = ErrorBound -> ConvertResult ErrorBound
forall a b. b -> Either a b
Right (ErrorBound -> ConvertResult ErrorBound)
-> ErrorBound -> ConvertResult ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ Precision -> Rational -> MPFloat
MPFloat.fromRationalUp Precision
errorBoundPrecision Rational
x
    | Bool
otherwise = String -> Rational -> ConvertResult ErrorBound
forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"Trying to construct a negative ErrorBound" Rational
x

instance Convertible MPFloat ErrorBound where
  safeConvert :: MPFloat -> ConvertResult ErrorBound
safeConvert MPFloat
x
    | MPFloat
x MPFloat -> Integer -> OrderCompareType MPFloat Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Integer
0 = ErrorBound -> ConvertResult ErrorBound
forall a b. b -> Either a b
Right (ErrorBound -> ConvertResult ErrorBound)
-> ErrorBound -> ConvertResult ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ BoundsCEDU MPFloat -> MPFloat
forall a. BoundsCEDU a -> a
ceduUp (BoundsCEDU MPFloat -> MPFloat) -> BoundsCEDU MPFloat -> MPFloat
forall a b. (a -> b) -> a -> b
$ Precision -> MPFloat -> BoundsCEDU MPFloat
MPFloat.setPrecisionCEDU Precision
errorBoundPrecision MPFloat
x
    | Bool
otherwise = String -> MPFloat -> ConvertResult ErrorBound
forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"Trying to construct a negative ErrorBound" MPFloat
x

instance Convertible Integer ErrorBound where
  safeConvert :: Integer -> ConvertResult ErrorBound
safeConvert Integer
x
    | Integer
x Integer -> Integer -> OrderCompareType Integer Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Integer
0 = ErrorBound -> ConvertResult ErrorBound
forall a b. b -> Either a b
Right (ErrorBound -> ConvertResult ErrorBound)
-> ErrorBound -> ConvertResult ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ Precision -> Integer -> MPFloat
MPFloat.fromIntegerUp Precision
errorBoundPrecision Integer
x
    | Bool
otherwise = String -> Integer -> ConvertResult ErrorBound
forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"Trying to construct a negative ErrorBound" Integer
x

instance Convertible Int ErrorBound where
  safeConvert :: Int -> ConvertResult ErrorBound
safeConvert = Integer -> ConvertResult ErrorBound
forall a b. Convertible a b => a -> ConvertResult b
safeConvert (Integer -> ConvertResult ErrorBound)
-> (Int -> Integer) -> Int -> ConvertResult ErrorBound
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall t. CanBeInteger t => t -> Integer
integer

{- comparisons -}

instance HasOrderAsymmetric ErrorBound ErrorBound

instance HasOrderAsymmetric ErrorBound MPFloat where
  lessThan :: ErrorBound -> MPFloat -> OrderCompareType ErrorBound MPFloat
lessThan = (MPFloat -> MPFloat -> Bool) -> ErrorBound -> MPFloat -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst MPFloat -> MPFloat -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
  leq :: ErrorBound -> MPFloat -> OrderCompareType ErrorBound MPFloat
leq = (MPFloat -> MPFloat -> Bool) -> ErrorBound -> MPFloat -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst MPFloat -> MPFloat -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq
instance HasOrderAsymmetric MPFloat ErrorBound where
  lessThan :: MPFloat -> ErrorBound -> OrderCompareType MPFloat ErrorBound
lessThan = (MPFloat -> MPFloat -> Bool) -> MPFloat -> ErrorBound -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond MPFloat -> MPFloat -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
  leq :: MPFloat -> ErrorBound -> OrderCompareType MPFloat ErrorBound
leq = (MPFloat -> MPFloat -> Bool) -> MPFloat -> ErrorBound -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond MPFloat -> MPFloat -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq

instance HasEqAsymmetric ErrorBound Rational where
  equalTo :: ErrorBound -> Rational -> EqCompareType ErrorBound Rational
equalTo = (Rational -> Rational -> Bool) -> ErrorBound -> Rational -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst Rational -> Rational -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric Rational ErrorBound where
  equalTo :: Rational -> ErrorBound -> EqCompareType Rational ErrorBound
equalTo = (Rational -> Rational -> Bool) -> Rational -> ErrorBound -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond Rational -> Rational -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasOrderAsymmetric ErrorBound Rational where
  lessThan :: ErrorBound -> Rational -> OrderCompareType ErrorBound Rational
lessThan = (Rational -> Rational -> Bool) -> ErrorBound -> Rational -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst Rational -> Rational -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
  leq :: ErrorBound -> Rational -> OrderCompareType ErrorBound Rational
leq = (Rational -> Rational -> Bool) -> ErrorBound -> Rational -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst Rational -> Rational -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq
instance HasOrderAsymmetric Rational ErrorBound where
  lessThan :: Rational -> ErrorBound -> OrderCompareType Rational ErrorBound
lessThan = (Rational -> Rational -> Bool) -> Rational -> ErrorBound -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond Rational -> Rational -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
  leq :: Rational -> ErrorBound -> OrderCompareType Rational ErrorBound
leq = (Rational -> Rational -> Bool) -> Rational -> ErrorBound -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond Rational -> Rational -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq

instance HasEqAsymmetric ErrorBound Integer where
  equalTo :: ErrorBound -> Integer -> EqCompareType ErrorBound Integer
equalTo ErrorBound
a Integer
b = Dyadic -> Dyadic -> EqCompareType Dyadic Dyadic
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
b)
instance HasEqAsymmetric Integer ErrorBound where
  equalTo :: Integer -> ErrorBound -> EqCompareType Integer ErrorBound
equalTo Integer
a ErrorBound
b = Dyadic -> Dyadic -> EqCompareType Dyadic Dyadic
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)
instance HasOrderAsymmetric ErrorBound Integer where
  lessThan :: ErrorBound -> Integer -> OrderCompareType ErrorBound Integer
lessThan ErrorBound
a Integer
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
b)
  leq :: ErrorBound -> Integer -> OrderCompareType ErrorBound Integer
leq ErrorBound
a Integer
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
b)
instance HasOrderAsymmetric Integer ErrorBound where
  lessThan :: Integer -> ErrorBound -> OrderCompareType Integer ErrorBound
lessThan Integer
a ErrorBound
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)
  leq :: Integer -> ErrorBound -> OrderCompareType Integer ErrorBound
leq Integer
a ErrorBound
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq (Integer -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Integer
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)

instance HasEqAsymmetric ErrorBound Int where
  equalTo :: ErrorBound -> Int -> EqCompareType ErrorBound Int
equalTo ErrorBound
a Int
b = Dyadic -> Dyadic -> EqCompareType Dyadic Dyadic
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
b)
instance HasEqAsymmetric Int ErrorBound where
  equalTo :: Int -> ErrorBound -> EqCompareType Int ErrorBound
equalTo Int
a ErrorBound
b = Dyadic -> Dyadic -> EqCompareType Dyadic Dyadic
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)
instance HasOrderAsymmetric ErrorBound Int where
  lessThan :: ErrorBound -> Int -> OrderCompareType ErrorBound Int
lessThan ErrorBound
a Int
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
b)
  leq :: ErrorBound -> Int -> OrderCompareType ErrorBound Int
leq ErrorBound
a Int
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
a) (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
b)
instance HasOrderAsymmetric Int ErrorBound where
  lessThan :: Int -> ErrorBound -> OrderCompareType Int ErrorBound
lessThan Int
a ErrorBound
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)
  leq :: Int -> ErrorBound -> OrderCompareType Int ErrorBound
leq Int
a ErrorBound
b = Dyadic -> Dyadic -> OrderCompareType Dyadic Dyadic
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq (Int -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Int
a) (ErrorBound -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic ErrorBound
b)

instance CanMinMaxAsymmetric ErrorBound ErrorBound

{- converting operations -}

subMP :: MPFloat -> MPFloat -> ErrorBound
MPFloat
a subMP :: MPFloat -> MPFloat -> ErrorBound
`subMP` MPFloat
b = MPFloat -> ErrorBound
forall t. CanBeErrorBound t => t -> ErrorBound
errorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat
a MPFloat -> MPFloat -> MPFloat
-^ MPFloat
b

absMP :: MPFloat -> ErrorBound
absMP :: MPFloat -> ErrorBound
absMP = MPFloat -> ErrorBound
forall t. CanBeErrorBound t => t -> ErrorBound
errorBound (MPFloat -> ErrorBound)
-> (MPFloat -> MPFloat) -> MPFloat -> ErrorBound
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> MPFloat
forall t. CanAbs t => t -> AbsType t
abs

{- up-rounded operations -}

instance CanAddAsymmetric ErrorBound ErrorBound where
    add :: ErrorBound -> ErrorBound -> AddType ErrorBound ErrorBound
add (ErrorBound MPFloat
a) (ErrorBound MPFloat
b) = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat
a MPFloat -> MPFloat -> MPFloat
+^ MPFloat
b

instance CanAddAsymmetric ErrorBound MPFloat where
  type AddType ErrorBound MPFloat = ErrorBound
  add :: ErrorBound -> MPFloat -> AddType ErrorBound MPFloat
add = (ErrorBound -> MPFloat -> ErrorBound)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> ErrorBound
-> MPFloat
-> ErrorBound
forall a b c. (a -> b -> a) -> (a -> a -> c) -> a -> b -> c
convertSecondUsing (\ ErrorBound
_ MPFloat
f -> MPFloat -> ErrorBound
forall a b. Convertible a b => a -> b
convert MPFloat
f) ErrorBound -> ErrorBound -> ErrorBound
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add
instance CanAddAsymmetric MPFloat ErrorBound where
  type AddType MPFloat ErrorBound = ErrorBound
  add :: MPFloat -> ErrorBound -> AddType MPFloat ErrorBound
add = (MPFloat -> ErrorBound -> ErrorBound)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> MPFloat
-> ErrorBound
-> ErrorBound
forall a b c. (a -> b -> b) -> (b -> b -> c) -> a -> b -> c
convertFirstUsing (\ MPFloat
f ErrorBound
_ -> MPFloat -> ErrorBound
forall a b. Convertible a b => a -> b
convert MPFloat
f) ErrorBound -> ErrorBound -> ErrorBound
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add

instance CanMulAsymmetric ErrorBound ErrorBound where
    mul :: ErrorBound -> ErrorBound -> MulType ErrorBound ErrorBound
mul (ErrorBound MPFloat
a) (ErrorBound MPFloat
b) = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat
a MPFloat -> MPFloat -> MPFloat
*^ MPFloat
b

instance CanMulAsymmetric ErrorBound MPFloat where
  type MulType ErrorBound MPFloat = ErrorBound
  mul :: ErrorBound -> MPFloat -> MulType ErrorBound MPFloat
mul = (ErrorBound -> MPFloat -> ErrorBound)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> ErrorBound
-> MPFloat
-> ErrorBound
forall a b c. (a -> b -> a) -> (a -> a -> c) -> a -> b -> c
convertSecondUsing (\ ErrorBound
_ MPFloat
f -> MPFloat -> ErrorBound
forall a b. Convertible a b => a -> b
convert MPFloat
f) ErrorBound -> ErrorBound -> ErrorBound
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul
instance CanMulAsymmetric MPFloat ErrorBound where
  type MulType MPFloat ErrorBound = ErrorBound
  mul :: MPFloat -> ErrorBound -> MulType MPFloat ErrorBound
mul = (MPFloat -> ErrorBound -> ErrorBound)
-> (ErrorBound -> ErrorBound -> ErrorBound)
-> MPFloat
-> ErrorBound
-> ErrorBound
forall a b c. (a -> b -> b) -> (b -> b -> c) -> a -> b -> c
convertFirstUsing (\ MPFloat
f ErrorBound
_ -> MPFloat -> ErrorBound
forall a b. Convertible a b => a -> b
convert MPFloat
f) ErrorBound -> ErrorBound -> ErrorBound
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul

instance CanMulAsymmetric ErrorBound Integer where
    type MulType ErrorBound Integer = ErrorBound
    mul :: ErrorBound -> Integer -> MulType ErrorBound Integer
mul (ErrorBound MPFloat
a) Integer
i
        | Integer
i Integer -> Integer -> OrderCompareType Integer Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Integer
0 = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat
a MPFloat -> MPFloat -> MPFloat
*^ (Precision -> Integer -> MPFloat
MPFloat.fromIntegerUp Precision
errorBoundPrecision Integer
i)
        | Bool
otherwise = String -> ErrorBound
forall a. HasCallStack => String -> a
error String
"trying to multiply ErrorBound by a negative integer"
instance CanMulAsymmetric Integer ErrorBound where
    type MulType Integer ErrorBound = ErrorBound
    mul :: Integer -> ErrorBound -> MulType Integer ErrorBound
mul Integer
i (ErrorBound MPFloat
b)
        | Integer
i Integer -> Integer -> OrderCompareType Integer Integer
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Integer
0 = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ (Precision -> Integer -> MPFloat
MPFloat.fromIntegerUp Precision
errorBoundPrecision Integer
i) MPFloat -> MPFloat -> MPFloat
*^ MPFloat
b
        | Bool
otherwise = String -> ErrorBound
forall a. HasCallStack => String -> a
error String
"trying to multiply ErrorBound by a negative integer"

instance CanMulAsymmetric ErrorBound Rational where
    type MulType ErrorBound Rational = ErrorBound
    mul :: ErrorBound -> Rational -> MulType ErrorBound Rational
mul (ErrorBound MPFloat
a) Rational
r
        | Rational
r Rational -> Rational -> OrderCompareType Rational Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Rational
0.0 = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ MPFloat
a MPFloat -> MPFloat -> MPFloat
*^ (Precision -> Rational -> MPFloat
MPFloat.fromRationalUp Precision
errorBoundPrecision Rational
r)
        | Bool
otherwise = String -> ErrorBound
forall a. HasCallStack => String -> a
error String
"trying to multiply ErrorBound by a negative integer"
instance CanMulAsymmetric Rational ErrorBound where
    type MulType Rational ErrorBound = ErrorBound
    mul :: Rational -> ErrorBound -> MulType Rational ErrorBound
mul Rational
r (ErrorBound MPFloat
b)
        | Rational
r Rational -> Rational -> OrderCompareType Rational Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
>= Rational
0.0 = MPFloat -> ErrorBound
ErrorBound (MPFloat -> ErrorBound) -> MPFloat -> ErrorBound
forall a b. (a -> b) -> a -> b
$ (Precision -> Rational -> MPFloat
MPFloat.fromRationalUp Precision
errorBoundPrecision Rational
r) MPFloat -> MPFloat -> MPFloat
*^ MPFloat
b
        | Bool
otherwise = String -> ErrorBound
forall a. HasCallStack => String -> a
error String
"trying to multiply ErrorBound by a negative integer"

instance CanDiv ErrorBound Integer where
    type DivType ErrorBound Integer = ErrorBound
    divide :: ErrorBound -> Integer -> DivType ErrorBound Integer
divide = ErrorBound -> Integer -> DivType ErrorBound Integer
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide
    -- divide (ErrorBound a) i
    --     | i > 0 = ErrorBound $ a /^ (MPFloat.fromIntegerUp errorBoundPrecision i)
    --     | otherwise = error "trying to multiply ErrorBound by a non-positive integer"

instance Arbitrary ErrorBound where
  arbitrary :: Gen ErrorBound
arbitrary =
    do
    Bool
giveSpecialValue <- [(Integer, Bool)] -> Gen Bool
forall t a. ConvertibleExactly t Int => [(t, a)] -> Gen a
frequencyElements [(Integer
5, Bool
False),(Integer
1, Bool
True)]
    Bool -> Gen ErrorBound
forall a. Convertible Rational a => Bool -> Gen a
aux Bool
giveSpecialValue
    where
      aux :: Bool -> Gen a
aux Bool
giveSpecialValue
        | Bool
giveSpecialValue =
            [a] -> Gen a
forall a. [a] -> Gen a
elements ((Rational -> a) -> [Rational] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Rational -> a
forall a b. Convertible a b => a -> b
convert [Rational
0.0,Rational
0.0,Rational
0.0,Rational
10.0,Rational
1.0,Rational
0.5,Rational
0.125])
        | Bool
otherwise =
          do
          (Integer
s :: Integer) <- Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
          let resultR :: DivType Integer Rational
resultR = ((Integer -> AbsType Integer
forall t. CanAbs t => t -> AbsType t
abs Integer
s) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`P.mod` (Rational -> Integer
forall a. Ratio a -> a
numerator (Rational -> Integer) -> Rational -> Integer
forall a b. (a -> b) -> a -> b
$ Integer
2Integer -> Integer -> PowType Integer Integer
forall t1 t2. CanPow t1 t2 => t1 -> t2 -> PowType t1 t2
^Integer
35))Integer -> Rational -> DivType Integer Rational
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
/(Integer
2Integer -> Integer -> PowType Integer Integer
forall t1 t2. CanPow t1 t2 => t1 -> t2 -> PowType t1 t2
^Integer
32)
          let result :: a
result = Rational -> a
forall a b. Convertible a b => a -> b
convert Rational
DivType Integer Rational
resultR
          a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result