{-# LANGUAGE CPP #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Numeric.Interval
-- Copyright   :  (c) Edward Kmett 2010-2014
-- License     :  BSD3
-- Maintainer  :  ekmett@gmail.com
-- Stability   :  experimental
-- Portability :  DeriveDataTypeable
--
-- \"Directed\" Interval arithmetic
--
-----------------------------------------------------------------------------

module Numeric.Interval.Kaucher
  ( Interval(..)
  , (...)
  , interval
  , whole
  , empty
  , null
  , singleton
  , member
  , notMember
  , elem
  , notElem
  , inf
  , sup
  , singular
  , width
  , midpoint
  , intersection
  , hull
  , bisect
  , magnitude
  , mignitude
  , distance
  , inflate, deflate
  , scale, symmetric
  , contains
  , isSubsetOf
  , certainly, (<!), (<=!), (==!), (/=!), (>=!), (>!)
  , possibly, (<?), (<=?), (==?), (/=?), (>=?), (>?)
  , clamp
  , idouble
  , ifloat
  , iquot
  , irem
  , idiv
  , imod
  ) where

import Control.Applicative hiding (empty)
import Control.Exception as Exception
import Data.Data
import Data.Distributive
import Data.Foldable hiding (minimum, maximum, elem, notElem, null)
import Data.Function (on)
import Data.Traversable
import GHC.Generics
import Numeric.Interval.Exception
import Prelude hiding (null, elem, notElem)

import qualified Data.Semigroup
import qualified Data.Monoid

-- $setup
-- >>> :set -Wno-deprecations
-- >>> let null = Numeric.Interval.Kaucher.null
-- >>> let elem = Numeric.Interval.Kaucher.elem
-- >>> let notElem = Numeric.Interval.Kaucher.notElem

data Interval a = I !a !a deriving
  (Interval a -> Interval a -> Bool
(Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Bool) -> Eq (Interval a)
forall a. Eq a => Interval a -> Interval a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Interval a -> Interval a -> Bool
== :: Interval a -> Interval a -> Bool
$c/= :: forall a. Eq a => Interval a -> Interval a -> Bool
/= :: Interval a -> Interval a -> Bool
Eq, Eq (Interval a)
Eq (Interval a) =>
(Interval a -> Interval a -> Ordering)
-> (Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Interval a)
-> (Interval a -> Interval a -> Interval a)
-> Ord (Interval a)
Interval a -> Interval a -> Bool
Interval a -> Interval a -> Ordering
Interval a -> Interval a -> Interval a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Interval a)
forall a. Ord a => Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Ordering
forall a. Ord a => Interval a -> Interval a -> Interval a
$ccompare :: forall a. Ord a => Interval a -> Interval a -> Ordering
compare :: Interval a -> Interval a -> Ordering
$c< :: forall a. Ord a => Interval a -> Interval a -> Bool
< :: Interval a -> Interval a -> Bool
$c<= :: forall a. Ord a => Interval a -> Interval a -> Bool
<= :: Interval a -> Interval a -> Bool
$c> :: forall a. Ord a => Interval a -> Interval a -> Bool
> :: Interval a -> Interval a -> Bool
$c>= :: forall a. Ord a => Interval a -> Interval a -> Bool
>= :: Interval a -> Interval a -> Bool
$cmax :: forall a. Ord a => Interval a -> Interval a -> Interval a
max :: Interval a -> Interval a -> Interval a
$cmin :: forall a. Ord a => Interval a -> Interval a -> Interval a
min :: Interval a -> Interval a -> Interval a
Ord, Typeable (Interval a)
Typeable (Interval a) =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Interval a -> c (Interval a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Interval a))
-> (Interval a -> Constr)
-> (Interval a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Interval a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Interval a)))
-> ((forall b. Data b => b -> b) -> Interval a -> Interval a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Interval a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Interval a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Interval a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> Interval a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Interval a -> m (Interval a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Interval a -> m (Interval a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Interval a -> m (Interval a))
-> Data (Interval a)
Interval a -> Constr
Interval a -> DataType
(forall b. Data b => b -> b) -> Interval a -> Interval a
forall a. Data a => Typeable (Interval a)
forall a. Data a => Interval a -> Constr
forall a. Data a => Interval a -> DataType
forall a.
Data a =>
(forall b. Data b => b -> b) -> Interval a -> Interval a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Interval a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> Interval a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Interval a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interval a -> c (Interval a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Interval a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Interval a))
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Interval a -> u
forall u. (forall d. Data d => d -> u) -> Interval a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Interval a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interval a -> c (Interval a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Interval a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Interval a))
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interval a -> c (Interval a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Interval a -> c (Interval a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Interval a)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Interval a)
$ctoConstr :: forall a. Data a => Interval a -> Constr
toConstr :: Interval a -> Constr
$cdataTypeOf :: forall a. Data a => Interval a -> DataType
dataTypeOf :: Interval a -> DataType
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Interval a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Interval a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Interval a))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Interval a))
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b) -> Interval a -> Interval a
gmapT :: (forall b. Data b => b -> b) -> Interval a -> Interval a
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Interval a -> r
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> Interval a -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Interval a -> [u]
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> Interval a -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Interval a -> u
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Interval a -> m (Interval a)
Data, (forall x. Interval a -> Rep (Interval a) x)
-> (forall x. Rep (Interval a) x -> Interval a)
-> Generic (Interval a)
forall x. Rep (Interval a) x -> Interval a
forall x. Interval a -> Rep (Interval a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Interval a) x -> Interval a
forall a x. Interval a -> Rep (Interval a) x
$cfrom :: forall a x. Interval a -> Rep (Interval a) x
from :: forall x. Interval a -> Rep (Interval a) x
$cto :: forall a x. Rep (Interval a) x -> Interval a
to :: forall x. Rep (Interval a) x -> Interval a
Generic, (forall a. Interval a -> Rep1 Interval a)
-> (forall a. Rep1 Interval a -> Interval a) -> Generic1 Interval
forall a. Rep1 Interval a -> Interval a
forall a. Interval a -> Rep1 Interval a
forall k (f :: k -> *).
(forall (a :: k). f a -> Rep1 f a)
-> (forall (a :: k). Rep1 f a -> f a) -> Generic1 f
$cfrom1 :: forall a. Interval a -> Rep1 Interval a
from1 :: forall a. Interval a -> Rep1 Interval a
$cto1 :: forall a. Rep1 Interval a -> Interval a
to1 :: forall a. Rep1 Interval a -> Interval a
Generic1)

-- | 'Data.Semigroup.<>' is 'hull'
instance Ord a => Data.Semigroup.Semigroup (Interval a) where
  <> :: Interval a -> Interval a -> Interval a
(<>) = Interval a -> Interval a -> Interval a
forall a. Ord a => Interval a -> Interval a -> Interval a
hull

instance Functor Interval where
  fmap :: forall a b. (a -> b) -> Interval a -> Interval b
fmap a -> b
f (I a
a a
b) = b -> b -> Interval b
forall a. a -> a -> Interval a
I (a -> b
f a
a) (a -> b
f a
b)
  {-# INLINE fmap #-}

instance Foldable Interval where
  foldMap :: forall m a. Monoid m => (a -> m) -> Interval a -> m
foldMap a -> m
f (I a
a a
b) = a -> m
f a
a m -> m -> m
forall a. Monoid a => a -> a -> a
`Data.Monoid.mappend` a -> m
f a
b
  {-# INLINE foldMap #-}

instance Traversable Interval where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Interval a -> f (Interval b)
traverse a -> f b
f (I a
a a
b) = b -> b -> Interval b
forall a. a -> a -> Interval a
I (b -> b -> Interval b) -> f b -> f (b -> Interval b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a f (b -> Interval b) -> f b -> f (Interval b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> f b
f a
b
  {-# INLINE traverse #-}

instance Applicative Interval where
  pure :: forall a. a -> Interval a
pure a
a = a -> a -> Interval a
forall a. a -> a -> Interval a
I a
a a
a
  {-# INLINE pure #-}
  I a -> b
f a -> b
g <*> :: forall a b. Interval (a -> b) -> Interval a -> Interval b
<*> I a
a a
b = b -> b -> Interval b
forall a. a -> a -> Interval a
I (a -> b
f a
a) (a -> b
g a
b)
  {-# INLINE (<*>) #-}

instance Monad Interval where
#if !(MIN_VERSION_base(4,11,0))
  return a = I a a
  {-# INLINE return #-}
#endif
  I a
a a
b >>= :: forall a b. Interval a -> (a -> Interval b) -> Interval b
>>= a -> Interval b
f = b -> b -> Interval b
forall a. a -> a -> Interval a
I b
a' b
b' where
    I b
a' b
_ = a -> Interval b
f a
a
    I b
_ b
b' = a -> Interval b
f a
b
  {-# INLINE (>>=) #-}

instance Distributive Interval where
  distribute :: forall (f :: * -> *) a.
Functor f =>
f (Interval a) -> Interval (f a)
distribute f (Interval a)
f = (Interval a -> a) -> f (Interval a) -> f a
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Interval a -> a
forall a. Interval a -> a
inf f (Interval a)
f f a -> f a -> Interval (f a)
forall a. a -> a -> Interval a
... (Interval a -> a) -> f (Interval a) -> f a
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Interval a -> a
forall a. Interval a -> a
sup f (Interval a)
f
  {-# INLINE distribute #-}

infix 3 ...

negInfinity :: Fractional a => a
negInfinity :: forall a. Fractional a => a
negInfinity = (-a
1)a -> a -> a
forall a. Fractional a => a -> a -> a
/a
0
{-# INLINE negInfinity #-}

posInfinity :: Fractional a => a
posInfinity :: forall a. Fractional a => a
posInfinity = a
1a -> a -> a
forall a. Fractional a => a -> a -> a
/a
0
{-# INLINE posInfinity #-}

nan :: Fractional a => a
nan :: forall a. Fractional a => a
nan = a
0a -> a -> a
forall a. Fractional a => a -> a -> a
/a
0

fmod :: RealFrac a => a -> a -> a
fmod :: forall a. RealFrac a => a -> a -> a
fmod a
a a
b = a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
qa -> a -> a
forall a. Num a => a -> a -> a
*a
b where
  q :: a
q = Integer -> a
forall a b. (Real a, Fractional b) => a -> b
realToFrac (a -> Integer
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (a -> Integer) -> a -> Integer
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
b :: Integer)
{-# INLINE fmod #-}

-- | Create a directed interval.
(...) :: a -> a -> Interval a
... :: forall a. a -> a -> Interval a
(...) = a -> a -> Interval a
forall a. a -> a -> Interval a
I
{-# INLINE (...) #-}

-- | Try to create a non-empty interval.
interval :: Ord a => a -> a -> Maybe (Interval a)
interval :: forall a. Ord a => a -> a -> Maybe (Interval a)
interval a
a a
b
  | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
b = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ a -> a -> Interval a
forall a. a -> a -> Interval a
I a
a a
b
  | Bool
otherwise = Maybe (Interval a)
forall a. Maybe a
Nothing


-- | The whole real number line
--
-- >>> whole
-- -Infinity ... Infinity
whole :: Fractional a => Interval a
whole :: forall a. Fractional a => Interval a
whole = a
forall a. Fractional a => a
negInfinity a -> a -> Interval a
forall a. a -> a -> Interval a
... a
forall a. Fractional a => a
posInfinity
{-# INLINE whole #-}

-- | An empty interval
--
-- >>> empty
-- NaN ... NaN
empty :: Fractional a => Interval a
empty :: forall a. Fractional a => Interval a
empty = a
forall a. Fractional a => a
nan a -> a -> Interval a
forall a. a -> a -> Interval a
... a
forall a. Fractional a => a
nan
{-# INLINE empty #-}

-- | negation handles NaN properly
--
-- >>> null (1 ... 5)
-- False
--
-- >>> null (1 ... 1)
-- False
--
-- >>> null empty
-- True
null :: Ord a => Interval a -> Bool
null :: forall a. Ord a => Interval a -> Bool
null Interval a
x = Bool -> Bool
not (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
{-# INLINE null #-}

-- | A singleton point
--
-- >>> singleton 1
-- 1 ... 1
singleton :: a -> Interval a
singleton :: forall a. a -> Interval a
singleton a
a = a
a a -> a -> Interval a
forall a. a -> a -> Interval a
... a
a
{-# INLINE singleton #-}

-- | The infinumum (lower bound) of an interval
--
-- >>> inf (1 ... 20)
-- 1
inf :: Interval a -> a
inf :: forall a. Interval a -> a
inf (I a
a a
_) = a
a
{-# INLINE inf #-}

-- | The supremum (upper bound) of an interval
--
-- >>> sup (1 ... 20)
-- 20
sup :: Interval a -> a
sup :: forall a. Interval a -> a
sup (I a
_ a
b) = a
b
{-# INLINE sup #-}

-- | Is the interval a singleton point?
-- N.B. This is fairly fragile and likely will not hold after
-- even a few operations that only involve singletons
--
-- >>> singular (singleton 1)
-- True
--
-- >>> singular (1.0 ... 20.0)
-- False
singular :: Ord a => Interval a -> Bool
singular :: forall a. Ord a => Interval a -> Bool
singular Interval a
x = Bool -> Bool
not (Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x) Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Interval a -> a
forall a. Interval a -> a
sup Interval a
x
{-# INLINE singular #-}

instance Show a => Show (Interval a) where
  showsPrec :: Int -> Interval a -> ShowS
showsPrec Int
n (I a
a a
b) =
    Bool -> ShowS -> ShowS
showParen (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
3) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
3 a
a ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      String -> ShowS
showString String
" ... " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      Int -> a -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
3 a
b

-- | Calculate the width of an interval.
--
-- >>> width (1 ... 20)
-- 19
--
-- >>> width (singleton 1)
-- 0
--
-- >>> width empty
-- NaN
width :: Num a => Interval a -> a
width :: forall a. Num a => Interval a -> a
width (I a
a a
b) = a
b a -> a -> a
forall a. Num a => a -> a -> a
- a
a
{-# INLINE width #-}

-- | Magnitude
--
-- >>> magnitude (1 ... 20)
-- 20
--
-- >>> magnitude (-20 ... 10)
-- 20
--
-- >>> magnitude (singleton 5)
-- 5
magnitude :: (Num a, Ord a) => Interval a -> a
magnitude :: forall a. (Num a, Ord a) => Interval a -> a
magnitude = Interval a -> a
forall a. Interval a -> a
sup (Interval a -> a) -> (Interval a -> Interval a) -> Interval a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> Interval a
forall a. Num a => a -> a
abs
{-# INLINE magnitude #-}

-- | \"mignitude\"
--
-- >>> mignitude (1 ... 20)
-- 1
--
-- >>> mignitude (-20 ... 10)
-- 0
--
-- >>> mignitude (singleton 5)
-- 5
--
-- >>> mignitude empty
-- NaN
mignitude :: (Num a, Ord a) => Interval a -> a
mignitude :: forall a. (Num a, Ord a) => Interval a -> a
mignitude = Interval a -> a
forall a. Interval a -> a
inf (Interval a -> a) -> (Interval a -> Interval a) -> Interval a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> Interval a
forall a. Num a => a -> a
abs
{-# INLINE mignitude #-}

-- | Hausdorff distance between non-empty intervals.
--
-- >>> distance (1 ... 7) (6 ... 10)
-- 0
--
-- >>> distance (1 ... 7) (15 ... 24)
-- 8
--
-- >>> distance (1 ... 7) (-10 ... -2)
-- 3
--
-- >>> distance empty (1 ... 1)
-- NaN
distance :: (Num a, Ord a) => Interval a -> Interval a -> a
distance :: forall a. (Num a, Ord a) => Interval a -> Interval a -> a
distance Interval a
i1 Interval a
i2 = Interval a -> a
forall a. (Num a, Ord a) => Interval a -> a
mignitude (Interval a
i1 Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
- Interval a
i2)

-- | Inflate an interval by enlarging it at both ends.
--
-- >>> inflate 3 (-1 ... 7)
-- -4 ... 10
--
-- >>> inflate (-2) (0 ... 4)
-- 2 ... 2
inflate :: (Num a, Ord a) => a -> Interval a -> Interval a
inflate :: forall a. (Num a, Ord a) => a -> Interval a -> Interval a
inflate a
x Interval a
y = a -> Interval a
forall a. Num a => a -> Interval a
symmetric a
x Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
+ Interval a
y

-- | Deflate an interval by shrinking it from both ends.
--
-- >>> deflate 3.0 (-4.0 ... 10.0)
-- -1.0 ... 7.0
--
-- >>> deflate 2.0 (-1.0 ... 1.0)
-- 1.0 ... -1.0
deflate :: Fractional a => a -> Interval a -> Interval a
deflate :: forall a. Fractional a => a -> Interval a -> Interval a
deflate a
x (I a
a a
b) = a -> a -> Interval a
forall a. a -> a -> Interval a
I a
a' a
b'
  where
    a' :: a
a' = a
a a -> a -> a
forall a. Num a => a -> a -> a
+ a
x
    b' :: a
b' = a
b a -> a -> a
forall a. Num a => a -> a -> a
- a
x

-- | Scale an interval about its midpoint.
--
-- >>> scale 1.1 (-6.0 ... 4.0)
-- -6.5 ... 4.5
--
-- >>> scale (-2.0) (-1.0 ... 1.0)
-- 2.0 ... -2.0
scale :: Fractional a => a -> Interval a -> Interval a
scale :: forall a. Fractional a => a -> Interval a -> Interval a
scale a
x Interval a
i = a -> a -> Interval a
forall a. a -> a -> Interval a
I a
a a
b where
  h :: a
h = a
x a -> a -> a
forall a. Num a => a -> a -> a
* Interval a -> a
forall a. Num a => Interval a -> a
width Interval a
i a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
  mid :: a
mid = Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
i
  a :: a
a = a
mid a -> a -> a
forall a. Num a => a -> a -> a
- a
h
  b :: a
b = a
mid a -> a -> a
forall a. Num a => a -> a -> a
+ a
h

-- | Construct a symmetric interval.
--
-- >>> symmetric 3
-- -3 ... 3
--
-- >>> symmetric (-2)
-- 2 ... -2
symmetric :: Num a => a -> Interval a
symmetric :: forall a. Num a => a -> Interval a
symmetric a
x = a -> a
forall a. Num a => a -> a
negate a
x a -> a -> Interval a
forall a. a -> a -> Interval a
... a
x

instance (Num a, Ord a) => Num (Interval a) where
  I a
a a
b + :: Interval a -> Interval a -> Interval a
+ I a
a' a
b' = (a
a a -> a -> a
forall a. Num a => a -> a -> a
+ a
a') a -> a -> Interval a
forall a. a -> a -> Interval a
... (a
b a -> a -> a
forall a. Num a => a -> a -> a
+ a
b')
  {-# INLINE (+) #-}
  I a
a a
b - :: Interval a -> Interval a -> Interval a
- I a
a' a
b' = (a
a a -> a -> a
forall a. Num a => a -> a -> a
- a
b') a -> a -> Interval a
forall a. a -> a -> Interval a
... (a
b a -> a -> a
forall a. Num a => a -> a -> a
- a
a')
  {-# INLINE (-) #-}
  I a
a a
b * :: Interval a -> Interval a -> Interval a
* I a
a' a
b' =
    [a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
a', a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
b', a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
a', a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b']
    a -> a -> Interval a
forall a. a -> a -> Interval a
...
    [a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
a', a
a a -> a -> a
forall a. Num a => a -> a -> a
* a
b', a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
a', a
b a -> a -> a
forall a. Num a => a -> a -> a
* a
b']
  {-# INLINE (*) #-}
  abs :: Interval a -> Interval a
abs x :: Interval a
x@(I a
a a
b)
    | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0    = Interval a
x
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0    = Interval a -> Interval a
forall a. Num a => a -> a
negate Interval a
x
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 Bool -> Bool -> Bool
&& a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = a
0 a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a -> a
forall a. Ord a => a -> a -> a
max (- a
a) a
b
    | Bool
otherwise      = Interval a
x -- preserve the empty interval
  {-# INLINE abs #-}

  signum :: Interval a -> Interval a
signum = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Num a => a -> a
signum
  {-# INLINE signum #-}

  fromInteger :: Integer -> Interval a
fromInteger Integer
i = a -> Interval a
forall a. a -> Interval a
singleton (Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
i)
  {-# INLINE fromInteger #-}

-- | Bisect an interval at its midpoint.
--
-- >>> bisect (10.0 ... 20.0)
-- (10.0 ... 15.0,15.0 ... 20.0)
--
-- >>> bisect (singleton 5.0)
-- (5.0 ... 5.0,5.0 ... 5.0)
--
-- >>> bisect empty
-- (NaN ... NaN,NaN ... NaN)
bisect :: Fractional a => Interval a -> (Interval a, Interval a)
bisect :: forall a. Fractional a => Interval a -> (Interval a, Interval a)
bisect Interval a
x = (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Interval a
forall a. a -> a -> Interval a
... a
m, a
m a -> a -> Interval a
forall a. a -> a -> Interval a
... Interval a -> a
forall a. Interval a -> a
sup Interval a
x) where m :: a
m = Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
x
{-# INLINE bisect #-}

-- | Nearest point to the midpoint of the interval.
--
-- >>> midpoint (10.0 ... 20.0)
-- 15.0
--
-- >>> midpoint (singleton 5.0)
-- 5.0
--
-- >>> midpoint empty
-- NaN
midpoint :: Fractional a => Interval a -> a
midpoint :: forall a. Fractional a => Interval a -> a
midpoint Interval a
x = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> a
forall a. Num a => a -> a -> a
+ (Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> a
forall a. Num a => a -> a -> a
- Interval a -> a
forall a. Interval a -> a
inf Interval a
x) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
{-# INLINE midpoint #-}

-- | Determine if a point is in the interval.
--
-- >>> member 3.2 (1.0 ... 5.0)
-- True
--
-- >>> member 5 (1.0 ... 5.0)
-- True
--
-- >>> member 1 (1.0 ... 5.0)
-- True
--
-- >>> member 8 (1.0 ... 5.0)
-- False
--
-- >>> member 5 empty
-- False
--
member :: Ord a => a -> Interval a -> Bool
member :: forall a. Ord a => a -> Interval a -> Bool
member a
x (I a
a a
b) = a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
a Bool -> Bool -> Bool
&& a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
b
{-# INLINE member #-}

-- | Determine if a point is not included in the interval
--
-- >>> notMember 8 (1.0 ... 5.0)
-- True
--
-- >>> notMember 1.4 (1.0 ... 5.0)
-- False
--
-- And of course, nothing is a member of the empty interval.
--
-- >>> notMember 5 empty
-- True
notMember :: Ord a => a -> Interval a -> Bool
notMember :: forall a. Ord a => a -> Interval a -> Bool
notMember a
x Interval a
xs = Bool -> Bool
not (a -> Interval a -> Bool
forall a. Ord a => a -> Interval a -> Bool
member a
x Interval a
xs)
{-# INLINE notMember #-}

-- | Determine if a point is in the interval.
--
-- >>> elem 3.2 (1.0 ... 5.0)
-- True
--
-- >>> elem 5 (1.0 ... 5.0)
-- True
--
-- >>> elem 1 (1.0 ... 5.0)
-- True
--
-- >>> elem 8 (1.0 ... 5.0)
-- False
--
-- >>> elem 5 empty
-- False
--
elem :: Ord a => a -> Interval a -> Bool
elem :: forall a. Ord a => a -> Interval a -> Bool
elem = a -> Interval a -> Bool
forall a. Ord a => a -> Interval a -> Bool
member
{-# INLINE elem #-}
{-# DEPRECATED elem "Use `member` instead." #-}

-- | Determine if a point is not included in the interval
--
-- >>> notElem 8 (1.0 ... 5.0)
-- True
--
-- >>> notElem 1.4 (1.0 ... 5.0)
-- False
--
-- And of course, nothing is a member of the empty interval.
--
-- >>> notElem 5 empty
-- True
notElem :: Ord a => a -> Interval a -> Bool
notElem :: forall a. Ord a => a -> Interval a -> Bool
notElem = a -> Interval a -> Bool
forall a. Ord a => a -> Interval a -> Bool
notMember
{-# INLINE notElem #-}
{-# DEPRECATED notElem "Use `notMember` instead." #-}

-- | 'realToFrac' will use the midpoint
instance Real a => Real (Interval a) where
  toRational :: Interval a -> Rational
toRational Interval a
x
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x    = EmptyInterval -> Rational
forall a e. Exception e => e -> a
Exception.throw EmptyInterval
EmptyInterval
    | Bool
otherwise = Rational
a Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
+ (Rational
b Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- Rational
a) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
2
    where
      a :: Rational
a = a -> Rational
forall a. Real a => a -> Rational
toRational (Interval a -> a
forall a. Interval a -> a
inf Interval a
x)
      b :: Rational
b = a -> Rational
forall a. Real a => a -> Rational
toRational (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  {-# INLINE toRational #-}

-- @'divNonZero' X Y@ assumes @0 `'notElem'` Y@
divNonZero :: (Fractional a, Ord a) => Interval a -> Interval a -> Interval a
divNonZero :: forall a.
(Fractional a, Ord a) =>
Interval a -> Interval a -> Interval a
divNonZero (I a
a a
b) (I a
a' a
b') =
  [a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
a', a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
b', a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
a', a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
b']
  a -> a -> Interval a
forall a. a -> a -> Interval a
...
  [a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
a', a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
b', a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
a', a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
b']

-- @'divPositive' X y@ assumes y > 0, and divides @X@ by [0 ... y]
divPositive :: (Fractional a, Ord a) => Interval a -> a -> Interval a
divPositive :: forall a. (Fractional a, Ord a) => Interval a -> a -> Interval a
divPositive x :: Interval a
x@(I a
a a
b) a
y
  | a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = Interval a
x
  -- b < 0 || isNegativeZero b = negInfinity ... ( b / y)
  | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = a
forall a. Fractional a => a
negInfinity a -> a -> Interval a
forall a. a -> a -> Interval a
... ( a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
y)
  | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = Interval a
forall a. Fractional a => Interval a
whole
  | Bool
otherwise = (a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
y) a -> a -> Interval a
forall a. a -> a -> Interval a
... a
forall a. Fractional a => a
posInfinity
{-# INLINE divPositive #-}

-- divNegative assumes y < 0 and divides the interval @X@ by [y ... 0]
divNegative :: (Fractional a, Ord a) => Interval a -> a -> Interval a
divNegative :: forall a. (Fractional a, Ord a) => Interval a -> a -> Interval a
divNegative x :: Interval a
x@(I a
a a
b) a
y
  | a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = - Interval a
x -- flip negative zeros
  -- b < 0 || isNegativeZero b = (b / y) ... posInfinity
  | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = (a
b a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
y) a -> a -> Interval a
forall a. a -> a -> Interval a
... a
forall a. Fractional a => a
posInfinity
  | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = Interval a
forall a. Fractional a => Interval a
whole
  | Bool
otherwise = a
forall a. Fractional a => a
negInfinity a -> a -> Interval a
forall a. a -> a -> Interval a
... (a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
y)
{-# INLINE divNegative #-}

divZero :: (Fractional a, Ord a) => Interval a -> Interval a
divZero :: forall a. (Fractional a, Ord a) => Interval a -> Interval a
divZero Interval a
x
  | Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 = Interval a
x
  | Bool
otherwise = Interval a
forall a. Fractional a => Interval a
whole
{-# INLINE divZero #-}

instance (Fractional a, Ord a) => Fractional (Interval a) where
  -- TODO: check isNegativeZero properly
  Interval a
x / :: Interval a -> Interval a -> Interval a
/ Interval a
y
    | a
0 a -> Interval a -> Bool
forall a. Ord a => a -> Interval a -> Bool
`notElem` Interval a
y = Interval a -> Interval a -> Interval a
forall a.
(Fractional a, Ord a) =>
Interval a -> Interval a -> Interval a
divNonZero Interval a
x Interval a
y
    | Bool
iz Bool -> Bool -> Bool
&& Bool
sz  = Interval a
forall a. Fractional a => Interval a
empty -- division by 0
    | Bool
iz        = Interval a -> a -> Interval a
forall a. (Fractional a, Ord a) => Interval a -> a -> Interval a
divPositive Interval a
x (Interval a -> a
forall a. Interval a -> a
inf Interval a
y)
    |       Bool
sz  = Interval a -> a -> Interval a
forall a. (Fractional a, Ord a) => Interval a -> a -> Interval a
divNegative Interval a
x (Interval a -> a
forall a. Interval a -> a
sup Interval a
y)
    | Bool
otherwise = Interval a -> Interval a
forall a. (Fractional a, Ord a) => Interval a -> Interval a
divZero Interval a
x
    where
      iz :: Bool
iz = Interval a -> a
forall a. Interval a -> a
inf Interval a
y a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
      sz :: Bool
sz = Interval a -> a
forall a. Interval a -> a
sup Interval a
y a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0
  recip :: Interval a -> Interval a
recip (I a
a a
b)   = (a -> a -> a) -> (a -> a) -> a -> a -> a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on a -> a -> a
forall a. Ord a => a -> a -> a
min a -> a
forall a. Fractional a => a -> a
recip a
a a
b a -> a -> Interval a
forall a. a -> a -> Interval a
... (a -> a -> a) -> (a -> a) -> a -> a -> a
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on a -> a -> a
forall a. Ord a => a -> a -> a
max a -> a
forall a. Fractional a => a -> a
recip a
a a
b
  {-# INLINE recip #-}
  fromRational :: Rational -> Interval a
fromRational Rational
r  = let r' :: a
r' = Rational -> a
forall a. Fractional a => Rational -> a
fromRational Rational
r in a
r' a -> a -> Interval a
forall a. a -> a -> Interval a
... a
r'
  {-# INLINE fromRational #-}

instance RealFrac a => RealFrac (Interval a) where
  properFraction :: forall b. Integral b => Interval a -> (b, Interval a)
properFraction Interval a
x = (b
b, Interval a
x Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
- b -> Interval a
forall a b. (Integral a, Num b) => a -> b
fromIntegral b
b)
    where
      b :: b
b = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
x)
  {-# INLINE properFraction #-}
  ceiling :: forall b. Integral b => Interval a -> b
ceiling Interval a
x = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  {-# INLINE ceiling #-}
  floor :: forall b. Integral b => Interval a -> b
floor Interval a
x = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
floor (Interval a -> a
forall a. Interval a -> a
inf Interval a
x)
  {-# INLINE floor #-}
  round :: forall b. Integral b => Interval a -> b
round Interval a
x = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
x)
  {-# INLINE round #-}
  truncate :: forall b. Integral b => Interval a -> b
truncate Interval a
x = a -> b
forall b. Integral b => a -> b
forall a b. (RealFrac a, Integral b) => a -> b
truncate (Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
x)
  {-# INLINE truncate #-}

instance (RealFloat a, Ord a) => Floating (Interval a) where
  pi :: Interval a
pi = a -> Interval a
forall a. a -> Interval a
singleton a
forall a. Floating a => a
pi
  {-# INLINE pi #-}
  exp :: Interval a -> Interval a
exp = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
exp
  {-# INLINE exp #-}
  log :: Interval a -> Interval a
log (I a
a a
b) = (if a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 then a -> a
forall a. Floating a => a -> a
log a
a else a
forall a. Fractional a => a
negInfinity) a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a
forall a. Floating a => a -> a
log a
b
  {-# INLINE log #-}
  cos :: Interval a -> Interval a
cos Interval a
x
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x = Interval a
forall a. Fractional a => Interval a
empty
    | Interval a -> a
forall a. Num a => Interval a -> a
width Interval a
t a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
forall a. Floating a => a
pi = (-a
1) a -> a -> Interval a
forall a. a -> a -> Interval a
... a
1
    | Interval a -> a
forall a. Interval a -> a
inf Interval a
t a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
forall a. Floating a => a
pi = - Interval a -> Interval a
forall a. Floating a => a -> a
cos (Interval a
t Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
- Interval a
forall a. Floating a => a
pi)
    | Interval a -> a
forall a. Interval a -> a
sup Interval a
t a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
forall a. Floating a => a
pi = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
decreasing a -> a
forall a. Floating a => a -> a
cos Interval a
t
    | Interval a -> a
forall a. Interval a -> a
sup Interval a
t a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi = (-a
1) a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a
forall a. Floating a => a -> a
cos ((a
forall a. Floating a => a
pi a -> a -> a
forall a. Num a => a -> a -> a
* a
2 a -> a -> a
forall a. Num a => a -> a -> a
- Interval a -> a
forall a. Interval a -> a
sup Interval a
t) a -> a -> a
forall a. Ord a => a -> a -> a
`min` Interval a -> a
forall a. Interval a -> a
inf Interval a
t)
    | Bool
otherwise = (-a
1) a -> a -> Interval a
forall a. a -> a -> Interval a
... a
1
    where
      t :: Interval a
t = Interval a -> Interval a -> Interval a
forall a. RealFrac a => a -> a -> a
fmod Interval a
x (Interval a
forall a. Floating a => a
pi Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
* Interval a
2)
  {-# INLINE cos #-}
  sin :: Interval a -> Interval a
sin Interval a
x
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x = Interval a
forall a. Fractional a => Interval a
empty
    | Bool
otherwise = Interval a -> Interval a
forall a. Floating a => a -> a
cos (Interval a
x Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
- Interval a
forall a. Floating a => a
pi Interval a -> Interval a -> Interval a
forall a. Fractional a => a -> a -> a
/ Interval a
2)
  {-# INLINE sin #-}
  tan :: Interval a -> Interval a
tan Interval a
x
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x = Interval a
forall a. Fractional a => Interval a
empty
    | Interval a -> a
forall a. Interval a -> a
inf Interval a
t' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= - a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2 Bool -> Bool -> Bool
|| Interval a -> a
forall a. Interval a -> a
sup Interval a
t' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2 = Interval a
forall a. Fractional a => Interval a
whole
    | Bool
otherwise = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
tan Interval a
x
    where
      t :: Interval a
t = Interval a
x Interval a -> Interval a -> Interval a
forall a. RealFrac a => a -> a -> a
`fmod` Interval a
forall a. Floating a => a
pi
      t' :: Interval a
t' | Interval a
t Interval a -> Interval a -> Bool
forall a. Ord a => a -> a -> Bool
>= Interval a
forall a. Floating a => a
pi Interval a -> Interval a -> Interval a
forall a. Fractional a => a -> a -> a
/ Interval a
2 = Interval a
t Interval a -> Interval a -> Interval a
forall a. Num a => a -> a -> a
- Interval a
forall a. Floating a => a
pi
         | Bool
otherwise    = Interval a
t
  {-# INLINE tan #-}
  asin :: Interval a -> Interval a
asin x :: Interval a
x@(I a
a a
b)
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x Bool -> Bool -> Bool
|| a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< -a
1 Bool -> Bool -> Bool
|| a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1 = Interval a
forall a. Fractional a => Interval a
empty
    | Bool
otherwise =
      (if a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= -a
1 then -a
halfPi else a -> a
forall a. Floating a => a -> a
asin a
a)
      a -> a -> Interval a
forall a. a -> a -> Interval a
...
      (if a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1 then a
halfPi else a -> a
forall a. Floating a => a -> a
asin a
b)
    where
      halfPi :: a
halfPi = a
forall a. Floating a => a
pi a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
2
  {-# INLINE asin #-}
  acos :: Interval a -> Interval a
acos x :: Interval a
x@(I a
a a
b)
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x Bool -> Bool -> Bool
|| a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< -a
1 Bool -> Bool -> Bool
|| a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1 = Interval a
forall a. Fractional a => Interval a
empty
    | Bool
otherwise =
      (if a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1 then a
0 else a -> a
forall a. Floating a => a -> a
acos a
b)
      a -> a -> Interval a
forall a. a -> a -> Interval a
...
      (if a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< -a
1 then a
forall a. Floating a => a
pi else a -> a
forall a. Floating a => a -> a
acos a
a)
  {-# INLINE acos #-}
  atan :: Interval a -> Interval a
atan = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
atan
  {-# INLINE atan #-}
  sinh :: Interval a -> Interval a
sinh = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
sinh
  {-# INLINE sinh #-}
  cosh :: Interval a -> Interval a
cosh x :: Interval a
x@(I a
a a
b)
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x = Interval a
forall a. Fractional a => Interval a
empty
    | a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0  = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
decreasing a -> a
forall a. Floating a => a -> a
cosh Interval a
x
    | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0 = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
cosh Interval a
x
    | Bool
otherwise  = a -> a -> Interval a
forall a. a -> a -> Interval a
I a
0 (a -> Interval a) -> a -> Interval a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Floating a => a -> a
cosh (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ if - a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
b
                                then a
a
                                else a
b
  {-# INLINE cosh #-}
  tanh :: Interval a -> Interval a
tanh = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
tanh
  {-# INLINE tanh #-}
  asinh :: Interval a -> Interval a
asinh = (a -> a) -> Interval a -> Interval a
forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> a
forall a. Floating a => a -> a
asinh
  {-# INLINE asinh #-}
  acosh :: Interval a -> Interval a
acosh x :: Interval a
x@(I a
a a
b)
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x Bool -> Bool -> Bool
|| a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
1 = Interval a
forall a. Fractional a => Interval a
empty
    | Bool
otherwise = a -> a -> Interval a
forall a. a -> a -> Interval a
I a
lo (a -> Interval a) -> a -> Interval a
forall a b. (a -> b) -> a -> b
$ a -> a
forall a. Floating a => a -> a
acosh a
b
    where lo :: a
lo | a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
1 = a
0
             | Bool
otherwise = a -> a
forall a. Floating a => a -> a
acosh a
a
  {-# INLINE acosh #-}
  atanh :: Interval a -> Interval a
atanh x :: Interval a
x@(I a
a a
b)
    | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x Bool -> Bool -> Bool
|| a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< -a
1 Bool -> Bool -> Bool
|| a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1 = Interval a
forall a. Fractional a => Interval a
empty
    | Bool
otherwise =
      (if a
a a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= - a
1 then a
forall a. Fractional a => a
negInfinity else a -> a
forall a. Floating a => a -> a
atanh a
a)
      a -> a -> Interval a
forall a. a -> a -> Interval a
...
      (if a
b a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1 then a
forall a. Fractional a => a
posInfinity else a -> a
forall a. Floating a => a -> a
atanh a
b)
  {-# INLINE atanh #-}

-- | lift a monotone increasing function over a given interval
increasing :: (a -> b) -> Interval a -> Interval b
increasing :: forall a b. (a -> b) -> Interval a -> Interval b
increasing a -> b
f (I a
a a
b) = a -> b
f a
a b -> b -> Interval b
forall a. a -> a -> Interval a
... a -> b
f a
b

-- | lift a monotone decreasing function over a given interval
decreasing :: (a -> b) -> Interval a -> Interval b
decreasing :: forall a b. (a -> b) -> Interval a -> Interval b
decreasing a -> b
f (I a
a a
b) = a -> b
f a
b b -> b -> Interval b
forall a. a -> a -> Interval a
... a -> b
f a
a

-- | We have to play some semantic games to make these methods make sense.
-- Most compute with the midpoint of the interval.
instance RealFloat a => RealFloat (Interval a) where
  floatRadix :: Interval a -> Integer
floatRadix = a -> Integer
forall a. RealFloat a => a -> Integer
floatRadix (a -> Integer) -> (Interval a -> a) -> Interval a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint

  floatDigits :: Interval a -> Int
floatDigits = a -> Int
forall a. RealFloat a => a -> Int
floatDigits (a -> Int) -> (Interval a -> a) -> Interval a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint
  floatRange :: Interval a -> (Int, Int)
floatRange = a -> (Int, Int)
forall a. RealFloat a => a -> (Int, Int)
floatRange (a -> (Int, Int)) -> (Interval a -> a) -> Interval a -> (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint
  decodeFloat :: Interval a -> (Integer, Int)
decodeFloat = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (a -> (Integer, Int))
-> (Interval a -> a) -> Interval a -> (Integer, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint
  encodeFloat :: Integer -> Int -> Interval a
encodeFloat Integer
m Int
e = a -> Interval a
forall a. a -> Interval a
singleton (Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
m Int
e)
  exponent :: Interval a -> Int
exponent = a -> Int
forall a. RealFloat a => a -> Int
exponent (a -> Int) -> (Interval a -> a) -> Interval a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint
  significand :: Interval a -> Interval a
significand Interval a
x = a -> a -> a
forall a. Ord a => a -> a -> a
min a
a a
b a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a -> a
forall a. Ord a => a -> a -> a
max a
a a
b
    where
      (Integer
_ ,Int
em) = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (Interval a -> a
forall a. Fractional a => Interval a -> a
midpoint Interval a
x)
      (Integer
mi,Int
ei) = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (Interval a -> a
forall a. Interval a -> a
inf Interval a
x)
      (Integer
ms,Int
es) = a -> (Integer, Int)
forall a. RealFloat a => a -> (Integer, Int)
decodeFloat (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
      a :: a
a = Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
mi (Int
ei Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
em Int -> Int -> Int
forall a. Num a => a -> a -> a
- Interval a -> Int
forall a. RealFloat a => a -> Int
floatDigits Interval a
x)
      b :: a
b = Integer -> Int -> a
forall a. RealFloat a => Integer -> Int -> a
encodeFloat Integer
ms (Int
es Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
em Int -> Int -> Int
forall a. Num a => a -> a -> a
- Interval a -> Int
forall a. RealFloat a => a -> Int
floatDigits Interval a
x)
  scaleFloat :: Int -> Interval a -> Interval a
scaleFloat Int
n Interval a
x = Int -> a -> a
forall a. RealFloat a => Int -> a -> a
scaleFloat Int
n (Interval a -> a
forall a. Interval a -> a
inf Interval a
x) a -> a -> Interval a
forall a. a -> a -> Interval a
... Int -> a -> a
forall a. RealFloat a => Int -> a -> a
scaleFloat Int
n (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  isNaN :: Interval a -> Bool
isNaN Interval a
x = a -> Bool
forall a. RealFloat a => a -> Bool
isNaN (Interval a -> a
forall a. Interval a -> a
inf Interval a
x) Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  isInfinite :: Interval a -> Bool
isInfinite Interval a
x = a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite (Interval a -> a
forall a. Interval a -> a
inf Interval a
x) Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  isDenormalized :: Interval a -> Bool
isDenormalized Interval a
x = a -> Bool
forall a. RealFloat a => a -> Bool
isDenormalized (Interval a -> a
forall a. Interval a -> a
inf Interval a
x) Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isDenormalized (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  -- contains negative zero
  isNegativeZero :: Interval a -> Bool
isNegativeZero Interval a
x = Bool -> Bool
not (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0)
                  Bool -> Bool -> Bool
&& Bool -> Bool
not (Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0)
                  Bool -> Bool -> Bool
&& (  (Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNegativeZero (Interval a -> a
forall a. Interval a -> a
inf Interval a
x)))
                     Bool -> Bool -> Bool
|| (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
0 Bool -> Bool -> Bool
&& a -> Bool
forall a. RealFloat a => a -> Bool
isNegativeZero (Interval a -> a
forall a. Interval a -> a
inf Interval a
x))
                     Bool -> Bool -> Bool
|| (Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0))
  isIEEE :: Interval a -> Bool
isIEEE Interval a
x = a -> Bool
forall a. RealFloat a => a -> Bool
isIEEE (Interval a -> a
forall a. Interval a -> a
inf Interval a
x) Bool -> Bool -> Bool
&& a -> Bool
forall a. RealFloat a => a -> Bool
isIEEE (Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
  atan2 :: Interval a -> Interval a -> Interval a
atan2 = String -> Interval a -> Interval a -> Interval a
forall a. HasCallStack => String -> a
error String
"unimplemented"

-- TODO: (^), (^^) to give tighter bounds

-- | Calculate the intersection of two intervals.
--
-- >>> intersection (1 ... 10 :: Interval Double) (5 ... 15 :: Interval Double)
-- 5.0 ... 10.0
intersection :: (Fractional a, Ord a) => Interval a -> Interval a -> Interval a
intersection :: forall a.
(Fractional a, Ord a) =>
Interval a -> Interval a -> Interval a
intersection x :: Interval a
x@(I a
a a
b) y :: Interval a
y@(I a
a' a
b')
  | Interval a
x Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
/=! Interval a
y = Interval a
forall a. Fractional a => Interval a
empty
  | Bool
otherwise = a -> a -> a
forall a. Ord a => a -> a -> a
max a
a a
a' a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a -> a
forall a. Ord a => a -> a -> a
min a
b a
b'
{-# INLINE intersection #-}

-- | Calculate the convex hull of two intervals
--
-- >>> hull (0 ... 10 :: Interval Double) (5 ... 15 :: Interval Double)
-- 0.0 ... 15.0
--
-- >>> hull (15 ... 85 :: Interval Double) (0 ... 10 :: Interval Double)
-- 0.0 ... 85.0
--
-- >>> hull (10 ... 20 :: Interval Double) (15 ... 0 :: Interval Double)
-- 10.0 ... 20.0
--
hull :: Ord a => Interval a -> Interval a -> Interval a
hull :: forall a. Ord a => Interval a -> Interval a -> Interval a
hull x :: Interval a
x@(I a
a a
b) y :: Interval a
y@(I a
a' a
b')
  | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x = Interval a
y
  | Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
y = Interval a
x
  | Bool
otherwise = a -> a -> a
forall a. Ord a => a -> a -> a
min a
a a
a' a -> a -> Interval a
forall a. a -> a -> Interval a
... a -> a -> a
forall a. Ord a => a -> a -> a
max a
b a
b'
{-# INLINE hull #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '<' y@
--
-- >>> (5 ... 10 :: Interval Double) <! (20 ... 30 :: Interval Double)
-- True
--
-- >>> (5 ... 10 :: Interval Double) <! (10 ... 30 :: Interval Double)
-- False
--
-- >>> (20 ... 30 :: Interval Double) <! (5 ... 10 :: Interval Double)
-- False
(<!)  :: Ord a => Interval a -> Interval a -> Bool
Interval a
x <! :: forall a. Ord a => Interval a -> Interval a -> Bool
<! Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (<!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '<=' y@
--
-- >>> (5 ... 10 :: Interval Double) <=! (20 ... 30 :: Interval Double)
-- True
--
-- >>> (5 ... 10 :: Interval Double) <=! (10 ... 30 :: Interval Double)
-- True
--
-- >>> (20 ... 30 :: Interval Double) <=! (5 ... 10 :: Interval Double)
-- False
(<=!) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x <=! :: forall a. Ord a => Interval a -> Interval a -> Bool
<=! Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (<=!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '==' y@
--
-- Only singleton intervals return true
--
-- >>> (singleton 5 :: Interval Double) ==! (singleton 5 :: Interval Double)
-- True
--
-- >>> (5 ... 10 :: Interval Double) ==! (5 ... 10 :: Interval Double)
-- False
(==!) :: Eq a => Interval a -> Interval a -> Bool
Interval a
x ==! :: forall a. Eq a => Interval a -> Interval a -> Bool
==! Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Interval a -> a
forall a. Interval a -> a
inf Interval a
y Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (==!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '/=' y@
--
-- >>> (5 ... 15 :: Interval Double) /=! (20 ... 40 :: Interval Double)
-- True
--
-- >>> (5 ... 15 :: Interval Double) /=! (15 ... 40 :: Interval Double)
-- False
(/=!) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x /=! :: forall a. Ord a => Interval a -> Interval a -> Bool
/=! Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< Interval a -> a
forall a. Interval a -> a
inf Interval a
y Bool -> Bool -> Bool
|| Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (/=!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '>' y@
--
-- >>> (20 ... 40 :: Interval Double) >! (10 ... 19 :: Interval Double)
-- True
--
-- >>> (5 ... 20 :: Interval Double) >! (15 ... 40 :: Interval Double)
-- False
(>!)  :: Ord a => Interval a -> Interval a -> Bool
Interval a
x >! :: forall a. Ord a => Interval a -> Interval a -> Bool
>! Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (>!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x '>=' y@
--
-- >>> (20 ... 40 :: Interval Double) >=! (10 ... 20 :: Interval Double)
-- True
--
-- >>> (5 ... 20 :: Interval Double) >=! (15 ... 40 :: Interval Double)
-- False
(>=!) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x >=! :: forall a. Ord a => Interval a -> Interval a -> Bool
>=! Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (>=!) #-}

-- | For all @x@ in @X@, @y@ in @Y@. @x `op` y@
--
--
certainly :: Ord a => (forall b. Ord b => b -> b -> Bool) -> Interval a -> Interval a -> Bool
certainly :: forall a.
Ord a =>
(forall a. Ord a => a -> a -> Bool)
-> Interval a -> Interval a -> Bool
certainly forall a. Ord a => a -> a -> Bool
cmp Interval a
l Interval a
r
    | Bool
lt Bool -> Bool -> Bool
&& Bool
eq Bool -> Bool -> Bool
&& Bool
gt = Bool
True
    | Bool
lt Bool -> Bool -> Bool
&& Bool
eq       = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
<=! Interval a
r
    | Bool
lt Bool -> Bool -> Bool
&&       Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
/=! Interval a
r
    | Bool
lt             = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
<!  Interval a
r
    |       Bool
eq Bool -> Bool -> Bool
&& Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
>=! Interval a
r
    |       Bool
eq       = Interval a
l Interval a -> Interval a -> Bool
forall a. Eq a => Interval a -> Interval a -> Bool
==! Interval a
r
    |             Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
>!  Interval a
r
    | Bool
otherwise      = Bool
False
    where
        lt :: Bool
lt = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
LT Ordering
EQ
        eq :: Bool
eq = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
EQ Ordering
EQ
        gt :: Bool
gt = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
GT Ordering
EQ
{-# INLINE certainly #-}

-- | Check if interval @X@ totally contains interval @Y@
--
-- >>> (20 ... 40 :: Interval Double) `contains` (25 ... 35 :: Interval Double)
-- True
--
-- >>> (20 ... 40 :: Interval Double) `contains` (15 ... 35 :: Interval Double)
-- False
contains :: Ord a => Interval a -> Interval a -> Bool
contains :: forall a. Ord a => Interval a -> Interval a -> Bool
contains Interval a
x Interval a
y = Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
y
            Bool -> Bool -> Bool
|| (Bool -> Bool
not (Interval a -> Bool
forall a. Ord a => Interval a -> Bool
null Interval a
x) Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
inf Interval a
y Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
sup Interval a
y a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
sup Interval a
x)
{-# INLINE contains #-}

-- | Flipped version of `contains`. Check if interval @X@ a subset of interval @Y@
--
-- >>> (25 ... 35 :: Interval Double) `isSubsetOf` (20 ... 40 :: Interval Double)
-- True
--
-- >>> (20 ... 40 :: Interval Double) `isSubsetOf` (15 ... 35 :: Interval Double)
-- False
isSubsetOf :: Ord a => Interval a -> Interval a -> Bool
isSubsetOf :: forall a. Ord a => Interval a -> Interval a -> Bool
isSubsetOf = (Interval a -> Interval a -> Bool)
-> Interval a -> Interval a -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
contains
{-# INLINE isSubsetOf #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<' y@?
(<?) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x <? :: forall a. Ord a => Interval a -> Interval a -> Bool
<? Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (<?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<=' y@?
(<=?) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x <=? :: forall a. Ord a => Interval a -> Interval a -> Bool
<=? Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
sup Interval a
y
{-# INLINE (<=?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '==' y@?
(==?) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x ==? :: forall a. Ord a => Interval a -> Interval a -> Bool
==? Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall a. Interval a -> a
sup Interval a
y Bool -> Bool -> Bool
&& Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (==?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '/=' y@?
(/=?) :: Eq a => Interval a -> Interval a -> Bool
Interval a
x /=? :: forall a. Eq a => Interval a -> Interval a -> Bool
/=? Interval a
y = Interval a -> a
forall a. Interval a -> a
inf Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= Interval a -> a
forall a. Interval a -> a
sup Interval a
y Bool -> Bool -> Bool
|| Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (/=?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>' y@?
(>?) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x >? :: forall a. Ord a => Interval a -> Interval a -> Bool
>? Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (>?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>=' y@?
(>=?) :: Ord a => Interval a -> Interval a -> Bool
Interval a
x >=? :: forall a. Ord a => Interval a -> Interval a -> Bool
>=? Interval a
y = Interval a -> a
forall a. Interval a -> a
sup Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= Interval a -> a
forall a. Interval a -> a
inf Interval a
y
{-# INLINE (>=?) #-}

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x `op` y@?
possibly :: Ord a => (forall b. Ord b => b -> b -> Bool) -> Interval a -> Interval a -> Bool
possibly :: forall a.
Ord a =>
(forall a. Ord a => a -> a -> Bool)
-> Interval a -> Interval a -> Bool
possibly forall a. Ord a => a -> a -> Bool
cmp Interval a
l Interval a
r
    | Bool
lt Bool -> Bool -> Bool
&& Bool
eq Bool -> Bool -> Bool
&& Bool
gt = Bool
True
    | Bool
lt Bool -> Bool -> Bool
&& Bool
eq       = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
<=? Interval a
r
    | Bool
lt Bool -> Bool -> Bool
&&       Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Eq a => Interval a -> Interval a -> Bool
/=? Interval a
r
    | Bool
lt             = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
<? Interval a
r
    |       Bool
eq Bool -> Bool -> Bool
&& Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
>=? Interval a
r
    |       Bool
eq       = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
==? Interval a
r
    |             Bool
gt = Interval a
l Interval a -> Interval a -> Bool
forall a. Ord a => Interval a -> Interval a -> Bool
>? Interval a
r
    | Bool
otherwise      = Bool
False
    where
        lt :: Bool
lt = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
LT Ordering
EQ
        eq :: Bool
eq = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
EQ Ordering
EQ
        gt :: Bool
gt = Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
cmp Ordering
GT Ordering
EQ
{-# INLINE possibly #-}

-- | The nearest value to that supplied which is contained in the interval.
clamp :: Ord a => Interval a -> a -> a
clamp :: forall a. Ord a => Interval a -> a -> a
clamp (I a
a a
b) a
x | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a     = a
a
                | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
b     = a
b
                | Bool
otherwise = a
x

-- | id function. Useful for type specification
--
-- >>> :t idouble (1 ... 3)
-- idouble (1 ... 3) :: Interval Double
idouble :: Interval Double -> Interval Double
idouble :: Interval Double -> Interval Double
idouble = Interval Double -> Interval Double
forall a. a -> a
id

-- | id function. Useful for type specification
--
-- >>> :t ifloat (1 ... 3)
-- ifloat (1 ... 3) :: Interval Float
ifloat :: Interval Float -> Interval Float
ifloat :: Interval Float -> Interval Float
ifloat = Interval Float -> Interval Float
forall a. a -> a
id

-- Bugs:
-- sin 1 :: Interval Double


default (Integer,Double)

-- | an interval containing all x `quot` y
-- >>> (5 `quot` 3) `member` ((4...6) `iquot` (2...4))
-- True
-- >>> (1...10) `iquot` ((-5)...4)
-- *** Exception: divide by zero
iquot :: Integral a => Interval a -> Interval a -> Interval a
iquot :: forall a. Integral a => Interval a -> Interval a -> Interval a
iquot (I a
l a
u) (I a
l' a
u') =
  if a
l' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 Bool -> Bool -> Bool
&& a
0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
u' then ArithException -> Interval a
forall a e. Exception e => e -> a
throw ArithException
DivideByZero else a -> a -> Interval a
forall a. a -> a -> Interval a
I
    ([a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [a
a a -> a -> a
forall a. Integral a => a -> a -> a
`quot` a
b | a
a <- [a
l,a
u], a
b <- [a
l',a
u']])
    ([a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [a
a a -> a -> a
forall a. Integral a => a -> a -> a
`quot` a
b | a
a <- [a
l,a
u], a
b <- [a
l',a
u']])

-- | an interval containing all x `rem` y
-- >>> (5 `rem` 3) `member` ((4...6) `irem` (2...4))
-- True
-- >>> (1...10) `irem` ((-5)...4)
-- *** Exception: divide by zero
irem :: Integral a => Interval a -> Interval a -> Interval a
irem :: forall a. Integral a => Interval a -> Interval a -> Interval a
irem (I a
l a
u) (I a
l' a
u') =
  if a
l' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 Bool -> Bool -> Bool
&& a
0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
u' then ArithException -> Interval a
forall a e. Exception e => e -> a
throw ArithException
DivideByZero else a -> a -> Interval a
forall a. a -> a -> Interval a
I
    ([a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [a
0, a -> a
forall a. Num a => a -> a
signum a
l a -> a -> a
forall a. Num a => a -> a -> a
* (a -> a
forall a. Num a => a -> a
abs a
u' a -> a -> a
forall a. Num a => a -> a -> a
- a
1), a -> a
forall a. Num a => a -> a
signum a
l a -> a -> a
forall a. Num a => a -> a -> a
* (a -> a
forall a. Num a => a -> a
abs a
l' a -> a -> a
forall a. Num a => a -> a -> a
- a
1)])
    ([a] -> a
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [a
0, a -> a
forall a. Num a => a -> a
signum a
u a -> a -> a
forall a. Num a => a -> a -> a
* (a -> a
forall a. Num a => a -> a
abs a
u' a -> a -> a
forall a. Num a => a -> a -> a
- a
1), a -> a
forall a. Num a => a -> a
signum a
u a -> a -> a
forall a. Num a => a -> a -> a
* (a -> a
forall a. Num a => a -> a
abs a
l' a -> a -> a
forall a. Num a => a -> a -> a
- a
1)])

-- | an interval containing all x `div` y
-- >>> (5 `div` 3) `member` ((4...6) `idiv` (2...4))
-- True
-- >>> (1...10) `idiv` ((-5)...4)
-- *** Exception: divide by zero
idiv :: Integral a => Interval a -> Interval a -> Interval a
idiv :: forall a. Integral a => Interval a -> Interval a -> Interval a
idiv (I a
l a
u) (I a
l' a
u') =
  if a
l' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 Bool -> Bool -> Bool
&& a
0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
u' then ArithException -> Interval a
forall a e. Exception e => e -> a
throw ArithException
DivideByZero else a -> a -> Interval a
forall a. a -> a -> Interval a
I
    (a -> a -> a
forall a. Ord a => a -> a -> a
min (a
l a -> a -> a
forall a. Integral a => a -> a -> a
`Prelude.div` a -> a -> a
forall a. Ord a => a -> a -> a
max a
1 a
l') (a
u a -> a -> a
forall a. Integral a => a -> a -> a
`Prelude.div` a -> a -> a
forall a. Ord a => a -> a -> a
min (-a
1) a
u'))
    (a -> a -> a
forall a. Ord a => a -> a -> a
max (a
u a -> a -> a
forall a. Integral a => a -> a -> a
`Prelude.div` a -> a -> a
forall a. Ord a => a -> a -> a
max a
1 a
l') (a
l a -> a -> a
forall a. Integral a => a -> a -> a
`Prelude.div` a -> a -> a
forall a. Ord a => a -> a -> a
min (-a
1) a
u'))

-- | an interval containing all x `mod` y
-- >>> (5 `mod` 3) `member` ((4...6) `imod` (2...4))
-- True
-- >>> (1...10) `imod` ((-5)...4)
-- *** Exception: divide by zero
imod :: Integral a => Interval a -> Interval a -> Interval a
imod :: forall a. Integral a => Interval a -> Interval a -> Interval a
imod Interval a
_ (I a
l' a
u') =
  if a
l' a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
0 Bool -> Bool -> Bool
&& a
0 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
u' then ArithException -> Interval a
forall a e. Exception e => e -> a
throw ArithException
DivideByZero else
    a -> a -> Interval a
forall a. a -> a -> Interval a
I (a -> a -> a
forall a. Ord a => a -> a -> a
min (a
l'a -> a -> a
forall a. Num a => a -> a -> a
+a
1) a
0) (a -> a -> a
forall a. Ord a => a -> a -> a
max a
0 (a
u'a -> a -> a
forall a. Num a => a -> a -> a
-a
1))