{-# OPTIONS_GHC -Wno-orphans #-}
{-|
    Module      :  AERN2.MP.Float.Conversions
    Description :  Conversions and comparisons of arbitrary precision floats
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

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

    Conversions and comparisons of arbitrary precision floating point numbers
-}
module AERN2.MP.Float.Conversions
  (
   -- * MPFloat to other types (see also instances)
   toDouble
   -- * MPFloat constructors (see also instances)
   , CanBeMPFloat, mpFloat
   , fromIntegerCEDU
   , fromRationalCEDU
   -- * comparisons and constants (see also instances)
   , zero, one, two
   , nan, infinity
   )
where

import MixedTypesNumPrelude
import qualified Prelude as P

import Data.Ratio
-- import Data.Convertible

-- import AERN2.Norm
import AERN2.MP.Precision

import qualified Data.CDAR as MPLow

import AERN2.MP.Float.Auxi
import AERN2.MP.Float.Type
import AERN2.MP.Float.Arithmetic


{- conversions to MPFloat -}

type CanBeMPFloat t = ConvertibleExactly t MPFloat
mpFloat :: (CanBeMPFloat t) => t -> MPFloat
mpFloat :: t -> MPFloat
mpFloat = t -> MPFloat
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> t2
convertExactly

instance ConvertibleExactly Integer MPFloat where
    safeConvertExactly :: Integer -> ConvertResult MPFloat
safeConvertExactly =
      MPFloat -> ConvertResult MPFloat
forall a b. b -> Either a b
Right (MPFloat -> ConvertResult MPFloat)
-> (Integer -> MPFloat) -> Integer -> ConvertResult MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Approx -> MPFloat
MPFloat (Approx -> MPFloat) -> (Integer -> Approx) -> Integer -> MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Approx
forall a. Num a => Integer -> a
P.fromInteger

instance ConvertibleExactly Int MPFloat where
    safeConvertExactly :: Int -> ConvertResult MPFloat
safeConvertExactly = Integer -> ConvertResult MPFloat
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> ConvertResult t2
safeConvertExactly (Integer -> ConvertResult MPFloat)
-> (Int -> Integer) -> Int -> ConvertResult MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Integer
forall t. CanBeInteger t => t -> Integer
integer

fromIntegerCEDU :: Precision -> Integer -> BoundsCEDU MPFloat
fromIntegerCEDU :: Precision -> Integer -> BoundsCEDU MPFloat
fromIntegerCEDU Precision
pp =
  Precision -> MPFloat -> BoundsCEDU MPFloat
setPrecisionCEDU Precision
pp (MPFloat -> BoundsCEDU MPFloat)
-> (Integer -> MPFloat) -> Integer -> BoundsCEDU MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Approx -> MPFloat
MPFloat (Approx -> MPFloat) -> (Integer -> Approx) -> Integer -> MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Approx
forall a. Num a => Integer -> a
P.fromInteger

fromRationalCEDU :: Precision -> Rational -> BoundsCEDU MPFloat
fromRationalCEDU :: Precision -> Rational -> BoundsCEDU MPFloat
fromRationalCEDU Precision
pp =
  Precision -> MPFloat -> BoundsCEDU MPFloat
setPrecisionCEDU Precision
pp (MPFloat -> BoundsCEDU MPFloat)
-> (Rational -> MPFloat) -> Rational -> BoundsCEDU MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Approx -> MPFloat
MPFloat (Approx -> MPFloat) -> (Rational -> Approx) -> Rational -> MPFloat
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Rational -> Approx
MPLow.toApproxMB (Precision -> Int
p2cdarPrec Precision
pp))

{- conversions from MPFloat -}

instance ConvertibleExactly MPLow.Approx Rational where
  safeConvertExactly :: Approx -> ConvertResult Rational
safeConvertExactly = Rational -> ConvertResult Rational
forall a b. b -> Either a b
Right (Rational -> ConvertResult Rational)
-> (Approx -> Rational) -> Approx -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Approx -> Rational
forall a. Real a => a -> Rational
P.toRational

instance ConvertibleExactly MPFloat Rational where
  safeConvertExactly :: MPFloat -> ConvertResult Rational
safeConvertExactly = Approx -> ConvertResult Rational
forall t1 t2. ConvertibleExactly t1 t2 => t1 -> ConvertResult t2
safeConvertExactly (Approx -> ConvertResult Rational)
-> (MPFloat -> Approx) -> MPFloat -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Approx
unMPFloat
    
toDouble :: MPFloat -> Double
toDouble :: MPFloat -> Double
toDouble = Rational -> Double
forall a. Fractional a => Rational -> a
P.fromRational (Rational -> Double) -> (MPFloat -> Rational) -> MPFloat -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Rational
forall t. CanBeRational t => t -> Rational
rational

instance Convertible MPFloat Double where
  safeConvert :: MPFloat -> ConvertResult Double
safeConvert MPFloat
x
    | Double -> Bool
forall t. CanTestFinite t => t -> Bool
isFinite Double
dbl = Double -> ConvertResult Double
forall a b. b -> Either a b
Right Double
dbl
    | Bool
otherwise = String -> MPFloat -> ConvertResult Double
forall a b.
(Show a, Typeable a, Typeable b) =>
String -> a -> ConvertResult b
convError String
"conversion to double: out of bounds" MPFloat
x
    where
    dbl :: Double
dbl = MPFloat -> Double
toDouble MPFloat
x


instance CanRound MPFloat where
  properFraction :: MPFloat -> (RoundType MPFloat, MPFloat)
properFraction (MPFloat Approx
x) = (Integer
RoundType MPFloat
n,MPFloat
f)
    where
      r :: Rational
r = Approx -> Rational
forall t. CanBeRational t => t -> Rational
rational Approx
x
      n :: Integer
n = (Rational -> Integer
forall a. Ratio a -> a
numerator Rational
r) Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`P.quot` (Rational -> Integer
forall a. Ratio a -> a
denominator Rational
r)
      f :: MPFloat
f =  BoundsCEDU MPFloat -> MPFloat
forall a. BoundsCEDU a -> a
ceduCentre (BoundsCEDU MPFloat -> MPFloat) -> BoundsCEDU MPFloat -> MPFloat
forall a b. (a -> b) -> a -> b
$ (Approx -> MPFloat
MPFloat Approx
x) MPFloat -> MPFloat -> BoundsCEDU MPFloat
`subCEDU` (Approx -> MPFloat
MPFloat (Approx -> MPFloat) -> Approx -> MPFloat
forall a b. (a -> b) -> a -> b
$ Integer -> Approx
forall a. Num a => Integer -> a
P.fromInteger Integer
n)
  
{- comparisons -}

instance HasEqAsymmetric MPLow.Approx MPLow.Approx
instance HasEqAsymmetric MPFloat MPFloat where
  equalTo :: MPFloat -> MPFloat -> EqCompareType MPFloat MPFloat
equalTo = (Approx -> Approx -> Bool) -> MPFloat -> MPFloat -> Bool
forall t. (Approx -> Approx -> t) -> MPFloat -> MPFloat -> t
lift2R Approx -> Approx -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric MPFloat Integer where
  equalTo :: MPFloat -> Integer -> EqCompareType MPFloat Integer
equalTo = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Integer -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond MPFloat -> MPFloat -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric Integer MPFloat where
  equalTo :: Integer -> MPFloat -> EqCompareType Integer MPFloat
equalTo = (MPFloat -> MPFloat -> Bool) -> Integer -> MPFloat -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst MPFloat -> MPFloat -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric MPFloat Int where
  equalTo :: MPFloat -> Int -> EqCompareType MPFloat Int
equalTo = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Int -> Bool
forall b a c.
ConvertibleExactly b a =>
(a -> a -> c) -> a -> b -> c
convertSecond MPFloat -> MPFloat -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric Int MPFloat where
  equalTo :: Int -> MPFloat -> EqCompareType Int MPFloat
equalTo = (MPFloat -> MPFloat -> Bool) -> Int -> MPFloat -> Bool
forall a b c.
ConvertibleExactly a b =>
(b -> b -> c) -> a -> b -> c
convertFirst MPFloat -> MPFloat -> Bool
forall a b. HasEqAsymmetric a b => a -> b -> EqCompareType a b
equalTo
instance HasEqAsymmetric MPFloat Rational where
  equalTo :: MPFloat -> Rational -> EqCompareType MPFloat Rational
equalTo = (Rational -> Rational -> Bool) -> MPFloat -> 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 MPFloat where
  equalTo :: Rational -> MPFloat -> EqCompareType Rational MPFloat
equalTo = (Rational -> Rational -> Bool) -> Rational -> MPFloat -> 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 CanTestZero MPFloat

instance HasOrderAsymmetric MPLow.Approx MPLow.Approx
instance HasOrderAsymmetric MPFloat MPFloat where
  lessThan :: MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
lessThan = (Approx -> Approx -> Bool) -> MPFloat -> MPFloat -> Bool
forall t. (Approx -> Approx -> t) -> MPFloat -> MPFloat -> t
lift2R Approx -> Approx -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
lessThan
  leq :: MPFloat -> MPFloat -> OrderCompareType MPFloat MPFloat
leq = (Approx -> Approx -> Bool) -> MPFloat -> MPFloat -> Bool
forall t. (Approx -> Approx -> t) -> MPFloat -> MPFloat -> t
lift2R Approx -> Approx -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
leq
instance HasOrderAsymmetric MPFloat Integer where
  lessThan :: MPFloat -> Integer -> OrderCompareType MPFloat Integer
lessThan = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Integer -> 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 -> Integer -> OrderCompareType MPFloat Integer
leq = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Integer -> 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 HasOrderAsymmetric Integer MPFloat where
  lessThan :: Integer -> MPFloat -> OrderCompareType Integer MPFloat
lessThan = (MPFloat -> MPFloat -> Bool) -> Integer -> 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 :: Integer -> MPFloat -> OrderCompareType Integer MPFloat
leq = (MPFloat -> MPFloat -> Bool) -> Integer -> 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 Int where
  lessThan :: MPFloat -> Int -> OrderCompareType MPFloat Int
lessThan = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Int -> 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 -> Int -> OrderCompareType MPFloat Int
leq = (MPFloat -> MPFloat -> Bool) -> MPFloat -> Int -> 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 HasOrderAsymmetric Int MPFloat where
  lessThan :: Int -> MPFloat -> OrderCompareType Int MPFloat
lessThan = (MPFloat -> MPFloat -> Bool) -> Int -> 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 :: Int -> MPFloat -> OrderCompareType Int MPFloat
leq = (MPFloat -> MPFloat -> Bool) -> Int -> 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 Rational MPFloat where
  lessThan :: Rational -> MPFloat -> OrderCompareType Rational MPFloat
lessThan = (Rational -> Rational -> Bool) -> Rational -> MPFloat -> 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 -> MPFloat -> OrderCompareType Rational MPFloat
leq = (Rational -> Rational -> Bool) -> Rational -> MPFloat -> 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 HasOrderAsymmetric MPFloat Rational where
  lessThan :: MPFloat -> Rational -> OrderCompareType MPFloat Rational
lessThan = (Rational -> Rational -> Bool) -> MPFloat -> 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 :: MPFloat -> Rational -> OrderCompareType MPFloat Rational
leq = (Rational -> Rational -> Bool) -> MPFloat -> 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 CanTestPosNeg MPFloat

{- min, max -}

instance CanMinMaxAsymmetric MPFloat MPFloat where
  type MinMaxType MPFloat MPFloat = MPFloat
  max :: MPFloat -> MPFloat -> MinMaxType MPFloat MPFloat
max MPFloat
x MPFloat
y
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x = MinMaxType MPFloat MPFloat
MPFloat
x
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = MinMaxType MPFloat MPFloat
MPFloat
y
    | Bool
otherwise = (Approx -> Approx -> Approx) -> MPFloat -> MPFloat -> MPFloat
lift2 Approx -> Approx -> Approx
forall a. Ord a => a -> a -> a
P.max MPFloat
x MPFloat
y
  min :: MPFloat -> MPFloat -> MinMaxType MPFloat MPFloat
min MPFloat
x MPFloat
y
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
x = MinMaxType MPFloat MPFloat
MPFloat
x
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = MinMaxType MPFloat MPFloat
MPFloat
y
    | Bool
otherwise = (Approx -> Approx -> Approx) -> MPFloat -> MPFloat -> MPFloat
lift2 Approx -> Approx -> Approx
forall a. Ord a => a -> a -> a
P.min MPFloat
x MPFloat
y

{- constants -}

zero, one, two :: MPFloat
zero :: MPFloat
zero = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
0
one :: MPFloat
one = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
1
two :: MPFloat
two = Integer -> MPFloat
forall t. CanBeMPFloat t => t -> MPFloat
mpFloat Integer
2

nan, infinity :: MPFloat
nan :: MPFloat
nan = Approx -> MPFloat
MPFloat Approx
MPLow.Bottom
infinity :: MPFloat
infinity = MPFloat
nan

itisNaN :: MPFloat -> Bool
itisNaN :: MPFloat -> Bool
itisNaN (MPFloat Approx
MPLow.Bottom) = Bool
True
itisNaN MPFloat
_ = Bool
False

instance CanTestFinite MPFloat where
  isInfinite :: MPFloat -> Bool
isInfinite = MPFloat -> Bool
itisNaN
  isFinite :: MPFloat -> Bool
isFinite = Bool -> Bool
forall t. CanNeg t => t -> NegType t
not (Bool -> Bool) -> (MPFloat -> Bool) -> MPFloat -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Bool
itisNaN

instance CanTestNaN MPFloat where
  isNaN :: MPFloat -> Bool
isNaN = MPFloat -> Bool
itisNaN