{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_GHC -Wall #-}
module NumHask.Analysis.Metric
( Signed (..),
Normed (..),
Metric (..),
Epsilon (..),
(~=),
)
where
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Natural (Natural (..))
import NumHask.Algebra.Abstract.Additive
import NumHask.Algebra.Abstract.Lattice
import NumHask.Algebra.Abstract.Multiplicative
import Prelude hiding
( (-),
Bounded (..),
Integral (..),
negate,
)
import qualified Prelude as P
class
(Multiplicative a) =>
Signed a where
sign :: a -> a
abs :: a -> a
instance Signed Double where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Float where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Int where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Integer where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Natural where
sign a
| a == zero = zero
| otherwise = one
abs = id
instance Signed Int8 where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Int16 where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Int32 where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Int64 where
sign a
| a == zero = zero
| a > zero = one
| otherwise = negate one
abs = P.abs
instance Signed Word where
sign a
| a == zero = zero
| otherwise = one
abs = P.abs
instance Signed Word8 where
sign a
| a == zero = zero
| otherwise = one
abs = P.abs
instance Signed Word16 where
sign a
| a == zero = zero
| otherwise = one
abs = P.abs
instance Signed Word32 where
sign a
| a == zero = zero
| otherwise = one
abs = P.abs
instance Signed Word64 where
sign a
| a == zero = zero
| otherwise = one
abs = P.abs
class (Additive a, Additive b) => Normed a b where
norm :: a -> b
instance Normed Double Double where
norm = P.abs
instance Normed Float Float where
norm = P.abs
instance Normed Int Int where
norm = P.abs
instance Normed Integer Integer where
norm = P.abs
instance Normed Natural Natural where
norm = P.abs
instance Normed Int8 Int8 where
norm = P.abs
instance Normed Int16 Int16 where
norm = P.abs
instance Normed Int32 Int32 where
norm = P.abs
instance Normed Int64 Int64 where
norm = P.abs
instance Normed Word Word where
norm = P.abs
instance Normed Word8 Word8 where
norm = P.abs
instance Normed Word16 Word16 where
norm = P.abs
instance Normed Word32 Word32 where
norm = P.abs
instance Normed Word64 Word64 where
norm = P.abs
class Metric a b where
distance :: a -> a -> b
instance Metric Double Double where
distance a b = norm (a - b)
instance Metric Float Float where
distance a b = norm (a - b)
instance Metric Int Int where
distance a b = norm (a - b)
instance Metric Integer Integer where
distance a b = norm (a - b)
instance Metric Natural Natural where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
instance Metric Int8 Int8 where
distance a b = norm (a - b)
instance Metric Int16 Int16 where
distance a b = norm (a - b)
instance Metric Int32 Int32 where
distance a b = norm (a - b)
instance Metric Int64 Int64 where
distance a b = norm (a - b)
instance Metric Word Word where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
instance Metric Word8 Word8 where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
instance Metric Word16 Word16 where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
instance Metric Word32 Word32 where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
instance Metric Word64 Word64 where
distance a b = P.fromInteger $ norm (P.toInteger a - P.toInteger b)
class
(Eq a, Additive a, Subtractive a, MeetSemiLattice a) =>
Epsilon a where
epsilon :: a
epsilon = zero
nearZero :: a -> Bool
nearZero a = epsilon `meetLeq` a && epsilon `meetLeq` negate a
aboutEqual :: a -> a -> Bool
aboutEqual a b = nearZero $ a - b
infixl 4 ~=
(~=) :: (Epsilon a) => a -> a -> Bool
(~=) = aboutEqual
instance Epsilon Double where
epsilon = 1e-14
instance Epsilon Float where
epsilon = 1e-6
instance Epsilon Int
instance Epsilon Integer
instance Epsilon Int8
instance Epsilon Int16
instance Epsilon Int32
instance Epsilon Int64
instance Epsilon Word
instance Epsilon Word8
instance Epsilon Word16
instance Epsilon Word32
instance Epsilon Word64