{-# 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
. Integer -> MPFloat
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
. Integer -> MPFloat
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
. (Int -> Rational -> MPFloat
MPLow.toApproxMB (Precision -> Int
p2cdarPrec Precision
pp))

{- conversions from MPFloat -}

instance ConvertibleExactly MPFloat Rational where
  safeConvertExactly :: MPFloat -> ConvertResult Rational
safeConvertExactly = Rational -> ConvertResult Rational
forall a b. b -> Either a b
Right (Rational -> ConvertResult Rational)
-> (MPFloat -> Rational) -> MPFloat -> ConvertResult Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MPFloat -> Rational
forall a. Real a => a -> Rational
P.toRational
    
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
x = (Integer
RoundType MPFloat
n,MPFloat
f)
    where
      r :: Rational
r = MPFloat -> Rational
forall t. CanBeRational t => t -> Rational
rational MPFloat
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
$ MPFloat
x MPFloat -> MPFloat -> BoundsCEDU MPFloat
`subCEDU` (Integer -> MPFloat
forall a. Num a => Integer -> a
P.fromInteger Integer
n)
  
{- comparisons -}

instance HasEqAsymmetric MPFloat MPFloat
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 MPFloat MPFloat
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 = MPFloat
MinMaxType MPFloat MPFloat
x
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = MPFloat
MinMaxType MPFloat MPFloat
y
    | Bool
otherwise = MPFloat -> MPFloat -> MPFloat
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 = MPFloat
MinMaxType MPFloat MPFloat
x
    | MPFloat -> Bool
forall t. CanTestNaN t => t -> Bool
isNaN MPFloat
y = MPFloat
MinMaxType MPFloat MPFloat
y
    | Bool
otherwise = MPFloat -> MPFloat -> MPFloat
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 = MPFloat
MPLow.Bottom
infinity :: MPFloat
infinity = MPFloat
nan

itisNaN :: MPFloat -> Bool
itisNaN :: MPFloat -> Bool
itisNaN MPFloat
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