{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# OPTIONS_GHC -Wall #-}
module NumHask.Analysis.Metric
( Signed (..),
Norm (..),
distance,
Direction (..),
Polar (..),
polar,
coord,
Epsilon (..),
(~=),
)
where
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Generics (Generic)
import GHC.Natural (Natural (..))
import NumHask.Algebra.Additive
import NumHask.Algebra.Lattice
import NumHask.Algebra.Module
import NumHask.Algebra.Multiplicative
import Prelude hiding
( (*),
(-),
Bounded (..),
Integral (..),
negate,
)
import qualified Prelude as P
class
(Additive a, Multiplicative a) =>
Signed a where
sign :: a -> a
abs :: a -> a
instance Signed Double where
sign :: Double -> Double
sign Double
a
| Double
a Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
forall a. Additive a => a
zero = Double
forall a. Additive a => a
zero
| Double
a Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
forall a. Additive a => a
zero = Double
forall a. Multiplicative a => a
one
| Bool
otherwise = Double -> Double
forall a. Subtractive a => a -> a
negate Double
forall a. Multiplicative a => a
one
abs :: Double -> Double
abs = Double -> Double
forall a. Num a => a -> a
P.abs
instance Signed Float where
sign :: Float -> Float
sign Float
a
| Float
a Float -> Float -> Bool
forall a. Eq a => a -> a -> Bool
== Float
forall a. Additive a => a
zero = Float
forall a. Additive a => a
zero
| Float
a Float -> Float -> Bool
forall a. Ord a => a -> a -> Bool
> Float
forall a. Additive a => a
zero = Float
forall a. Multiplicative a => a
one
| Bool
otherwise = Float -> Float
forall a. Subtractive a => a -> a
negate Float
forall a. Multiplicative a => a
one
abs :: Float -> Float
abs = Float -> Float
forall a. Num a => a -> a
P.abs
instance Signed Int where
sign :: Int -> Int
sign Int
a
| Int
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall a. Additive a => a
zero = Int
forall a. Additive a => a
zero
| Int
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
forall a. Additive a => a
zero = Int
forall a. Multiplicative a => a
one
| Bool
otherwise = Int -> Int
forall a. Subtractive a => a -> a
negate Int
forall a. Multiplicative a => a
one
abs :: Int -> Int
abs = Int -> Int
forall a. Num a => a -> a
P.abs
instance Signed Integer where
sign :: Integer -> Integer
sign Integer
a
| Integer
a Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
forall a. Additive a => a
zero = Integer
forall a. Additive a => a
zero
| Integer
a Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
forall a. Additive a => a
zero = Integer
forall a. Multiplicative a => a
one
| Bool
otherwise = Integer -> Integer
forall a. Subtractive a => a -> a
negate Integer
forall a. Multiplicative a => a
one
abs :: Integer -> Integer
abs = Integer -> Integer
forall a. Num a => a -> a
P.abs
instance Signed Natural where
sign :: Natural -> Natural
sign Natural
a
| Natural
a Natural -> Natural -> Bool
forall a. Eq a => a -> a -> Bool
== Natural
forall a. Additive a => a
zero = Natural
forall a. Additive a => a
zero
| Bool
otherwise = Natural
forall a. Multiplicative a => a
one
abs :: Natural -> Natural
abs = Natural -> Natural
forall a. a -> a
id
instance Signed Int8 where
sign :: Int8 -> Int8
sign Int8
a
| Int8
a Int8 -> Int8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int8
forall a. Additive a => a
zero = Int8
forall a. Additive a => a
zero
| Int8
a Int8 -> Int8 -> Bool
forall a. Ord a => a -> a -> Bool
> Int8
forall a. Additive a => a
zero = Int8
forall a. Multiplicative a => a
one
| Bool
otherwise = Int8 -> Int8
forall a. Subtractive a => a -> a
negate Int8
forall a. Multiplicative a => a
one
abs :: Int8 -> Int8
abs = Int8 -> Int8
forall a. Num a => a -> a
P.abs
instance Signed Int16 where
sign :: Int16 -> Int16
sign Int16
a
| Int16
a Int16 -> Int16 -> Bool
forall a. Eq a => a -> a -> Bool
== Int16
forall a. Additive a => a
zero = Int16
forall a. Additive a => a
zero
| Int16
a Int16 -> Int16 -> Bool
forall a. Ord a => a -> a -> Bool
> Int16
forall a. Additive a => a
zero = Int16
forall a. Multiplicative a => a
one
| Bool
otherwise = Int16 -> Int16
forall a. Subtractive a => a -> a
negate Int16
forall a. Multiplicative a => a
one
abs :: Int16 -> Int16
abs = Int16 -> Int16
forall a. Num a => a -> a
P.abs
instance Signed Int32 where
sign :: Int32 -> Int32
sign Int32
a
| Int32
a Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== Int32
forall a. Additive a => a
zero = Int32
forall a. Additive a => a
zero
| Int32
a Int32 -> Int32 -> Bool
forall a. Ord a => a -> a -> Bool
> Int32
forall a. Additive a => a
zero = Int32
forall a. Multiplicative a => a
one
| Bool
otherwise = Int32 -> Int32
forall a. Subtractive a => a -> a
negate Int32
forall a. Multiplicative a => a
one
abs :: Int32 -> Int32
abs = Int32 -> Int32
forall a. Num a => a -> a
P.abs
instance Signed Int64 where
sign :: Int64 -> Int64
sign Int64
a
| Int64
a Int64 -> Int64 -> Bool
forall a. Eq a => a -> a -> Bool
== Int64
forall a. Additive a => a
zero = Int64
forall a. Additive a => a
zero
| Int64
a Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
> Int64
forall a. Additive a => a
zero = Int64
forall a. Multiplicative a => a
one
| Bool
otherwise = Int64 -> Int64
forall a. Subtractive a => a -> a
negate Int64
forall a. Multiplicative a => a
one
abs :: Int64 -> Int64
abs = Int64 -> Int64
forall a. Num a => a -> a
P.abs
instance Signed Word where
sign :: Word -> Word
sign Word
a
| Word
a Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
forall a. Additive a => a
zero = Word
forall a. Additive a => a
zero
| Bool
otherwise = Word
forall a. Multiplicative a => a
one
abs :: Word -> Word
abs = Word -> Word
forall a. Num a => a -> a
P.abs
instance Signed Word8 where
sign :: Word8 -> Word8
sign Word8
a
| Word8
a Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
forall a. Additive a => a
zero = Word8
forall a. Additive a => a
zero
| Bool
otherwise = Word8
forall a. Multiplicative a => a
one
abs :: Word8 -> Word8
abs = Word8 -> Word8
forall a. Num a => a -> a
P.abs
instance Signed Word16 where
sign :: Word16 -> Word16
sign Word16
a
| Word16
a Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== Word16
forall a. Additive a => a
zero = Word16
forall a. Additive a => a
zero
| Bool
otherwise = Word16
forall a. Multiplicative a => a
one
abs :: Word16 -> Word16
abs = Word16 -> Word16
forall a. Num a => a -> a
P.abs
instance Signed Word32 where
sign :: Word32 -> Word32
sign Word32
a
| Word32
a Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
forall a. Additive a => a
zero = Word32
forall a. Additive a => a
zero
| Bool
otherwise = Word32
forall a. Multiplicative a => a
one
abs :: Word32 -> Word32
abs = Word32 -> Word32
forall a. Num a => a -> a
P.abs
instance Signed Word64 where
sign :: Word64 -> Word64
sign Word64
a
| Word64
a Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
forall a. Additive a => a
zero = Word64
forall a. Additive a => a
zero
| Bool
otherwise = Word64
forall a. Multiplicative a => a
one
abs :: Word64 -> Word64
abs = Word64 -> Word64
forall a. Num a => a -> a
P.abs
class (Additive a, Multiplicative b, Additive b) => Norm a b | a -> b where
norm :: a -> b
basis :: a -> a
instance Norm Double Double where
norm :: Double -> Double
norm = Double -> Double
forall a. Num a => a -> a
P.abs
basis :: Double -> Double
basis = Double -> Double
forall a. Num a => a -> a
P.signum
instance Norm Float Float where
norm :: Float -> Float
norm = Float -> Float
forall a. Num a => a -> a
P.abs
basis :: Float -> Float
basis = Float -> Float
forall a. Num a => a -> a
P.signum
instance Norm Int Int where
norm :: Int -> Int
norm = Int -> Int
forall a. Num a => a -> a
P.abs
basis :: Int -> Int
basis = Int -> Int
forall a. Num a => a -> a
P.signum
instance Norm Integer Integer where
norm :: Integer -> Integer
norm = Integer -> Integer
forall a. Num a => a -> a
P.abs
basis :: Integer -> Integer
basis = Integer -> Integer
forall a. Num a => a -> a
P.signum
instance Norm Natural Natural where
norm :: Natural -> Natural
norm = Natural -> Natural
forall a. Num a => a -> a
P.abs
basis :: Natural -> Natural
basis = Natural -> Natural
forall a. Num a => a -> a
P.signum
instance Norm Int8 Int8 where
norm :: Int8 -> Int8
norm = Int8 -> Int8
forall a. Num a => a -> a
P.abs
basis :: Int8 -> Int8
basis = Int8 -> Int8
forall a. Num a => a -> a
P.signum
instance Norm Int16 Int16 where
norm :: Int16 -> Int16
norm = Int16 -> Int16
forall a. Num a => a -> a
P.abs
basis :: Int16 -> Int16
basis = Int16 -> Int16
forall a. Num a => a -> a
P.signum
instance Norm Int32 Int32 where
norm :: Int32 -> Int32
norm = Int32 -> Int32
forall a. Num a => a -> a
P.abs
basis :: Int32 -> Int32
basis = Int32 -> Int32
forall a. Num a => a -> a
P.signum
instance Norm Int64 Int64 where
norm :: Int64 -> Int64
norm = Int64 -> Int64
forall a. Num a => a -> a
P.abs
basis :: Int64 -> Int64
basis = Int64 -> Int64
forall a. Num a => a -> a
P.signum
instance Norm Word Word where
norm :: Word -> Word
norm = Word -> Word
forall a. Num a => a -> a
P.abs
basis :: Word -> Word
basis = Word -> Word
forall a. Num a => a -> a
P.signum
instance Norm Word8 Word8 where
norm :: Word8 -> Word8
norm = Word8 -> Word8
forall a. Num a => a -> a
P.abs
basis :: Word8 -> Word8
basis = Word8 -> Word8
forall a. Num a => a -> a
P.signum
instance Norm Word16 Word16 where
norm :: Word16 -> Word16
norm = Word16 -> Word16
forall a. Num a => a -> a
P.abs
basis :: Word16 -> Word16
basis = Word16 -> Word16
forall a. Num a => a -> a
P.signum
instance Norm Word32 Word32 where
norm :: Word32 -> Word32
norm = Word32 -> Word32
forall a. Num a => a -> a
P.abs
basis :: Word32 -> Word32
basis = Word32 -> Word32
forall a. Num a => a -> a
P.signum
instance Norm Word64 Word64 where
norm :: Word64 -> Word64
norm = Word64 -> Word64
forall a. Num a => a -> a
P.abs
basis :: Word64 -> Word64
basis = Word64 -> Word64
forall a. Num a => a -> a
P.signum
distance :: (Norm a b, Subtractive a) => a -> a -> b
distance :: a -> a -> b
distance a
a a
b = a -> b
forall a b. Norm a b => a -> b
norm (a
a a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
b)
class (Additive coord, Multiplicative coord, Additive dir, Multiplicative dir) => Direction coord dir | coord -> dir where
angle :: coord -> dir
ray :: dir -> coord
data Polar mag dir
= Polar {Polar mag dir -> mag
magnitude :: mag, Polar mag dir -> dir
direction :: dir}
deriving (Polar mag dir -> Polar mag dir -> Bool
(Polar mag dir -> Polar mag dir -> Bool)
-> (Polar mag dir -> Polar mag dir -> Bool) -> Eq (Polar mag dir)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall mag dir.
(Eq mag, Eq dir) =>
Polar mag dir -> Polar mag dir -> Bool
/= :: Polar mag dir -> Polar mag dir -> Bool
$c/= :: forall mag dir.
(Eq mag, Eq dir) =>
Polar mag dir -> Polar mag dir -> Bool
== :: Polar mag dir -> Polar mag dir -> Bool
$c== :: forall mag dir.
(Eq mag, Eq dir) =>
Polar mag dir -> Polar mag dir -> Bool
Eq, Int -> Polar mag dir -> ShowS
[Polar mag dir] -> ShowS
Polar mag dir -> String
(Int -> Polar mag dir -> ShowS)
-> (Polar mag dir -> String)
-> ([Polar mag dir] -> ShowS)
-> Show (Polar mag dir)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall mag dir.
(Show mag, Show dir) =>
Int -> Polar mag dir -> ShowS
forall mag dir. (Show mag, Show dir) => [Polar mag dir] -> ShowS
forall mag dir. (Show mag, Show dir) => Polar mag dir -> String
showList :: [Polar mag dir] -> ShowS
$cshowList :: forall mag dir. (Show mag, Show dir) => [Polar mag dir] -> ShowS
show :: Polar mag dir -> String
$cshow :: forall mag dir. (Show mag, Show dir) => Polar mag dir -> String
showsPrec :: Int -> Polar mag dir -> ShowS
$cshowsPrec :: forall mag dir.
(Show mag, Show dir) =>
Int -> Polar mag dir -> ShowS
Show, (forall x. Polar mag dir -> Rep (Polar mag dir) x)
-> (forall x. Rep (Polar mag dir) x -> Polar mag dir)
-> Generic (Polar mag dir)
forall x. Rep (Polar mag dir) x -> Polar mag dir
forall x. Polar mag dir -> Rep (Polar mag dir) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall mag dir x. Rep (Polar mag dir) x -> Polar mag dir
forall mag dir x. Polar mag dir -> Rep (Polar mag dir) x
$cto :: forall mag dir x. Rep (Polar mag dir) x -> Polar mag dir
$cfrom :: forall mag dir x. Polar mag dir -> Rep (Polar mag dir) x
Generic)
polar :: (Norm coord mag, Direction coord dir) => coord -> Polar mag dir
polar :: coord -> Polar mag dir
polar coord
z = mag -> dir -> Polar mag dir
forall mag dir. mag -> dir -> Polar mag dir
Polar (coord -> mag
forall a b. Norm a b => a -> b
norm coord
z) (coord -> dir
forall coord dir. Direction coord dir => coord -> dir
angle coord
z)
coord :: (MultiplicativeAction coord mag, Direction coord dir) => Polar mag dir -> coord
coord :: Polar mag dir -> coord
coord (Polar mag
m dir
d) = mag
m mag -> coord -> coord
forall m a. MultiplicativeAction m a => a -> m -> m
.* dir -> coord
forall coord dir. Direction coord dir => dir -> coord
ray dir
d
class
(Eq a, Additive a, Subtractive a, MeetSemiLattice a) =>
Epsilon a where
epsilon :: a
epsilon = a
forall a. Additive a => a
zero
nearZero :: a -> Bool
nearZero a
a = a
forall a. Epsilon a => a
epsilon a -> a -> Bool
forall a. MeetSemiLattice a => a -> a -> Bool
`meetLeq` a
a Bool -> Bool -> Bool
&& a
forall a. Epsilon a => a
epsilon a -> a -> Bool
forall a. MeetSemiLattice a => a -> a -> Bool
`meetLeq` a -> a
forall a. Subtractive a => a -> a
negate a
a
aboutEqual :: a -> a -> Bool
aboutEqual a
a a
b = a -> Bool
forall a. Epsilon a => a -> Bool
nearZero (a -> Bool) -> a -> Bool
forall a b. (a -> b) -> a -> b
$ a
a a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
b
infixl 4 ~=
(~=) :: (Epsilon a) => a -> a -> Bool
~= :: a -> a -> Bool
(~=) = a -> a -> Bool
forall a. Epsilon a => a -> a -> Bool
aboutEqual
instance Epsilon Double where
epsilon :: Double
epsilon = Double
1e-14
instance Epsilon Float where
epsilon :: Float
epsilon = Float
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