AERN-Real-Double-2011.1: src/Numeric/AERN/DoubleBasis/Interval.hs
{-# LANGUAGE FlexibleContexts #-}
{-|
Module : Numeric.AERN.DoubleBasis.Interval
Description : Interval Double type and operations
Copyright : (c) Michal Konecny, Jan Duracz
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Intervals with Double endpoints.
-}
module Numeric.AERN.DoubleBasis.Interval
(
-- |
-- A convenience module re-exporting various interval operations
-- with default effort indicators.
-- * Main type
DI,
-- ** associated operations
width, bisect,
-- * Order relations
-- |
-- There are two types of order relations to consider:
--
-- * the /numerical/ order, generalising the order relation
-- on Doubles and
--
-- * the /refinement/ order, generalising the reverse-inclusion
-- relation on consistent intervals.
--
-- The consistent intervals in 'DI' form a /meet/-semilattice
-- corresponding to the refiniement order under the operation /\\
-- returning the subset-least interval containing the /union/ of
-- its argument intervals. The operation is extended to all of 'DI'
-- by returning the highest interval below both of its argument
-- intervals.
--
-- The structure ({ 'di' | 'di' is consistent \}, /\\,
-- 'bottom') is a complete meet-semilattice.
--
-- Lower and upper approximations of the exact operation /\\
-- are given by '</\>' and '>/\<' respectively.
--
-- The dual operation to /\\ is partial on consistent intervals,
-- since the /intersection/ of disjoint sets is empty. Therefore,
-- the /join/-semilattice structure on 'DI' comes in two flavours:
--
-- * the partial consistent interval-valued join \\/\? which
-- returns 'Nothing' for disjoint and anticonsistent arguments
-- and
--
-- * the total join \\/ which returns the lowest interval in
-- 'DI' above both of its argument intervals.
--
-- The structure ('DI', \/\\, \\\/, 'bottom', 'top') is a complete
-- lattice.
--
-- Lower and upper approximations of the exact operations \\/\?
-- and \\\/ are given by '<\/>?', '<\/>' and '>\/<' respectively.
-- ** Numerical order
-- |
-- Interval extensions of the corresponding tests and relations on
-- Double.
-- *** Extrema
-- |
-- The values retured by 'least' and 'greatest' complete the
-- numerical partial order on 'DI'.
least,greatest,
-- *** Comparability tests
(==?),(<==>?),(</=>?),
-- *** Order relations
(<?),(>?),(<=?),(>=?),
-- ** Refinement order
-- |
-- Tests and relations in the interval poset.
-- *** Extrema
-- |
-- The values retured by 'bottom' and 'top' complete the
-- refinement partial order on 'DI'.
-- **** ASCII versions
bottom,top,
-- **** Unicode versions
(⊥),(⊤),
-- *** Comparability tests
(|==?),(|<==>?),(|</=>?),
-- *** Order relations
-- **** ASCII versions
(|<?),(|>?),(|<=?),(|>=?),
-- **** Unicode versions
(⊏?),(⊑?),(⊒?),(⊐?),
-- * Outward rounded operations
-- |
-- Interval extensions of common functions. The 'Num', 'Fractional'
-- and 'Floating' instances for 'DI' use such versions as instance
-- methods.
-- ** Order operations
-- *** Numerical order
-- |
-- Outward rounded interval extensions of the corresponding
-- operations on Double.
minOut,maxOut,
-- *** Refinement order
-- |
-- Outward rounded lattice operations in the interval poset.
-- **** ASCII versions
(</\>),(<\/>),(<\/>?),
-- **** Unicode versions
(<⊓>),(<⊔>),(<⊔>?),
-- ** Field operations
-- *** Interval operations
(<+>),(<->),(<*>),(</>),
-- *** Mixed type operations
(|<+>),(<+>|),(|<*>),(<*>|),(</>|),(<^>),
-- ** Special constants
piOut,eOut,
-- ** Elementary functions
absOut,expOut,sqrtOut,
-- *** Elementary functions with iteration effort control
-- |
-- To be used eg as follows:
--
-- > expOutIters 10 x
--
-- which means that at most 10 iterations should be used while computing exp
expOutIters,sqrtOutIters,
-- * Inward rounded operations
-- ** Order operations
-- *** Numerical order
-- |
-- Inward rounded interval extensions of the corresponding
-- operations on Double.
minIn,maxIn,
-- *** Refinement order
-- **** ASCII versions
(>/\<),(>\/<),
-- **** Unicode versions
(>⊓<),(>⊔<),
-- ** Field operations
-- *** Interval operations
(>+<),(>-<),(>*<),(>/<),
-- *** Mixed type operations
(|>+<),(>+<|),(|>*<),(>*<|),(>/<|),(>^<),
-- ** Special constants
piIn,eIn,
-- ** Elementary functions
absIn,expIn,sqrtIn,
-- *** Elementary functions with iteration effort control
-- |
-- To be used eg as follows:
--
-- > expInIters 10 x
--
-- which means that at most 10 iterations should be used while computing exp
expInIters,sqrtInIters,
-- * Low level facilities
-- ** Access functions
getEndpoints,fromEndpoints,
-- ** Base type
Interval(..),
)
where
import Numeric.AERN.Basics.Interval
(Interval(..))
import qualified Numeric.AERN.Basics.Interval as BI
(getEndpoints,fromEndpoints)
import qualified Numeric.AERN.Basics.NumericOrder as BNO
(least,greatest)
import qualified Numeric.AERN.Basics.NumericOrder.OpsDefaultEffort as BNOODE
((==?),(<==>?),(</=>?),
(<?),(>?),(<=?),(>=?),
minOut,maxOut,minIn,maxIn)
import qualified Numeric.AERN.Basics.RefinementOrder as BRO
(bottom,top,(⊥),(⊤))
import qualified Numeric.AERN.Basics.RefinementOrder.OpsDefaultEffort as BROODE
((|==?),(|<==>?),(|</=>?),
(|<?),(|>?),(|<=?),(|>=?),(⊏?),(⊑?),(⊒?),(⊐?),
(</\>),(<\/>),(<\/>?),(<⊓>),(<⊔>),(<⊔>?),
(>/\<),(>\/<),(>⊓<),(>⊔<))
import Numeric.AERN.RealArithmetic.Interval()
import qualified Numeric.AERN.RealArithmetic.RefinementOrderRounding as RAROR
(RoundedMixedAdd(..),RoundedMixedMultiply(..),RoundedMixedDivide(..))
import qualified Numeric.AERN.RealArithmetic.RefinementOrderRounding.OpsDefaultEffort as RARORODE
((<+>),(<->),(<*>),(</>),(|<+>),(<+>|),(|<*>),(<*>|),(</>|),(<^>),
piOut,eOut,absOut,expOut,sqrtOut,
(>+<),(>-<),(>*<),(>/<),(|>+<),(>+<|),(|>*<),(>*<|),(>/<|),(>^<),
piIn,eIn,absIn,expIn,sqrtIn)
import qualified Numeric.AERN.RealArithmetic.Interval.ElementaryFromFieldOps as RAIEFFO
(expOutIters, expInIters, sqrtOutIters, sqrtInIters)
import Numeric.AERN.RealArithmetic.Basis.Double()
import Numeric.AERN.RealArithmetic.Interval.Double(width, bisect)
import qualified Numeric.AERN.Basics.NumericOrder as NumOrd
import Test.QuickCheck
infix 4 ==?, <==>?, </=>?, <?, <=?, >=?, >?
infix 4 |==?, |<==>?, |</=>?, |<?, |<=?, |>=?, |>?, ⊏?, ⊑?, ⊒?, ⊐?
infixr 3 </\>, >/\<, <⊓>, >⊓<
infixr 2 <\/>?, <\/>, >\/<, <⊔>?, <⊔>, >⊔<
infixl 6 <+>, >+<, <->, >-<
infixl 7 <*>, >*<
infixl 8 <^>, >^<
infixl 7 </>, >/<
infixr 6 |<+>, |>+<
infixl 6 <+>|, >+<|
infixr 7 |<*>, |>*<
infixl 7 <*>|, >*<|
infixl 7 </>|, >/<|
-- |
-- Intervals with Double endpoints.
--
-- Note that ('l','r') = 'getEndpoints' ('di' :: 'DI') does not
-- fix an ordering of 'l' and 'r'.
--
-- * 'di' is called /consistent/ when 'l' '<=' 'r'
--
-- * 'di' is called /anticonsistent/ when 'r' '<=' 'l'
--
-- A consistent interval 'di' may be identified with the set defined by
-- \{ 'x' | 'l' '<=' 'x' and 'x' '<=' 'r' \}.
type DI = Interval Double
-- | Given an argument interval 'i' 'getEndpoints' returns the endpoint pair
-- ('leftEndpoint' 'i','rightEndpoint' 'i').
getEndpoints :: DI -> (Double, Double)
getEndpoints = BI.getEndpoints
-- | Constructs an interval from an endpoint pair.
fromEndpoints :: (Double, Double) -> DI
fromEndpoints = BI.fromEndpoints
sampleDI :: DI
sampleDI = Interval 0 0
least :: DI
least = BNO.least
greatest :: DI
greatest = BNO.greatest
-- | Partial equality
(==?) :: DI -> DI -> Maybe Bool
(==?) = (BNOODE.==?)
-- | Partial `is comparable to`
(<==>?) :: DI -> DI -> Maybe Bool
(<==>?) = (BNOODE.<==>?)
-- | Partial `is not comparable to`
(</=>?) :: DI -> DI -> Maybe Bool
(</=>?) = (BNOODE.</=>?)
-- | Partial `strictly less than`
(<?) :: DI -> DI -> Maybe Bool
(<?) = (BNOODE.<?)
-- | Partial `strictly greater than`
(>?) :: DI -> DI -> Maybe Bool
(>?) = (BNOODE.>?)
-- | Partial `less than or equal to`
(<=?) :: DI -> DI -> Maybe Bool
(<=?) = (BNOODE.<=?)
-- | Partial `greater than or equal to`
(>=?) :: DI -> DI -> Maybe Bool
(>=?) = (BNOODE.>=?)
-- | Outward rounded minimum
minOut :: DI -> DI -> DI
minOut = BNOODE.minOut
-- | Outward rounded maximum
maxOut :: DI -> DI -> DI
maxOut = BNOODE.maxOut
-- | Inward rounded minimum
minIn :: DI -> DI -> DI
minIn = BNOODE.minIn
-- | Inward rounded maximum
maxIn :: DI -> DI -> DI
maxIn = BNOODE.maxIn
bottom :: DI
bottom = BRO.bottom
top :: DI
top = BRO.top
-- | Convenience Unicode notation for 'bottom'
(⊥) :: DI
(⊥) = (BRO.⊥)
-- | Convenience Unicode notation for 'top'
(⊤) :: DI
(⊤) = (BRO.⊤)
-- | Partial equality
(|==?) :: DI -> DI -> Maybe Bool
(|==?) = (BROODE.|==?)
-- | Partial `is comparable to`
(|<==>?) :: DI -> DI -> Maybe Bool
(|<==>?) = (BROODE.|<==>?)
-- | Partial `is not comparable to`
(|</=>?) :: DI -> DI -> Maybe Bool
(|</=>?) = (BROODE.|</=>?)
-- | Partial `strictly below`
(|<?) :: DI -> DI -> Maybe Bool
(|<?) = (BROODE.|<?)
-- | Partial `strictly above`
(|>?) :: DI -> DI -> Maybe Bool
(|>?) = (BROODE.|>?)
-- | Partial `below or equal to`
(|<=?) :: DI -> DI -> Maybe Bool
(|<=?) = (BROODE.|<=?)
-- | Partial `above or equal to`
(|>=?) :: DI -> DI -> Maybe Bool
(|>=?) = (BROODE.|>=?)
{-| Convenience Unicode notation for '|<?' -}
(⊏?) :: DI -> DI -> Maybe Bool
(⊏?) = (BROODE.⊏?)
{-| Convenience Unicode notation for '|<=?' -}
(⊑?) :: DI -> DI -> Maybe Bool
(⊑?) = (BROODE.⊑?)
{-| Convenience Unicode notation for '|>=?' -}
(⊒?) :: DI -> DI -> Maybe Bool
(⊒?) = (BROODE.⊒?)
{-| Convenience Unicode notation for '|>?' -}
(⊐?) :: DI -> DI -> Maybe Bool
(⊐?) = (BROODE.⊐?)
-- | Outward rounded meet
(</\>) :: DI -> DI -> DI
(</\>) = (BROODE.</\>)
-- | Outward rounded join
(<\/>) :: DI -> DI -> DI
(<\/>) = (BROODE.<\/>)
-- | Inward rounded meet
(>/\<) :: DI -> DI -> DI
(>/\<) = (BROODE.>/\<)
-- | Inward rounded join
(>\/<) :: DI -> DI -> DI
(>\/<) = (BROODE.>\/<)
{-| Convenience Unicode notation for '</\>' -}
(<⊓>) :: DI -> DI -> DI
(<⊓>) = (BROODE.<⊓>)
{-| Convenience Unicode notation for '<\/>' -}
(<⊔>) :: DI -> DI -> DI
(<⊔>) = (BROODE.<⊔>)
{-| Convenience Unicode notation for '>/\<' -}
(>⊓<) :: DI -> DI -> DI
(>⊓<) = (BROODE.>⊓<)
{-| Convenience Unicode notation for '>\/<' -}
(>⊔<) :: DI -> DI -> DI
(>⊔<) = (BROODE.>⊔<)
-- | Partial outward rounded join
(<\/>?) :: DI -> DI -> Maybe DI
(<\/>?) = (BROODE.<\/>?)
{-| Convenience Unicode notation for '<\/>?' -}
(<⊔>?) :: DI -> DI -> Maybe DI
(<⊔>?) = (BROODE.<⊔>?)
-- | Outward rounded addition
(<+>) :: DI -> DI -> DI
(<+>) = (RARORODE.<+>)
-- | Outward rounded subtraction
(<->) :: DI -> DI -> DI
(<->) = (RARORODE.<->)
-- | Outward rounded multiplication
(<*>) :: DI -> DI -> DI
(<*>) = (RARORODE.<*>)
-- | Outward rounded division
(</>) :: DI -> DI -> DI
(</>) = (RARORODE.</>)
-- | Inward rounded addition
(>+<) :: DI -> DI -> DI
(>+<) = (RARORODE.>+<)
-- | Inward rounded subtraction
(>-<) :: DI -> DI -> DI
(>-<) = (RARORODE.>-<)
-- | Inward rounded multiplication
(>*<) :: DI -> DI -> DI
(>*<) = (RARORODE.>*<)
-- | Inward rounded division
(>/<) :: DI -> DI -> DI
(>/<) = (RARORODE.>/<)
-- | Outward rounded additive scalar left action
(|<+>) :: RAROR.RoundedMixedAdd DI tn => tn -> DI -> DI
(|<+>) = (RARORODE.|<+>)
-- | Inward rounded additive scalar left action
(|>+<) :: RAROR.RoundedMixedAdd DI tn => tn -> DI -> DI
(|>+<) = (RARORODE.|>+<)
-- | Outward rounded additive scalar right action
(<+>|) :: RAROR.RoundedMixedAdd DI tn => DI -> tn -> DI
(<+>|) = (RARORODE.<+>|)
-- | Inward rounded additive scalar right action
(>+<|) :: RAROR.RoundedMixedAdd DI tn => DI -> tn -> DI
(>+<|) = (RARORODE.>+<|)
-- | Outward rounded multiplicative scalar left action
(|<*>) :: RAROR.RoundedMixedMultiply DI tn => tn -> DI -> DI
(|<*>) = (RARORODE.|<*>)
-- | Inward rounded multiplicative scalar left action
(|>*<) :: RAROR.RoundedMixedMultiply DI tn => tn -> DI -> DI
(|>*<) = (RARORODE.|>*<)
-- | Outward rounded multiplicative scalar right action
(<*>|) :: RAROR.RoundedMixedMultiply DI tn => DI -> tn -> DI
(<*>|) = (RARORODE.<*>|)
-- | Inward rounded multiplicative scalar right action
(>*<|) :: RAROR.RoundedMixedMultiply DI tn => DI -> tn -> DI
(>*<|) = (RARORODE.>*<|)
-- | Outward rounded multiplicative scalar reciprocal right action
(</>|) :: RAROR.RoundedMixedDivide DI tn => DI -> tn -> DI
(</>|) = (RARORODE.</>|)
-- | Inward rounded multiplicative scalar reciprocal right action
(>/<|) :: RAROR.RoundedMixedDivide DI tn => DI -> tn -> DI
(>/<|) = (RARORODE.>/<|)
-- | Outward rounded power
(<^>) :: DI -> Int -> DI
(<^>) = (RARORODE.<^>)
-- | Inward rounded power
(>^<) :: DI -> Int -> DI
(>^<) = (RARORODE.>^<)
-- | Outward rounded pi
piOut :: DI
piOut = RARORODE.piOut
-- | Outward rounded e
eOut :: DI
eOut = RARORODE.eOut
-- | Inward rounded pi
piIn :: DI
piIn = RARORODE.piIn
-- | Inward rounded e
eIn :: DI
eIn = RARORODE.eIn
-- | Outward rounded absolute value
absOut :: DI -> DI
absOut = RARORODE.absOut
-- | Outward rounded exponential
expOut :: DI -> DI
expOut = RARORODE.expOut
-- | Outward rounded square root
sqrtOut :: DI -> DI
sqrtOut = RARORODE.sqrtOut
-- | Inward rounded absolute value
absIn :: DI -> DI
absIn = RARORODE.absIn
-- | Inward rounded exponential
expIn :: DI -> DI
expIn = RARORODE.expIn
-- | Inward rounded square root
sqrtIn :: DI -> DI
sqrtIn = RARORODE.sqrtIn
expOutIters :: Int -> DI -> DI
expOutIters = RAIEFFO.expOutIters
sqrtOutIters :: Int -> DI -> DI
sqrtOutIters = RAIEFFO.sqrtOutIters
expInIters :: Int -> DI -> DI
expInIters = RAIEFFO.expInIters
sqrtInIters :: Int -> DI -> DI
sqrtInIters = RAIEFFO.sqrtInIters
newtype PositiveDI = PositiveDI { unPositiveDI :: DI }
instance Show PositiveDI where
show (PositiveDI i) = show i
instance Arbitrary PositiveDI
where
arbitrary =
do
NumOrd.UniformlyOrderedPair (l,h) <- arbitrary
return $ PositiveDI (Interval (pos l) (pos h))
where
pos e
| e > 0 = e
| e == 0 = 1
| otherwise = (-e)