AERN-Real-2011.1: src/Numeric/AERN/RealArithmetic/RefinementOrderRounding/MixedFieldOps.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImplicitParams #-}
{-|
Module : Numeric.AERN.RefinementOrderRounding.MixedFieldOps
Description : rounded basic arithmetic operations mixing 2 types
Copyright : (c) Michal Konecny
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Rounded basic arithmetical operations mixing 2 types.
This module is hidden and reexported via its parent RefinementOrderRounding.
-}
module Numeric.AERN.RealArithmetic.RefinementOrderRounding.MixedFieldOps where
import Numeric.AERN.RealArithmetic.RefinementOrderRounding.FieldOps
import Numeric.AERN.RealArithmetic.RefinementOrderRounding.Conversion
import Numeric.AERN.RealArithmetic.ExactOps
import Numeric.AERN.Basics.Effort
import Numeric.AERN.Basics.Exception (HasLegalValues)
import Numeric.AERN.RealArithmetic.Laws
import Numeric.AERN.RealArithmetic.Measures
import qualified Numeric.AERN.Basics.NumericOrder as NumOrd
import qualified Numeric.AERN.Basics.RefinementOrder as RefOrd
import Numeric.AERN.Basics.RefinementOrder.OpsImplicitEffort
import Test.QuickCheck
import Test.Framework (testGroup, Test)
import Test.Framework.Providers.QuickCheck2 (testProperty)
class RoundedMixedAddEffort t tn where
type MixedAddEffortIndicator t tn
mixedAddDefaultEffort :: t -> tn -> MixedAddEffortIndicator t tn
class (RoundedMixedAddEffort t tn) => RoundedMixedAdd t tn where
mixedAddInEff :: MixedAddEffortIndicator t tn -> t -> tn -> t
mixedAddOutEff :: MixedAddEffortIndicator t tn -> t -> tn -> t
mixedAddDefaultEffortByConversion d n =
(addDefaultEffort d, convertDefaultEffort n d)
mixedAddInEffByConversion ::
(Convertible tn t, RoundedAdd t) =>
(AddEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedAddInEffByConversion (effAdd, effConv) d n =
addInEff effAdd d (convertInEff effConv n)
mixedAddOutEffByConversion ::
(Convertible tn t, RoundedAdd t) =>
(AddEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedAddOutEffByConversion (effAdd, effConv) d n =
addOutEff effAdd d (convertOutEff effConv n)
propMixedAddEqualsConvert ::
(RefOrd.PartialComparison t, Convertible tn t,
RoundedMixedAdd t tn, RoundedAdd t,
Show t, HasLegalValues t,
Show (MixedAddEffortIndicator t tn),
EffortIndicator (MixedAddEffortIndicator t tn),
Show (ConvertEffortIndicator tn t),
EffortIndicator (ConvertEffortIndicator tn t),
Show (AddEffortIndicator t),
EffortIndicator (AddEffortIndicator t),
Show (RefOrd.PartialCompareEffortIndicator t),
EffortIndicator (RefOrd.PartialCompareEffortIndicator t)
) =>
t -> tn ->
(RefOrd.PartialCompareEffortIndicator t,
(MixedAddEffortIndicator t tn,
AddEffortIndicator t,
ConvertEffortIndicator tn t)) ->
(RefOrd.UniformlyOrderedSingleton t) ->
tn -> Bool
propMixedAddEqualsConvert sample sampleN initEffort
(RefOrd.UniformlyOrderedSingleton d) n =
equalRoundingUpDn "mixed addition by conversion"
expr1In expr1Out expr2In expr2Out
RefOrd.pLeqEff initEffort
where
expr1In (effMAdd,_,_) =
let (>+<|) = mixedAddInEff effMAdd in d >+<| n
expr1Out (effMAdd,_,_) =
let (<+>|) = mixedAddOutEff effMAdd in d <+>| n
expr2In (_,effAdd,effConv) =
let (>+<) = addInEff effAdd in d >+< (convertInEff effConv n)
expr2Out (_,effAdd,effConv) =
let (<+>) = addOutEff effAdd in d <+> (convertOutEff effConv n)
class RoundedMixedMultiplyEffort t tn where
type MixedMultEffortIndicator t tn
mixedMultDefaultEffort :: t -> tn -> MixedMultEffortIndicator t tn
class (RoundedMixedMultiplyEffort t tn) => RoundedMixedMultiply t tn where
mixedMultInEff :: MixedMultEffortIndicator t tn -> t -> tn -> t
mixedMultOutEff :: MixedMultEffortIndicator t tn -> t -> tn -> t
mixedMultDefaultEffortByConversion d n =
(multDefaultEffort d, convertDefaultEffort n d)
mixedMultInEffByConversion ::
(Convertible tn t, RoundedMultiply t) =>
(MultEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedMultInEffByConversion (effMult, effConv) d n =
multInEff effMult d (convertInEff effConv n)
mixedMultOutEffByConversion ::
(Convertible tn t, RoundedMultiply t) =>
(MultEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedMultOutEffByConversion (effMult, effConv) d n =
multOutEff effMult d (convertOutEff effConv n)
propMixedMultEqualsConvert ::
(RefOrd.PartialComparison t, Convertible tn t,
RoundedMixedMultiply t tn, RoundedMultiply t,
Show t, HasLegalValues t,
Show (MixedMultEffortIndicator t tn),
EffortIndicator (MixedMultEffortIndicator t tn),
Show (ConvertEffortIndicator tn t),
EffortIndicator (ConvertEffortIndicator tn t),
Show (MultEffortIndicator t),
EffortIndicator (MultEffortIndicator t),
Show (RefOrd.PartialCompareEffortIndicator t),
EffortIndicator (RefOrd.PartialCompareEffortIndicator t)
) =>
t -> tn ->
(RefOrd.PartialCompareEffortIndicator t,
(MixedMultEffortIndicator t tn,
MultEffortIndicator t,
ConvertEffortIndicator tn t)) ->
(RefOrd.UniformlyOrderedSingleton t) ->
tn -> Bool
propMixedMultEqualsConvert sample sampleN initEffort
(RefOrd.UniformlyOrderedSingleton d) n =
equalRoundingUpDn "mixed multiplication by conversion"
expr1In expr1Out expr2In expr2Out
RefOrd.pLeqEff initEffort
where
expr1In (effMMult,_,_) =
let (>*<|) = mixedMultInEff effMMult in d >*<| n
expr1Out (effMMult,_,_) =
let (<*>|) = mixedMultOutEff effMMult in d <*>| n
expr2In (_,effMult,effConv) =
let (>*<) = multInEff effMult in d >*< (convertInEff effConv n)
expr2Out (_,effMult,effConv) =
let (<*>) = multOutEff effMult in d <*> (convertOutEff effConv n)
class RoundedMixedDivideEffort t tn where
type MixedDivEffortIndicator t tn
mixedDivDefaultEffort :: t -> tn -> MixedDivEffortIndicator t tn
class (RoundedMixedDivideEffort t tn) => RoundedMixedDivide t tn where
mixedDivInEff :: MixedDivEffortIndicator t tn -> t -> tn -> t
mixedDivOutEff :: MixedDivEffortIndicator t tn -> t -> tn -> t
mixedDivDefaultEffortByConversion d n =
(divDefaultEffort d, convertDefaultEffort n d)
mixedDivInEffByConversion ::
(Convertible tn t, RoundedDivide t) =>
(DivEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedDivInEffByConversion (effDiv, effConv) d n =
divInEff effDiv d (convertInEff effConv n)
mixedDivOutEffByConversion ::
(Convertible tn t, RoundedDivide t) =>
(DivEffortIndicator t, ConvertEffortIndicator tn t) ->
t -> tn -> t
mixedDivOutEffByConversion (effDiv, effConv) d n =
divOutEff effDiv d (convertOutEff effConv n)
propMixedDivEqualsConvert ::
(RefOrd.PartialComparison t, Convertible tn t,
RoundedMixedDivide t tn, RoundedDivide t,
Show t, HasZero t, HasLegalValues t,
Show (MixedDivEffortIndicator t tn),
EffortIndicator (MixedDivEffortIndicator t tn),
Show (ConvertEffortIndicator tn t),
EffortIndicator (ConvertEffortIndicator tn t),
Show (DivEffortIndicator t),
EffortIndicator (DivEffortIndicator t),
Show (RefOrd.PartialCompareEffortIndicator t),
EffortIndicator (RefOrd.PartialCompareEffortIndicator t)
) =>
t -> tn ->
(RefOrd.PartialCompareEffortIndicator t,
(MixedDivEffortIndicator t tn,
DivEffortIndicator t,
ConvertEffortIndicator tn t)) ->
(RefOrd.UniformlyOrderedSingleton t) ->
tn -> Bool
propMixedDivEqualsConvert sample sampleN initEffort@(effComp,(_,_,effConv))
(RefOrd.UniformlyOrderedSingleton d) n
=
equalRoundingUpDn "mixed division by conversion"
expr1In expr1Out expr2In expr2Out
RefOrd.pLeqEff initEffort
where
expr1In (effMDiv,_,_) =
let (>/<|) = mixedDivInEff effMDiv in d >/<| n
expr1Out (effMDiv,_,_) =
let (</>|) = mixedDivOutEff effMDiv in d </>| n
expr2In (_,effDiv,effConv) =
let (>/<) = divInEff effDiv in d >/< (convertInEff effConv n)
expr2Out (_,effDiv,effConv) =
let (</>) = divOutEff effDiv in d </> (convertOutEff effConv n)
testsInOutMixedFieldOps (name, sample) (nameN, sampleN) =
testGroup (name ++ " with " ++ nameN ++ ": mixed in/out rounded ops") $
[
testProperty "addition" (propMixedAddEqualsConvert sample sampleN)
,
testProperty "multiplication" (propMixedMultEqualsConvert sample sampleN)
,
testProperty "division" (propMixedDivEqualsConvert sample sampleN)
]
class (RoundedMixedAddEffort t tn, RoundedMixedMultiplyEffort t tn) =>
RoundedMixedRingEffort t tn
where
type MixedRingOpsEffortIndicator t tn
mixedRingOpsDefaultEffort :: t -> tn -> MixedRingOpsEffortIndicator t tn
mxringEffortAdd :: t -> tn -> MixedRingOpsEffortIndicator t tn -> MixedAddEffortIndicator t tn
mxringEffortMult :: t -> tn -> MixedRingOpsEffortIndicator t tn -> MixedMultEffortIndicator t tn
class (RoundedMixedAdd t tn, RoundedMixedMultiply t tn) =>
RoundedMixedRing t tn
class (RoundedMixedRingEffort t tn, RoundedMixedDivideEffort t tn) =>
RoundedMixedFieldEffort t tn
where
type MixedFieldOpsEffortIndicator t tn
mixedFieldOpsDefaultEffort :: t -> tn -> MixedFieldOpsEffortIndicator t tn
mxfldEffortAdd :: t -> tn -> MixedFieldOpsEffortIndicator t tn -> MixedAddEffortIndicator t tn
mxfldEffortMult :: t -> tn -> MixedFieldOpsEffortIndicator t tn -> MixedMultEffortIndicator t tn
mxfldEffortDiv :: t -> tn -> MixedFieldOpsEffortIndicator t tn -> MixedDivEffortIndicator t tn
class (RoundedMixedRing t tn, RoundedMixedDivide t tn, RoundedMixedFieldEffort t tn) =>
RoundedMixedField t tn