packages feed

AERN-Real-Interval-2011.1: src/Numeric/AERN/RealArithmetic/Interval/MixedFieldOps.hs

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-|
    Module      :  Numeric.AERN.RealArithmetic.Interval.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 an interval and another type.
    
    This module is hidden and reexported via its parent Interval. 
-}

module Numeric.AERN.RealArithmetic.Interval.MixedFieldOps 
()
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.RoundedMixedAddEffort e tn) => 
    RoundedMixedAddEffort (Interval e) tn 
    where
    type MixedAddEffortIndicator (Interval e) tn = ArithUpDn.MixedAddEffortIndicator e tn
    mixedAddDefaultEffort (Interval l r) n = ArithUpDn.mixedAddDefaultEffort l n

instance (ArithUpDn.RoundedMixedAdd e tn) => 
    RoundedMixedAdd (Interval e) tn 
    where
    mixedAddInEff effort (Interval l2 r2) n =
        Interval
            (ArithUpDn.mixedAddUpEff effort l2 n)
            (ArithUpDn.mixedAddDnEff effort r2 n)
    mixedAddOutEff effort (Interval l2 r2) n =
        Interval 
            (ArithUpDn.mixedAddDnEff effort l2 n)
            (ArithUpDn.mixedAddUpEff effort r2 n)

instance (ArithUpDn.RoundedMixedMultiplyEffort e tn,
          NumOrd.PartialComparison tn, NumOrd.PartialComparison e,
          NumOrd.RoundedLatticeEffort e) => 
    RoundedMixedMultiplyEffort (Interval e) tn 
    where
    type MixedMultEffortIndicator (Interval e) tn = 
        ((NumOrd.PartialCompareEffortIndicator tn, 
          NumOrd.PartialCompareEffortIndicator e), 
         NumOrd.MinmaxEffortIndicator e,
         ArithUpDn.MixedMultEffortIndicator e tn)
    mixedMultDefaultEffort (Interval l r) n = 
        ((NumOrd.pCompareDefaultEffort n, 
          NumOrd.pCompareDefaultEffort l), 
         NumOrd.minmaxDefaultEffort l,
         ArithUpDn.mixedMultDefaultEffort l n) 

instance (ArithUpDn.RoundedMixedMultiply e tn,
          HasZero tn, HasZero e,
          NumOrd.PartialComparison tn, NumOrd.PartialComparison e,
          NumOrd.RoundedLattice e) => 
    RoundedMixedMultiply (Interval e) tn 
    where
    mixedMultInEff ((effortCompS, effortCompE), effortMinmax, effortMult) i n =
        fromEndpoints $
        multiplySingletonWithInterval 
            (pNonnegNonposEff effortCompS)
            (pNonnegNonposEff effortCompE)
            (flip $ ArithUpDn.mixedMultUpEff effortMult)
            (flip $ ArithUpDn.mixedMultDnEff effortMult) 
            (NumOrd.maxUpEff effortMinmax) 
            (NumOrd.minDnEff effortMinmax)
            n i
    mixedMultOutEff ((effortCompS, effortCompE), effortMinmax, effortMult) i n =
        fromEndpoints $
        multiplySingletonWithInterval 
            (pNonnegNonposEff effortCompS)
            (pNonnegNonposEff effortCompE)
            (flip $ ArithUpDn.mixedMultDnEff effortMult) 
            (flip $ ArithUpDn.mixedMultUpEff effortMult)
            (NumOrd.minDnEff effortMinmax)
            (NumOrd.maxUpEff effortMinmax) 
            n i

multiplySingletonWithInterval 
        sNonnegNonpos iNonnegNonpos timesL timesR 
        combineL combineR
        s1 (Interval l2 r2) =
    let _ = [combineL, combineR] in
        case (sNonnegNonpos s1, -- sign of s1 
              iNonnegNonpos l2, -- sign of l2
              iNonnegNonpos r2 -- sign of r2 
             ) of
             
            -- s1 is zero
            ((Just True, Just True), _, _) -> 
                (zero, zero)
 
            -- s1 non negative
            ((Just True, _), _, _) -> 
                (s1 `timesL` l2, s1 `timesR` r2)
            
            -- s1 non positive
            ((_, Just True), _, _) -> 
                (s1 `timesL` r2, s1 `timesR` l2)

            -- nothing known about s1, i2 positive
            (_, (Just True, _), (Just True, _)) -> 
                ((s1 `timesL` r2) `combineL` (s1 `timesL` l2), 
                 (s1 `timesR` r2) `combineR` (s1 `timesR` l2))

            -- nothing known about s1, i2 negative
            (_, (_, Just True), (_, Just True)) -> 
                ((s1 `timesL` r2) `combineL` (s1 `timesL` l2), 
                 (s1 `timesR` r2) `combineR` (s1 `timesR` l2))

            -- both s1 and i2 are around zero
            _ ->
                ((s1 `timesL` l2) `combineL` (s1 `timesL` r2) `combineL` zero,
                 (s1 `timesR` l2) `combineR` (s1 `timesR` r2) `combineR` zero) 
                -- need to include zero to account for 
                -- consistent vs anti-consistent cases giving constant 0

instance (RoundedDivideEffort (Interval e),
          Convertible tn (Interval e)) => 
    RoundedMixedDivideEffort (Interval e) tn 
    where
    type MixedDivEffortIndicator (Interval e) tn =
        (DivEffortIndicator (Interval e), 
         ConvertEffortIndicator tn (Interval e))
    mixedDivDefaultEffort = mixedDivDefaultEffortByConversion

instance (RoundedDivide (Interval e),
          Convertible tn (Interval e)) => 
    RoundedMixedDivide (Interval e) tn 
    where
    mixedDivInEff = mixedDivInEffByConversion
    mixedDivOutEff = mixedDivOutEffByConversion
    
instance (RoundedMixedAddEffort (Interval e) tn,
          RoundedMixedMultiplyEffort (Interval e) tn, 
          NumOrd.PartialComparison e,
          NumOrd.RoundedLatticeEffort e,
          NumOrd.PartialComparison tn,
          ArithUpDn.RoundedMixedRingEffort e tn) => 
        RoundedMixedRingEffort (Interval e) tn
    where
    type MixedRingOpsEffortIndicator (Interval e) tn =
        (ArithUpDn.MixedRingOpsEffortIndicator e tn,
         (NumOrd.PartialCompareEffortIndicator e, 
          NumOrd.MinmaxEffortIndicator e, 
          NumOrd.PartialCompareEffortIndicator tn))
    mixedRingOpsDefaultEffort i@(Interval l r) n =
        (ArithUpDn.mixedRingOpsDefaultEffort l n,
         (NumOrd.pCompareDefaultEffort l,
          NumOrd.minmaxDefaultEffort l,
          NumOrd.pCompareDefaultEffort n))
    mxringEffortAdd (Interval l r) n (effortRing, _) = 
        ArithUpDn.mxringEffortAdd l n effortRing
    mxringEffortMult (Interval l r) n (effortRing, (effortCompEpt, effortMinmax, effortCompS)) =
        ((effortCompS, effortCompEpt), 
          effortMinmax, 
          ArithUpDn.mxringEffortMult l n effortRing) 

instance (RoundedMixedAdd (Interval e) tn,
          RoundedMixedMultiply (Interval e) tn,
          RoundedMixedRingEffort (Interval e) tn) => 
        RoundedMixedRing (Interval e) tn
    
instance (RoundedMixedRingEffort (Interval e) tn,
          RoundedMixedDivideEffort (Interval e) tn,
          NumOrd.PartialComparison e,
          NumOrd.RoundedLatticeEffort e,
          NumOrd.PartialComparison tn,
          ArithUpDn.RoundedMixedFieldEffort e tn) => 
        RoundedMixedFieldEffort (Interval e) tn
    where
    type MixedFieldOpsEffortIndicator (Interval e) tn =
        (ArithUpDn.MixedFieldOpsEffortIndicator e tn,
         (NumOrd.PartialCompareEffortIndicator e, 
          NumOrd.MinmaxEffortIndicator e, 
          NumOrd.PartialCompareEffortIndicator tn),
         MixedDivEffortIndicator (Interval e) tn)
    mixedFieldOpsDefaultEffort i@(Interval l r) n =
        (ArithUpDn.mixedFieldOpsDefaultEffort l n,
         (NumOrd.pCompareDefaultEffort l,
          NumOrd.minmaxDefaultEffort l,
          NumOrd.pCompareDefaultEffort n),
         mixedDivDefaultEffort i n)
    mxfldEffortAdd (Interval l r) n (effortFld, _, _) = 
        ArithUpDn.mxfldEffortAdd l n effortFld
    mxfldEffortMult (Interval l r) n (effortFld, (effortCompEpt, effortMinmax, effortCompS), _) =
        ((effortCompS, effortCompEpt), 
          effortMinmax, 
          ArithUpDn.mxfldEffortMult l n effortFld) 
    mxfldEffortDiv _ _ (_, _, effortDiv) = effortDiv
    
instance (RoundedMixedRing (Interval e) tn,
          RoundedMixedDivide (Interval e) tn,
          RoundedMixedFieldEffort (Interval e) tn) => 
        RoundedMixedField (Interval e) tn