{-# OPTIONS_GHC -Wall -fno-warn-orphans #-}
{-# LANGUAGE CPP, LambdaCase, ScopedTypeVariables #-}
{-# LANGUAGE Safe #-}
#if __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE RoleAnnotations #-}
#endif
-----------------------------------------------------------------------------
-- |
-- Module      :  Data.Interval
-- Copyright   :  (c) Masahiro Sakai 2011-2013, Andrew Lelechenko 2020
-- License     :  BSD-style
--
-- Maintainer  :  masahiro.sakai@gmail.com
-- Stability   :  provisional
-- Portability :  non-portable (CPP, ScopedTypeVariables, DeriveDataTypeable)
--
-- Interval datatype and interval arithmetic.
--
-- Unlike the intervals package (<http://hackage.haskell.org/package/intervals>),
-- this module provides both open and closed intervals and is intended to be used
-- with 'Rational'.
--
-- For the purpose of abstract interpretation, it might be convenient to use
-- 'Lattice' instance. See also lattices package
-- (<http://hackage.haskell.org/package/lattices>).
--
-----------------------------------------------------------------------------
module Data.Interval
  (
  -- * Interval type
    Interval
  , module Data.ExtendedReal
  , Boundary(..)

  -- * Construction
  , interval
  , (<=..<=)
  , (<..<=)
  , (<=..<)
  , (<..<)
  , whole
  , empty
  , singleton

  -- * Query
  , null
  , isSingleton
  , extractSingleton
  , member
  , notMember
  , isSubsetOf
  , isProperSubsetOf
  , isConnected
  , lowerBound
  , upperBound
  , lowerBound'
  , upperBound'
  , width

  -- * Universal comparison operators
  , (<!), (<=!), (==!), (>=!), (>!), (/=!)

  -- * Existential comparison operators
  , (<?), (<=?), (==?), (>=?), (>?), (/=?)

  -- * Existential comparison operators that produce witnesses (experimental)
  , (<??), (<=??), (==??), (>=??), (>??), (/=??)

  -- * Combine
  , intersection
  , intersections
  , hull
  , hulls

  -- * Map
  , mapMonotonic

  -- * Operations
  , pickup
  , simplestRationalWithin

  -- * Intervals relation
  , relate
  ) where

#ifdef MIN_VERSION_lattices
import Algebra.Lattice
#endif
import Control.Exception (assert)
import Control.Monad hiding (join)
import Data.ExtendedReal
import Data.Interval.Internal
import Data.IntervalRelation
import Data.List (foldl', maximumBy, minimumBy)
import Data.Maybe
import Data.Monoid
import Data.Ratio
import Prelude hiding (null)

infix 5 <=..<=
infix 5 <..<=
infix 5 <=..<
infix 5 <..<
infix 4 <!
infix 4 <=!
infix 4 ==!
infix 4 >=!
infix 4 >!
infix 4 /=!
infix 4 <?
infix 4 <=?
infix 4 ==?
infix 4 >=?
infix 4 >?
infix 4 /=?
infix 4 <??
infix 4 <=??
infix 4 ==??
infix 4 >=??
infix 4 >??
infix 4 /=??

#ifdef MIN_VERSION_lattices
#if MIN_VERSION_lattices(2,0,0)

instance (Ord r) => Lattice (Interval r) where
  (\/) = hull
  (/\) = intersection

instance (Ord r) => BoundedJoinSemiLattice (Interval r) where
  bottom = empty

instance (Ord r) => BoundedMeetSemiLattice (Interval r) where
  top = whole

#else

instance (Ord r) => JoinSemiLattice (Interval r) where
  join = hull

instance (Ord r) => MeetSemiLattice (Interval r) where
  meet = intersection

instance (Ord r) => Lattice (Interval r)

instance (Ord r) => BoundedJoinSemiLattice (Interval r) where
  bottom = empty

instance (Ord r) => BoundedMeetSemiLattice (Interval r) where
  top = whole

instance (Ord r) => BoundedLattice (Interval r)

#endif
#endif

instance (Ord r, Show r) => Show (Interval r) where
  showsPrec :: Int -> Interval r -> ShowS
showsPrec Int
_ Interval r
x | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x = String -> ShowS
showString String
"empty"
  showsPrec Int
p Interval r
i =
    Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
rangeOpPrec) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      Int -> Extended r -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
rangeOpPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Extended r
lb ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
op ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
      Int -> Extended r -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec (Int
rangeOpPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Extended r
ub
    where
      (Extended r
lb, Boundary
in1) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i
      (Extended r
ub, Boundary
in2) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i
      op :: String
op = Boundary -> String
sign Boundary
in1 String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
".." String -> ShowS
forall a. [a] -> [a] -> [a]
++ Boundary -> String
sign Boundary
in2
      sign :: Boundary -> String
sign = \case
        Boundary
Open   -> String
"<"
        Boundary
Closed -> String
"<="

instance (Ord r, Read r) => Read (Interval r) where
  readsPrec :: Int -> ReadS (Interval r)
readsPrec Int
p String
r =
    (Bool -> ReadS (Interval r) -> ReadS (Interval r)
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (ReadS (Interval r) -> ReadS (Interval r))
-> ReadS (Interval r) -> ReadS (Interval r)
forall a b. (a -> b) -> a -> b
$ \String
s0 -> do
      (String
"interval",String
s1) <- ReadS String
lex String
s0
      ((Extended r, Boundary)
lb,String
s2) <- Int -> ReadS (Extended r, Boundary)
forall a. Read a => Int -> ReadS a
readsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
s1
      ((Extended r, Boundary)
ub,String
s3) <- Int -> ReadS (Extended r, Boundary)
forall a. Read a => Int -> ReadS a
readsPrec (Int
appPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
s2
      (Interval r, String) -> [(Interval r, String)]
forall (m :: * -> *) a. Monad m => a -> m a
return ((Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r, Boundary)
lb (Extended r, Boundary)
ub, String
s3)) String
r
    [(Interval r, String)]
-> [(Interval r, String)] -> [(Interval r, String)]
forall a. [a] -> [a] -> [a]
++
    (Bool -> ReadS (Interval r) -> ReadS (Interval r)
forall a. Bool -> ReadS a -> ReadS a
readParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
rangeOpPrec) (ReadS (Interval r) -> ReadS (Interval r))
-> ReadS (Interval r) -> ReadS (Interval r)
forall a b. (a -> b) -> a -> b
$ \String
s0 -> do
      (do (Extended r
l,String
s1) <- Int -> ReadS (Extended r)
forall a. Read a => Int -> ReadS a
readsPrec (Int
rangeOpPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
s0
          (String
op',String
s2) <- ReadS String
lex String
s1
          Extended r -> Extended r -> Interval r
op <-
            case String
op' of
              String
"<=..<=" -> (Extended r -> Extended r -> Interval r)
-> [Extended r -> Extended r -> Interval r]
forall (m :: * -> *) a. Monad m => a -> m a
return Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
(<=..<=)
              String
"<..<="  -> (Extended r -> Extended r -> Interval r)
-> [Extended r -> Extended r -> Interval r]
forall (m :: * -> *) a. Monad m => a -> m a
return Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
(<..<=)
              String
"<=..<"  -> (Extended r -> Extended r -> Interval r)
-> [Extended r -> Extended r -> Interval r]
forall (m :: * -> *) a. Monad m => a -> m a
return Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
(<=..<)
              String
"<..<"   -> (Extended r -> Extended r -> Interval r)
-> [Extended r -> Extended r -> Interval r]
forall (m :: * -> *) a. Monad m => a -> m a
return Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
(<..<)
              String
_ -> []
          (Extended r
u,String
s3) <- Int -> ReadS (Extended r)
forall a. Read a => Int -> ReadS a
readsPrec (Int
rangeOpPrecInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String
s2
          (Interval r, String) -> [(Interval r, String)]
forall (m :: * -> *) a. Monad m => a -> m a
return (Extended r -> Extended r -> Interval r
op Extended r
l Extended r
u, String
s3))) String
r
    [(Interval r, String)]
-> [(Interval r, String)] -> [(Interval r, String)]
forall a. [a] -> [a] -> [a]
++
    (do (String
"empty", String
s) <- ReadS String
lex String
r
        (Interval r, String) -> [(Interval r, String)]
forall (m :: * -> *) a. Monad m => a -> m a
return (Interval r
forall r. Ord r => Interval r
empty, String
s))

-- | Lower endpoint (/i.e./ greatest lower bound)  of the interval.
--
-- * 'lowerBound' of the empty interval is 'PosInf'.
--
-- * 'lowerBound' of a left unbounded interval is 'NegInf'.
--
-- * 'lowerBound' of an interval may or may not be a member of the interval.
lowerBound :: Interval r -> Extended r
lowerBound :: Interval r -> Extended r
lowerBound = (Extended r, Boundary) -> Extended r
forall a b. (a, b) -> a
fst ((Extended r, Boundary) -> Extended r)
-> (Interval r -> (Extended r, Boundary))
-> Interval r
-> Extended r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound'

-- | Upper endpoint (/i.e./ least upper bound) of the interval.
--
-- * 'upperBound' of the empty interval is 'NegInf'.
--
-- * 'upperBound' of a right unbounded interval is 'PosInf'.
--
-- * 'upperBound' of an interval may or may not be a member of the interval.
upperBound :: Interval r -> Extended r
upperBound :: Interval r -> Extended r
upperBound = (Extended r, Boundary) -> Extended r
forall a b. (a, b) -> a
fst ((Extended r, Boundary) -> Extended r)
-> (Interval r -> (Extended r, Boundary))
-> Interval r
-> Extended r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound'

-- | closed interval [@l@,@u@]
(<=..<=)
  :: (Ord r)
  => Extended r -- ^ lower bound @l@
  -> Extended r -- ^ upper bound @u@
  -> Interval r
<=..<= :: Extended r -> Extended r -> Interval r
(<=..<=) Extended r
lb Extended r
ub = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
lb, Boundary
Closed) (Extended r
ub, Boundary
Closed)

-- | left-open right-closed interval (@l@,@u@]
(<..<=)
  :: (Ord r)
  => Extended r -- ^ lower bound @l@
  -> Extended r -- ^ upper bound @u@
  -> Interval r
<..<= :: Extended r -> Extended r -> Interval r
(<..<=) Extended r
lb Extended r
ub = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
lb, Boundary
Open) (Extended r
ub, Boundary
Closed)

-- | left-closed right-open interval [@l@, @u@)
(<=..<)
  :: (Ord r)
  => Extended r -- ^ lower bound @l@
  -> Extended r -- ^ upper bound @u@
  -> Interval r
<=..< :: Extended r -> Extended r -> Interval r
(<=..<) Extended r
lb Extended r
ub = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
lb, Boundary
Closed) (Extended r
ub, Boundary
Open)

-- | open interval (@l@, @u@)
(<..<)
  :: (Ord r)
  => Extended r -- ^ lower bound @l@
  -> Extended r -- ^ upper bound @u@
  -> Interval r
<..< :: Extended r -> Extended r -> Interval r
(<..<) Extended r
lb Extended r
ub = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
lb, Boundary
Open) (Extended r
ub, Boundary
Open)

-- | whole real number line (-∞, ∞)
whole :: Ord r => Interval r
whole :: Interval r
whole = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
forall r. Extended r
NegInf, Boundary
Open) (Extended r
forall r. Extended r
PosInf, Boundary
Open)

-- | singleton set [x,x]
singleton :: Ord r => r -> Interval r
singleton :: r -> Interval r
singleton r
x = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (r -> Extended r
forall r. r -> Extended r
Finite r
x, Boundary
Closed) (r -> Extended r
forall r. r -> Extended r
Finite r
x, Boundary
Closed)

-- | intersection of two intervals
intersection :: forall r. Ord r => Interval r -> Interval r -> Interval r
intersection :: Interval r -> Interval r -> Interval r
intersection Interval r
i1 Interval r
i2 = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval
  ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
maxLB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i2))
  ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
minUB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2))
  where
    maxLB :: (Extended r, Boundary) -> (Extended r, Boundary) -> (Extended r, Boundary)
    maxLB :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
maxLB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) =
      ( Extended r -> Extended r -> Extended r
forall a. Ord a => a -> a -> a
max Extended r
x1 Extended r
x2
      , case Extended r
x1 Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
x2 of
          Ordering
EQ -> Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`min` Boundary
in2
          Ordering
LT -> Boundary
in2
          Ordering
GT -> Boundary
in1
      )
    minUB :: (Extended r, Boundary) -> (Extended r, Boundary) -> (Extended r, Boundary)
    minUB :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
minUB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) =
      ( Extended r -> Extended r -> Extended r
forall a. Ord a => a -> a -> a
min Extended r
x1 Extended r
x2
      , case Extended r
x1 Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
x2 of
          Ordering
EQ -> Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`min` Boundary
in2
          Ordering
LT -> Boundary
in1
          Ordering
GT -> Boundary
in2
      )

-- | intersection of a list of intervals.
--
-- Since 0.6.0
intersections :: Ord r => [Interval r] -> Interval r
intersections :: [Interval r] -> Interval r
intersections = (Interval r -> Interval r -> Interval r)
-> Interval r -> [Interval r] -> Interval r
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
forall r. Ord r => Interval r
whole

-- | convex hull of two intervals
hull :: forall r. Ord r => Interval r -> Interval r -> Interval r
hull :: Interval r -> Interval r -> Interval r
hull Interval r
x1 Interval r
x2
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x1 = Interval r
x2
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x2 = Interval r
x1
hull Interval r
i1 Interval r
i2 = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval
  ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
minLB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i2))
  ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
maxUB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2))
  where
    maxUB :: (Extended r, Boundary) -> (Extended r, Boundary) -> (Extended r, Boundary)
    maxUB :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
maxUB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) =
      ( Extended r -> Extended r -> Extended r
forall a. Ord a => a -> a -> a
max Extended r
x1 Extended r
x2
      , case Extended r
x1 Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
x2 of
          Ordering
EQ -> Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`max` Boundary
in2
          Ordering
LT -> Boundary
in2
          Ordering
GT -> Boundary
in1
      )
    minLB :: (Extended r, Boundary) -> (Extended r, Boundary) -> (Extended r, Boundary)
    minLB :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
minLB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) =
      ( Extended r -> Extended r -> Extended r
forall a. Ord a => a -> a -> a
min Extended r
x1 Extended r
x2
      , case Extended r
x1 Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
x2 of
          Ordering
EQ -> Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`max` Boundary
in2
          Ordering
LT -> Boundary
in1
          Ordering
GT -> Boundary
in2
      )

-- | convex hull of a list of intervals.
--
-- Since 0.6.0
hulls :: Ord r => [Interval r] -> Interval r
hulls :: [Interval r] -> Interval r
hulls = (Interval r -> Interval r -> Interval r)
-> Interval r -> [Interval r] -> Interval r
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
hull Interval r
forall r. Ord r => Interval r
empty

-- | Is the interval empty?
null :: Ord r => Interval r -> Bool
null :: Interval r -> Bool
null Interval r
i =
  case Extended r
x1 Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
x2 of
    Ordering
EQ -> Bool -> Bool -> Bool
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed) Bool
False
    Ordering
LT -> Bool
False
    Ordering
GT -> Bool
True
  where
    (Extended r
x1, Boundary
in1) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i
    (Extended r
x2, Boundary
in2) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i

-- | Is the interval single point?
--
-- @since 2.0.0
isSingleton :: Ord r => Interval r -> Bool
isSingleton :: Interval r -> Bool
isSingleton = Maybe r -> Bool
forall a. Maybe a -> Bool
isJust (Maybe r -> Bool) -> (Interval r -> Maybe r) -> Interval r -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Maybe r
forall r. Ord r => Interval r -> Maybe r
extractSingleton

-- | If the interval is a single point, return this point.
--
-- @since 2.1.0
extractSingleton :: Ord r => Interval r -> Maybe r
extractSingleton :: Interval r -> Maybe r
extractSingleton Interval r
i = case (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i, Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i) of
  ((Finite r
l, Boundary
Closed), (Finite r
u, Boundary
Closed))
    | r
l r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
u -> r -> Maybe r
forall a. a -> Maybe a
Just r
l
  ((Extended r, Boundary), (Extended r, Boundary))
_ -> Maybe r
forall a. Maybe a
Nothing

-- | Is the element in the interval?
member :: Ord r => r -> Interval r -> Bool
member :: r -> Interval r -> Bool
member r
x Interval r
i = Bool
condLB Bool -> Bool -> Bool
&& Bool
condUB
  where
    (Extended r
x1, Boundary
in1) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i
    (Extended r
x2, Boundary
in2) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i
    condLB :: Bool
condLB = case Boundary
in1 of
      Boundary
Open   -> Extended r
x1 Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<  r -> Extended r
forall r. r -> Extended r
Finite r
x
      Boundary
Closed -> Extended r
x1 Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<= r -> Extended r
forall r. r -> Extended r
Finite r
x
    condUB :: Bool
condUB = case Boundary
in2 of
      Boundary
Open   -> r -> Extended r
forall r. r -> Extended r
Finite r
x Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<  Extended r
x2
      Boundary
Closed -> r -> Extended r
forall r. r -> Extended r
Finite r
x Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<= Extended r
x2

-- | Is the element not in the interval?
notMember :: Ord r => r -> Interval r -> Bool
notMember :: r -> Interval r -> Bool
notMember r
a Interval r
i = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
member r
a Interval r
i

-- | Is this a subset?
-- @(i1 \``isSubsetOf`\` i2)@ tells whether @i1@ is a subset of @i2@.
isSubsetOf :: Ord r => Interval r -> Interval r -> Bool
isSubsetOf :: Interval r -> Interval r -> Bool
isSubsetOf Interval r
i1 Interval r
i2 = (Extended r, Boundary) -> (Extended r, Boundary) -> Bool
forall a a. (Ord a, Ord a) => (a, a) -> (a, a) -> Bool
testLB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i2) Bool -> Bool -> Bool
&& (Extended r, Boundary) -> (Extended r, Boundary) -> Bool
forall a a. (Ord a, Ord a) => (a, a) -> (a, a) -> Bool
testUB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2)
  where
    testLB :: (a, a) -> (a, a) -> Bool
testLB (a
x1,a
in1) (a
x2,a
in2) =
      case a
x1 a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` a
x2 of
        Ordering
GT -> Bool
True
        Ordering
LT -> Bool
False
        Ordering
EQ -> a
in1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
in2
    testUB :: (a, a) -> (a, a) -> Bool
testUB (a
x1,a
in1) (a
x2,a
in2) =
      case a
x1 a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` a
x2 of
        Ordering
LT -> Bool
True
        Ordering
GT -> Bool
False
        Ordering
EQ -> a
in1 a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
in2

-- | Is this a proper subset? (/i.e./ a subset but not equal).
isProperSubsetOf :: Ord r => Interval r -> Interval r -> Bool
isProperSubsetOf :: Interval r -> Interval r -> Bool
isProperSubsetOf Interval r
i1 Interval r
i2 = Interval r
i1 Interval r -> Interval r -> Bool
forall a. Eq a => a -> a -> Bool
/= Interval r
i2 Bool -> Bool -> Bool
&& Interval r
i1 Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
`isSubsetOf` Interval r
i2

-- | Does the union of two range form a connected set?
--
-- Since 1.3.0
isConnected :: Ord r => Interval r -> Interval r -> Bool
isConnected :: Interval r -> Interval r -> Bool
isConnected Interval r
x Interval r
y
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x = Bool
True
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
y = Bool
True
  | Bool
otherwise = Interval r
x Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
==? Interval r
y Bool -> Bool -> Bool
|| (Extended r
lb1Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
==Extended r
ub2 Bool -> Bool -> Bool
&& (Boundary
lb1in Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed Bool -> Bool -> Bool
|| Boundary
ub2in Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed)) Bool -> Bool -> Bool
|| (Extended r
ub1Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
==Extended r
lb2 Bool -> Bool -> Bool
&& (Boundary
ub1in Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed Bool -> Bool -> Bool
|| Boundary
lb2in Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed))
  where
    (Extended r
lb1,Boundary
lb1in) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
x
    (Extended r
lb2,Boundary
lb2in) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
y
    (Extended r
ub1,Boundary
ub1in) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
x
    (Extended r
ub2,Boundary
ub2in) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
y

-- | Width of a interval. Width of an unbounded interval is @undefined@.
width :: (Num r, Ord r) => Interval r -> r
width :: Interval r -> r
width Interval r
x
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x = r
0
  | Bool
otherwise = case ((Extended r, Boundary) -> Extended r
forall a b. (a, b) -> a
fst (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
x), (Extended r, Boundary) -> Extended r
forall a b. (a, b) -> a
fst (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
x)) of
    (Finite r
l, Finite r
u) -> r
u r -> r -> r
forall a. Num a => a -> a -> a
- r
l
    (Extended r, Extended r)
_ -> String -> r
forall a. (?callStack::CallStack) => String -> a
error String
"Data.Interval.width: unbounded interval"

-- | pick up an element from the interval if the interval is not empty.
pickup :: (Real r, Fractional r) => Interval r -> Maybe r
pickup :: Interval r -> Maybe r
pickup Interval r
i = case (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i, Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i) of
  ((Extended r
NegInf,Boundary
_), (Extended r
PosInf,Boundary
_))             -> r -> Maybe r
forall a. a -> Maybe a
Just r
0
  ((Finite r
x1, Boundary
in1), (Extended r
PosInf,Boundary
_))       -> r -> Maybe r
forall a. a -> Maybe a
Just (r -> Maybe r) -> r -> Maybe r
forall a b. (a -> b) -> a -> b
$ case Boundary
in1 of
    Boundary
Open   -> r
x1 r -> r -> r
forall a. Num a => a -> a -> a
+ r
1
    Boundary
Closed -> r
x1
  ((Extended r
NegInf,Boundary
_), (Finite r
x2, Boundary
in2))       -> r -> Maybe r
forall a. a -> Maybe a
Just (r -> Maybe r) -> r -> Maybe r
forall a b. (a -> b) -> a -> b
$ case Boundary
in2 of
    Boundary
Open   -> r
x2 r -> r -> r
forall a. Num a => a -> a -> a
- r
1
    Boundary
Closed -> r
x2
  ((Finite r
x1, Boundary
in1), (Finite r
x2, Boundary
in2)) ->
    case r
x1 r -> r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` r
x2 of
      Ordering
GT -> Maybe r
forall a. Maybe a
Nothing
      Ordering
LT -> r -> Maybe r
forall a. a -> Maybe a
Just (r -> Maybe r) -> r -> Maybe r
forall a b. (a -> b) -> a -> b
$ (r
x1r -> r -> r
forall a. Num a => a -> a -> a
+r
x2) r -> r -> r
forall a. Fractional a => a -> a -> a
/ r
2
      Ordering
EQ -> if Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed then r -> Maybe r
forall a. a -> Maybe a
Just r
x1 else Maybe r
forall a. Maybe a
Nothing
  ((Extended r, Boundary), (Extended r, Boundary))
_ -> Maybe r
forall a. Maybe a
Nothing

-- | 'simplestRationalWithin' returns the simplest rational number within the interval.
--
-- A rational number @y@ is said to be /simpler/ than another @y'@ if
--
-- * @'abs' ('numerator' y) <= 'abs' ('numerator' y')@, and
--
-- * @'denominator' y <= 'denominator' y'@.
--
-- (see also 'approxRational')
--
-- Since 0.4.0
simplestRationalWithin :: RealFrac r => Interval r -> Maybe Rational
simplestRationalWithin :: Interval r -> Maybe Rational
simplestRationalWithin Interval r
i | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
i = Maybe Rational
forall a. Maybe a
Nothing
simplestRationalWithin Interval r
i
  | Interval r
0 Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
<! Interval r
i    = Rational -> Maybe Rational
forall a. a -> Maybe a
Just (Rational -> Maybe Rational) -> Rational -> Maybe Rational
forall a b. (a -> b) -> a -> b
$ Interval r -> Rational
forall r p. (Fractional p, RealFrac r) => Interval r -> p
go Interval r
i
  | Interval r
i Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
<! Interval r
0    = Rational -> Maybe Rational
forall a. a -> Maybe a
Just (Rational -> Maybe Rational) -> Rational -> Maybe Rational
forall a b. (a -> b) -> a -> b
$ - Interval r -> Rational
forall r p. (Fractional p, RealFrac r) => Interval r -> p
go (- Interval r
i)
  | Bool
otherwise = Bool -> Maybe Rational -> Maybe Rational
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (r
0 r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
i) (Maybe Rational -> Maybe Rational)
-> Maybe Rational -> Maybe Rational
forall a b. (a -> b) -> a -> b
$ Rational -> Maybe Rational
forall a. a -> Maybe a
Just Rational
0
  where
    go :: Interval r -> p
go Interval r
j
      | Integer -> r
forall a. Num a => Integer -> a
fromInteger Integer
lb_floor       r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
j = Integer -> p
forall a. Num a => Integer -> a
fromInteger Integer
lb_floor
      | Integer -> r
forall a. Num a => Integer -> a
fromInteger (Integer
lb_floor Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1) r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
j = Integer -> p
forall a. Num a => Integer -> a
fromInteger (Integer
lb_floor Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1)
      | Bool
otherwise = Integer -> p
forall a. Num a => Integer -> a
fromInteger Integer
lb_floor p -> p -> p
forall a. Num a => a -> a -> a
+ p -> p
forall a. Fractional a => a -> a
recip (Interval r -> p
go (Interval r -> Interval r
forall a. Fractional a => a -> a
recip (Interval r
j Interval r -> Interval r -> Interval r
forall a. Num a => a -> a -> a
- r -> Interval r
forall r. Ord r => r -> Interval r
singleton (Integer -> r
forall a. Num a => Integer -> a
fromInteger Integer
lb_floor))))
      where
        Finite r
lb = Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
j
        lb_floor :: Integer
lb_floor  = r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor r
lb

-- | @mapMonotonic f i@ is the image of @i@ under @f@, where @f@ must be a strict monotone function,
-- preserving negative and positive infinities.
mapMonotonic :: (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic :: (a -> b) -> Interval a -> Interval b
mapMonotonic a -> b
f Interval a
i = (Extended b, Boundary) -> (Extended b, Boundary) -> Interval b
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval ((a -> b) -> Extended a -> Extended b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Extended a
lb, Boundary
in1) ((a -> b) -> Extended a -> Extended b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Extended a
ub, Boundary
in2)
  where
    (Extended a
lb, Boundary
in1) = Interval a -> (Extended a, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval a
i
    (Extended a
ub, Boundary
in2) = Interval a -> (Extended a, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval a
i

mapAntiMonotonic :: (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapAntiMonotonic :: (a -> b) -> Interval a -> Interval b
mapAntiMonotonic a -> b
f Interval a
i
  | Interval a -> Bool
forall r. Ord r => Interval r -> Bool
null Interval a
i = Interval b
forall r. Ord r => Interval r
empty
  | Bool
otherwise = (Extended b, Boundary) -> (Extended b, Boundary) -> Interval b
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval ((a -> b) -> Extended a -> Extended b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Extended a
ub, Boundary
in2) ((a -> b) -> Extended a -> Extended b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Extended a
lb, Boundary
in1)
  where
    (Extended a
lb, Boundary
in1) = Interval a -> (Extended a, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval a
i
    (Extended a
ub, Boundary
in2) = Interval a -> (Extended a, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval a
i

-- | For all @x@ in @X@, @y@ in @Y@. @x '<' y@?
(<!) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a <! :: Interval r -> Interval r -> Bool
<! Interval r
b =
  case Extended r
ub_a Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
lb_b of
    Ordering
LT -> Bool
True
    Ordering
GT -> Bool
False
    Ordering
EQ ->
      case Extended r
ub_a of
        Extended r
NegInf   -> Bool
True -- a is empty, so it holds vacuously
        Extended r
PosInf   -> Bool
True -- b is empty, so it holds vacuously
        Finite r
_ -> Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open Bool -> Bool -> Bool
|| Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open
  where
    (Extended r
ub_a, Boundary
in1) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a
    (Extended r
lb_b, Boundary
in2) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b

-- | For all @x@ in @X@, @y@ in @Y@. @x '<=' y@?
(<=!) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a <=! :: Interval r -> Interval r -> Bool
<=! Interval r
b = Interval r -> Extended r
forall r. Interval r -> Extended r
upperBound Interval r
a Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
b

-- | For all @x@ in @X@, @y@ in @Y@. @x '==' y@?
(==!) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a ==! :: Interval r -> Interval r -> Bool
==! Interval r
b = Interval r
a Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
<=! Interval r
b Bool -> Bool -> Bool
&& Interval r
a Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
>=! Interval r
b

-- | For all @x@ in @X@, @y@ in @Y@. @x '/=' y@?
--
-- Since 1.0.1
(/=!) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a /=! :: Interval r -> Interval r -> Bool
/=! Interval r
b = Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r -> Bool) -> Interval r -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r
a Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
b

-- | For all @x@ in @X@, @y@ in @Y@. @x '>=' y@?
(>=!) :: Ord r => Interval r -> Interval r -> Bool
>=! :: Interval r -> Interval r -> Bool
(>=!) = (Interval r -> Interval r -> Bool)
-> Interval r -> Interval r -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
(<=!)

-- | For all @x@ in @X@, @y@ in @Y@. @x '>' y@?
(>!) :: Ord r => Interval r -> Interval r -> Bool
>! :: Interval r -> Interval r -> Bool
(>!) = (Interval r -> Interval r -> Bool)
-> Interval r -> Interval r -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
(<!)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<' y@?
(<?) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a <? :: Interval r -> Interval r -> Bool
<? Interval r
b = Extended r
lb_a Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
< Extended r
ub_b
  where
    lb_a :: Extended r
lb_a = Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
a
    ub_b :: Extended r
ub_b = Interval r -> Extended r
forall r. Interval r -> Extended r
upperBound Interval r
b

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<' y@?
--
-- Since 1.0.0
(<??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
Interval r
a <?? :: Interval r -> Interval r -> Maybe (r, r)
<?? Interval r
b = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
a Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
< Interval r -> Extended r
forall r. Interval r -> Extended r
upperBound Interval r
b
  let c :: Interval r
c = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
a Interval r
b
  case Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval r
c of
    Maybe r
Nothing -> do
      r
x <- Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval r
a
      r
y <- Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval r
b
      (r, r) -> Maybe (r, r)
forall (m :: * -> *) a. Monad m => a -> m a
return (r
x,r
y)
    Just r
z -> do
      let r
x:r
y:[r]
_ = Int -> [r] -> [r]
forall a. Int -> [a] -> [a]
take Int
2 ([r] -> [r]) -> [r] -> [r]
forall a b. (a -> b) -> a -> b
$
                    Maybe r -> [r]
forall a. Maybe a -> [a]
maybeToList (Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup (Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
a (-Extended r
forall r. Extended r
inf Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< r -> Extended r
forall r. r -> Extended r
Finite r
z))) [r] -> [r] -> [r]
forall a. [a] -> [a] -> [a]
++
                    [r
z] [r] -> [r] -> [r]
forall a. [a] -> [a] -> [a]
++
                    Maybe r -> [r]
forall a. Maybe a -> [a]
maybeToList (Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup (Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
b (r -> Extended r
forall r. r -> Extended r
Finite r
z Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
inf)))
      (r, r) -> Maybe (r, r)
forall (m :: * -> *) a. Monad m => a -> m a
return (r
x,r
y)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<=' y@?
(<=?) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a <=? :: Interval r -> Interval r -> Bool
<=? Interval r
b =
  case Extended r
lb_a Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
ub_b of
    Ordering
LT -> Bool
True
    Ordering
GT -> Bool
False
    Ordering
EQ ->
      case Extended r
lb_a of
        Extended r
NegInf -> Bool
False -- b is empty
        Extended r
PosInf -> Bool
False -- a is empty
        Finite r
_ -> Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Closed
  where
    (Extended r
lb_a, Boundary
in1) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a
    (Extended r
ub_b, Boundary
in2) = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '<=' y@?
--
-- Since 1.0.0
(<=??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
Interval r
a <=?? :: Interval r -> Interval r -> Maybe (r, r)
<=?? Interval r
b =
  case Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup (Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
a Interval r
b) of
    Just r
x -> (r, r) -> Maybe (r, r)
forall (m :: * -> *) a. Monad m => a -> m a
return (r
x,r
x)
    Maybe r
Nothing -> do
      Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Interval r -> Extended r
forall r. Interval r -> Extended r
upperBound Interval r
a Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
b
      r
x <- Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval r
a
      r
y <- Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval r
b
      (r, r) -> Maybe (r, r)
forall (m :: * -> *) a. Monad m => a -> m a
return (r
x,r
y)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '==' y@?
--
-- Since 1.0.0
(==?) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a ==? :: Interval r -> Interval r -> Bool
==? Interval r
b = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r -> Bool) -> Interval r -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
a Interval r
b

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '==' y@?
--
-- Since 1.0.0
(==??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
Interval r
a ==?? :: Interval r -> Interval r -> Maybe (r, r)
==?? Interval r
b = do
  r
x <- Interval r -> Maybe r
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup (Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection Interval r
a Interval r
b)
  (r, r) -> Maybe (r, r)
forall (m :: * -> *) a. Monad m => a -> m a
return (r
x,r
x)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '/=' y@?
--
-- Since 1.0.1
(/=?) :: Ord r => Interval r -> Interval r -> Bool
Interval r
a /=? :: Interval r -> Interval r -> Bool
/=? Interval r
b = Bool -> Bool
not (Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a) Bool -> Bool -> Bool
&& Bool -> Bool
not (Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
b) Bool -> Bool -> Bool
&& Bool -> Bool
not (Interval r
a Interval r -> Interval r -> Bool
forall a. Eq a => a -> a -> Bool
== Interval r
b Bool -> Bool -> Bool
&& Interval r -> Bool
forall r. Ord r => Interval r -> Bool
isSingleton Interval r
a)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '/=' y@?
--
-- Since 1.0.1
(/=??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
Interval r
a /=?? :: Interval r -> Interval r -> Maybe (r, r)
/=?? Interval r
b = do
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
b
  Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Interval r
a Interval r -> Interval r -> Bool
forall a. Eq a => a -> a -> Bool
== Interval r
b Bool -> Bool -> Bool
&& Interval r -> Bool
forall r. Ord r => Interval r -> Bool
isSingleton Interval r
a
  if Bool -> Bool
not (Interval r -> Bool
forall r. Ord r => Interval r -> Bool
isSingleton Interval r
b)
    then Interval r -> Interval r -> Maybe (r, r)
forall b.
(Real b, Fractional b) =>
Interval b -> Interval b -> Maybe (b, b)
f Interval r
a Interval r
b
    else ((r, r) -> (r, r)) -> Maybe (r, r) -> Maybe (r, r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (\(r
y,r
x) -> (r
x,r
y)) (Maybe (r, r) -> Maybe (r, r)) -> Maybe (r, r) -> Maybe (r, r)
forall a b. (a -> b) -> a -> b
$ Interval r -> Interval r -> Maybe (r, r)
forall b.
(Real b, Fractional b) =>
Interval b -> Interval b -> Maybe (b, b)
f Interval r
b Interval r
a
  where
    f :: Interval b -> Interval b -> Maybe (b, b)
f Interval b
i Interval b
j = do
      b
x <- Interval b -> Maybe b
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup Interval b
i
      b
y <- [Maybe b] -> Maybe b
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, MonadPlus m) =>
t (m a) -> m a
msum [Interval b -> Maybe b
forall r. (Real r, Fractional r) => Interval r -> Maybe r
pickup (Interval b
j Interval b -> Interval b -> Interval b
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval b
c) | Interval b
c <- [-Extended b
forall r. Extended r
inf Extended b -> Extended b -> Interval b
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< b -> Extended b
forall r. r -> Extended r
Finite b
x, b -> Extended b
forall r. r -> Extended r
Finite b
x Extended b -> Extended b -> Interval b
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended b
forall r. Extended r
inf]]
      (b, b) -> Maybe (b, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b
x,b
y)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>=' y@?
(>=?) :: Ord r => Interval r -> Interval r -> Bool
>=? :: Interval r -> Interval r -> Bool
(>=?) = (Interval r -> Interval r -> Bool)
-> Interval r -> Interval r -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
(<=?)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>' y@?
(>?) :: Ord r => Interval r -> Interval r -> Bool
>? :: Interval r -> Interval r -> Bool
(>?) = (Interval r -> Interval r -> Bool)
-> Interval r -> Interval r -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
(<?)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>=' y@?
--
-- Since 1.0.0
(>=??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
>=?? :: Interval r -> Interval r -> Maybe (r, r)
(>=??) = (Interval r -> Interval r -> Maybe (r, r))
-> Interval r -> Interval r -> Maybe (r, r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Maybe (r, r)
forall b.
(Real b, Fractional b) =>
Interval b -> Interval b -> Maybe (b, b)
(<=??)

-- | Does there exist an @x@ in @X@, @y@ in @Y@ such that @x '>' y@?
--
-- Since 1.0.0
(>??) :: (Real r, Fractional r) => Interval r -> Interval r -> Maybe (r,r)
>?? :: Interval r -> Interval r -> Maybe (r, r)
(>??) = (Interval r -> Interval r -> Maybe (r, r))
-> Interval r -> Interval r -> Maybe (r, r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip Interval r -> Interval r -> Maybe (r, r)
forall b.
(Real b, Fractional b) =>
Interval b -> Interval b -> Maybe (b, b)
(<??)

appPrec :: Int
appPrec :: Int
appPrec = Int
10

rangeOpPrec :: Int
rangeOpPrec :: Int
rangeOpPrec = Int
5

scaleInterval :: (Num r, Ord r) => r -> Interval r -> Interval r
scaleInterval :: r -> Interval r -> Interval r
scaleInterval r
c Interval r
x
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
x = Interval r
forall r. Ord r => Interval r
empty
  | Bool
otherwise = case r -> r -> Ordering
forall a. Ord a => a -> a -> Ordering
compare r
c r
0 of
    Ordering
EQ -> r -> Interval r
forall r. Ord r => r -> Interval r
singleton r
0
    Ordering
LT -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (r -> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' r
c (Extended r, Boundary)
ub) (r -> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' r
c (Extended r, Boundary)
lb)
    Ordering
GT -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (r -> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' r
c (Extended r, Boundary)
lb) (r -> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' r
c (Extended r, Boundary)
ub)
  where
    lb :: (Extended r, Boundary)
lb = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
x
    ub :: (Extended r, Boundary)
ub = Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
x

-- | When results of 'abs' or 'signum' do not form a connected interval,
-- a convex hull is returned instead.
instance (Num r, Ord r) => Num (Interval r) where
  Interval r
a + :: Interval r -> Interval r -> Interval r
+ Interval r
b
    | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a Bool -> Bool -> Bool
|| Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
b = Interval r
forall r. Ord r => Interval r
empty
    | Bool
otherwise = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
(Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
f (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b)) ((Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
Num r =>
(Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
g (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b))
    where
      f :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
f (Finite r
x1, Boundary
in1) (Finite r
x2, Boundary
in2) = (r -> Extended r
forall r. r -> Extended r
Finite (r
x1r -> r -> r
forall a. Num a => a -> a -> a
+r
x2), Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`min` Boundary
in2)
      f (Extended r
NegInf,Boundary
_) (Extended r, Boundary)
_ = (-Extended r
forall r. Extended r
inf, Boundary
Open)
      f (Extended r, Boundary)
_ (Extended r
NegInf,Boundary
_) = (-Extended r
forall r. Extended r
inf, Boundary
Open)
      f (Extended r, Boundary)
_ (Extended r, Boundary)
_ = String -> (Extended r, Boundary)
forall a. (?callStack::CallStack) => String -> a
error String
"Interval.(+) should not happen"

      g :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
g (Finite r
x1, Boundary
in1) (Finite r
x2, Boundary
in2) = (r -> Extended r
forall r. r -> Extended r
Finite (r
x1r -> r -> r
forall a. Num a => a -> a -> a
+r
x2), Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`min` Boundary
in2)
      g (Extended r
PosInf,Boundary
_) (Extended r, Boundary)
_ = (Extended r
forall r. Extended r
inf, Boundary
Open)
      g (Extended r, Boundary)
_ (Extended r
PosInf,Boundary
_) = (Extended r
forall r. Extended r
inf, Boundary
Open)
      g (Extended r, Boundary)
_ (Extended r, Boundary)
_ = String -> (Extended r, Boundary)
forall a. (?callStack::CallStack) => String -> a
error String
"Interval.(+) should not happen"

  negate :: Interval r -> Interval r
negate = r -> Interval r -> Interval r
forall r. (Num r, Ord r) => r -> Interval r -> Interval r
scaleInterval (-r
1)

  fromInteger :: Integer -> Interval r
fromInteger Integer
i = r -> Interval r
forall r. Ord r => r -> Interval r
singleton (Integer -> r
forall a. Num a => Integer -> a
fromInteger Integer
i)

  abs :: Interval r -> Interval r
abs Interval r
x = (Interval r
x Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
nonneg) Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`hull` (Interval r -> Interval r
forall a. Num a => a -> a
negate Interval r
x Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
nonneg)
    where
      nonneg :: Interval r
nonneg = Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..< Extended r
forall r. Extended r
inf

  signum :: Interval r -> Interval r
signum Interval r
x = Interval r
zero Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`hull` Interval r
pos Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`hull` Interval r
neg
    where
      zero :: Interval r
zero = if r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
member r
0 Interval r
x then r -> Interval r
forall r. Ord r => r -> Interval r
singleton r
0 else Interval r
forall r. Ord r => Interval r
empty
      pos :: Interval r
pos = if Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r -> Bool) -> Interval r -> Bool
forall a b. (a -> b) -> a -> b
$ (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
inf) Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
x
            then Interval r
forall r. Ord r => Interval r
empty
            else r -> Interval r
forall r. Ord r => r -> Interval r
singleton r
1
      neg :: Interval r
neg = if Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r -> Bool) -> Interval r -> Bool
forall a b. (a -> b) -> a -> b
$ (-Extended r
forall r. Extended r
inf Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
0) Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
x
            then Interval r
forall r. Ord r => Interval r
empty
            else r -> Interval r
forall r. Ord r => r -> Interval r
singleton (-r
1)

  Interval r
a * :: Interval r -> Interval r -> Interval r
* Interval r
b
    | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a Bool -> Bool -> Bool
|| Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
b = Interval r
forall r. Ord r => Interval r
empty
    | Bool
otherwise = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r, Boundary)
lb3 (Extended r, Boundary)
ub3
    where
      xs :: [(Extended r, Boundary)]
xs = [ (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Num r, Ord r) =>
(Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
mulInf' (Extended r, Boundary)
x1 (Extended r, Boundary)
x2 | (Extended r, Boundary)
x1 <- [Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a, Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a], (Extended r, Boundary)
x2 <- [Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b, Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b] ]
      ub3 :: (Extended r, Boundary)
ub3 = ((Extended r, Boundary) -> (Extended r, Boundary) -> Ordering)
-> [(Extended r, Boundary)] -> (Extended r, Boundary)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpUB [(Extended r, Boundary)]
xs
      lb3 :: (Extended r, Boundary)
lb3 = ((Extended r, Boundary) -> (Extended r, Boundary) -> Ordering)
-> [(Extended r, Boundary)] -> (Extended r, Boundary)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpLB [(Extended r, Boundary)]
xs

-- | 'recip' returns 'whole' when 0 is an interior point.
-- Otherwise @recip (recip xs)@ equals to @xs@ without 0.
instance forall r. (Real r, Fractional r) => Fractional (Interval r) where
  fromRational :: Rational -> Interval r
fromRational Rational
r = r -> Interval r
forall r. Ord r => r -> Interval r
singleton (Rational -> r
forall a. Fractional a => Rational -> a
fromRational Rational
r)
  recip :: Interval r -> Interval r
recip Interval r
a
    | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a = Interval r
forall r. Ord r => Interval r
empty
    | Interval r
a Interval r -> Interval r -> Bool
forall a. Eq a => a -> a -> Bool
== Interval r
0 = Interval r
forall r. Ord r => Interval r
empty
    | r
0 r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
a Bool -> Bool -> Bool
&& Extended r
0 Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
/= Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
a Bool -> Bool -> Bool
&& Extended r
0 Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
/= Interval r -> Extended r
forall r. Interval r -> Extended r
upperBound Interval r
a = Interval r
forall r. Ord r => Interval r
whole
    | Bool
otherwise = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r, Boundary)
lb3 (Extended r, Boundary)
ub3
    where
      ub3 :: (Extended r, Boundary)
ub3 = ((Extended r, Boundary) -> (Extended r, Boundary) -> Ordering)
-> [(Extended r, Boundary)] -> (Extended r, Boundary)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
maximumBy (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpUB [(Extended r, Boundary)]
xs
      lb3 :: (Extended r, Boundary)
lb3 = ((Extended r, Boundary) -> (Extended r, Boundary) -> Ordering)
-> [(Extended r, Boundary)] -> (Extended r, Boundary)
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpLB [(Extended r, Boundary)]
xs
      xs :: [(Extended r, Boundary)]
xs = [(Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Fractional r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
recipLB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a), (Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Fractional r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
recipUB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a)]

-- | When results of 'tan' or '**' do not form a connected interval,
-- a convex hull is returned instead.
instance (RealFrac r, Floating r) => Floating (Interval r) where
  pi :: Interval r
pi = r -> Interval r
forall r. Ord r => r -> Interval r
singleton r
forall a. Floating a => a
pi

  exp :: Interval r -> Interval r
exp = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
PosInf) (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
exp
  log :: Interval r -> Interval r
log Interval r
a = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval ((Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Floating r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
logB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b)) ((Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Floating r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
logB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b))
    where
      b :: Interval r
b = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
PosInf) Interval r
a

  sqrt :: Interval r -> Interval r
sqrt = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
sqrt (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..< Extended r
forall r. Extended r
PosInf)

  Interval r
a ** :: Interval r -> Interval r -> Interval r
** Interval r
b = [Interval r] -> Interval r
forall r. Ord r => [Interval r] -> Interval r
hulls (Interval r
posBase Interval r -> [Interval r] -> [Interval r]
forall a. a -> [a] -> [a]
: Interval r
negBasePosPower Interval r -> [Interval r] -> [Interval r]
forall a. a -> [a] -> [a]
: Interval r
negBaseNegPower Interval r -> [Interval r] -> [Interval r]
forall a. a -> [a] -> [a]
: [Interval r]
zeroPower [Interval r] -> [Interval r] -> [Interval r]
forall a. [a] -> [a] -> [a]
++ [Interval r]
zeroBase)
    where
      posBase :: Interval r
posBase = Interval r -> Interval r
forall a. Floating a => a -> a
exp (Interval r -> Interval r
forall a. Floating a => a -> a
log Interval r
a Interval r -> Interval r -> Interval r
forall a. Num a => a -> a -> a
* Interval r
b)
      zeroPower :: [Interval r]
zeroPower = [ Interval r
1 | r
0 r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
b, Bool -> Bool
not (Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a) ]
      zeroBase :: [Interval r]
zeroBase  = [ Interval r
0 | r
0 r -> Interval r -> Bool
forall r. Ord r => r -> Interval r -> Bool
`member` Interval r
a, Bool -> Bool
not (Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r
b Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
PosInf))) ]
      negBasePosPower :: Interval r
negBasePosPower = Interval r -> Interval r -> Interval r
forall r. RealFrac r => Interval r -> Interval r -> Interval r
positiveIntegralPowersOfNegativeValues
        (Interval r
a Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` (Extended r
forall r. Extended r
NegInf Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
0))
        (Interval r
b Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` (Extended r
0 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
forall r. Extended r
PosInf))
      negBaseNegPower :: Interval r
negBaseNegPower = Interval r -> Interval r -> Interval r
forall r. RealFrac r => Interval r -> Interval r -> Interval r
positiveIntegralPowersOfNegativeValues
        (Interval r -> Interval r
forall a. Fractional a => a -> a
recip  (Interval r
a Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` (Extended r
forall r. Extended r
NegInf Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
0)))
        (Interval r -> Interval r
forall a. Num a => a -> a
negate (Interval r
b Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` (Extended r
forall r. Extended r
NegInf Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
0)))

  cos :: Interval r -> Interval r
cos Interval r
a = case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a of
    (Extended r
NegInf, Boundary
_) -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1
    (Extended r
PosInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
empty
    (Finite r
lb, Boundary
in1) -> case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a of
      (Extended r
NegInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
empty
      (Extended r
PosInf, Boundary
_) -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1
      (Finite r
ub, Boundary
in2)
        | r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Ord a => a -> a -> Bool
> r
2 r -> r -> r
forall a. Num a => a -> a -> a
* r
forall a. Floating a => a
pi                                             -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1
        | Extended r
clb Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
== -Extended r
1 Bool -> Bool -> Bool
&& r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
2 r -> r -> r
forall a. Num a => a -> a -> a
* r
forall a. Floating a => a
pi Bool -> Bool -> Bool
&& Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..<= Extended r
1
        | Extended r
clb Extended r -> Extended r -> Bool
forall a. Eq a => a -> a -> Bool
==  Extended r
1 Bool -> Bool -> Bool
&& r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
2 r -> r -> r
forall a. Num a => a -> a -> a
* r
forall a. Floating a => a
pi Bool -> Bool -> Bool
&& Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..< Extended r
1
        | r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
2 r -> r -> r
forall a. Num a => a -> a -> a
* r
forall a. Floating a => a
pi                                            -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1

        | Bool
lbNorth, Bool
ubNorth, Extended r
clb Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
>= Extended r
cub -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
cub, Boundary
in2) (Extended r
clb, Boundary
in1)
        | Bool
lbNorth, Bool
ubNorth -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1
        | Bool
lbNorth -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (-Extended r
1, Boundary
Closed) ((Extended r, Boundary) -> Interval r)
-> (Extended r, Boundary) -> Interval r
forall a b. (a -> b) -> a -> b
$ case Extended r
clb Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
cub of
          Ordering
LT -> (Extended r
cub, Boundary
in2)
          Ordering
EQ -> (Extended r
cub, Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`max` Boundary
in2)
          Ordering
GT -> (Extended r
clb, Boundary
in1)
        | Bool
ubNorth -> ((Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
`interval` (Extended r
1, Boundary
Closed)) ((Extended r, Boundary) -> Interval r)
-> (Extended r, Boundary) -> Interval r
forall a b. (a -> b) -> a -> b
$ case Extended r
clb Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Extended r
cub of
          Ordering
LT -> (Extended r
clb, Boundary
in1)
          Ordering
EQ -> (Extended r
clb, Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`max` Boundary
in2)
          Ordering
GT -> (Extended r
cub, Boundary
in2)
        | Extended r
clb Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
> Extended r
cub -> -Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1
        | Bool
otherwise -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (Extended r
clb, Boundary
in1) (Extended r
cub, Boundary
in2)
        where
          mod2pi :: a -> a
mod2pi a
x = let y :: a
y = a
x a -> a -> a
forall a. Fractional a => a -> a -> a
/ (a
2 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi) in a
y a -> a -> a
forall a. Num a => a -> a -> a
- Integer -> a
forall a. Num a => Integer -> a
fromInteger (a -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor a
y)
          -- is lower bound in the northern half-plane [0,pi)?
          lbNorth :: Bool
lbNorth = (r -> r
forall a. (RealFrac a, Floating a) => a -> a
mod2pi r
lb, Boundary
in1) (r, Boundary) -> (r, Boundary) -> Bool
forall a. Ord a => a -> a -> Bool
< (r
1 r -> r -> r
forall a. Fractional a => a -> a -> a
/ r
2, Boundary
Closed)
          -- is upper bound in the northern half-plane [0,pi)?
          ubNorth :: Bool
ubNorth = (r -> r
forall a. (RealFrac a, Floating a) => a -> a
mod2pi r
ub, Boundary
in2) (r, Boundary) -> (r, Boundary) -> Bool
forall a. Ord a => a -> a -> Bool
< (r
1 r -> r -> r
forall a. Fractional a => a -> a -> a
/ r
2, Boundary
Closed)
          clb :: Extended r
clb = r -> Extended r
forall r. r -> Extended r
Finite (r -> r
forall a. Floating a => a -> a
cos r
lb)
          cub :: Extended r
cub = r -> Extended r
forall r. r -> Extended r
Finite (r -> r
forall a. Floating a => a -> a
cos r
ub)

  acos :: Interval r -> Interval r
acos = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapAntiMonotonic r -> r
forall a. Floating a => a -> a
acos (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (-Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1)

  sin :: Interval r -> Interval r
sin Interval r
a = Interval r -> Interval r
forall a. Floating a => a -> a
cos (Interval r
forall a. Floating a => a
pi Interval r -> Interval r -> Interval r
forall a. Fractional a => a -> a -> a
/ Interval r
2 Interval r -> Interval r -> Interval r
forall a. Num a => a -> a -> a
- Interval r
a)
  asin :: Interval r -> Interval r
asin = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
asin (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (-Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= Extended r
1)

  tan :: Interval r -> Interval r
tan Interval r
a = case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
a of
    (Extended r
NegInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
whole
    (Extended r
PosInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
empty
    (Finite r
lb, Boundary
in1) -> case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
a of
      (Extended r
NegInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
empty
      (Extended r
PosInf, Boundary
_) -> Interval r
forall r. Ord r => Interval r
whole
      (Finite r
ub, Boundary
in2)
        | r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Ord a => a -> a -> Bool
> r
forall a. Floating a => a
pi -> Interval r
forall r. Ord r => Interval r
whole
        -- the next case corresponds to (tan lb, +inf) + (-inf, tan ub)
        -- with tan lb == tan ub, but a convex hull is returned instead
        | r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
forall a. Floating a => a
pi Bool -> Bool -> Bool
&& Boundary
in1 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open Bool -> Bool -> Bool
&& Boundary
in2 Boundary -> Boundary -> Bool
forall a. Eq a => a -> a -> Bool
== Boundary
Open Bool -> Bool -> Bool
&& r -> r
forall a. (RealFrac a, Floating a) => a -> a
modpi r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
/= r
1r -> r -> r
forall a. Fractional a => a -> a -> a
/r
2 -> Interval r
forall r. Ord r => Interval r
whole
        | r
ub r -> r -> r
forall a. Num a => a -> a -> a
- r
lb r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
forall a. Floating a => a
pi -> Interval r
forall r. Ord r => Interval r
whole
        | r -> r
forall a. Floating a => a -> a
tan r
lb r -> r -> Bool
forall a. Ord a => a -> a -> Bool
<= r -> r
forall a. Floating a => a -> a
tan r
ub -> (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
tan r
lb, Boundary
in1) (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
tan r
ub, Boundary
in2)
        -- the next case corresponds to (tan lb, +inf) + (-inf, tan ub),
        -- but a convex hull is returned instead
        | Bool
otherwise -> Interval r
forall r. Ord r => Interval r
whole
        where
          modpi :: a -> a
modpi a
x = let y :: a
y = a
x a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Floating a => a
pi in a
y a -> a -> a
forall a. Num a => a -> a -> a
- Integer -> a
forall a. Num a => Integer -> a
fromInteger (a -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor a
y)

  atan :: Interval r -> Interval r
atan = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (r -> Extended r
forall r. r -> Extended r
Finite (-r
forall a. Floating a => a
pi r -> r -> r
forall a. Fractional a => a -> a -> a
/ r
2) Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..<= r -> Extended r
forall r. r -> Extended r
Finite (r
forall a. Floating a => a
pi r -> r -> r
forall a. Fractional a => a -> a -> a
/ r
2)) (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
atan

  sinh :: Interval r -> Interval r
sinh  = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
sinh
  asinh :: Interval r -> Interval r
asinh = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
asinh

  cosh :: Interval r -> Interval r
cosh  = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
cosh (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Interval r
forall a. Num a => a -> a
abs
  acosh :: Interval r -> Interval r
acosh = (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
acosh (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<=..< Extended r
forall r. Extended r
PosInf)

  tanh :: Interval r -> Interval r
tanh  = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (-Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
1) (Interval r -> Interval r)
-> (Interval r -> Interval r) -> Interval r -> Interval r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> r) -> Interval r -> Interval r
forall a b. (Ord a, Ord b) => (a -> b) -> Interval a -> Interval b
mapMonotonic r -> r
forall a. Floating a => a -> a
tanh
  atanh :: Interval r -> Interval r
atanh Interval r
a = (Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Interval r
interval ((Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Floating r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
atanhB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b)) ((Extended r, Boundary) -> (Extended r, Boundary)
forall r.
(Floating r, Ord r) =>
(Extended r, Boundary) -> (Extended r, Boundary)
atanhB (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b))
    where
      b :: Interval r
b = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
intersection (-Extended r
1 Extended r -> Extended r -> Interval r
forall r. Ord r => Extended r -> Extended r -> Interval r
<..< Extended r
1) Interval r
a

positiveIntegralPowersOfNegativeValues
  :: RealFrac r => Interval r -> Interval r -> Interval r
positiveIntegralPowersOfNegativeValues :: Interval r -> Interval r -> Interval r
positiveIntegralPowersOfNegativeValues Interval r
a Interval r
b
  | Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
a Bool -> Bool -> Bool
|| Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null Interval r
b         = Interval r
forall r. Ord r => Interval r
empty
  | Just Integer
ub <- Maybe Integer
mub, Integer
lb Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
ub  = Interval r
forall r. Ord r => Interval r
empty
  | Just Integer
ub <- Maybe Integer
mub, Integer
lb Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
ub = Interval r
a Interval r -> Integer -> Interval r
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
lb
  -- cases below connects two intervals (a ^ k, 0) + (0, a ^ k'))
  -- into a single convex hull
  | Interval r -> Extended r
forall r. Interval r -> Extended r
lowerBound Interval r
a Extended r -> Extended r -> Bool
forall a. Ord a => a -> a -> Bool
>= -Extended r
1       = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
hull (Interval r
a Interval r -> Integer -> Interval r
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
lb) (Interval r
a Interval r -> Integer -> Interval r
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
lb Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1))
  | Just Integer
ub <- Maybe Integer
mub           = Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
hull (Interval r
a Interval r -> Integer -> Interval r
forall a b. (Num a, Integral b) => a -> b -> a
^ Integer
ub) (Interval r
a Interval r -> Integer -> Interval r
forall a b. (Num a, Integral b) => a -> b -> a
^ (Integer
ub Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1))
  | Maybe Integer
Nothing <- Maybe Integer
mub           = Interval r
forall r. Ord r => Interval r
whole
  where
    -- Similar to Data.IntegerInterval.fromIntervalUnder
    lb :: Integer
    lb :: Integer
lb = case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
b of
      (Finite r
x, Boundary
Open)
        | Integer -> r
forall a. Num a => Integer -> a
fromInteger (r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling r
x) r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
x
        -> r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling r
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1
      (Finite r
x, Boundary
_) -> r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
ceiling r
x
      (Extended r, Boundary)
_ -> Integer
0 -- PosInf is not expected, because b is not null
    mub :: Maybe Integer
    mub :: Maybe Integer
mub = case Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
b of
      (Finite r
x, Boundary
Open)
        | Integer -> r
forall a. Num a => Integer -> a
fromInteger (r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor r
x) r -> r -> Bool
forall a. Eq a => a -> a -> Bool
== r
x
        -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor r
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1
      (Finite r
x, Boundary
_) -> Integer -> Maybe Integer
forall a. a -> Maybe a
Just (Integer -> Maybe Integer) -> Integer -> Maybe Integer
forall a b. (a -> b) -> a -> b
$ r -> Integer
forall a b. (RealFrac a, Integral b) => a -> b
floor r
x
      (Extended r, Boundary)
_ -> Maybe Integer
forall a. Maybe a
Nothing -- NegInf is not expected, because b is not null

cmpUB, cmpLB :: Ord r => (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpUB :: (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpUB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) = Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Extended r
x1 Extended r
x2 Ordering -> Ordering -> Ordering
forall a. Monoid a => a -> a -> a
`mappend` Boundary -> Boundary -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Boundary
in1 Boundary
in2
cmpLB :: (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
cmpLB (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) = Extended r -> Extended r -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Extended r
x1 Extended r
x2 Ordering -> Ordering -> Ordering
forall a. Monoid a => a -> a -> a
`mappend` Boundary -> Boundary -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Boundary
in2 Boundary
in1

scaleInf' :: (Num r, Ord r) => r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' :: r -> (Extended r, Boundary) -> (Extended r, Boundary)
scaleInf' r
a (Extended r
x1, Boundary
in1) = (r -> Extended r -> Extended r
forall r. (Num r, Ord r) => r -> Extended r -> Extended r
scaleEndPoint r
a Extended r
x1, Boundary
in1)

scaleEndPoint :: (Num r, Ord r) => r -> Extended r -> Extended r
scaleEndPoint :: r -> Extended r -> Extended r
scaleEndPoint r
a Extended r
e =
  case r
a r -> r -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` r
0 of
    Ordering
EQ -> Extended r
0
    Ordering
GT ->
      case Extended r
e of
        Extended r
NegInf   -> Extended r
forall r. Extended r
NegInf
        Finite r
b -> r -> Extended r
forall r. r -> Extended r
Finite (r
ar -> r -> r
forall a. Num a => a -> a -> a
*r
b)
        Extended r
PosInf   -> Extended r
forall r. Extended r
PosInf
    Ordering
LT ->
      case Extended r
e of
        Extended r
NegInf   -> Extended r
forall r. Extended r
PosInf
        Finite r
b -> r -> Extended r
forall r. r -> Extended r
Finite (r
ar -> r -> r
forall a. Num a => a -> a -> a
*r
b)
        Extended r
PosInf   -> Extended r
forall r. Extended r
NegInf

mulInf' :: (Num r, Ord r) => (Extended r, Boundary) -> (Extended r, Boundary) -> (Extended r, Boundary)
mulInf' :: (Extended r, Boundary)
-> (Extended r, Boundary) -> (Extended r, Boundary)
mulInf' (Extended r
0, Boundary
Closed) (Extended r, Boundary)
_ = (Extended r
0, Boundary
Closed)
mulInf' (Extended r, Boundary)
_ (Extended r
0, Boundary
Closed) = (Extended r
0, Boundary
Closed)
mulInf' (Extended r
x1,Boundary
in1) (Extended r
x2,Boundary
in2) = (Extended r
x1Extended r -> Extended r -> Extended r
forall a. Num a => a -> a -> a
*Extended r
x2, Boundary
in1 Boundary -> Boundary -> Boundary
forall a. Ord a => a -> a -> a
`min` Boundary
in2)

recipLB :: (Fractional r, Ord r) => (Extended r, Boundary) -> (Extended r, Boundary)
recipLB :: (Extended r, Boundary) -> (Extended r, Boundary)
recipLB (Extended r
0, Boundary
_) = (Extended r
forall r. Extended r
PosInf, Boundary
Open)
recipLB (Extended r
x1, Boundary
in1) = (Extended r -> Extended r
forall a. Fractional a => a -> a
recip Extended r
x1, Boundary
in1)

recipUB :: (Fractional r, Ord r) => (Extended r, Boundary) -> (Extended r, Boundary)
recipUB :: (Extended r, Boundary) -> (Extended r, Boundary)
recipUB (Extended r
0, Boundary
_) = (Extended r
forall r. Extended r
NegInf, Boundary
Open)
recipUB (Extended r
x1, Boundary
in1) = (Extended r -> Extended r
forall a. Fractional a => a -> a
recip Extended r
x1, Boundary
in1)

logB :: (Floating r, Ord r) => (Extended r, Boundary) -> (Extended r, Boundary)
logB :: (Extended r, Boundary) -> (Extended r, Boundary)
logB (Extended r
NegInf, Boundary
in1) = (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
log (r -> r
forall a. Floating a => a -> a
log r
0), Boundary
in1)
logB (Finite r
0, Boundary
_) = (Extended r
forall r. Extended r
NegInf, Boundary
Open)
logB (Finite r
x1, Boundary
in1) = (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
log r
x1, Boundary
in1)
logB (Extended r
PosInf, Boundary
in1) = (Extended r
forall r. Extended r
PosInf, Boundary
in1)

atanhB :: (Floating r, Ord r) => (Extended r, Boundary) -> (Extended r, Boundary)
atanhB :: (Extended r, Boundary) -> (Extended r, Boundary)
atanhB (Extended r
NegInf, Boundary
in1) = (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
atanh (-r
1r -> r -> r
forall a. Fractional a => a -> a -> a
/r
0), Boundary
in1)
atanhB (Finite (-1), Boundary
_) = (Extended r
forall r. Extended r
NegInf, Boundary
Open)
atanhB (Finite r
1, Boundary
_) = (Extended r
forall r. Extended r
PosInf, Boundary
Open)
atanhB (Finite r
x1, Boundary
in1) = (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
atanh r
x1, Boundary
in1)
atanhB (Extended r
PosInf, Boundary
in1) = (r -> Extended r
forall r. r -> Extended r
Finite (r -> Extended r) -> r -> Extended r
forall a b. (a -> b) -> a -> b
$ r -> r
forall a. Floating a => a -> a
atanh (r
1r -> r -> r
forall a. Fractional a => a -> a -> a
/r
0), Boundary
in1)

-- | Computes how two intervals are related according to the @`Data.IntervalRelation.Relation`@ classification
relate :: Ord r => Interval r -> Interval r -> Relation
relate :: Interval r -> Interval r -> Relation
relate Interval r
i1 Interval r
i2 =
  case (Interval r
i1 Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
`isSubsetOf` Interval r
i2, Interval r
i2 Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
`isSubsetOf` Interval r
i1) of
    -- 'i1' ad 'i2' are equal
    (Bool
True , Bool
True ) -> Relation
Equal
    -- 'i1' is strictly contained in `i2`
    (Bool
True , Bool
False) | (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i2) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ -> Relation
Starts
                   | (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ -> Relation
Finishes
                   | Bool
otherwise                                            -> Relation
During
    -- 'i2' is strictly contained in `i1`
    (Bool
False, Bool
True ) | (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
lowerBound' Interval r
i2) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ -> Relation
StartedBy
                   | (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2) Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ -> Relation
FinishedBy
                   | Bool
otherwise                                            -> Relation
Contains
    -- neither `i1` nor `i2` is contained in the other
    (Bool
False, Bool
False) -> case ( Interval r -> Bool
forall r. Ord r => Interval r -> Bool
null (Interval r
i1 Interval r -> Interval r -> Interval r
forall r. Ord r => Interval r -> Interval r -> Interval r
`intersection` Interval r
i2)
                           , (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall r.
Ord r =>
(Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i1) (Interval r -> (Extended r, Boundary)
forall r. Interval r -> (Extended r, Boundary)
upperBound' Interval r
i2) Ordering -> Ordering -> Bool
forall a. Ord a => a -> a -> Bool
<= Ordering
EQ
                           , Interval r
i1 Interval r -> Interval r -> Bool
forall r. Ord r => Interval r -> Interval r -> Bool
`isConnected` Interval r
i2
                           ) of
      (Bool
True , Bool
True , Bool
True ) -> Relation
JustBefore
      (Bool
True , Bool
True , Bool
False) -> Relation
Before
      (Bool
True , Bool
False, Bool
True ) -> Relation
JustAfter
      (Bool
True , Bool
False, Bool
False) -> Relation
After
      (Bool
False, Bool
True , Bool
_    ) -> Relation
Overlaps
      (Bool
False, Bool
False, Bool
_    ) -> Relation
OverlappedBy
  where
    compareBound :: Ord r => (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
    compareBound :: (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
compareBound (Extended r
PosInf, Boundary
_) (Extended r
PosInf, Boundary
_) = Ordering
EQ
    compareBound (Extended r
PosInf, Boundary
_) (Extended r, Boundary)
_           = Ordering
GT
    compareBound (Extended r
NegInf, Boundary
_) (Extended r
NegInf, Boundary
_) = Ordering
EQ
    compareBound (Extended r
NegInf, Boundary
_) (Extended r, Boundary)
_           = Ordering
LT
    compareBound (Extended r, Boundary)
a           (Extended r, Boundary)
b           = (Extended r, Boundary) -> (Extended r, Boundary) -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Extended r, Boundary)
a (Extended r, Boundary)
b