{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module NumHask.Algebra.Field
( SemiField,
Field,
ExpField (..),
QuotientField (..),
Quotient (..),
toQuotient,
fromQuotient,
mulQuotient,
infinity,
negInfinity,
nan,
TrigField (..),
half,
modF,
divF,
divModF,
)
where
import Data.Bool (bool)
import Data.Kind
import NumHask.Algebra.Additive (Additive (..), Subtractive (..), (-))
import NumHask.Algebra.Multiplicative
( Divisive (..),
Multiplicative (..),
(/),
)
import NumHask.Algebra.Ring (Distributive, Ring, two)
import NumHask.Data.Integral (DivMod (..), FromIntegral (..), Integral, even)
import Prelude (Eq (..), Show, (.))
import Prelude qualified as P
type SemiField a = (Distributive a, Divisive a)
type Field a = (Ring a, Divisive a)
class
(Field a) =>
ExpField a
where
exp :: a -> a
log :: a -> a
(**) :: a -> a -> a
(**) a
a a
b = a -> a
forall a. ExpField a => a -> a
exp (a -> a
forall a. ExpField a => a -> a
log a
a a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
b)
logBase :: a -> a -> a
logBase a
a a
b = a -> a
forall a. ExpField a => a -> a
log a
b a -> a -> a
forall a. Divisive a => a -> a -> a
/ a -> a
forall a. ExpField a => a -> a
log a
a
sqrt :: a -> a
sqrt a
a = a
a a -> a -> a
forall a. ExpField a => a -> a -> a
** (a
forall a. Multiplicative a => a
one a -> a -> a
forall a. Divisive a => a -> a -> a
/ (a
forall a. Multiplicative a => a
one a -> a -> a
forall a. Additive a => a -> a -> a
+ a
forall a. Multiplicative a => a
one))
instance ExpField P.Double where
exp :: Double -> Double
exp = Double -> Double
forall a. Floating a => a -> a
P.exp
log :: Double -> Double
log = Double -> Double
forall a. Floating a => a -> a
P.log
** :: Double -> Double -> Double
(**) = Double -> Double -> Double
forall a. Floating a => a -> a -> a
(P.**)
instance ExpField P.Float where
exp :: Float -> Float
exp = Float -> Float
forall a. Floating a => a -> a
P.exp
log :: Float -> Float
log = Float -> Float
forall a. Floating a => a -> a
P.log
** :: Float -> Float -> Float
(**) = Float -> Float -> Float
forall a. Floating a => a -> a -> a
(P.**)
instance (ExpField b) => ExpField (a -> b) where
exp :: (a -> b) -> a -> b
exp a -> b
f = b -> b
forall a. ExpField a => a -> a
exp (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
log :: (a -> b) -> a -> b
log a -> b
f = b -> b
forall a. ExpField a => a -> a
log (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
data Quotient w a = Quotient
{ forall w a. Quotient w a -> w
whole :: w,
forall w a. Quotient w a -> a
fraction :: a
}
deriving (Quotient w a -> Quotient w a -> Bool
(Quotient w a -> Quotient w a -> Bool)
-> (Quotient w a -> Quotient w a -> Bool) -> Eq (Quotient w a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall w a. (Eq w, Eq a) => Quotient w a -> Quotient w a -> Bool
$c== :: forall w a. (Eq w, Eq a) => Quotient w a -> Quotient w a -> Bool
== :: Quotient w a -> Quotient w a -> Bool
$c/= :: forall w a. (Eq w, Eq a) => Quotient w a -> Quotient w a -> Bool
/= :: Quotient w a -> Quotient w a -> Bool
Eq, Int -> Quotient w a -> ShowS
[Quotient w a] -> ShowS
Quotient w a -> String
(Int -> Quotient w a -> ShowS)
-> (Quotient w a -> String)
-> ([Quotient w a] -> ShowS)
-> Show (Quotient w a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall w a. (Show w, Show a) => Int -> Quotient w a -> ShowS
forall w a. (Show w, Show a) => [Quotient w a] -> ShowS
forall w a. (Show w, Show a) => Quotient w a -> String
$cshowsPrec :: forall w a. (Show w, Show a) => Int -> Quotient w a -> ShowS
showsPrec :: Int -> Quotient w a -> ShowS
$cshow :: forall w a. (Show w, Show a) => Quotient w a -> String
show :: Quotient w a -> String
$cshowList :: forall w a. (Show w, Show a) => [Quotient w a] -> ShowS
showList :: [Quotient w a] -> ShowS
Show)
class (SemiField a) => QuotientField a where
type Whole a :: Type
properFraction :: a -> Quotient (Whole a) a
fromWhole :: Whole a -> a
default fromWhole :: (FromIntegral a (Whole a)) => Whole a -> a
fromWhole = Whole a -> a
forall a b. FromIntegral a b => b -> a
fromIntegral
round :: a -> Whole a
default round :: (P.Ord a, P.Eq (Whole a), Integral (Whole a)) => a -> Whole a
round a
x = case a -> Quotient (Whole a) a
forall a. QuotientField a => a -> Quotient (Whole a) a
properFraction a
x of
Quotient Whole a
n a
f ->
case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
P.compare a
f a
forall a. (Additive a, Divisive a) => a
half of
Ordering
P.LT -> Whole a
n
Ordering
P.EQ -> Whole a -> Whole a -> Bool -> Whole a
forall a. a -> a -> Bool -> a
bool (Whole a
n Whole a -> Whole a -> Whole a
forall a. Additive a => a -> a -> a
+ Whole a
forall a. Multiplicative a => a
one) Whole a
n (Whole a -> Bool
forall a. (Eq a, Integral a) => a -> Bool
even Whole a
n)
Ordering
P.GT -> Whole a
n Whole a -> Whole a -> Whole a
forall a. Additive a => a -> a -> a
+ Whole a
forall a. Multiplicative a => a
one
ceiling :: a -> Whole a
default ceiling :: (P.Ord a, Distributive (Whole a)) => a -> Whole a
ceiling a
x = Whole a -> Whole a -> Bool -> Whole a
forall a. a -> a -> Bool -> a
bool Whole a
n (Whole a
n Whole a -> Whole a -> Whole a
forall a. Additive a => a -> a -> a
+ Whole a
forall a. Multiplicative a => a
one) (a
r a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.> a
forall a. Additive a => a
zero)
where
Quotient Whole a
n a
r = a -> Quotient (Whole a) a
forall a. QuotientField a => a -> Quotient (Whole a) a
properFraction a
x
floor :: a -> Whole a
floor a
x = Quotient (Whole a) a -> Whole a
forall w a. Quotient w a -> w
whole (a -> Quotient (Whole a) a
forall a. QuotientField a => a -> Quotient (Whole a) a
properFraction a
x)
truncate :: a -> Whole a
default truncate :: (P.Ord a) => a -> Whole a
truncate a
x = Whole a -> Whole a -> Bool -> Whole a
forall a. a -> a -> Bool -> a
bool (a -> Whole a
forall a. QuotientField a => a -> Whole a
ceiling a
x) (a -> Whole a
forall a. QuotientField a => a -> Whole a
floor a
x) (a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
P.> a
forall a. Additive a => a
zero)
toQuotient :: (QuotientField a) => a -> Quotient (Whole a) a
toQuotient :: forall a. QuotientField a => a -> Quotient (Whole a) a
toQuotient = a -> Quotient (Whole a) a
forall a. QuotientField a => a -> Quotient (Whole a) a
properFraction
fromQuotient :: (QuotientField a) => Quotient (Whole a) a -> a
fromQuotient :: forall a. QuotientField a => Quotient (Whole a) a -> a
fromQuotient (Quotient Whole a
w a
f) = Whole a -> a
forall a. QuotientField a => Whole a -> a
fromWhole Whole a
w a -> a -> a
forall a. Additive a => a -> a -> a
+ a
f
mulQuotient ::
(QuotientField a) =>
Quotient (Whole a) a ->
Quotient (Whole a) a ->
Quotient (Whole a) a
mulQuotient :: forall a.
QuotientField a =>
Quotient (Whole a) a
-> Quotient (Whole a) a -> Quotient (Whole a) a
mulQuotient Quotient (Whole a) a
q1 Quotient (Whole a) a
q2 = a -> Quotient (Whole a) a
forall a. QuotientField a => a -> Quotient (Whole a) a
toQuotient (Quotient (Whole a) a -> a
forall a. QuotientField a => Quotient (Whole a) a -> a
fromQuotient Quotient (Whole a) a
q1 a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Quotient (Whole a) a -> a
forall a. QuotientField a => Quotient (Whole a) a -> a
fromQuotient Quotient (Whole a) a
q2)
instance QuotientField P.Float where
type Whole P.Float = P.Int
properFraction :: Float -> Quotient (Whole Float) Float
properFraction Float
a = Int -> Float -> Quotient Int Float
forall w a. w -> a -> Quotient w a
Quotient Int
n (Float
a Float -> Float -> Float
forall a. Subtractive a => a -> a -> a
- Int -> Float
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral Int
n)
where
n :: Int
n = Float -> Int
forall b. Integral b => Float -> b
forall a b. (RealFrac a, Integral b) => a -> b
P.floor Float
a
instance QuotientField P.Double where
type Whole P.Double = P.Int
properFraction :: Double -> Quotient (Whole Double) Double
properFraction Double
a = Int -> Double -> Quotient Int Double
forall w a. w -> a -> Quotient w a
Quotient Int
n (Double
a Double -> Double -> Double
forall a. Subtractive a => a -> a -> a
- Int -> Double
forall a b. (Integral a, Num b) => a -> b
P.fromIntegral Int
n)
where
n :: Int
n = Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
P.floor Double
a
infinity :: (SemiField a) => a
infinity :: forall a. SemiField a => a
infinity = a
forall a. Multiplicative a => a
one a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
forall a. Additive a => a
zero
nan :: (SemiField a) => a
nan :: forall a. SemiField a => a
nan = a
forall a. Additive a => a
zero a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
forall a. Additive a => a
zero
negInfinity :: (Field a) => a
negInfinity :: forall a. Field a => a
negInfinity = a -> a
forall a. Subtractive a => a -> a
negate a
forall a. SemiField a => a
infinity
class
(Field a) =>
TrigField a
where
pi :: a
sin :: a -> a
cos :: a -> a
tan :: a -> a
tan a
x = a -> a
forall a. TrigField a => a -> a
sin a
x a -> a -> a
forall a. Divisive a => a -> a -> a
/ a -> a
forall a. TrigField a => a -> a
cos a
x
asin :: a -> a
acos :: a -> a
atan :: a -> a
atan2 :: a -> a -> a
sinh :: a -> a
cosh :: a -> a
tanh :: a -> a
tanh a
x = a -> a
forall a. TrigField a => a -> a
sinh a
x a -> a -> a
forall a. Divisive a => a -> a -> a
/ a -> a
forall a. TrigField a => a -> a
cosh a
x
asinh :: a -> a
acosh :: a -> a
atanh :: a -> a
instance TrigField P.Double where
pi :: Double
pi = Double
forall a. Floating a => a
P.pi
sin :: Double -> Double
sin = Double -> Double
forall a. Floating a => a -> a
P.sin
cos :: Double -> Double
cos = Double -> Double
forall a. Floating a => a -> a
P.cos
asin :: Double -> Double
asin = Double -> Double
forall a. Floating a => a -> a
P.asin
acos :: Double -> Double
acos = Double -> Double
forall a. Floating a => a -> a
P.acos
atan :: Double -> Double
atan = Double -> Double
forall a. Floating a => a -> a
P.atan
atan2 :: Double -> Double -> Double
atan2 = Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
P.atan2
sinh :: Double -> Double
sinh = Double -> Double
forall a. Floating a => a -> a
P.sinh
cosh :: Double -> Double
cosh = Double -> Double
forall a. Floating a => a -> a
P.cosh
asinh :: Double -> Double
asinh = Double -> Double
forall a. Floating a => a -> a
P.asinh
acosh :: Double -> Double
acosh = Double -> Double
forall a. Floating a => a -> a
P.acosh
atanh :: Double -> Double
atanh = Double -> Double
forall a. Floating a => a -> a
P.atanh
instance TrigField P.Float where
pi :: Float
pi = Float
forall a. Floating a => a
P.pi
sin :: Float -> Float
sin = Float -> Float
forall a. Floating a => a -> a
P.sin
cos :: Float -> Float
cos = Float -> Float
forall a. Floating a => a -> a
P.cos
asin :: Float -> Float
asin = Float -> Float
forall a. Floating a => a -> a
P.asin
acos :: Float -> Float
acos = Float -> Float
forall a. Floating a => a -> a
P.acos
atan :: Float -> Float
atan = Float -> Float
forall a. Floating a => a -> a
P.atan
atan2 :: Float -> Float -> Float
atan2 = Float -> Float -> Float
forall a. RealFloat a => a -> a -> a
P.atan2
sinh :: Float -> Float
sinh = Float -> Float
forall a. Floating a => a -> a
P.sinh
cosh :: Float -> Float
cosh = Float -> Float
forall a. Floating a => a -> a
P.cosh
asinh :: Float -> Float
asinh = Float -> Float
forall a. Floating a => a -> a
P.asinh
acosh :: Float -> Float
acosh = Float -> Float
forall a. Floating a => a -> a
P.acosh
atanh :: Float -> Float
atanh = Float -> Float
forall a. Floating a => a -> a
P.atanh
instance (TrigField b) => TrigField (a -> b) where
pi :: a -> b
pi a
_ = b
forall a. TrigField a => a
pi
sin :: (a -> b) -> a -> b
sin a -> b
f = b -> b
forall a. TrigField a => a -> a
sin (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
cos :: (a -> b) -> a -> b
cos a -> b
f = b -> b
forall a. TrigField a => a -> a
cos (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
asin :: (a -> b) -> a -> b
asin a -> b
f = b -> b
forall a. TrigField a => a -> a
asin (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
acos :: (a -> b) -> a -> b
acos a -> b
f = b -> b
forall a. TrigField a => a -> a
acos (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
atan :: (a -> b) -> a -> b
atan a -> b
f = b -> b
forall a. TrigField a => a -> a
atan (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
atan2 :: (a -> b) -> (a -> b) -> a -> b
atan2 a -> b
f a -> b
g a
x = b -> b -> b
forall a. TrigField a => a -> a -> a
atan2 (a -> b
f a
x) (a -> b
g a
x)
sinh :: (a -> b) -> a -> b
sinh a -> b
f = b -> b
forall a. TrigField a => a -> a
sinh (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
cosh :: (a -> b) -> a -> b
cosh a -> b
f = b -> b
forall a. TrigField a => a -> a
cosh (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
asinh :: (a -> b) -> a -> b
asinh a -> b
f = b -> b
forall a. TrigField a => a -> a
asinh (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
acosh :: (a -> b) -> a -> b
acosh a -> b
f = b -> b
forall a. TrigField a => a -> a
acosh (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
atanh :: (a -> b) -> a -> b
atanh a -> b
f = b -> b
forall a. TrigField a => a -> a
atanh (b -> b) -> (a -> b) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
half :: (Additive a, Divisive a) => a
half :: forall a. (Additive a, Divisive a) => a
half = a
forall a. Multiplicative a => a
one a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
forall a. (Multiplicative a, Additive a) => a
two
modF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> a
modF :: forall a.
(Eq a, Field a, FromIntegral a (Whole a), QuotientField a) =>
a -> a -> a
modF a
n a
d
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. SemiField a => a
infinity = a
n
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
zero = a
forall a. SemiField a => a
nan
| Bool
P.True = a
n a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
d a -> a -> a
forall a. Multiplicative a => a -> a -> a
* Whole a -> a
forall a b. FromIntegral a b => b -> a
fromIntegral (a -> Whole a
forall a. QuotientField a => a -> Whole a
floor (a
n a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
d))
divF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> a
divF :: forall a.
(Eq a, Field a, FromIntegral a (Whole a), QuotientField a) =>
a -> a -> a
divF a
n a
d
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. SemiField a => a
infinity = a
forall a. Additive a => a
zero
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
zero = a
forall a. SemiField a => a
infinity
| Bool
P.True = Whole a -> a
forall a b. FromIntegral a b => b -> a
fromIntegral (a -> Whole a
forall a. QuotientField a => a -> Whole a
floor (a
n a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
d))
divModF :: (Eq a, Field a, FromIntegral a (Whole a), QuotientField a) => a -> a -> DivMod a
divModF :: forall a.
(Eq a, Field a, FromIntegral a (Whole a), QuotientField a) =>
a -> a -> DivMod a
divModF a
n a
d
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. SemiField a => a
infinity = a -> a -> DivMod a
forall a. a -> a -> DivMod a
DivMod a
forall a. Additive a => a
zero a
n
| a
d a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. Additive a => a
zero = a -> a -> DivMod a
forall a. a -> a -> DivMod a
DivMod a
forall a. SemiField a => a
infinity a
forall a. SemiField a => a
nan
| Bool
P.True = a -> a -> DivMod a
forall a. a -> a -> DivMod a
DivMod a
div' (a
n a -> a -> a
forall a. Subtractive a => a -> a -> a
- a
d a -> a -> a
forall a. Multiplicative a => a -> a -> a
* a
div')
where
div' :: a
div' = Whole a -> a
forall a b. FromIntegral a b => b -> a
fromIntegral (a -> Whole a
forall a. QuotientField a => a -> Whole a
floor (a
n a -> a -> a
forall a. Divisive a => a -> a -> a
/ a
d))