I'm currently writing some test code in a second-degree extension of GF(11). Specifically, elements of this extension are represented as (x + yu), where u^2 = 2. I am using the semirings interface for this, defining things as so:
-- Prelude is imported qualified as P, any clashing operations not qualified as from `semirings`
newtype GF11Elem2 = GF11E2 (Int, Int)
deriving (Eq) via (Int, Int)
instance Semiring GF11Elem2 where
plus (GF11E2 (r1, i1)) (GF11E2 (r2, i2)) = GF11E2 . reduce $ (r1 + r2, i1 + i2)
times (GF11E2 (r1, i1)) (GF11E2 (r2, i2)) =
let r1r2 = r1 * r2
r1i2 = r1 * i2
i1r2 = i1 * r2
i1i2 = i1 * i2
in GF11E2 . reduce $ (r1r2 + 2 * i1i2, r1i2 + i1r2)
zero = GF11E2 (0, 0)
one = GF11E2 (1, 0)
fromNatural n = GF11E2 (P.fromIntegral $ n `mod` 11, 0)
instance Ring GF11Elem2 where
negate (GF11E2 (r, i)) = GF11E2 . reduce $ (negate r, negate i)
instance GcdDomain GF11Elem2
instance Euclidean GF11Elem2 where
quot (GF11E2 (u, v)) = \case
GF11E2 (0, 0) -> P.error "Division by zero"
GF11E2 (x, y) -> let recipExpr = (x * x) - (2 * y * y)
(_, recipr) = gcdExt recipExpr 11
ux = u * x
yv = y * v
xv = x * v
uy = u * y
in GF11E2 . reduce $ ((ux - (2 * yv)) * recipr, (xv - uy) * recipr)
rem _ = \case
GF11E2 (0, 0) -> P.error "Division by zero"
_ -> zero
quotRem x y = let !q = quot x y
in (q, zero)
degree = const zero
-- Helpers
reduce ::
forall (f :: Type -> Type -> Type) (a :: Type).
(Bifunctor f, Integral a) => f a a -> f a a
reduce = bimap (`mod` 11) (`mod` 11)
Part of my test code requires testing for squarefreeness of polynomials over GF11Elem2, as per this method. My 'initial' polynomials are always of the form toPoly [B, A, 0, 1], where A and B are constants. However, I find that even the initial gcd f (deriv f) loops forever, or at least runs so slowly it might as well loop forever. Furthermore, if I use the boxed polynomial representation, I rapidly exhaust all available RAM; switching to unboxed representation solves this (but still runs forever).
Am I missing something here, or is there some kind of bug or performance limitation in poly I need to be aware of?
I'm currently writing some test code in a second-degree extension of
GF(11). Specifically, elements of this extension are represented as(x + yu), whereu^2 = 2. I am using thesemiringsinterface for this, defining things as so:Part of my test code requires testing for squarefreeness of polynomials over
GF11Elem2, as per this method. My 'initial' polynomials are always of the formtoPoly [B, A, 0, 1], whereAandBare constants. However, I find that even the initialgcd f (deriv f)loops forever, or at least runs so slowly it might as well loop forever. Furthermore, if I use the boxed polynomial representation, I rapidly exhaust all available RAM; switching to unboxed representation solves this (but still runs forever).Am I missing something here, or is there some kind of bug or performance limitation in
polyI need to be aware of?