{-# LANGUAGE GADTs               #-}
{-# LANGUAGE MagicHash           #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | See: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
module Data.Double.Approximate
  ( SafeDouble
  , DoubleRelAbs(..)
  ) where

import Control.DeepSeq
import Data.Proxy
import GHC.TypeLits
import Numeric.MathFunctions.Comparison
import Numeric.MathFunctions.Constants
import System.Random
import Text.Read

-- | Relatively safe double floating-point type with a relative error
--   margin of 10 <https://en.wikipedia.org/wiki/Unit_in_the_last_place ULPs>
--   and an absolute margin around zero of
--   @10*<https://en.wikipedia.org/wiki/Machine_epsilon epsilon>@.
--
--   Warning: All numbers within
--   @10*<https://en.wikipedia.org/wiki/Machine_epsilon epsilon>@ of zero will be considered zero.
--
-- >>> m_epsilon * 10
-- 2.220446049250313e-15
--
-- >>> realToFrac (m_epsilon * 10) == (0::SafeDouble)
-- False
--
-- >>> realToFrac (m_epsilon * 9) == (0::SafeDouble)
-- True
--
-- >>> 1e-20 == (5e-20 :: Double)
-- False
-- >>> 1e-20 == (5e-20 :: SafeDouble)
-- True
--
-- 'pi' and 'sin' are approximations:
--
-- >>> sin pi
-- 1.2246467991473532e-16
--
-- >>> sin pi == (0 :: Double)
-- False
--
-- >>> sin pi == (0 :: SafeDouble)
-- True
--
type SafeDouble = DoubleRelAbs 10 10

-- | Custom double floating-point type with a relative error margin of
--   @rel@ number of
--   <https://en.wikipedia.org/wiki/Unit_in_the_last_place ULPs> and an
--   absolute error margin of @abs@ times
--   <https://en.wikipedia.org/wiki/Machine_epsilon epsilon>.
--
--   The relative error margin is the primary tool for good numerical
--   robustness and can relatively safely be set to a high number such
--   as 100. The absolute error margin is a last ditch attempt at fixing
--   broken algorithms and dramatically limits the resolution around zero.
--   If possible, use a low absolute error margin.
newtype DoubleRelAbs (abs :: Nat) (rel :: Nat) = DoubleRelAbs Double
  deriving (Integer -> DoubleRelAbs abs rel
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
(DoubleRelAbs abs rel
 -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (Integer -> DoubleRelAbs abs rel)
-> Num (DoubleRelAbs abs rel)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall (abs :: Nat) (rel :: Nat). Integer -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
fromInteger :: Integer -> DoubleRelAbs abs rel
$cfromInteger :: forall (abs :: Nat) (rel :: Nat). Integer -> DoubleRelAbs abs rel
signum :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csignum :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
abs :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cabs :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
negate :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cnegate :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
* :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$c* :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
- :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$c- :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
+ :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$c+ :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
Num, Int -> DoubleRelAbs abs rel
DoubleRelAbs abs rel -> Int
DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> [DoubleRelAbs abs rel]
(DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (Int -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> Int)
-> (DoubleRelAbs abs rel -> [DoubleRelAbs abs rel])
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel])
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel])
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel
    -> [DoubleRelAbs abs rel])
-> Enum (DoubleRelAbs abs rel)
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
forall (abs :: Nat) (rel :: Nat). Int -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel -> Int
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> [DoubleRelAbs abs rel]
enumFromThenTo :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> [DoubleRelAbs abs rel]
$cenumFromThenTo :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> DoubleRelAbs abs rel
-> [DoubleRelAbs abs rel]
enumFromTo :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
$cenumFromTo :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
enumFromThen :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
$cenumFromThen :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
enumFrom :: DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
$cenumFrom :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> [DoubleRelAbs abs rel]
fromEnum :: DoubleRelAbs abs rel -> Int
$cfromEnum :: forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel -> Int
toEnum :: Int -> DoubleRelAbs abs rel
$ctoEnum :: forall (abs :: Nat) (rel :: Nat). Int -> DoubleRelAbs abs rel
pred :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cpred :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
succ :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csucc :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
Enum, Fractional (DoubleRelAbs abs rel)
DoubleRelAbs abs rel
Fractional (DoubleRelAbs abs rel)
-> DoubleRelAbs abs rel
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> Floating (DoubleRelAbs abs rel)
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall a.
Fractional a
-> a
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> Floating a
forall (abs :: Nat) (rel :: Nat). Fractional (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
log1mexp :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$clog1mexp :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
log1pexp :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$clog1pexp :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
expm1 :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cexpm1 :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
log1p :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$clog1p :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
atanh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$catanh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
acosh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cacosh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
asinh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$casinh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
tanh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$ctanh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
cosh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$ccosh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
sinh :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csinh :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
atan :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$catan :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
acos :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cacos :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
asin :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$casin :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
tan :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$ctan :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
cos :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$ccos :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
sin :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csin :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
logBase :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$clogBase :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
** :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$c** :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
sqrt :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csqrt :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
log :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$clog :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
exp :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cexp :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
pi :: DoubleRelAbs abs rel
$cpi :: forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel
$cp1Floating :: forall (abs :: Nat) (rel :: Nat). Fractional (DoubleRelAbs abs rel)
Floating, Num (DoubleRelAbs abs rel)
Num (DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (Rational -> DoubleRelAbs abs rel)
-> Fractional (DoubleRelAbs abs rel)
Rational -> DoubleRelAbs abs rel
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall a.
Num a
-> (a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
forall (abs :: Nat) (rel :: Nat). Num (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat). Rational -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
fromRational :: Rational -> DoubleRelAbs abs rel
$cfromRational :: forall (abs :: Nat) (rel :: Nat). Rational -> DoubleRelAbs abs rel
recip :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$crecip :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
/ :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$c/ :: forall (abs :: Nat) (rel :: Nat).
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cp1Fractional :: forall (abs :: Nat) (rel :: Nat). Num (DoubleRelAbs abs rel)
Fractional, Num (DoubleRelAbs abs rel)
Ord (DoubleRelAbs abs rel)
Num (DoubleRelAbs abs rel)
-> Ord (DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> Rational)
-> Real (DoubleRelAbs abs rel)
DoubleRelAbs abs rel -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Num (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Ord (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Rational
toRational :: DoubleRelAbs abs rel -> Rational
$ctoRational :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Rational
$cp2Real :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Ord (DoubleRelAbs abs rel)
$cp1Real :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Num (DoubleRelAbs abs rel)
Real, Floating (DoubleRelAbs abs rel)
RealFrac (DoubleRelAbs abs rel)
RealFrac (DoubleRelAbs abs rel)
-> Floating (DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> Integer)
-> (DoubleRelAbs abs rel -> Int)
-> (DoubleRelAbs abs rel -> (Int, Int))
-> (DoubleRelAbs abs rel -> (Integer, Int))
-> (Integer -> Int -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> Int)
-> (DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (Int -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> (DoubleRelAbs abs rel -> Bool)
-> (DoubleRelAbs abs rel -> Bool)
-> (DoubleRelAbs abs rel -> Bool)
-> (DoubleRelAbs abs rel -> Bool)
-> (DoubleRelAbs abs rel -> Bool)
-> (DoubleRelAbs abs rel
    -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel)
-> RealFloat (DoubleRelAbs abs rel)
Int -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
Integer -> Int -> DoubleRelAbs abs rel
DoubleRelAbs abs rel -> Bool
DoubleRelAbs abs rel -> Int
DoubleRelAbs abs rel -> Integer
DoubleRelAbs abs rel -> (Int, Int)
DoubleRelAbs abs rel -> (Integer, Int)
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall a.
RealFrac a
-> Floating a
-> (a -> Integer)
-> (a -> Int)
-> (a -> (Int, Int))
-> (a -> (Integer, Int))
-> (Integer -> Int -> a)
-> (a -> Int)
-> (a -> a)
-> (Int -> a -> a)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> Bool)
-> (a -> a -> a)
-> RealFloat a
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Floating (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
RealFrac (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Int -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Integer -> Int -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Int
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Integer
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> (Int, Int)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> (Integer, Int)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
atan2 :: DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$catan2 :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel
-> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
isIEEE :: DoubleRelAbs abs rel -> Bool
$cisIEEE :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
isNegativeZero :: DoubleRelAbs abs rel -> Bool
$cisNegativeZero :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
isDenormalized :: DoubleRelAbs abs rel -> Bool
$cisDenormalized :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
isInfinite :: DoubleRelAbs abs rel -> Bool
$cisInfinite :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
isNaN :: DoubleRelAbs abs rel -> Bool
$cisNaN :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Bool
scaleFloat :: Int -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$cscaleFloat :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Int -> DoubleRelAbs abs rel -> DoubleRelAbs abs rel
significand :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel
$csignificand :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> DoubleRelAbs abs rel
exponent :: DoubleRelAbs abs rel -> Int
$cexponent :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Int
encodeFloat :: Integer -> Int -> DoubleRelAbs abs rel
$cencodeFloat :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Integer -> Int -> DoubleRelAbs abs rel
decodeFloat :: DoubleRelAbs abs rel -> (Integer, Int)
$cdecodeFloat :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> (Integer, Int)
floatRange :: DoubleRelAbs abs rel -> (Int, Int)
$cfloatRange :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> (Int, Int)
floatDigits :: DoubleRelAbs abs rel -> Int
$cfloatDigits :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Int
floatRadix :: DoubleRelAbs abs rel -> Integer
$cfloatRadix :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
DoubleRelAbs abs rel -> Integer
$cp2RealFloat :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Floating (DoubleRelAbs abs rel)
$cp1RealFloat :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
RealFrac (DoubleRelAbs abs rel)
RealFloat, Fractional (DoubleRelAbs abs rel)
Real (DoubleRelAbs abs rel)
Real (DoubleRelAbs abs rel)
-> Fractional (DoubleRelAbs abs rel)
-> (forall b.
    Integral b =>
    DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel))
-> (forall b. Integral b => DoubleRelAbs abs rel -> b)
-> (forall b. Integral b => DoubleRelAbs abs rel -> b)
-> (forall b. Integral b => DoubleRelAbs abs rel -> b)
-> (forall b. Integral b => DoubleRelAbs abs rel -> b)
-> RealFrac (DoubleRelAbs abs rel)
DoubleRelAbs abs rel -> b
DoubleRelAbs abs rel -> b
DoubleRelAbs abs rel -> b
DoubleRelAbs abs rel -> b
DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel)
forall b. Integral b => DoubleRelAbs abs rel -> b
forall b.
Integral b =>
DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel)
forall a.
Real a
-> Fractional a
-> (forall b. Integral b => a -> (b, a))
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> (forall b. Integral b => a -> b)
-> RealFrac a
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Fractional (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Real (DoubleRelAbs abs rel)
forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> b
forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel)
floor :: DoubleRelAbs abs rel -> b
$cfloor :: forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> b
ceiling :: DoubleRelAbs abs rel -> b
$cceiling :: forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> b
round :: DoubleRelAbs abs rel -> b
$cround :: forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> b
truncate :: DoubleRelAbs abs rel -> b
$ctruncate :: forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> b
properFraction :: DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel)
$cproperFraction :: forall (abs :: Nat) (rel :: Nat) b.
(KnownNat abs, KnownNat rel, Integral b) =>
DoubleRelAbs abs rel -> (b, DoubleRelAbs abs rel)
$cp2RealFrac :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Fractional (DoubleRelAbs abs rel)
$cp1RealFrac :: forall (abs :: Nat) (rel :: Nat).
(KnownNat abs, KnownNat rel) =>
Real (DoubleRelAbs abs rel)
RealFrac, g -> (DoubleRelAbs abs rel, g)
g -> [DoubleRelAbs abs rel]
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> (DoubleRelAbs abs rel, g)
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> [DoubleRelAbs abs rel]
(forall g.
 RandomGen g =>
 (DoubleRelAbs abs rel, DoubleRelAbs abs rel)
 -> g -> (DoubleRelAbs abs rel, g))
-> (forall g. RandomGen g => g -> (DoubleRelAbs abs rel, g))
-> (forall g.
    RandomGen g =>
    (DoubleRelAbs abs rel, DoubleRelAbs abs rel)
    -> g -> [DoubleRelAbs abs rel])
-> (forall g. RandomGen g => g -> [DoubleRelAbs abs rel])
-> Random (DoubleRelAbs abs rel)
forall g. RandomGen g => g -> [DoubleRelAbs abs rel]
forall g. RandomGen g => g -> (DoubleRelAbs abs rel, g)
forall g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> [DoubleRelAbs abs rel]
forall g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> (DoubleRelAbs abs rel, g)
forall a.
(forall g. RandomGen g => (a, a) -> g -> (a, g))
-> (forall g. RandomGen g => g -> (a, g))
-> (forall g. RandomGen g => (a, a) -> g -> [a])
-> (forall g. RandomGen g => g -> [a])
-> Random a
forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
g -> [DoubleRelAbs abs rel]
forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
g -> (DoubleRelAbs abs rel, g)
forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> [DoubleRelAbs abs rel]
forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> (DoubleRelAbs abs rel, g)
randoms :: g -> [DoubleRelAbs abs rel]
$crandoms :: forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
g -> [DoubleRelAbs abs rel]
randomRs :: (DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> [DoubleRelAbs abs rel]
$crandomRs :: forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> [DoubleRelAbs abs rel]
random :: g -> (DoubleRelAbs abs rel, g)
$crandom :: forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
g -> (DoubleRelAbs abs rel, g)
randomR :: (DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> (DoubleRelAbs abs rel, g)
$crandomR :: forall (abs :: Nat) (rel :: Nat) g.
RandomGen g =>
(DoubleRelAbs abs rel, DoubleRelAbs abs rel)
-> g -> (DoubleRelAbs abs rel, g)
Random, DoubleRelAbs abs rel -> ()
(DoubleRelAbs abs rel -> ()) -> NFData (DoubleRelAbs abs rel)
forall a. (a -> ()) -> NFData a
forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel -> ()
rnf :: DoubleRelAbs abs rel -> ()
$crnf :: forall (abs :: Nat) (rel :: Nat). DoubleRelAbs abs rel -> ()
NFData)

instance (KnownNat abs, KnownNat rel) => Eq (DoubleRelAbs abs rel) where
  DoubleRelAbs Double
d1 == :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel -> Bool
== DoubleRelAbs Double
d2 =
    Int -> Double -> Double -> Bool
within (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy rel -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal @rel Proxy rel
forall k (t :: k). Proxy t
Proxy)) Double
d1 Double
d2 Bool -> Bool -> Bool
||
    (Double -> Double
forall a. Num a => a -> a
abs Double
d1 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
m_epsilon Double -> Double -> Double
forall a. Num a => a -> a -> a
* Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy abs -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal @abs Proxy abs
forall k (t :: k). Proxy t
Proxy) Bool -> Bool -> Bool
&&
     Double -> Double
forall a. Num a => a -> a
abs Double
d2 Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
m_epsilon Double -> Double -> Double
forall a. Num a => a -> a -> a
* Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy abs -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal @abs Proxy abs
forall k (t :: k). Proxy t
Proxy))

instance (KnownNat abs, KnownNat rel) => Ord (DoubleRelAbs abs rel) where
  lhs :: DoubleRelAbs abs rel
lhs@(DoubleRelAbs Double
d1) compare :: DoubleRelAbs abs rel -> DoubleRelAbs abs rel -> Ordering
`compare` rhs :: DoubleRelAbs abs rel
rhs@(DoubleRelAbs Double
d2)
    | DoubleRelAbs abs rel
lhs DoubleRelAbs abs rel -> DoubleRelAbs abs rel -> Bool
forall a. Eq a => a -> a -> Bool
== DoubleRelAbs abs rel
rhs = Ordering
EQ
    | Bool
otherwise  = Double
d1 Double -> Double -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Double
d2

instance Show (DoubleRelAbs abs rel) where
  showsPrec :: Int -> DoubleRelAbs abs rel -> ShowS
showsPrec Int
i (DoubleRelAbs Double
d) = Int -> Double -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
i Double
d

instance Read (DoubleRelAbs abs rel) where
  readPrec :: ReadPrec (DoubleRelAbs abs rel)
readPrec = Double -> DoubleRelAbs abs rel
forall (abs :: Nat) (rel :: Nat). Double -> DoubleRelAbs abs rel
DoubleRelAbs (Double -> DoubleRelAbs abs rel)
-> ReadPrec Double -> ReadPrec (DoubleRelAbs abs rel)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadPrec Double
forall a. Read a => ReadPrec a
readPrec