module MathObj.Wrapper.NumericPrelude where
import qualified Algebra.Absolute as Absolute
import qualified Algebra.Additive as Additive
import qualified Algebra.Algebraic as Algebraic
import qualified Algebra.Field as Field
import qualified Algebra.FloatingPoint as Float
import qualified Algebra.IntegralDomain as Integral
import qualified Algebra.PrincipalIdealDomain as PID
import qualified Algebra.RealField as RealField
import qualified Algebra.RealIntegral as RealIntegral
import qualified Algebra.RealRing as RealRing
import qualified Algebra.RealTranscendental as RealTrans
import qualified Algebra.Ring as Ring
import qualified Algebra.ToInteger as ToInteger
import qualified Algebra.ToRational as ToRational
import qualified Algebra.Transcendental as Trans
import qualified Algebra.Units as Units
import qualified Algebra.ZeroTestable as ZeroTestable
import qualified Algebra.NormedSpace.Euclidean as NormEuc
import qualified Algebra.NormedSpace.Maximum as NormMax
import qualified Algebra.NormedSpace.Sum as NormSum
import qualified Algebra.OccasionallyScalar as OccScalar
import qualified Algebra.Differential as Differential
import qualified Algebra.DivisibleSpace as Divisible
import qualified Algebra.VectorSpace as VectorSpace
import qualified Algebra.Module as Module
import qualified Number.Ratio as Ratio
import Data.Ix (Ix, )
import Data.Tuple.HT (mapPair, )
newtype T a = Cons {decons :: a}
deriving
(Show, Eq, Ord, Ix, Bounded, Enum,
Ring.C, Additive.C, Field.C, Algebraic.C, Trans.C,
Integral.C, PID.C, Units.C,
Absolute.C, ZeroTestable.C,
RealField.C, RealIntegral.C, RealRing.C, RealTrans.C,
ToInteger.C, ToRational.C, Float.C,
Differential.C)
lift1 :: (a -> b) -> T a -> T b
lift1 f (Cons a) = Cons (f a)
lift2 :: (a -> b -> c) -> T a -> T b -> T c
lift2 f (Cons a) (Cons b) = Cons (f a b)
instance Functor T where
fmap f (Cons a) = Cons (f a)
instance (Ring.C a, Absolute.C a, Eq a, Show a) => Num (T a) where
(+) = lift2 (Additive.+)
() = lift2 (Additive.-)
negate = lift1 Additive.negate
fromInteger = Cons . Ring.fromInteger
(*) = lift2 (Ring.*)
abs = lift1 Absolute.abs
signum = lift1 Absolute.signum
instance (RealIntegral.C a, Absolute.C a, ToInteger.C a, Ord a, Enum a, Show a) => Integral (T a) where
quot = lift2 RealIntegral.quot
rem = lift2 RealIntegral.rem
quotRem (Cons a) (Cons b) =
mapPair (Cons, Cons) (RealIntegral.quotRem a b)
div = lift2 Integral.div
mod = lift2 Integral.mod
divMod (Cons a) (Cons b) =
mapPair (Cons, Cons) (Integral.divMod a b)
toInteger (Cons a) = ToInteger.toInteger a
instance (Field.C a, Absolute.C a, Eq a, Show a) => Fractional (T a) where
(/) = lift2 (Field./)
recip = lift1 Field.recip
fromRational = Cons . Field.fromRational
instance (Trans.C a, Absolute.C a, Eq a, Show a) => Floating (T a) where
sqrt = lift1 Algebraic.sqrt
pi = Cons Trans.pi
log = lift1 Trans.log
exp = lift1 Trans.exp
logBase = lift2 Trans.logBase
(**) = lift2 (Trans.**)
cos = lift1 Trans.cos
tan = lift1 Trans.tan
sin = lift1 Trans.sin
acos = lift1 Trans.acos
atan = lift1 Trans.atan
asin = lift1 Trans.asin
cosh = lift1 Trans.cosh
tanh = lift1 Trans.tanh
sinh = lift1 Trans.sinh
acosh = lift1 Trans.acosh
atanh = lift1 Trans.atanh
asinh = lift1 Trans.asinh
instance (ToRational.C a, Absolute.C a, Ord a, Show a) => Real (T a) where
toRational (Cons a) =
Ratio.toRational98 (ToRational.toRational a)
instance (Field.C a, RealRing.C a, ToRational.C a, Absolute.C a, Ord a, Show a) => RealFrac (T a) where
properFraction (Cons a) =
let b = RealRing.truncate a
in (fromInteger b, Cons (a Additive.- Ring.fromInteger b))
ceiling (Cons a) = fromInteger (RealRing.ceiling a)
floor (Cons a) = fromInteger (RealRing.floor a)
truncate (Cons a) = fromInteger (RealRing.truncate a)
round (Cons a) = fromInteger (RealRing.round a)
instance (RealTrans.C a, Float.C a, ToRational.C a, Absolute.C a, Ord a, Show a) => RealFloat (T a) where
atan2 = RealTrans.atan2
floatRadix = Float.radix . decons
floatDigits = Float.digits . decons
floatRange = Float.range . decons
decodeFloat = Float.decode . decons
encodeFloat m = Cons . Float.encode m
exponent = Float.exponent . decons
significand = lift1 Float.significand
scaleFloat = lift1 . Float.scale
isNaN = Float.isNaN . decons
isInfinite = Float.isInfinite . decons
isDenormalized = Float.isDenormalized . decons
isNegativeZero = Float.isNegativeZero . decons
isIEEE = Float.isIEEE . decons
instance Module.C a v => Module.C (T a) (T v) where
(*>) = lift2 (Module.*>)
instance VectorSpace.C a v => VectorSpace.C (T a) (T v) where
instance Divisible.C a v => Divisible.C (T a) (T v) where
(</>) = lift2 (Divisible.</>)
instance OccScalar.C a v => OccScalar.C (T a) (T v) where
toScalar = lift1 OccScalar.toScalar
toMaybeScalar (Cons a) = fmap Cons (OccScalar.toMaybeScalar a)
fromScalar = lift1 OccScalar.fromScalar
instance NormEuc.Sqr a v => NormEuc.Sqr (T a) (T v) where
normSqr = lift1 NormEuc.normSqr
instance NormEuc.C a v => NormEuc.C (T a) (T v) where
norm = lift1 NormEuc.norm
instance NormMax.C a v => NormMax.C (T a) (T v) where
norm = lift1 NormMax.norm
instance NormSum.C a v => NormSum.C (T a) (T v) where
norm = lift1 NormSum.norm
unimplemented :: String -> a
unimplemented name =
error (name ++ "cannot be implemented in terms of NumericPrelude type classes")