{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module NumHask.Algebra.Field
( Field,
ExpField (..),
QuotientField (..),
infinity,
negInfinity,
nan,
TrigField (..),
half,
)
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 (Integral, even)
import Prelude ((.))
import qualified Prelude as P
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 = forall a. ExpField a => a -> a
exp (forall a. ExpField a => a -> a
log a
a forall a. Multiplicative a => a -> a -> a
* a
b)
logBase :: a -> a -> a
logBase a
a a
b = forall a. ExpField a => a -> a
log a
b forall a. Divisive a => a -> a -> a
/ forall a. ExpField a => a -> a
log a
a
sqrt :: a -> a
sqrt a
a = a
a forall a. ExpField a => a -> a -> a
** (forall a. Multiplicative a => a
one forall a. Divisive a => a -> a -> a
/ (forall a. Multiplicative a => a
one forall a. Additive a => a -> a -> a
+ forall a. Multiplicative a => a
one))
instance ExpField P.Double where
exp :: Double -> Double
exp = forall a. Floating a => a -> a
P.exp
log :: Double -> Double
log = forall a. Floating a => a -> a
P.log
** :: Double -> Double -> Double
(**) = forall a. Floating a => a -> a -> a
(P.**)
instance ExpField P.Float where
exp :: Float -> Float
exp = forall a. Floating a => a -> a
P.exp
log :: Float -> Float
log = forall a. Floating a => a -> a
P.log
** :: 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 = forall a. ExpField a => a -> a
exp forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
log :: (a -> b) -> a -> b
log a -> b
f = forall a. ExpField a => a -> a
log forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
class (Field a) => QuotientField a where
type Whole a :: Type
properFraction :: a -> (Whole a, a)
round :: (P.Eq (Whole a), Ring (Whole a)) => a -> Whole a
default round :: (Integral (Whole a), P.Eq (Whole a), P.Ord a, Ring (Whole a)) => a -> Whole a
round a
x = case forall a. QuotientField a => a -> (Whole a, a)
properFraction a
x of
(Whole a
n, a
r) ->
let m :: Whole a
m = forall a. a -> a -> Bool -> a
bool (Whole a
n forall a. Additive a => a -> a -> a
+ forall a. Multiplicative a => a
one) (Whole a
n forall a. Subtractive a => a -> a -> a
- forall a. Multiplicative a => a
one) (a
r forall a. Ord a => a -> a -> Bool
P.< forall a. Additive a => a
zero)
half_down :: a
half_down = forall {a}. (Ord a, Subtractive a) => a -> a
abs' a
r forall a. Subtractive a => a -> a -> a
- forall a. Field a => a
half
abs' :: a -> a
abs' a
a
| a
a forall a. Ord a => a -> a -> Bool
P.< forall a. Additive a => a
zero = forall a. Subtractive a => a -> a
negate a
a
| Bool
P.otherwise = a
a
in case forall a. Ord a => a -> a -> Ordering
P.compare a
half_down forall a. Additive a => a
zero of
Ordering
P.LT -> Whole a
n
Ordering
P.EQ -> forall a. a -> a -> Bool -> a
bool Whole a
m Whole a
n (forall a. (Eq a, Integral a) => a -> Bool
even Whole a
n)
Ordering
P.GT -> Whole a
m
ceiling :: (Distributive (Whole a)) => a -> Whole a
default ceiling :: (P.Ord a, Distributive (Whole a)) => a -> Whole a
ceiling a
x = forall a. a -> a -> Bool -> a
bool Whole a
n (Whole a
n forall a. Additive a => a -> a -> a
+ forall a. Multiplicative a => a
one) (a
r forall a. Ord a => a -> a -> Bool
P.>= forall a. Additive a => a
zero)
where
(Whole a
n, a
r) = forall a. QuotientField a => a -> (Whole a, a)
properFraction a
x
floor :: (Ring (Whole a)) => a -> Whole a
default floor :: (P.Ord a, Ring (Whole a)) => a -> Whole a
floor a
x = forall a. a -> a -> Bool -> a
bool Whole a
n (Whole a
n forall a. Subtractive a => a -> a -> a
- forall a. Multiplicative a => a
one) (a
r forall a. Ord a => a -> a -> Bool
P.< forall a. Additive a => a
zero)
where
(Whole a
n, a
r) = forall a. QuotientField a => a -> (Whole a, a)
properFraction a
x
truncate :: (Ring (Whole a)) => a -> Whole a
default truncate :: (P.Ord a, Ring (Whole a)) => a -> Whole a
truncate a
x = forall a. a -> a -> Bool -> a
bool (forall a. (QuotientField a, Distributive (Whole a)) => a -> Whole a
ceiling a
x) (forall a. (QuotientField a, Ring (Whole a)) => a -> Whole a
floor a
x) (a
x forall a. Ord a => a -> a -> Bool
P.> forall a. Additive a => a
zero)
instance QuotientField P.Float where
type Whole P.Float = P.Int
properFraction :: Float -> (Whole Float, Float)
properFraction = forall a b. (RealFrac a, Integral b) => a -> (b, a)
P.properFraction
instance QuotientField P.Double where
type Whole P.Double = P.Int
properFraction :: Double -> (Whole Double, Double)
properFraction = forall a b. (RealFrac a, Integral b) => a -> (b, a)
P.properFraction
infinity :: (Field a) => a
infinity :: forall a. Field a => a
infinity = forall a. Multiplicative a => a
one forall a. Divisive a => a -> a -> a
/ forall a. Additive a => a
zero
nan :: (Field a) => a
nan :: forall a. Field a => a
nan = forall a. Additive a => a
zero forall a. Divisive a => a -> a -> a
/ forall a. Additive a => a
zero
negInfinity :: (Field a) => a
negInfinity :: forall a. Field a => a
negInfinity = forall a. Subtractive a => a -> a
negate forall a. Field a => a
infinity
class
(Field a) =>
TrigField a
where
pi :: a
sin :: a -> a
cos :: a -> a
tan :: a -> a
tan a
x = forall a. TrigField a => a -> a
sin a
x forall a. Divisive 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 = forall a. TrigField a => a -> a
sinh a
x forall a. Divisive 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 = forall a. Floating a => a
P.pi
sin :: Double -> Double
sin = forall a. Floating a => a -> a
P.sin
cos :: Double -> Double
cos = forall a. Floating a => a -> a
P.cos
asin :: Double -> Double
asin = forall a. Floating a => a -> a
P.asin
acos :: Double -> Double
acos = forall a. Floating a => a -> a
P.acos
atan :: Double -> Double
atan = forall a. Floating a => a -> a
P.atan
atan2 :: Double -> Double -> Double
atan2 = forall a. RealFloat a => a -> a -> a
P.atan2
sinh :: Double -> Double
sinh = forall a. Floating a => a -> a
P.sinh
cosh :: Double -> Double
cosh = forall a. Floating a => a -> a
P.cosh
asinh :: Double -> Double
asinh = forall a. Floating a => a -> a
P.sinh
acosh :: Double -> Double
acosh = forall a. Floating a => a -> a
P.acosh
atanh :: Double -> Double
atanh = forall a. Floating a => a -> a
P.atanh
instance TrigField P.Float where
pi :: Float
pi = forall a. Floating a => a
P.pi
sin :: Float -> Float
sin = forall a. Floating a => a -> a
P.sin
cos :: Float -> Float
cos = forall a. Floating a => a -> a
P.cos
asin :: Float -> Float
asin = forall a. Floating a => a -> a
P.asin
acos :: Float -> Float
acos = forall a. Floating a => a -> a
P.acos
atan :: Float -> Float
atan = forall a. Floating a => a -> a
P.atan
atan2 :: Float -> Float -> Float
atan2 = forall a. RealFloat a => a -> a -> a
P.atan2
sinh :: Float -> Float
sinh = forall a. Floating a => a -> a
P.sinh
cosh :: Float -> Float
cosh = forall a. Floating a => a -> a
P.cosh
asinh :: Float -> Float
asinh = forall a. Floating a => a -> a
P.sinh
acosh :: Float -> Float
acosh = forall a. Floating a => a -> a
P.acosh
atanh :: Float -> Float
atanh = forall a. Floating a => a -> a
P.atanh
instance (TrigField b) => TrigField (a -> b) where
pi :: a -> b
pi a
_ = forall a. TrigField a => a
pi
sin :: (a -> b) -> a -> b
sin a -> b
f = forall a. TrigField a => a -> a
sin forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
cos :: (a -> b) -> a -> b
cos a -> b
f = forall a. TrigField a => a -> a
cos forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
asin :: (a -> b) -> a -> b
asin a -> b
f = forall a. TrigField a => a -> a
asin forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
acos :: (a -> b) -> a -> b
acos a -> b
f = forall a. TrigField a => a -> a
acos forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
atan :: (a -> b) -> a -> b
atan a -> b
f = forall a. TrigField a => a -> a
atan 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 = 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 = forall a. TrigField a => a -> a
sinh forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
cosh :: (a -> b) -> a -> b
cosh a -> b
f = forall a. TrigField a => a -> a
cosh forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
asinh :: (a -> b) -> a -> b
asinh a -> b
f = forall a. TrigField a => a -> a
asinh forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
acosh :: (a -> b) -> a -> b
acosh a -> b
f = forall a. TrigField a => a -> a
acosh forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
atanh :: (a -> b) -> a -> b
atanh a -> b
f = forall a. TrigField a => a -> a
atanh forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f
half :: (Field a) => a
half :: forall a. Field a => a
half = forall a. Multiplicative a => a
one forall a. Divisive a => a -> a -> a
/ forall a. (Multiplicative a, Additive a) => a
two