{-# OPTIONS_GHC -Wno-orphans #-}
{-|
    Module      :  AERN2.MP.Ball.Conversions
    Description :  Conversions of arbitrary precision dyadic balls
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

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

    Conversions of arbitrary precision dyadic balls
-}
module AERN2.MP.Ball.Conversions
(
  integerBounds
)
where

import MixedTypesNumPrelude
-- import qualified Prelude as P

-- import qualified Numeric.CollectErrors as CN

import Data.Typeable
-- import Data.Convertible

import AERN2.MP.Dyadic (Dyadic, dyadic)
import qualified AERN2.MP.Float as MPFloat
import AERN2.MP.Float (MPFloat, mpFloat)
-- import AERN2.MP.Float.Operators
import AERN2.MP.Precision
-- import qualified AERN2.MP.ErrorBound as EB
-- import qualified AERN2.MP.ErrorBound as EB
import AERN2.MP.ErrorBound (ErrorBound, errorBound, CanBeErrorBound)

import AERN2.MP.Ball.Type

{--- extracting from a ball ---}

instance HasIntegerBounds MPBall where
  integerBounds :: MPBall -> (Integer, Integer)
integerBounds MPBall
b =
    (forall t. CanRound t => t -> RoundType t
floor IntervalEndpoint MPBall
l, forall t. CanRound t => t -> RoundType t
ceiling IntervalEndpoint MPBall
r)
    where
      (IntervalEndpoint MPBall
l,IntervalEndpoint MPBall
r) = forall i.
IsInterval i =>
i -> (IntervalEndpoint i, IntervalEndpoint i)
endpoints MPBall
b

instance Convertible MPBall ErrorBound where
  safeConvert :: MPBall -> ConvertResult ErrorBound
safeConvert MPBall
b =
    forall a b. b -> Either a b
Right (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound (forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max (forall t. CanAbs t => t -> AbsType t
abs IntervalEndpoint MPBall
l) (forall t. CanAbs t => t -> AbsType t
abs IntervalEndpoint MPBall
r)))
    where
    (IntervalEndpoint MPBall
l,IntervalEndpoint MPBall
r) = forall i.
IsInterval i =>
i -> (IntervalEndpoint i, IntervalEndpoint i)
endpoints MPBall
b

{--- constructing an exact ball ---}

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

instance ConvertibleExactly Dyadic MPBall where
  safeConvertExactly :: Dyadic -> ConvertResult MPBall
safeConvertExactly Dyadic
x = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Dyadic
x) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Integer
0)

instance ConvertibleExactly ErrorBound MPBall where
  safeConvertExactly :: ErrorBound -> ConvertResult MPBall
safeConvertExactly ErrorBound
eb = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat ErrorBound
eb) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Integer
0)

instance
  (ConvertibleExactly c Dyadic, ConvertibleExactly e Dyadic
  , Show c, Show e, Typeable c, Typeable e)
  =>
  ConvertibleExactly (c, e) MPBall
  where
  safeConvertExactly :: (c, e) -> ConvertResult MPBall
safeConvertExactly (c
c,e
e)
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"too large to convert to MPBall" (c
c,e
e)
    where
    b :: MPBall
b = MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat forall a b. (a -> b) -> a -> b
$ forall t. CanBeDyadic t => t -> Dyadic
dyadic c
c) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound forall a b. (a -> b) -> a -> b
$ forall t. CanBeMPFloat t => t -> MPFloat
mpFloat forall a b. (a -> b) -> a -> b
$ forall t. CanBeDyadic t => t -> Dyadic
dyadic e
e)

instance ConvertibleExactly Integer MPBall where
  safeConvertExactly :: Integer -> ConvertResult MPBall
safeConvertExactly Integer
x
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"too large to convert to MPBall" Integer
x
    where
      b :: MPBall
b = MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
x) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Integer
0)

instance ConvertibleExactly Int MPBall where
  safeConvertExactly :: Int -> ConvertResult MPBall
safeConvertExactly Int
x = forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Int
x) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Integer
0)

{--- constructing a ball with a given precision ---}

instance ConvertibleWithPrecision Integer MPBall where
  safeConvertP :: Precision -> Integer -> ConvertResult MPBall
safeConvertP Precision
p Integer
x
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError (String
"too large to convert to MPBall with precision " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Precision
p) Integer
x
    where
    b :: MPBall
b = MPFloat -> ErrorBound -> MPBall
MPBall MPFloat
xC (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound MPFloat
xErr)
    (MPFloat
xC, MPFloat
xErr) = forall a. BoundsCEDU a -> (a, a)
MPFloat.ceduCentreErr forall a b. (a -> b) -> a -> b
$ Precision -> Integer -> BoundsCEDU MPFloat
MPFloat.fromIntegerCEDU Precision
p Integer
x

instance ConvertibleWithPrecision Int MPBall where
  safeConvertP :: Precision -> Int -> ConvertResult MPBall
safeConvertP Precision
p = forall t1 t2.
ConvertibleWithPrecision t1 t2 =>
Precision -> t1 -> ConvertResult t2
safeConvertP Precision
p forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. CanBeInteger t => t -> Integer
integer

instance ConvertibleWithPrecision Dyadic MPBall where
  safeConvertP :: Precision -> Dyadic -> ConvertResult MPBall
safeConvertP Precision
p Dyadic
x
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError (String
"too large to convert to MPBall with precision " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Precision
p) Dyadic
x
    where
    b :: MPBall
b = forall t. CanBeMPBall t => t -> MPBall
mpBall Dyadic
x

instance ConvertibleWithPrecision Rational MPBall where
  safeConvertP :: Precision -> Rational -> ConvertResult MPBall
safeConvertP Precision
p Rational
x
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError (String
"too large to convert to MPBall with precision " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Precision
p) Rational
x
    where
    b :: MPBall
b = MPFloat -> ErrorBound -> MPBall
MPBall MPFloat
xC (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound MPFloat
xErr)
    (MPFloat
xC, MPFloat
xErr) = forall a. BoundsCEDU a -> (a, a)
MPFloat.ceduCentreErr forall a b. (a -> b) -> a -> b
$ Precision -> Rational -> BoundsCEDU MPFloat
MPFloat.fromRationalCEDU Precision
p Rational
x

instance ConvertibleWithPrecision (Rational, Rational) MPBall where
  safeConvertP :: Precision -> (Rational, Rational) -> ConvertResult MPBall
safeConvertP Precision
p (Rational
x,Rational
e)
    | forall t. CanTestFinite t => t -> Bool
isFinite MPBall
b = forall a b. b -> Either a b
Right MPBall
b
    | Bool
otherwise = forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError (String
"too large to convert to MPBall with precision " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Precision
p) Rational
x
    where
    b :: MPBall
b = MPFloat -> ErrorBound -> MPBall
MPBall MPFloat
xFlt (ErrorBound
xe forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ ErrorBound
eUp) -- beware, precision may be too high relative to accuracy
    (MPBall MPFloat
xFlt ErrorBound
xe) = forall t. CanBeMPBallP t => Precision -> t -> MPBall
mpBallP Precision
p Rational
x
    eUp :: ErrorBound
eUp = forall t. CanBeErrorBound t => t -> ErrorBound
errorBound Rational
e

{--- constructing a fat ball ---}

instance (CanBeErrorBound t) => CanPlusMinus MPBall t where
  plusMinus :: MPBall -> t -> PlusMinusType MPBall t
plusMinus MPBall
b t
e = forall t. IsBall t => (ErrorBound -> ErrorBound) -> t -> t
updateRadius (forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)) MPBall
b

instance (CanBeErrorBound t) => CanPlusMinus (CN MPBall) t where
  plusMinus :: CN MPBall -> t -> PlusMinusType (CN MPBall) t
plusMinus CN MPBall
b t
e = forall t. IsBall t => (ErrorBound -> ErrorBound) -> t -> t
updateRadius (forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)) CN MPBall
b

instance (CanBeErrorBound t) => CanPlusMinus MPFloat t where
  type PlusMinusType MPFloat t = MPBall
  plusMinus :: MPFloat -> t -> PlusMinusType MPFloat t
plusMinus MPFloat
b t
e = MPFloat -> ErrorBound -> MPBall
MPBall MPFloat
b (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)

instance (CanBeErrorBound t) => CanPlusMinus Dyadic t where
  type PlusMinusType Dyadic t = MPBall
  plusMinus :: Dyadic -> t -> PlusMinusType Dyadic t
plusMinus Dyadic
b t
e = MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Dyadic
b) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)

instance (CanBeErrorBound t) => CanPlusMinus Integer t where
  type PlusMinusType Integer t = MPBall
  plusMinus :: Integer -> t -> PlusMinusType Integer t
plusMinus Integer
b t
e = MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
b) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)

instance (CanBeErrorBound t) => CanPlusMinus Int t where
  type PlusMinusType Int t = MPBall
  plusMinus :: Int -> t -> PlusMinusType Int t
plusMinus Int
b t
e = MPFloat -> ErrorBound -> MPBall
MPBall (forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Int
b) (forall t. CanBeErrorBound t => t -> ErrorBound
errorBound t
e)

instance (CanBeErrorBound t) => CanPlusMinus Rational t where
  type PlusMinusType Rational t = MPBall
  plusMinus :: Rational -> t -> PlusMinusType Rational t
plusMinus Rational
b t
e = (forall t. CanBeMPBallP t => Precision -> t -> MPBall
mpBallP Precision
p Rational
b) forall t1 t2. CanPlusMinus t1 t2 => t1 -> t2 -> PlusMinusType t1 t2
+- t
e
    where
    p :: Precision
p = Integer -> Precision
prec Integer
100