{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Number.GaloisField2p32m5 where
import qualified Number.ResidueClass as RC
import qualified Algebra.ZeroTestable as ZeroTestable
import qualified Algebra.Module as Module
import qualified Algebra.Field as Field
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import Data.Int (Int64, )
import Data.Word (Word32, Word64, )
import qualified Foreign.Storable.Newtype as SN
import qualified Foreign.Storable as St
import Test.QuickCheck (Arbitrary(arbitrary), )
import NumericPrelude.Base
import NumericPrelude.Numeric
newtype T = Cons {T -> Word32
decons :: Word32}
deriving T -> T -> Bool
(T -> T -> Bool) -> (T -> T -> Bool) -> Eq T
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: T -> T -> Bool
$c/= :: T -> T -> Bool
== :: T -> T -> Bool
$c== :: T -> T -> Bool
Eq
{-# INLINE appPrec #-}
appPrec :: Int
appPrec :: Int
appPrec = Int
10
instance Show T where
showsPrec :: Int -> T -> ShowS
showsPrec Int
p (Cons Word32
x) =
Int -> Word32 -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
p Word32
x
instance Arbitrary T where
arbitrary :: Gen T
arbitrary = (Integer -> T) -> Gen Integer -> Gen T
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word32 -> T
Cons (Word32 -> T) -> (Integer -> Word32) -> Integer -> T
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Word32
forall a. C a => Integer -> a
fromInteger (Integer -> Word32) -> (Integer -> Integer) -> Integer -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Integer -> Integer
forall a. C a => a -> a -> a
mod Integer
forall a. C a => a
base) Gen Integer
forall a. Arbitrary a => Gen a
arbitrary
instance St.Storable T where
sizeOf :: T -> Int
sizeOf = (T -> Word32) -> T -> Int
forall core wrapper.
Storable core =>
(wrapper -> core) -> wrapper -> Int
SN.sizeOf T -> Word32
decons
alignment :: T -> Int
alignment = (T -> Word32) -> T -> Int
forall core wrapper.
Storable core =>
(wrapper -> core) -> wrapper -> Int
SN.alignment T -> Word32
decons
peek :: Ptr T -> IO T
peek = (Word32 -> T) -> Ptr T -> IO T
forall core wrapper.
Storable core =>
(core -> wrapper) -> Ptr wrapper -> IO wrapper
SN.peek Word32 -> T
Cons
poke :: Ptr T -> T -> IO ()
poke = (T -> Word32) -> Ptr T -> T -> IO ()
forall core wrapper.
Storable core =>
(wrapper -> core) -> Ptr wrapper -> wrapper -> IO ()
SN.poke T -> Word32
decons
base :: Ring.C a => a
base :: a
base = a
2a -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
32a -> a -> a
forall a. C a => a -> a -> a
-a
5
{-# INLINE lift2 #-}
lift2 :: (Word64 -> Word64 -> Word64) -> (T -> T -> T)
lift2 :: (Word64 -> Word64 -> Word64) -> T -> T -> T
lift2 Word64 -> Word64 -> Word64
f (Cons Word32
x) (Cons Word32
y) =
Word32 -> T
Cons (Word64 -> Word32
forall a b. (C a, C b) => a -> b
fromIntegral (Word64 -> Word64 -> Word64
forall a. C a => a -> a -> a
mod (Word64 -> Word64 -> Word64
f (Word32 -> Word64
forall a b. (C a, C b) => a -> b
fromIntegral Word32
x) (Word32 -> Word64
forall a b. (C a, C b) => a -> b
fromIntegral Word32
y)) Word64
forall a. C a => a
base))
{-# INLINE lift2Integer #-}
lift2Integer :: (Int64 -> Int64 -> Int64) -> (T -> T -> T)
lift2Integer :: (Int64 -> Int64 -> Int64) -> T -> T -> T
lift2Integer Int64 -> Int64 -> Int64
f (Cons Word32
x) (Cons Word32
y) =
Word32 -> T
Cons (Int64 -> Word32
forall a b. (C a, C b) => a -> b
fromIntegral (Int64 -> Int64 -> Int64
forall a. C a => a -> a -> a
mod (Int64 -> Int64 -> Int64
f (Word32 -> Int64
forall a b. (C a, C b) => a -> b
fromIntegral Word32
x) (Word32 -> Int64
forall a b. (C a, C b) => a -> b
fromIntegral Word32
y)) Int64
forall a. C a => a
base))
instance Additive.C T where
zero :: T
zero = Word32 -> T
Cons Word32
forall a. C a => a
zero
+ :: T -> T -> T
(+) = (Word64 -> Word64 -> Word64) -> T -> T -> T
lift2 Word64 -> Word64 -> Word64
forall a. C a => a -> a -> a
(+)
T
x- :: T -> T -> T
-T
y = T
x T -> T -> T
forall a. C a => a -> a -> a
+ T -> T
forall a. C a => a -> a
negate T
y
negate :: T -> T
negate n :: T
n@(Cons Word32
x) =
if Word32
xWord32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
==Word32
0
then T
n
else Word32 -> T
Cons (Word32
forall a. C a => a
baseWord32 -> Word32 -> Word32
forall a. C a => a -> a -> a
-Word32
x)
instance Ring.C T where
one :: T
one = Word32 -> T
Cons Word32
forall a. C a => a
one
* :: T -> T -> T
(*) = (Word64 -> Word64 -> Word64) -> T -> T -> T
lift2 Word64 -> Word64 -> Word64
forall a. C a => a -> a -> a
(*)
fromInteger :: Integer -> T
fromInteger =
Word32 -> T
Cons (Word32 -> T) -> (Integer -> Word32) -> Integer -> T
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Word32
forall a. C a => Integer -> a
fromInteger (Integer -> Word32) -> (Integer -> Integer) -> Integer -> Word32
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> Integer -> Integer) -> Integer -> Integer -> Integer
forall a b c. (a -> b -> c) -> b -> a -> c
flip Integer -> Integer -> Integer
forall a. C a => a -> a -> a
mod Integer
forall a. C a => a
base
instance Field.C T where
/ :: T -> T -> T
(/) = (Int64 -> Int64 -> Int64) -> T -> T -> T
lift2Integer (Int64 -> Int64 -> Int64 -> Int64
forall a. C a => a -> a -> a -> a
RC.divide Int64
forall a. C a => a
base)
instance Module.C T T where
*> :: T -> T -> T
(*>) = T -> T -> T
forall a. C a => a -> a -> a
(*)
instance ZeroTestable.C T where
isZero :: T -> Bool
isZero T
x = T
forall a. C a => a
zero T -> T -> Bool
forall a. Eq a => a -> a -> Bool
== T
x