{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# OPTIONS_GHC -Wall #-}
module NumHask.Algebra.Metric
( Signed (..),
Norm (..),
distance,
Direction (..),
Polar (..),
polar,
coord,
Epsilon (..),
(~=),
)
where
import Data.Bool (bool)
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 (Additive (zero), Subtractive (..), (-))
import NumHask.Algebra.Module (MultiplicativeAction ((.*)))
import NumHask.Algebra.Multiplicative (Multiplicative (one))
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 =
case forall a. Ord a => a -> a -> Ordering
compare Double
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Double -> Double
abs = forall a. Num a => a -> a
P.abs
instance Signed Float where
sign :: Float -> Float
sign Float
a =
case forall a. Ord a => a -> a -> Ordering
compare Float
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Float -> Float
abs = forall a. Num a => a -> a
P.abs
instance Signed Int where
sign :: Int -> Int
sign Int
a =
case forall a. Ord a => a -> a -> Ordering
compare Int
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Int -> Int
abs = forall a. Num a => a -> a
P.abs
instance Signed Integer where
sign :: Integer -> Integer
sign Integer
a =
case forall a. Ord a => a -> a -> Ordering
compare Integer
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Integer -> Integer
abs = forall a. Num a => a -> a
P.abs
instance Signed Natural where
sign :: Natural -> Natural
sign Natural
a =
case forall a. Ord a => a -> a -> Ordering
compare Natural
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Natural -> Natural
abs = forall a. a -> a
id
instance Signed Int8 where
sign :: Int8 -> Int8
sign Int8
a =
case forall a. Ord a => a -> a -> Ordering
compare Int8
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Int8 -> Int8
abs = forall a. Num a => a -> a
P.abs
instance Signed Int16 where
sign :: Int16 -> Int16
sign Int16
a =
case forall a. Ord a => a -> a -> Ordering
compare Int16
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Int16 -> Int16
abs = forall a. Num a => a -> a
P.abs
instance Signed Int32 where
sign :: Int32 -> Int32
sign Int32
a =
case forall a. Ord a => a -> a -> Ordering
compare Int32
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Int32 -> Int32
abs = forall a. Num a => a -> a
P.abs
instance Signed Int64 where
sign :: Int64 -> Int64
sign Int64
a =
case forall a. Ord a => a -> a -> Ordering
compare Int64
a forall a. Additive a => a
zero of
Ordering
EQ -> forall a. Additive a => a
zero
Ordering
GT -> forall a. Multiplicative a => a
one
Ordering
LT -> forall a. Subtractive a => a -> a
negate forall a. Multiplicative a => a
one
abs :: Int64 -> Int64
abs = forall a. Num a => a -> a
P.abs
instance Signed Word where
sign :: Word -> Word
sign Word
a = forall a. a -> a -> Bool -> a
bool forall a. Multiplicative a => a
one forall a. Additive a => a
zero (Word
a forall a. Eq a => a -> a -> Bool
== forall a. Additive a => a
zero)
abs :: Word -> Word
abs = forall a. Num a => a -> a
P.abs
instance Signed Word8 where
sign :: Word8 -> Word8
sign Word8
a = forall a. a -> a -> Bool -> a
bool forall a. Multiplicative a => a
one forall a. Additive a => a
zero (Word8
a forall a. Eq a => a -> a -> Bool
== forall a. Additive a => a
zero)
abs :: Word8 -> Word8
abs = forall a. Num a => a -> a
P.abs
instance Signed Word16 where
sign :: Word16 -> Word16
sign Word16
a = forall a. a -> a -> Bool -> a
bool forall a. Multiplicative a => a
one forall a. Additive a => a
zero (Word16
a forall a. Eq a => a -> a -> Bool
== forall a. Additive a => a
zero)
abs :: Word16 -> Word16
abs = forall a. Num a => a -> a
P.abs
instance Signed Word32 where
sign :: Word32 -> Word32
sign Word32
a = forall a. a -> a -> Bool -> a
bool forall a. Multiplicative a => a
one forall a. Additive a => a
zero (Word32
a forall a. Eq a => a -> a -> Bool
== forall a. Additive a => a
zero)
abs :: Word32 -> Word32
abs = forall a. Num a => a -> a
P.abs
instance Signed Word64 where
sign :: Word64 -> Word64
sign Word64
a = forall a. a -> a -> Bool -> a
bool forall a. Multiplicative a => a
one forall a. Additive a => a
zero (Word64
a forall a. Eq a => a -> a -> Bool
== forall a. Additive a => a
zero)
abs :: Word64 -> Word64
abs = 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 = forall a. Num a => a -> a
P.abs
basis :: Double -> Double
basis = forall a. Num a => a -> a
P.signum
instance Norm Float Float where
norm :: Float -> Float
norm = forall a. Num a => a -> a
P.abs
basis :: Float -> Float
basis = forall a. Num a => a -> a
P.signum
instance Norm Int Int where
norm :: Int -> Int
norm = forall a. Num a => a -> a
P.abs
basis :: Int -> Int
basis = forall a. Num a => a -> a
P.signum
instance Norm Integer Integer where
norm :: Integer -> Integer
norm = forall a. Num a => a -> a
P.abs
basis :: Integer -> Integer
basis = forall a. Num a => a -> a
P.signum
instance Norm Natural Natural where
norm :: Natural -> Natural
norm = forall a. Num a => a -> a
P.abs
basis :: Natural -> Natural
basis = forall a. Num a => a -> a
P.signum
instance Norm Int8 Int8 where
norm :: Int8 -> Int8
norm = forall a. Num a => a -> a
P.abs
basis :: Int8 -> Int8
basis = forall a. Num a => a -> a
P.signum
instance Norm Int16 Int16 where
norm :: Int16 -> Int16
norm = forall a. Num a => a -> a
P.abs
basis :: Int16 -> Int16
basis = forall a. Num a => a -> a
P.signum
instance Norm Int32 Int32 where
norm :: Int32 -> Int32
norm = forall a. Num a => a -> a
P.abs
basis :: Int32 -> Int32
basis = forall a. Num a => a -> a
P.signum
instance Norm Int64 Int64 where
norm :: Int64 -> Int64
norm = forall a. Num a => a -> a
P.abs
basis :: Int64 -> Int64
basis = forall a. Num a => a -> a
P.signum
instance Norm Word Word where
norm :: Word -> Word
norm = forall a. Num a => a -> a
P.abs
basis :: Word -> Word
basis = forall a. Num a => a -> a
P.signum
instance Norm Word8 Word8 where
norm :: Word8 -> Word8
norm = forall a. Num a => a -> a
P.abs
basis :: Word8 -> Word8
basis = forall a. Num a => a -> a
P.signum
instance Norm Word16 Word16 where
norm :: Word16 -> Word16
norm = forall a. Num a => a -> a
P.abs
basis :: Word16 -> Word16
basis = forall a. Num a => a -> a
P.signum
instance Norm Word32 Word32 where
norm :: Word32 -> Word32
norm = forall a. Num a => a -> a
P.abs
basis :: Word32 -> Word32
basis = forall a. Num a => a -> a
P.signum
instance Norm Word64 Word64 where
norm :: Word64 -> Word64
norm = forall a. Num a => a -> a
P.abs
basis :: Word64 -> Word64
basis = forall a. Num a => a -> a
P.signum
distance :: (Norm a b, Subtractive a) => a -> a -> b
distance :: forall a b. (Norm a b, Subtractive a) => a -> a -> b
distance a
a a
b = forall a b. Norm a b => a -> b
norm (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 {forall mag dir. Polar mag dir -> mag
magnitude :: !mag, forall mag dir. Polar mag dir -> dir
direction :: !dir}
deriving (Polar mag dir -> Polar mag dir -> Bool
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
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 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 :: forall coord mag dir.
(Norm coord mag, Direction coord dir) =>
coord -> Polar mag dir
polar coord
z = forall mag dir. mag -> dir -> Polar mag dir
Polar (forall a b. Norm a b => a -> b
norm coord
z) (forall coord dir. Direction coord dir => coord -> dir
angle coord
z)
coord :: (MultiplicativeAction coord mag, Direction coord dir) => Polar mag dir -> coord
coord :: forall coord mag dir.
(MultiplicativeAction coord mag, Direction coord dir) =>
Polar mag dir -> coord
coord (Polar mag
m dir
d) = mag
m forall m a. MultiplicativeAction m a => a -> m -> m
.* forall coord dir. Direction coord dir => dir -> coord
ray dir
d
class
(Eq a, Additive a) =>
Epsilon a
where
epsilon :: a
epsilon = forall a. Additive a => a
zero
nearZero :: a -> Bool
default nearZero :: (Ord a, Subtractive a) => a -> Bool
nearZero a
a = forall a. Epsilon a => a
epsilon forall a. Ord a => a -> a -> Bool
>= a
a Bool -> Bool -> Bool
&& forall a. Epsilon a => a
epsilon forall a. Ord a => a -> a -> Bool
>= forall a. Subtractive a => a -> a
negate a
a
aboutEqual :: a -> a -> Bool
default aboutEqual :: (Subtractive a) => a -> a -> Bool
aboutEqual a
a a
b = forall a. Epsilon a => a -> Bool
nearZero forall a b. (a -> b) -> a -> b
$ a
a forall a. Subtractive a => a -> a -> a
- a
b
infixl 4 ~=
(~=) :: (Epsilon a) => a -> a -> Bool
~= :: forall a. Epsilon a => 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