AERN-Real-Interval-2011.1: src/Numeric/AERN/RealArithmetic/Interval/FieldOps.hs
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE UndecidableInstances #-}
{-|
Module : Numeric.AERN.RealArithmetic.Interval.FieldOps
Description : refinement rounded basic operations for intervals
Copyright : (c) Michal Konecny, Jan Duracz
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Refinement rounded basic operations for intervals.
This module is hidden and reexported via its parent Interval.
-}
module Numeric.AERN.RealArithmetic.Interval.FieldOps
()
where
import Numeric.AERN.Basics.Interval
import Numeric.AERN.RealArithmetic.ExactOps
import Numeric.AERN.RealArithmetic.Interval.ExactOps
import qualified Numeric.AERN.RealArithmetic.NumericOrderRounding as ArithUpDn
import Numeric.AERN.RealArithmetic.RefinementOrderRounding
import qualified Numeric.AERN.Basics.NumericOrder as NumOrd
import qualified Numeric.AERN.Basics.RefinementOrder as RefOrd
instance (ArithUpDn.RoundedAddEffort e) => RoundedAddEffort (Interval e) where
type AddEffortIndicator (Interval e) = ArithUpDn.AddEffortIndicator e
addDefaultEffort (Interval l r) = ArithUpDn.addDefaultEffort l
instance (ArithUpDn.RoundedAdd e) => RoundedAdd (Interval e) where
addInEff effort (Interval l1 r1) (Interval l2 r2) =
Interval
(ArithUpDn.addUpEff effort l1 l2)
(ArithUpDn.addDnEff effort r1 r2)
addOutEff effort (Interval l1 r1) (Interval l2 r2) =
Interval
(ArithUpDn.addDnEff effort l1 l2)
(ArithUpDn.addUpEff effort r1 r2)
instance (ArithUpDn.RoundedAdd e, Neg e) => RoundedSubtr (Interval e)
instance
(NumOrd.PartialComparison e,
NumOrd.RoundedLatticeEffort e) =>
RoundedAbsEffort (Interval e)
where
type AbsEffortIndicator (Interval e) =
(NumOrd.PartialCompareEffortIndicator e, NumOrd.MinmaxEffortIndicator e)
absDefaultEffort (Interval l r) =
(NumOrd.pCompareDefaultEffort l, NumOrd.minmaxDefaultEffort l)
instance
(ArithUpDn.RoundedAbs e,
HasZero e, Neg e,
NumOrd.PartialComparison e,
NumOrd.RoundedLattice e) =>
RoundedAbs (Interval e)
where
absOutEff = absOutUsingCompMax
absInEff = absInUsingCompMax
instance
(ArithUpDn.RoundedMultiplyEffort e,
NumOrd.PartialComparison e,
NumOrd.RoundedLatticeEffort e) =>
RoundedMultiplyEffort (Interval e)
where
type MultEffortIndicator (Interval e) =
(NumOrd.PartialCompareEffortIndicator e,
NumOrd.MinmaxEffortIndicator e,
ArithUpDn.MultEffortIndicator e)
multDefaultEffort (Interval l r) =
(NumOrd.pCompareDefaultEffort l,
NumOrd.minmaxDefaultEffort l,
ArithUpDn.multDefaultEffort l)
instance
(ArithUpDn.RoundedMultiply e,
HasZero e, Neg e,
NumOrd.PartialComparison e,
NumOrd.RoundedLattice e) =>
RoundedMultiply (Interval e)
where
multOutEff (effortComp, effortMinmax, effortMult) i1 i2 =
fromEndpoints $
multiplyIntervals
(pNonnegNonposEff effortComp)
(ArithUpDn.multDnEff effortMult) (ArithUpDn.multUpEff effortMult)
(NumOrd.minDnEff effortMinmax) -- minL
(NumOrd.minUpEff effortMinmax) -- minR
(NumOrd.maxDnEff effortMinmax) -- maxL
(NumOrd.maxUpEff effortMinmax) -- maxR
(NumOrd.minDnEff effortMinmax)
(NumOrd.maxUpEff effortMinmax)
i1 i2
multInEff (effortComp, effortMinmax, effortMult) i1 i2 =
fromEndpoints $
multiplyIntervals
(pNonnegNonposEff effortComp)
(ArithUpDn.multUpEff effortMult) (ArithUpDn.multDnEff effortMult)
(NumOrd.minUpEff effortMinmax) -- minL
(NumOrd.minDnEff effortMinmax) -- minR
(NumOrd.maxUpEff effortMinmax) -- maxL
(NumOrd.maxDnEff effortMinmax) -- maxR
(NumOrd.maxUpEff effortMinmax)
(NumOrd.minDnEff effortMinmax)
i1 i2
multiplyIntervals
pNonnegNonpos timesL timesR minL minR maxL maxR
combineL combineR
(Interval l1 r1) (Interval l2 r2) =
let _ = [minL, maxR, combineL, combineR] in
case (pNonnegNonpos l1, -- sign of l1
pNonnegNonpos r1, -- sign of r1
pNonnegNonpos l2, -- sign of l2
pNonnegNonpos r2 -- sign of r2
) of
-----------------------------------------------------------
-- cases where i1 or i2 is known to be positive or negative
-----------------------------------------------------------
-- i1 negative, i2 positive
((_, Just True), (_, Just True), (Just True, _), (Just True, _)) ->
(l1 `timesL` r2, r1 `timesR` l2)
-- i1 negative, i2 negative
((_, Just True), (_, Just True), (_, Just True), (_, Just True)) ->
(r1 `timesL` r2, l1 `timesR` l2)
-- i1 negative, i2 consistent and containing zero
((_, Just True), (_, Just True), (_, Just True), (Just True, _)) ->
(l1 `timesL` r2, l1 `timesR` l2)
-- i1 negative, i2 anti-consistent and anti-containing zero
((_, Just True), (_, Just True), (Just True, _), (_, Just True)) ->
(r1 `timesL` r2, r1 `timesR` l2)
-- i1 negative, nothing known about i2:
((_, Just True), (_, Just True), _, _) ->
((r1 `timesL` r2) `combineL` (l1 `timesL` r2),
(r1 `timesR` l2) `combineR` (l1 `timesR` l2))
-- i1 positive, i2 positive
((Just True, _), (Just True, _), (Just True, _), (Just True, _)) ->
(l1 `timesL` l2, r1 `timesR` r2)
-- i1 positive, i2 negative
((Just True, _), (Just True, _), (_, Just True), (_, Just True)) ->
(r1 `timesL` l2, l1 `timesR` r2)
-- i1 positive, i2 consistent and containing zero
((Just True, _), (Just True, _), (_, Just True), (Just True, _)) ->
(r1 `timesL` l2, r1 `timesR` r2)
-- i1 positive, i2 anti-consistent and anti-containing zero
((Just True, _), (Just True, _), (Just True, _), (_, Just True)) ->
(l1 `timesL` l2, l1 `timesR` r2)
-- i1 positive, nothing known about i2:
((Just True, _), (Just True, _), _, _) ->
((r1 `timesL` l2) `combineL` (l1 `timesL` l2),
(r1 `timesR` r2) `combineR` (l1 `timesR` r2))
-- i1 consistent and containing zero, i2 positive
((_, Just True), (Just True, _), (Just True, _), (Just True, _)) ->
(l1 `timesL` r2, r1 `timesR` r2)
-- i1 anti-consistent and anti-containing zero, i2 positive
((Just True, _), (_, Just True), (Just True, _), (Just True, _)) ->
(l1 `timesL` l2, r1 `timesR` l2)
-- nothing known about i1, i2 positive
(_, _, (Just True, _), (Just True, _)) ->
((l1 `timesL` r2) `combineL` (l1 `timesL` l2),
(r1 `timesR` r2) `combineR` (r1 `timesR` l2))
-- i1 consistent and containing zero, i2 negative
((_, Just True), (Just True, _), (_, Just True), (_, Just True)) ->
(r1 `timesL` l2, l1 `timesR` l2)
-- i1 anti-consistent and anti-containing zero, i2 negative
((Just True, _), (_, Just True), (_, Just True), (_, Just True)) ->
(r1 `timesL` r2, l1 `timesR` r2)
-- nothing known about i1, i2 negative
(_, _, (_, Just True), (_, Just True)) ->
((r1 `timesL` r2) `combineL` (r1 `timesL` l2),
(l1 `timesR` r2) `combineR` (l1 `timesR` l2))
-----------------------------------------------------------
-- cases where both i1 or i2 are around zero
-----------------------------------------------------------
-- i1 consistent and containing zero, i2 consistent and containing zero
((_, Just True), (Just True, _), (_, Just True), (Just True, _)) ->
((l1 `timesL` r2) `minL` (r1 `timesL` l2),
(l1 `timesR` l2) `maxR` (r1 `timesR` r2))
-- i1 consistent and containing zero, i2 anti-consistent and anti-containing zero
((_, Just True), (Just True, _), (Just True, _), (_, Just True)) ->
(zero, zero)
-- i1 consistent and containing zero, i2 unknown
((_, Just True), (Just True, _), _, _) ->
(((l1 `timesL` r2) `combineL` (r1 `timesL` l2)) `combineL` zero,
((l1 `timesR` l2) `combineR` (r1 `timesR` r2)) `combineR` zero)
-- i1 anti-consistent and anti-containing zero, i2 consistent and containing zero
((Just True, _), (_, Just True), (_, Just True), (Just True, _)) ->
(zero, zero)
-- i1 anti-consistent and anti-containing zero, i2 anti-consistent and anti-containing zero
((Just True, _), (_, Just True), (Just True, _), (_, Just True)) ->
((l1 `timesL` l2) `maxL` (r1 `timesL` r2),
(l1 `timesR` r2) `minR` (r1 `timesR` l2))
-- i1 anti-consistent and anti-containing zero, i2 unknown
((Just True, _), (_, Just True), _, _) ->
((l1 `timesL` l2) `combineL` (r1 `timesL` r2) `combineL` zero,
(l1 `timesR` r2) `combineR` (r1 `timesR` l2) `combineR` zero)
-- i1 unknown, i2 anti-consistent and anti-containing zero
(_, _, (Just True, _), (_, Just True)) ->
((l1 `timesL` l2) `combineL` (r1 `timesL` r2) `combineL` zero,
(l1 `timesR` r2) `combineR` (r1 `timesR` l2) `combineR` zero)
-- i1 unknown, i2 consistent and containing zero
(_, _, (_, Just True), (Just True, _)) ->
((l1 `timesL` r2) `combineL` (r1 `timesL` l2) `combineL` zero,
(l1 `timesR` l2) `combineR` (r1 `timesR` r2) `combineR` zero)
-- both i1 and i2 unknown sign
_ ->
(foldl1 combineL [l1 `timesL` r2, r1 `timesL` l2, l1 `timesL` l2, r1 `timesL` r2],
foldl1 combineR [l1 `timesR` r2, r1 `timesR` l2, l1 `timesR` l2, r1 `timesR` r2])
instance
(ArithUpDn.RoundedPowerNonnegToNonnegIntEffort e,
ArithUpDn.RoundedMultiplyEffort e,
NumOrd.PartialComparison e, NumOrd.RoundedLatticeEffort e
) =>
RoundedPowerToNonnegIntEffort (Interval e)
where
type PowerToNonnegIntEffortIndicator (Interval e) =
(ArithUpDn.PowerNonnegToNonnegIntEffortIndicator e,
NumOrd.PartialCompareEffortIndicator e,
PowerToNonnegIntEffortIndicatorFromMult (Interval e))
powerToNonnegIntDefaultEffort i@(Interval l r) =
(ArithUpDn.powerNonnegToNonnegIntDefaultEffort l,
NumOrd.pCompareDefaultEffort l,
powerToNonnegIntDefaultEffortFromMult i)
instance
(ArithUpDn.RoundedPowerNonnegToNonnegInt e,
ArithUpDn.RoundedMultiply e,
HasZero e, HasOne e, Neg e,
NumOrd.PartialComparison e, NumOrd.RoundedLattice e
) =>
RoundedPowerToNonnegInt (Interval e)
where
powerToNonnegIntInEff
(effPowerEndpt, effComp, effPowerFromMult@(_,effMinMax,_))
i@(Interval l r) n =
case (pNonnegNonposEff effComp l, pNonnegNonposEff effComp r) of
((Just True, _), (Just True, _)) -> -- both non-negative
Interval lPowerUp hPowerDn
((_, Just True), (_, Just True)) -> -- both non-positive
case even n of
True -> Interval hNegPowerUp lNegPowerDn -- switching sign!
False -> Interval lNegNegPowerUp hNegNegPowerDn
_ -> -- may involve crossing zero, revert to the default:
case even n of
True ->
NumOrd.maxInEff effMinMax zero iPowerFromMult
-- take advantage of the fact that the result is non-negative
False -> iPowerFromMult
where
lPowerUp = ArithUpDn.powerNonnegToNonnegIntUpEff effPowerEndpt l n
hPowerDn = ArithUpDn.powerNonnegToNonnegIntDnEff effPowerEndpt r n
lNegPowerDn = ArithUpDn.powerNonnegToNonnegIntDnEff effPowerEndpt (neg l) n
hNegPowerUp = ArithUpDn.powerNonnegToNonnegIntUpEff effPowerEndpt (neg r) n
lNegNegPowerUp = neg lNegPowerDn
hNegNegPowerDn = neg hNegPowerUp
iPowerFromMult = powerToNonnegIntInEffFromMult effPowerFromMult i n
powerToNonnegIntOutEff
(effPowerEndpt, effComp, effPowerFromMult@(_,effMinMax,_))
i@(Interval l r) n =
case (pNonnegNonposEff effComp l, pNonnegNonposEff effComp r) of
((Just True, _), (Just True, _)) -> -- both non-negative
Interval lPowerDn hPowerUp
((_, Just True), (_, Just True)) -> -- both non-positive
case even n of
True -> Interval hNegPowerDn lNegPowerUp -- switching sign!
False -> Interval lNegNegPowerDn hNegNegPowerUp
_ -> -- may involve crossing zero, revert to the default:
case even n of
True ->
NumOrd.maxOutEff effMinMax zero iPowerFromMult
-- take advantage of the fact that the result is non-negative
False -> iPowerFromMult
where
lPowerDn = ArithUpDn.powerNonnegToNonnegIntDnEff effPowerEndpt l n
hPowerUp = ArithUpDn.powerNonnegToNonnegIntUpEff effPowerEndpt r n
lNegPowerUp = ArithUpDn.powerNonnegToNonnegIntUpEff effPowerEndpt (neg l) n
hNegPowerDn = ArithUpDn.powerNonnegToNonnegIntDnEff effPowerEndpt (neg r) n
lNegNegPowerDn = neg lNegPowerUp
hNegNegPowerUp = neg hNegPowerDn
iPowerFromMult = powerToNonnegIntOutEffFromMult effPowerFromMult i n
instance
(ArithUpDn.RoundedMultiplyEffort e, ArithUpDn.RoundedDivideEffort e,
NumOrd.PartialComparison e,
NumOrd.RoundedLatticeEffort e) =>
RoundedDivideEffort (Interval e)
where
type DivEffortIndicator (Interval e) =
(NumOrd.PartialCompareEffortIndicator e,
NumOrd.MinmaxEffortIndicator e,
(ArithUpDn.MultEffortIndicator e,
ArithUpDn.DivEffortIndicator e))
divDefaultEffort (Interval l r) =
(NumOrd.pCompareDefaultEffort l,
NumOrd.minmaxDefaultEffort l,
(ArithUpDn.multDefaultEffort l,
ArithUpDn.divDefaultEffort l))
instance
(ArithUpDn.RoundedMultiply e, ArithUpDn.RoundedDivide e,
HasZero e, Neg e, HasOne e, NumOrd.HasExtrema e,
NumOrd.PartialComparison e,
NumOrd.RoundedLattice e) =>
RoundedDivide (Interval e)
where
divOutEff (effortComp, effortMinmax, (effortMult, effortDiv)) i1 i2 =
multOutEff (effortComp, effortMinmax, effortMult) i1 $
recipInterval
(pPosNonnegNegNonposEff effortComp)
(ArithUpDn.divDnEff effortDiv)
(ArithUpDn.divUpEff effortDiv)
RefOrd.bottom
i2
divInEff (effortComp, effortMinmax, (effortMult, effortDiv)) i1 i2 =
multInEff (effortComp, effortMinmax, effortMult) i1 $
recipInterval
(pPosNonnegNegNonposEff effortComp)
(ArithUpDn.divUpEff effortDiv)
(ArithUpDn.divDnEff effortDiv)
RefOrd.top
i2
recipInterval pPosNonnegNegNonpos divL divR fallback (Interval l r) =
case (pPosNonnegNegNonpos l, pPosNonnegNegNonpos r) of
-- positive:
((Just True, _, _, _), (Just True, _, _, _)) ->
Interval (divL one r) (divR one l)
-- negative:
((_, _, Just True, _), (_, _, Just True, _)) ->
Interval (divL one r) (divR one l)
-- consistent around zero:
((_, _, _, Just True), (_, Just True, _, _)) ->
RefOrd.bottom
-- anti-consistent around zero:
((_, Just True, _, _), (_,_,_, Just True)) ->
RefOrd.top
-- unknown:
_ ->
fallback
instance
(ArithUpDn.RoundedRingEffort e,
NumOrd.PartialComparison e,
NumOrd.RoundedLatticeEffort e) =>
RoundedRingEffort (Interval e)
where
type RingOpsEffortIndicator (Interval e) =
(ArithUpDn.RingOpsEffortIndicator e,
NumOrd.PartialCompareEffortIndicator e,
NumOrd.MinmaxEffortIndicator e)
ringOpsDefaultEffort (Interval l r) =
(ArithUpDn.ringOpsDefaultEffort l,
NumOrd.pCompareDefaultEffort l,
NumOrd.minmaxDefaultEffort l)
ringEffortAdd (Interval l r) (effortRing, effortComp, effortMinmax) =
ArithUpDn.ringEffortAdd l effortRing
ringEffortMult (Interval l r) (effortRing, effortComp, effortMinmax) =
(effortComp, effortMinmax,
ArithUpDn.ringEffortMult l effortRing)
ringEffortPow i@(Interval l r) e@(effortRing, effortComp, effortMinmax) =
(ArithUpDn.ringEffortPow l effortRing,
effortComp,
ringEffortMult i e)
instance
(ArithUpDn.RoundedRing e,
ArithUpDn.RoundedPowerNonnegToNonnegInt e,
HasOne e, HasZero e, Neg e,
NumOrd.PartialComparison e,
NumOrd.RoundedLattice e) =>
RoundedRing (Interval e)
instance
(ArithUpDn.RoundedFieldEffort e,
NumOrd.PartialComparison e,
NumOrd.RoundedLatticeEffort e) =>
RoundedFieldEffort (Interval e)
where
type FieldOpsEffortIndicator (Interval e) =
(ArithUpDn.FieldOpsEffortIndicator e,
NumOrd.PartialCompareEffortIndicator e,
NumOrd.MinmaxEffortIndicator e)
fieldOpsDefaultEffort (Interval l r) =
(ArithUpDn.fieldOpsDefaultEffort l,
NumOrd.pCompareDefaultEffort l,
NumOrd.minmaxDefaultEffort l)
fldEffortAdd (Interval l r) (effortField, effortComp, effortMinmax) =
ArithUpDn.fldEffortAdd l effortField
fldEffortMult (Interval l r) (effortField, effortComp, effortMinmax) =
(effortComp, effortMinmax,
ArithUpDn.fldEffortMult l effortField)
fldEffortPow i@(Interval l r) e@(effortField, effortComp, effortMinmax) =
(ArithUpDn.fldEffortPow l effortField,
effortComp,
fldEffortMult i e)
fldEffortDiv (Interval l r) (effortField, effortComp, effortMinmax) =
(effortComp, effortMinmax,
(ArithUpDn.fldEffortMult l effortField,
ArithUpDn.fldEffortDiv l effortField))
instance
(ArithUpDn.RoundedField e,
ArithUpDn.RoundedPowerNonnegToNonnegInt e,
HasZero e, Neg e, HasOne e,
NumOrd.HasExtrema e,
NumOrd.PartialComparison e,
NumOrd.RoundedLattice e) =>
RoundedField (Interval e)