AERN-Real-2011.1: src/Numeric/AERN/RealArithmetic/RefinementOrderRounding/Conversion.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ImplicitParams #-}
{-|
Module : Numeric.AERN.RealArithmetic.RefinementOrderRounding.Conversion
Description : conversion between approximations and other types
Copyright : (c) Michal Konecny
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Conversion between approximations and other types.
This module is hidden and reexported via its parent RefinementOrderRounding.
-}
module Numeric.AERN.RealArithmetic.RefinementOrderRounding.Conversion where
import Prelude hiding (EQ, LT, GT)
import Numeric.AERN.RealArithmetic.ExactOps
import Numeric.AERN.Basics.Effort
import Numeric.AERN.Basics.PartialOrdering
import qualified Numeric.AERN.Basics.RefinementOrder as RefOrd
import qualified Numeric.AERN.Basics.NumericOrder as NumOrd
import Numeric.AERN.Basics.NumericOrder.OpsImplicitEffort
import qualified Numeric.AERN.RealArithmetic.NumericOrderRounding.Conversion as UpDnConversion
import Numeric.AERN.Misc.Bool
import Numeric.AERN.Misc.Maybe
import Data.Ratio
import Data.Maybe
import Test.QuickCheck
import Test.Framework (testGroup, Test)
import Test.Framework.Providers.QuickCheck2 (testProperty)
class Convertible t1 t2 where
type ConvertEffortIndicator t1 t2
convertDefaultEffort :: t1 -> t2 -> ConvertEffortIndicator t1 t2
convertInEff :: ConvertEffortIndicator t1 t2 -> t1 -> t2
convertOutEff :: ConvertEffortIndicator t1 t2 -> t1 -> t2
propConvertMonotoneFromNumOrd ::
(Convertible t1 t2, NumOrd.ArbitraryOrderedTuple t1, NumOrd.PartialComparison t2) =>
t1 -> t2 ->
(ConvertEffortIndicator t1 t2, NumOrd.PartialCompareEffortIndicator t2) ->
NumOrd.LEPair t1 -> Bool
propConvertMonotoneFromNumOrd sample1 sample2 (effortFrom, effortComp) (NumOrd.LEPair (a, b)) =
(trueOrNothing $ let ?pCompareEffort = effortComp in aOut <=? bOut)
&&
(trueOrNothing $ let ?pCompareEffort = effortComp in aIn <=? bIn)
where
aOut = convertOutEff effortFrom a
aIn = convertInEff effortFrom a
bOut = convertOutEff effortFrom b
bIn = convertInEff effortFrom b
_ = [sample2, aOut, aIn]
propConvertRoundTripNumOrd ::
(UpDnConversion.Convertible t1 t2, Convertible t2 t1,
NumOrd.PartialComparison t1, Show t1, Show t2) =>
t1 -> t2 ->
(NumOrd.PartialCompareEffortIndicator t1,
ConvertEffortIndicator t2 t1,
UpDnConversion.ConvertEffortIndicator t1 t2) ->
t1 -> Bool
propConvertRoundTripNumOrd sample1 sample2 (effortComp, effortFrom, effortTo) a =
(defined maDn && defined maUp) ===>
let ?pCompareEffort = effortComp in
case (aDnOut <=? a, a <=? aUpOut) of
(Just False, _) -> printErrorDetail
(_, Just False) -> printErrorDetail
_ -> True
where
aDnOut = convertOutEff effortFrom aDn
maDn = UpDnConversion.convertDnEff effortTo a
aDn = fromJust maDn
aUpOut = convertOutEff effortFrom aUp
maUp = UpDnConversion.convertUpEff effortTo a
aUp = fromJust maUp
_ = [sample2, aDn, aUp]
printErrorDetail =
error $
"propToFromInteger failed:"
++ "\n a = " ++ show a
++ "\n aDnOut = " ++ show aDnOut
++ "\n aUpOut = " ++ show aUpOut
testsConvertNumOrd (name1, sample1, name2, sample2) =
testGroup (name1 ++ " -> " ++ name2 ++ " conversions") $
[
testProperty "monotone" (propConvertMonotoneFromNumOrd sample1 sample2)
,
testProperty "round trip" (propConvertRoundTripNumOrd sample2 sample1)
]