module Numeric.Eps where
-- * Numerical tolerance for "near-0" tests
-- | eps = 1e-8
eps :: Double
eps = 1e-8
-- * Rounding operations
-- | Rounding rule
almostZero, almostOne :: Double -> Bool
almostZero x = abs x <= eps
almostOne x = x >= (1-eps) && x < (1+eps)
isNz :: Double -> Bool
isNz = not . almostZero
withDefault :: (t -> Bool) -> t -> t -> t
withDefault q d x | q x = d
| otherwise = x
roundZero, roundOne :: Double -> Double
roundZero = withDefault almostZero 0
roundOne = withDefault almostOne 1
with2Defaults :: (t -> Bool) -> (t -> Bool) -> t -> t -> t -> t
with2Defaults q1 q2 d1 d2 x | q1 x = d1
| q2 x = d2
| otherwise = x
-- | Round to respectively 0 or 1 within some predefined numerical precision eps
roundZeroOne :: Double -> Double
roundZeroOne = with2Defaults almostZero almostOne 0 1