> < ^ Date: Mon, 21 Oct 2002 10:29:13 -0600 (MDT)
> < ^ From: Alexander Hulpke <hulpke@math.colostate.edu >
< ^ Subject: Re: Polynomials over Z/nZ?

Dear GAP-Forum,

Alon Amit wrote:

It seems that GAP is not willing to consider polynomials over the ring
Z/nZ when n is not prime. For instance,

gap> R:=Integers mod 4;
(Integers mod 4)
gap> x:=Indeterminate(R);
Error, You can only create rational functions over a UFD called from

As far as I could tell, the manual doesn't indicate that the underlying
ring needs to be a UFD, but all the examples given are over such rings.
Am I missing something? Is there a workaround? I simply need to make
some horrendous polynomial multiplications over Z/4Z.

When forming quotients of polynomials, there are occasions where the
routines need to obtain the gcd of the coefficients of a polynomial. Since
this potentially can cause problems later, the routines refuse to form
polynomial rings over non-UFDs. (There is a small remark on this at the end
of the introduction of the chapter on polynomials.)

If you never do quotients of polynomials and do not need to compute the gcd
(which basically skips the deliberate error message).

I hope this is of help,

Alexander Hulpke

-- Colorado State University, Department of Mathematics,
Weber Building, 1874 Campus Delivery, Fort Collins, CO 80523-1874, USA
email: hulpke@math.colostate.edu, Phone: ++1-970-4914288
http://www.math.colostate.edu/~hulpke

Save this in a file and read it in:

```#############################################################################
##
#M  RationalFunctionsFamily( <fam> )
##
InstallOtherMethod( RationalFunctionsFamily, true, [ IsObject ], 1,
function( efam )
local   fam;
```

if not IsUFDFamily(efam) then
Info(InfoWarning,1,"underlying ring is not an UFD\n",
" -- you might run into problems when taking quotients");
fi;

# create a new family in the category <IsRationalFunctionsFamily>
fam := NewFamily(
"RationalFunctionsFamily(...)",
IsRationalFunction and IsRationalFunctionsFamilyElement,
CanEasilySortElements,
IsUFDFamily and IsRationalFunctionsFamily and CanEasilySortElements);

# default type for rational functions
fam!.defaultRatFunType := NewType( fam,
IsRationalFunctionDefaultRep and
HasExtRepNumeratorRatFun and HasExtRepDenominatorRatFun);

# default type for polynomials
fam!.defaultPolynomialType := NewType( fam,
IsPolynomial and IsPolynomialDefaultRep and
HasExtRepPolynomialRatFun);

# default type for univariate laurent polynomials
fam!.threeLaurentPolynomialTypes :=
[ NewType( fam,
IsLaurentPolynomial
and IsLaurentPolynomialDefaultRep and
HasIndeterminateNumberOfLaurentPolynomial and
HasCoefficientsOfLaurentPolynomial),

NewType( fam,
IsLaurentPolynomial
and IsLaurentPolynomialDefaultRep and
HasIndeterminateNumberOfLaurentPolynomial and
HasCoefficientsOfLaurentPolynomial and
IsConstantRationalFunction and IsUnivariatePolynomial),

NewType( fam,
IsLaurentPolynomial and IsLaurentPolynomialDefaultRep and
HasIndeterminateNumberOfLaurentPolynomial and
HasCoefficientsOfLaurentPolynomial and
IsUnivariatePolynomial)];

# default type for univariate rational functions
fam!.univariateRatfunType := NewType( fam,
IsUnivariateRationalFunctionDefaultRep and
HasIndeterminateNumberOfLaurentPolynomial and
HasCoefficientsOfUnivariateRationalFunction);

# functions to add zipped lists
fam!.zippedSum := [ MONOM_GRLEX, \+ ];

# functions to multiply zipped lists
fam!.zippedProduct := [ MONOM_PROD,
MONOM_GRLEX, \+, \* ];

# set the one and zero coefficient
fam!.zeroCoefficient := Zero(efam);
fam!.oneCoefficient := One(efam);
fam!.oneCoefflist := Immutable([fam!.oneCoefficient]);

# set the coefficients
SetCoefficientsFamily( fam, efam );

# Set the characteristic.
if HasCharacteristic( efam ) then
SetCharacteristic( fam, Characteristic( efam ) );
fi;

# and set one and zero
SetZero( fam, PolynomialByExtRep(fam,[]));
SetOne( fam, PolynomialByExtRep(fam,[[],fam!.oneCoefficient]));

# we will store separate `one's for univariate polynomials. This will
# allow to keep univariate calculations in this one indeterminate.
fam!.univariateOnePolynomials:=[];
fam!.univariateZeroPolynomials:=[];

# assign a names list
fam!.namesIndets := [];

# and return
return fam;

```end );
```