AERN-Real-Double-2011.1: src/Numeric/AERN/DoubleBasis/RealIntervalApprox.hs
{-# LANGUAGE FlexibleContexts #-}
{-|
Module : Numeric.AERN.DoubleBasis.RealIntervalApprox
Description : Double intervals for approximating real intervals
Copyright : (c) Michal Konecny, Jan Duracz
License : BSD3
Maintainer : mikkonecny@gmail.com
Stability : experimental
Portability : portable
Intervals with Double endpoints as an
abstract data type for approximating real number intervals.
Each interval is either an outer or inner approximation
of another interval.
Only operations that respect this view are available
via this module.
-}
module Numeric.AERN.DoubleBasis.RealIntervalApprox
(
-- |
-- A convenience module re-exporting various interval operations
-- with default effort indicators.
-- * Main type
RealIntervalApprox,
-- ** 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 'RealIntevalApprox' 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 'RealIntevalApprox'
-- 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 'RealIntevalApprox' 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
-- 'RealIntevalApprox' above both of its argument intervals.
--
-- The structure ('RealIntevalApprox', \/\\, \\\/, '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 'RealIntevalApprox'.
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 'RealIntevalApprox'.
-- **** 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 'RealIntevalApprox' 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
)
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 qualified Numeric.AERN.RealArithmetic.Interval.Double as RAID
(width, bisect)
import qualified Numeric.AERN.Basics.NumericOrder as NumOrd
import Test.QuickCheck
-- |
-- Intervals with Double endpoints, presented as an abstract
-- data type for approximating real number intervals from outside
-- or from inside.
--
-- Note that ('l','r') = 'getEndpoints' ('di' :: 'RealIntervalApprox') 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 RealIntervalApprox = Interval Double
-- | Given an argument interval 'i' 'getEndpoints' returns the endpoint pair
-- ('leftEndpoint' 'i','rightEndpoint' 'i').
getEndpoints :: RealIntervalApprox -> (Double, Double)
getEndpoints = BI.getEndpoints
-- | Constructs an interval from an endpoint pair.
fromEndpoints :: (Double, Double) -> RealIntervalApprox
fromEndpoints = BI.fromEndpoints
sampleRealIntervalApprox :: RealIntervalApprox
sampleRealIntervalApprox = Interval 0 0
{-|
Calculate the width of an interval.
The result may not be thin since the width calculation uses outwards rounding.
-}
width :: RealIntervalApprox -> RealIntervalApprox
width = RAID.width
{-|
Split an interval into two subintervals that share only one point
and whose union is the original interval.
-}
bisect ::
Maybe Double {-^ optional parameter, indicating where to split the interval -} ->
RealIntervalApprox {-^ the interval to split -} ->
(RealIntervalApprox, RealIntervalApprox)
bisect = RAID.bisect
least :: RealIntervalApprox
least = BNO.least
greatest :: RealIntervalApprox
greatest = BNO.greatest
infix 4 ==?, <==>?, </=>?, <?, <=?, >=?, >?
-- | Partial equality
(==?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(==?) = (BNOODE.==?)
-- | Partial `is comparable to`
(<==>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(<==>?) = (BNOODE.<==>?)
-- | Partial `is not comparable to`
(</=>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(</=>?) = (BNOODE.</=>?)
-- | Partial `strictly less than`
(<?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(<?) = (BNOODE.<?)
-- | Partial `strictly greater than`
(>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(>?) = (BNOODE.>?)
-- | Partial `less than or equal to`
(<=?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(<=?) = (BNOODE.<=?)
-- | Partial `greater than or equal to`
(>=?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(>=?) = (BNOODE.>=?)
-- | Outward rounded minimum
minOut :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
minOut = BNOODE.minOut
-- | Outward rounded maximum
maxOut :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
maxOut = BNOODE.maxOut
-- | Inward rounded minimum
minIn :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
minIn = BNOODE.minIn
-- | Inward rounded maximum
maxIn :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
maxIn = BNOODE.maxIn
bottom :: RealIntervalApprox
bottom = BRO.bottom
top :: RealIntervalApprox
top = BRO.top
-- | Convenience Unicode notation for 'bottom'
(⊥) :: RealIntervalApprox
(⊥) = (BRO.⊥)
-- | Convenience Unicode notation for 'top'
(⊤) :: RealIntervalApprox
(⊤) = (BRO.⊤)
infix 4 |==?, |<==>?, |</=>?, |<?, |<=?, |>=?, |>?, ⊏?, ⊑?, ⊒?, ⊐?
infixr 3 </\>, >/\<, <⊓>, >⊓<
infixr 2 <\/>?, <\/>, >\/<, <⊔>?, <⊔>, >⊔<
-- | Partial equality
(|==?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|==?) = (BROODE.|==?)
-- | Partial `is comparable to`
(|<==>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|<==>?) = (BROODE.|<==>?)
-- | Partial `is not comparable to`
(|</=>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|</=>?) = (BROODE.|</=>?)
-- | Partial `strictly below`
(|<?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|<?) = (BROODE.|<?)
-- | Partial `strictly above`
(|>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|>?) = (BROODE.|>?)
-- | Partial `below or equal to`
(|<=?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|<=?) = (BROODE.|<=?)
-- | Partial `above or equal to`
(|>=?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(|>=?) = (BROODE.|>=?)
{-| Convenience Unicode notation for '|<?' -}
(⊏?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(⊏?) = (BROODE.⊏?)
{-| Convenience Unicode notation for '|<=?' -}
(⊑?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(⊑?) = (BROODE.⊑?)
{-| Convenience Unicode notation for '|>=?' -}
(⊒?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(⊒?) = (BROODE.⊒?)
{-| Convenience Unicode notation for '|>?' -}
(⊐?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe Bool
(⊐?) = (BROODE.⊐?)
-- | Outward rounded meet
(</\>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(</\>) = (BROODE.</\>)
-- | Outward rounded join
(<\/>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<\/>) = (BROODE.<\/>)
-- | Inward rounded meet
(>/\<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>/\<) = (BROODE.>/\<)
-- | Inward rounded join
(>\/<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>\/<) = (BROODE.>\/<)
{-| Convenience Unicode notation for '</\>' -}
(<⊓>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<⊓>) = (BROODE.<⊓>)
{-| Convenience Unicode notation for '<\/>' -}
(<⊔>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<⊔>) = (BROODE.<⊔>)
{-| Convenience Unicode notation for '>/\<' -}
(>⊓<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>⊓<) = (BROODE.>⊓<)
{-| Convenience Unicode notation for '>\/<' -}
(>⊔<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>⊔<) = (BROODE.>⊔<)
-- | Partial outward rounded join
(<\/>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe RealIntervalApprox
(<\/>?) = (BROODE.<\/>?)
{-| Convenience Unicode notation for '<\/>?' -}
(<⊔>?) :: RealIntervalApprox -> RealIntervalApprox -> Maybe RealIntervalApprox
(<⊔>?) = (BROODE.<⊔>?)
infixl 6 <+>, >+<, <->, >-<
infixl 7 <*>, >*<
infixl 8 <^>, >^<
infixl 7 </>, >/<
infixr 6 |<+>, |>+<
infixl 6 <+>|, >+<|
infixr 7 |<*>, |>*<
infixl 7 <*>|, >*<|
infixl 7 </>|, >/<|
-- | Outward rounded addition
(<+>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<+>) = (RARORODE.<+>)
-- | Outward rounded subtraction
(<->) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<->) = (RARORODE.<->)
-- | Outward rounded multiplication
(<*>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(<*>) = (RARORODE.<*>)
-- | Outward rounded division
(</>) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(</>) = (RARORODE.</>)
-- | Inward rounded addition
(>+<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>+<) = (RARORODE.>+<)
-- | Inward rounded subtraction
(>-<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>-<) = (RARORODE.>-<)
-- | Inward rounded multiplication
(>*<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>*<) = (RARORODE.>*<)
-- | Inward rounded division
(>/<) :: RealIntervalApprox -> RealIntervalApprox -> RealIntervalApprox
(>/<) = (RARORODE.>/<)
-- | Outward rounded additive scalar left action
(|<+>) :: RAROR.RoundedMixedAdd RealIntervalApprox tn => tn -> RealIntervalApprox -> RealIntervalApprox
(|<+>) = (RARORODE.|<+>)
-- | Inward rounded additive scalar left action
(|>+<) :: RAROR.RoundedMixedAdd RealIntervalApprox tn => tn -> RealIntervalApprox -> RealIntervalApprox
(|>+<) = (RARORODE.|>+<)
-- | Outward rounded additive scalar right action
(<+>|) :: RAROR.RoundedMixedAdd RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(<+>|) = (RARORODE.<+>|)
-- | Inward rounded additive scalar right action
(>+<|) :: RAROR.RoundedMixedAdd RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(>+<|) = (RARORODE.>+<|)
-- | Outward rounded multiplicative scalar left action
(|<*>) :: RAROR.RoundedMixedMultiply RealIntervalApprox tn => tn -> RealIntervalApprox -> RealIntervalApprox
(|<*>) = (RARORODE.|<*>)
-- | Inward rounded multiplicative scalar left action
(|>*<) :: RAROR.RoundedMixedMultiply RealIntervalApprox tn => tn -> RealIntervalApprox -> RealIntervalApprox
(|>*<) = (RARORODE.|>*<)
-- | Outward rounded multiplicative scalar right action
(<*>|) :: RAROR.RoundedMixedMultiply RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(<*>|) = (RARORODE.<*>|)
-- | Inward rounded multiplicative scalar right action
(>*<|) :: RAROR.RoundedMixedMultiply RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(>*<|) = (RARORODE.>*<|)
-- | Outward rounded multiplicative scalar reciprocal right action
(</>|) :: RAROR.RoundedMixedDivide RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(</>|) = (RARORODE.</>|)
-- | Inward rounded multiplicative scalar reciprocal right action
(>/<|) :: RAROR.RoundedMixedDivide RealIntervalApprox tn => RealIntervalApprox -> tn -> RealIntervalApprox
(>/<|) = (RARORODE.>/<|)
-- | Outward rounded power
(<^>) :: RealIntervalApprox -> Int -> RealIntervalApprox
(<^>) = (RARORODE.<^>)
-- | Inward rounded power
(>^<) :: RealIntervalApprox -> Int -> RealIntervalApprox
(>^<) = (RARORODE.>^<)
-- | Outward rounded pi
piOut :: RealIntervalApprox
piOut = RARORODE.piOut
-- | Outward rounded e
eOut :: RealIntervalApprox
eOut = RARORODE.eOut
-- | Inward rounded pi
piIn :: RealIntervalApprox
piIn = RARORODE.piIn
-- | Inward rounded e
eIn :: RealIntervalApprox
eIn = RARORODE.eIn
-- | Outward rounded absolute value
absOut :: RealIntervalApprox -> RealIntervalApprox
absOut = RARORODE.absOut
-- | Outward rounded exponential
expOut :: RealIntervalApprox -> RealIntervalApprox
expOut = RARORODE.expOut
-- | Outward rounded square root
sqrtOut :: RealIntervalApprox -> RealIntervalApprox
sqrtOut = RARORODE.sqrtOut
-- | Inward rounded absolute value
absIn :: RealIntervalApprox -> RealIntervalApprox
absIn = RARORODE.absIn
-- | Inward rounded exponential
expIn :: RealIntervalApprox -> RealIntervalApprox
expIn = RARORODE.expIn
-- | Inward rounded square root
sqrtIn :: RealIntervalApprox -> RealIntervalApprox
sqrtIn = RARORODE.sqrtIn
expOutIters :: Int -> RealIntervalApprox -> RealIntervalApprox
expOutIters = RAIEFFO.expOutIters
sqrtOutIters :: Int -> RealIntervalApprox -> RealIntervalApprox
sqrtOutIters = RAIEFFO.sqrtOutIters
expInIters :: Int -> RealIntervalApprox -> RealIntervalApprox
expInIters = RAIEFFO.expInIters
sqrtInIters :: Int -> RealIntervalApprox -> RealIntervalApprox
sqrtInIters = RAIEFFO.sqrtInIters
newtype PositiveRealIntervalApprox =
PositiveRealIntervalApprox
{ unPositiveRealIntervalApprox :: RealIntervalApprox }
instance Show PositiveRealIntervalApprox where
show (PositiveRealIntervalApprox i) = show i
instance Arbitrary PositiveRealIntervalApprox
where
arbitrary =
do
NumOrd.UniformlyOrderedPair (l,h) <- arbitrary
return $ PositiveRealIntervalApprox (Interval (pos l) (pos h))
where
pos e
| e > 0 = e
| e == 0 = 1
| otherwise = (-e)