/*
------------------------------------------------------------------------
Efficient Galois Fields in Maxima
by Alasdair McAndrew
and later extended by Fabrizio Caruso and Jacopo Daurizio
it is distribuited together with gf_roots by Jacopo Daurizio
Authors:
Fabrizio Caruso (optimizations, testing)
Jacopo D'Aurizio (optimizations, modular roots)
Alasdair McAndrew (original version of the package, pohlig-helman log, etc... )
------------------------------------------------------------------------*/
/* Released under terms of the GNU General Public License, version 2,
* by permission of the authors to Robert Dodier circa 2007-12-02.
*/
/* Defines a flag for dealing with large fields. If it is set to "false",
then lookup tables are used for exponentiation and logarithms. Otherwise
other algorithms are used */
define_variable(largefield,true,bool)$
define_variable(gf_char,0,integer)$
define_variable(gf_exp,0,integer)$
define_variable(gf_order,0,integer)$
define_variable (gf_one, 'gf_one, any_check)$
define_variable (gf_prim, 'gf_prim, any_check)$
define_variable (gf_irr, 'gf_irr, any_check)$
define_variable (gf_list, 'gf_list, any_check)$
define_variable (gen_powers, 'gf_list, any_check)$
remvalue(x,z,gf_char,gf_exp,gf_irr,pg,gp,lg,gf_prim,gf_one,gf_order,gf_list,gen_powers)$
/* --------------------------------------------------------------------------------------------- */
/* Settings */
GF_VERBOSE:false; /* Verbosity */
GF_WARNING: true; /* Warnings */
GF_IRREDUCIBILITY_CHECK:false; /* Irreducibility test for the minimal polynomial of the extension */
/*
------------------------------------------------------------------------------------------------ */
/* It defines a new current field with gf_char=b, min. pol.= p of deg= e*/
gf_set([ars]):=block([gj,m,i,j,dg],
if length(ars)=1 then
(
gf_setp(ars[1]),
return(true)
)
else
(
if length(ars)=2 then
(
if numberp(ars[2]) then
(
if ars[2]=0 and GF_WARNING then
(
print("WARNING: the irreducible is zero! We assume GF(",ars[1],")"),
gf_setp(ars[1]),
return(true)
)
else
(
error("ERROR: you tried to extend with a non-zero constant!"),
return(false)
)
)
else
(
dg:hipow(ars[2],x),
if dg=1 then
gf_setp(ars[1]),
gf_irr:ars[2],
gf_exp:dg,
return(true)
)
)
else
(
gf_exp:ars[2],
if gf_exp=1 then
(
gf_setp(ars[1]),
gf_irr:rat(ars[3]),
return(true)
),
gf_irr:rat(ars[3])
)
),
gf_char:ars[1],
gf_one:rat(1,x),
gf_order:gf_char^gf_exp-1,
m:makelist(coeff(gf_irr,x,i),i,0,gf_exp),
gf_list:[[first(m),0]],j:1,
for i:2 thru gf_exp+1 do if m[i]=0 then j:j+1 else ( gf_list:endcons([m[i],j],gf_list), j:1 ),
if not(primep(gf_char)) then error("ERROR: Gf_Char must be a prime number.")
else
modulus:gf_char,
if GF_IRREDUCIBILITY_CHECK and
hipow(args(factor(ars[3]))[1],x)#hipow(rat(ars[3]),x) then
error("ERROR: Polynomial is not irreducible"),
if not(largefield) then
(
pg:mkpowers(),
lg:mklogs()
)
else
(
if GF_VERBOSE then
print("finding a primitive element..."),
gf_prim:rat(gf_findprim(),x),
if GF_VERBOSE then
print("...primitive element found.")
),
modulus:false, /* it resets the modulus */
return(true)
)$
/* Prints out information about the field */
gf_info():=block(
print("Prime gf_char value: ",gf_char),
print("Exponent: ", gf_exp),
print("Multiplicative order: ",gf_order),
print("Irreducible polynomial: ",gf_irr),
print("Primitive element: ",gf_prim),
if (largefield) then
print("Largefield flag is true; powers and logarithms not computed.")
else
print("Largefield flag is false; powers and logarithms computed."),
disp()
)$