diff --git a/etc/ffgen.c b/etc/ffgen.c index 05f6c6ced0..46df593257 100644 --- a/etc/ffgen.c +++ b/etc/ffgen.c @@ -7,6 +7,8 @@ #include #include "gen/config.h" +/* These next lines control the size of internal finite field elements + in GAP. Changes here will propagate as needed */ #if (SIZEOF_VOID_P == 8) #define MAX_FF (1 << 24) #else @@ -44,109 +46,116 @@ void make_ff() ch[j] = i; num_ff++; } - if (d > 0 && d-1 > max_deg) - max_deg = d-1; + if (d > 0 && d - 1 > max_deg) + max_deg = d - 1; } } } -unsigned int needed_bits(unsigned int x) { +unsigned int needed_bits(unsigned int x) +{ if (x == 0) return 0; return 1 + needed_bits(x >> 1); } -void emit_code(FILE *dest, int header) +void emit_code(FILE * dest, int header) { unsigned i, j; if (header) { - fprintf( dest,"#ifndef GAP_FFDATA_H\n"); - fprintf( dest,"#define GAP_FFDATA_H\n"); - fprintf( dest,"\n"); - fprintf( dest,"enum {\n"); - fprintf( dest," NUM_SHORT_FINITE_FIELDS = %d,\n", num_ff); - fprintf( dest," SIZE_LARGEST_INTERNAL_FF = %d,\n", MAX_FF); - fprintf( dest," DEGREE_LARGEST_INTERNAL_FF = %d,\n", max_deg); - fprintf( dest," FIELD_BITS_FFE = %d,\n", needed_bits(num_ff)); - fprintf( dest," VAL_BITS_FFE = %d\n", needed_bits(MAX_FF-1)); - fprintf( dest,"};\n"); - fprintf( dest,"\n"); - fprintf( dest,"extern UInt4 SizeFF[NUM_SHORT_FINITE_FIELDS+1];\n"); - fprintf( dest,"extern UInt1 DegrFF[NUM_SHORT_FINITE_FIELDS+1];\n"); - fprintf( dest,"extern UInt4 CharFF[NUM_SHORT_FINITE_FIELDS+1];\n"); - fprintf( dest,"\n"); + fprintf(dest, "/* This file is generated by etc/ffgen.c during build" + " do not edit */\n"); + fprintf(dest, "#ifndef GAP_FFDATA_H\n"); + fprintf(dest, "#define GAP_FFDATA_H\n"); + fprintf(dest, "\n"); + fprintf(dest, "enum {\n"); + fprintf(dest, " NUM_SHORT_FINITE_FIELDS = %d,\n", num_ff); + fprintf(dest, " MAXSIZE_GF_INTERNAL = %d,\n", MAX_FF); + fprintf(dest, " DEGREE_LARGEST_INTERNAL_FF = %d,\n", max_deg); + fprintf(dest, " FIELD_BITS_FFE = %d,\n", needed_bits(num_ff)); + fprintf(dest, " VAL_BITS_FFE = %d\n", needed_bits(MAX_FF - 1)); + fprintf(dest, "};\n"); + fprintf(dest, "\n"); + fprintf(dest, "extern UInt4 SizeFF[NUM_SHORT_FINITE_FIELDS+1];\n"); + fprintf(dest, "extern UInt1 DegrFF[NUM_SHORT_FINITE_FIELDS+1];\n"); + fprintf(dest, "extern UInt4 CharFF[NUM_SHORT_FINITE_FIELDS+1];\n"); + fprintf(dest, "\n"); if (num_ff < 65536) - fprintf( dest,"typedef UInt2 FF;\n"); + fprintf(dest, "typedef UInt2 FF;\n"); else - fprintf( dest,"typedef UInt4 FF;\n"); + fprintf(dest, "typedef UInt4 FF;\n"); if (MAX_FF <= 65536) - fprintf( dest,"typedef UInt2 FFV;\n"); + fprintf(dest, "typedef UInt2 FFV;\n"); else - fprintf( dest,"typedef UInt4 FFV;\n"); - fprintf( dest,"\n"); - fprintf( dest,"#endif // GAP_FFDATA_H\n"); + fprintf(dest, "typedef UInt4 FFV;\n"); + fprintf(dest, "\n"); + fprintf(dest, "#endif // GAP_FFDATA_H\n"); } else { - fprintf( dest,"#include \"system.h\"\n"); - fprintf( dest,"#include \"ffdata.h\"\n"); - fprintf( dest,"\n"); - fprintf( dest,"/* Entries are ordered by value of p^d; can use binary search\n"); - fprintf( dest," * to find them. Indices start at 1.\n"); - fprintf( dest," */\n"); - fprintf( dest,"\n"); - fprintf( dest,"UInt1 DegrFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); - fprintf( dest," %3d,", 0); + fprintf(dest, "/* This file is generated by etc/ffgen.c during build" + " do not edit */\n"); + fprintf(dest, "#include \"system.h\"\n"); + fprintf(dest, "#include \"ffdata.h\"\n"); + fprintf(dest, "\n"); + fprintf(dest, "/* Entries are ordered by value of p^d; can use " + "binary search\n"); + fprintf(dest, " * to find them. Indices start at 1.\n"); + fprintf(dest, " */\n"); + fprintf(dest, "\n"); + fprintf(dest, "UInt1 DegrFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); + fprintf(dest, " %3d,", 0); for (i = 0, j = 1; i <= MAX_FF; i++) { if (is_ff[i]) { - fprintf( dest,"%3d,", deg[i]); + fprintf(dest, "%3d,", deg[i]); j++; j %= 16; if (!j) - fprintf( dest,"\n "); + fprintf(dest, "\n "); } } if (j) - fprintf( dest,"\n"); - fprintf( dest,"};\n"); - fprintf( dest,"\n"); - fprintf( dest,"UInt4 CharFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); - fprintf( dest," %9d,", 0); + fprintf(dest, "\n"); + fprintf(dest, "};\n"); + fprintf(dest, "\n"); + fprintf(dest, "UInt4 CharFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); + fprintf(dest, " %9d,", 0); for (i = 0, j = 1; i <= MAX_FF; i++) { if (is_ff[i]) { - fprintf( dest,"%9d,", ch[i]); + fprintf(dest, "%9d,", ch[i]); j++; j %= 6; if (!j) - fprintf( dest,"\n "); + fprintf(dest, "\n "); } } if (j) - fprintf( dest,"\n"); - fprintf( dest,"};\n"); - fprintf( dest,"\n"); - fprintf( dest,"UInt4 SizeFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); - fprintf( dest," %9d,", 0); + fprintf(dest, "\n"); + fprintf(dest, "};\n"); + fprintf(dest, "\n"); + fprintf(dest, "UInt4 SizeFF[NUM_SHORT_FINITE_FIELDS+1] = {\n"); + fprintf(dest, " %9d,", 0); for (i = 0, j = 1; i <= MAX_FF; i++) { if (is_ff[i]) { - fprintf( dest,"%9d,", i); + fprintf(dest, "%9d,", i); j++; j %= 6; if (!j) - fprintf( dest,"\n "); + fprintf(dest, "\n "); } } if (j) - fprintf( dest,"\n"); - fprintf( dest,"};\n"); + fprintf(dest, "\n"); + fprintf(dest, "};\n"); } } -void emit_code_to_file_by_basename( int header, char *basename) { - char *filename = malloc(strlen(basename)+3); - strcpy(filename,basename); - strcat(filename, header ? ".h": ".c"); - FILE *f = fopen(filename,"w"); +void emit_code_to_file_by_basename(int header, char * basename) +{ + char * filename = malloc(strlen(basename) + 3); + strcpy(filename, basename); + strcat(filename, header ? ".h" : ".c"); + FILE * f = fopen(filename, "w"); if (!f) { perror("opening output file"); exit(EXIT_FAILURE); @@ -154,7 +163,7 @@ void emit_code_to_file_by_basename( int header, char *basename) { emit_code(f, header); fclose(f); } - + int main(int argc, char * argv[]) { @@ -168,15 +177,16 @@ int main(int argc, char * argv[]) else if (!strcmp(opt, "c") || !strcmp(opt, ".c") || !strcmp(opt, "-c")) emit_code(stdout, 0); else if (!strcmp(opt, "-b") && argc > 2) { - char *basename = argv[2]; + char * basename = argv[2]; emit_code_to_file_by_basename(0, basename); emit_code_to_file_by_basename(1, basename); } - else { + else { fprintf(stderr, "Usage: ffgen [-h|-c|-b basename]\n"); fprintf(stderr, " -h for header file\n"); fprintf(stderr, " -c for C source file\n"); - fprintf(stderr, " -b basename, makes both as basename.c and basename.h\n"); + fprintf(stderr, + " -b basename, makes both as basename.c and basename.h\n"); return 1; } return 0; diff --git a/lib/ffe.g b/lib/ffe.g index 5c7977decd..9ea7446e2c 100644 --- a/lib/ffe.g +++ b/lib/ffe.g @@ -16,9 +16,8 @@ ## #V MAXSIZE_GF_INTERNAL . . . . . . . . . . . . maximal size of internal ffes ## -## Set by the kernel, we just need to tidy up +## Now set by the kernel. -MakeReadOnlyGVar("MAXSIZE_GF_INTERNAL"); ############################################################################# diff --git a/src/finfield.c b/src/finfield.c index 31086b9718..a2a55f9579 100644 --- a/src/finfield.c +++ b/src/finfield.c @@ -39,17 +39,17 @@ */ Obj SuccFF; -Obj TypeFF; -Obj TypeFF0; +static Obj TypeFF; +static Obj TypeFF0; /**************************************************************************** ** *V TYPE_FFE . . . . . kernel copy of GAP function TYPE_FFE *V TYPE_FFE0 . . . . . kernel copy of GAP function TYPE_FFE0 -*V TYPE_KERNEL_OBJECT .local copy of GAP variable TYPE_KERNEL_OBJECT used to type -** successor bags -*V PrimitiveRootMod . .local copy of GAP function PrimitiveRootMod, used +*V TYPE_KERNEL_OBJECT .local copy of GAP variable TYPE_KERNEL_OBJECT used to +** type successor bags +*V PrimitiveRootMod . .local copy of GAP function PrimitiveRootMod, used ** when initializing new fields. ** ** These GAP functions are called to compute types of finite field elemnents @@ -57,7 +57,7 @@ Obj TypeFF0; static Obj TYPE_FFE; static Obj TYPE_FFE0; -static Obj TYPE_KERNEL_OBJECT; +static Obj TYPE_KERNEL_OBJECT; static Obj PrimitiveRootMod; /**************************************************************************** @@ -67,26 +67,26 @@ static Obj PrimitiveRootMod; ** 'PolsFF' is a list of Conway polynomials for finite fields. The even ** entries are the proper prime powers, odd entries are the corresponding ** Conway polynomials. -** +** ** This data is now held in a separate file, and includes all fields of ** orders up to 2^32, although not all of that information is used. */ -#include "finfield_conway.h" +#include "finfield_conway.h" /**************************************************************************** ** - *F lookupPrimePower ( q ) . . . . . .search for a prime power in tables - ** + *F LookupPrimePower ( q ) . . . . . .search for a prime power in tables + ** ** searches the tables of prime powers from ffdata.c for q, returns the index ** of q in SizeFF if it is present and 0 if not (the 0 position of SizeFF is ** unused). */ -static FF lookupPrimePower(UInt q) +static FF LookupPrimePower(UInt q) { - UInt l,n; - FF ff; + UInt l, n; + FF ff; UInt e; /* search through the finite field table */ l = 1; @@ -115,25 +115,28 @@ static FF lookupPrimePower(UInt q) /**************************************************************************** ** *F FiniteFieldBySize( ) . .make the small finite field with elements -*F FiniteField(

,) . . .make the small finite field with

^ elements +*F FiniteField(

,) . . .make the small finite field with

^ +** elements ** -** The work is done in the lookup function above, and in FiniteFieldBySize +** The work is done in the Lookup function above, and in FiniteFieldBySize ** where the successor tables are computed. */ -FF FiniteFieldBySize ( UInt q) +FF FiniteFieldBySize(UInt q) { - FF ff; /* finite field, result */ - Obj tmp; /* temporary bag */ - Obj succBag; /* successor table bag */ - FFV * succ; /* successor table */ - FFV * indx; /* index table */ - UInt poly; /* Conway polynomial of extension */ - UInt i, l, f, n, e; /* loop variables */ - Obj root; /* will be a primitive root mod p */ - - - ff = lookupPrimePower(q); + FF ff; /* finite field, result */ + Obj tmp; /* temporary bag */ + Obj succBag; /* successor table bag */ + FFV * succ; /* successor table */ + FFV * indx; /* index table */ + UInt poly; /* Conway polynomial of extension */ + UInt i, l, f, n, e; /* loop variables */ + Obj root; /* will be a primitive root mod p */ + + + ff = LookupPrimePower(q); + if (!ff) + return 0; #ifdef HPCGAP /* Important correctness concern here: @@ -153,73 +156,78 @@ FF FiniteFieldBySize ( UInt q) * tables. */ if (ATOMIC_ELM_PLIST(TypeFF0, ff)) - return ff; + return ff; #else if (ELM_PLIST(TypeFF0, ff)) - return ff; + return ff; #endif - /* allocate a bag for the successor table and one for a temporary */ - tmp = NewBag( T_DATOBJ, sizeof(Obj) + q * sizeof(FFV) ); - SET_TYPE_DATOBJ(tmp, TYPE_KERNEL_OBJECT ); + /* allocate a bag for the successor table and one for a temporary */ + tmp = NewBag(T_DATOBJ, sizeof(Obj) + q * sizeof(FFV)); + SET_TYPE_DATOBJ(tmp, TYPE_KERNEL_OBJECT); - succBag = NewBag( T_DATOBJ, sizeof(Obj) + q * sizeof(FFV) ); - SET_TYPE_DATOBJ(succBag, TYPE_KERNEL_OBJECT ); + succBag = NewBag(T_DATOBJ, sizeof(Obj) + q * sizeof(FFV)); + SET_TYPE_DATOBJ(succBag, TYPE_KERNEL_OBJECT); - indx = (FFV*)(1+ADDR_OBJ( tmp )); - succ = (FFV*)(1+ADDR_OBJ( succBag )); + indx = (FFV *)(1 + ADDR_OBJ(tmp)); + succ = (FFV *)(1 + ADDR_OBJ(succBag)); /* if q is a prime find the smallest primitive root $e$, use $x - e$ */ - - if ( DEGR_FF(ff) == 1 ) { - if ( q < 65537 ) { - /* for smaller primes we do this in the kernel for performance and bootstrapping - reasons - TODO -- review the threshold */ - for ( e = 1, i = 1; i != q-1; ++e ) { - for ( f = e, i = 1; f != 1; ++i ) + + if (DEGR_FF(ff) == 1) { + if (q < 65537) { + /* for smaller primes we do this in the kernel for performance and + bootstrapping reasons + TODO -- review the threshold */ + for (e = 1, i = 1; i != q - 1; ++e) { + for (f = e, i = 1; f != 1; ++i) f = (f * e) % q; } } else { /* Otherwise we ask the library */ - root=CALL_1ARGS(PrimitiveRootMod, INTOBJ_INT(q)); - e = INT_INTOBJ(root)+1; + root = CALL_1ARGS(PrimitiveRootMod, INTOBJ_INT(q)); + e = INT_INTOBJ(root) + 1; } - poly = q-(e-1); + poly = q - (e - 1); } /* otherwise look up the polynomial used to construct this field */ else { - for ( i = 0; PolsFF[i] != q; i += 2 ) ; - poly = PolsFF[i+1]; + for (i = 0; PolsFF[i] != q; i += 2) + ; + poly = PolsFF[i + 1]; } /* construct 'indx' such that 'e = x^(indx[e]-1) % poly' for every e */ - indx[ 0 ] = 0; + indx[0] = 0; UInt p = CHAR_FF(ff); - for ( e = 1, n = 0; n < q-1; ++n ) { - indx[ e ] = n + 1; + for (e = 1, n = 0; n < q - 1; ++n) { + indx[e] = n + 1; /* e =p*e mod poly =x*e mod poly =x*x^n mod poly =x^{n+1} mod poly */ - if ( p != 2 ) { - f = p * (e % (q/p)); l = ((p-1) * (e / (q/p))) % p; e = 0; - for ( i = 1; i < q; i *= p ) - e = e + i * ((f/i + l * (poly/i)) % p); + if (p != 2) { + f = p * (e % (q / p)); + l = ((p - 1) * (e / (q / p))) % p; + e = 0; + for (i = 1; i < q; i *= p) + e = e + i * ((f / i + l * (poly / i)) % p); } else { - if ( 2*e & q ) e = 2*e ^ poly ^ q; - else e = 2*e; + if (2 * e & q) + e = 2 * e ^ poly ^ q; + else + e = 2 * e; } } /* construct 'succ' such that 'x^(n-1)+1 = x^(succ[n]-1)' for every n */ - succ[ 0 ] = q-1; - for ( e = 1, f = p-1; e < q; e++ ) { - if ( e < f ) { - succ[ indx[e] ] = indx[ e+1 ]; + succ[0] = q - 1; + for (e = 1, f = p - 1; e < q; e++) { + if (e < f) { + succ[indx[e]] = indx[e + 1]; } else { - succ[ indx[e] ] = indx[ e+1-p ]; + succ[indx[e]] = indx[e + 1 - p]; f += p; } } @@ -227,22 +235,22 @@ FF FiniteFieldBySize ( UInt q) /* enter the finite field in the tables */ #ifdef HPCGAP MakeBagReadOnly(succBag); - ATOMIC_SET_ELM_PLIST_ONCE( SuccFF, ff, succBag ); + ATOMIC_SET_ELM_PLIST_ONCE(SuccFF, ff, succBag); CHANGED_BAG(SuccFF); - tmp = CALL_1ARGS( TYPE_FFE, INTOBJ_INT(p) ); - ATOMIC_SET_ELM_PLIST_ONCE( TypeFF, ff, tmp ); + tmp = CALL_1ARGS(TYPE_FFE, INTOBJ_INT(p)); + ATOMIC_SET_ELM_PLIST_ONCE(TypeFF, ff, tmp); CHANGED_BAG(TypeFF); - tmp = CALL_1ARGS( TYPE_FFE0, INTOBJ_INT(p) ); - ATOMIC_SET_ELM_PLIST_ONCE( TypeFF0, ff, tmp ); + tmp = CALL_1ARGS(TYPE_FFE0, INTOBJ_INT(p)); + ATOMIC_SET_ELM_PLIST_ONCE(TypeFF0, ff, tmp); CHANGED_BAG(TypeFF0); #else - ASS_LIST( SuccFF, ff, succBag ); + ASS_LIST(SuccFF, ff, succBag); CHANGED_BAG(SuccFF); - tmp = CALL_1ARGS( TYPE_FFE, INTOBJ_INT(p) ); - ASS_LIST( TypeFF, ff, tmp ); + tmp = CALL_1ARGS(TYPE_FFE, INTOBJ_INT(p)); + ASS_LIST(TypeFF, ff, tmp); CHANGED_BAG(TypeFF); - tmp = CALL_1ARGS( TYPE_FFE0, INTOBJ_INT(p) ); - ASS_LIST( TypeFF0, ff, tmp ); + tmp = CALL_1ARGS(TYPE_FFE0, INTOBJ_INT(p)); + ASS_LIST(TypeFF0, ff, tmp); CHANGED_BAG(TypeFF0); #endif @@ -250,21 +258,22 @@ FF FiniteFieldBySize ( UInt q) return ff; } -FF FiniteField ( - UInt p, - UInt d ) +FF FiniteField(UInt p, UInt d) { - UInt q,i; + UInt q, i; + FF f; /* calculate size of field */ q = 1; - for ( i = 1; i <= d; i++ ) + for (i = 1; i <= d; i++) q *= p; - return FiniteFieldBySize(q); + f = FiniteFieldBySize(q); + if (f != 0 && CHAR_FF(f) != p) + ErrorMayQuit("Characteristic of Finite Field must be prime, not %i", + p, 0); + return f; } - - /**************************************************************************** ** *F CommonFF(,,,) . . . . . . . . . . . . find a common field @@ -392,13 +401,12 @@ Obj FuncDEGREE_FFE_DEFAULT ( ** 'TypeFFE' is the function in 'TypeObjFuncs' for elements in small finite ** fields. */ -Obj TypeFFE ( - Obj ffe ) +Obj TypeFFE(Obj ffe) { - if (VAL_FFE(ffe) == 0) - return TYPE_FF0( FLD_FFE( ffe ) ); - else - return TYPE_FF( FLD_FFE( ffe ) ); + if (VAL_FFE(ffe) == 0) + return ELM_PLIST(TypeFF0, FLD_FFE(ffe)); + else + return ELM_PLIST(TypeFF, FLD_FFE(ffe)); } @@ -1499,10 +1507,10 @@ Obj FuncZ ( FF ff; /* the finite field */ /* check the argument */ - if ( (IS_INTOBJ(q) && (INT_INTOBJ(q) > SIZE_LARGEST_INTERNAL_FF)) || - (TNUM_OBJ(q) == T_INTPOS)) - return CALL_1ARGS(ZOp, q); - + if ((IS_INTOBJ(q) && (INT_INTOBJ(q) > MAXSIZE_GF_INTERNAL)) || + (TNUM_OBJ(q) == T_INTPOS)) + return CALL_1ARGS(ZOp, q); + if ( !IS_INTOBJ(q) || INT_INTOBJ(q)<=1 ) { q = ErrorReturnObj( "Z: must be a positive prime power (not a %s)", @@ -1512,14 +1520,14 @@ Obj FuncZ ( } ff = FiniteFieldBySize(INT_INTOBJ(q)); - + if (!ff) { ErrorMayQuit("Z: must be a positive prime power (not a %s)", (Int)TNAM_OBJ(q), 0L); } /* make the root */ - return NEW_FFE( ff, (q == INTOBJ_INT(2)) ? 1 : 2 ); + return NEW_FFE(ff, (q == INTOBJ_INT(2)) ? 1 : 2); } Obj FuncZ2(Obj self, Obj p, Obj d) @@ -1531,12 +1539,12 @@ Obj FuncZ2(Obj self, Obj p, Obj d) ip = INT_INTOBJ(p); id = INT_INTOBJ(d); if (ip > 1 && id > 0 && id <= DEGREE_LARGEST_INTERNAL_FF && - ip <= SIZE_LARGEST_INTERNAL_FF) { + ip <= MAXSIZE_GF_INTERNAL) { id1 = id; q = ip; - while (--id1 > 0 && q <= SIZE_LARGEST_INTERNAL_FF) + while (--id1 > 0 && q <= MAXSIZE_GF_INTERNAL) q *= ip; - if (q <= SIZE_LARGEST_INTERNAL_FF) { + if (q <= MAXSIZE_GF_INTERNAL) { /* get the finite field */ ff = FiniteFieldBySize(q); @@ -1544,7 +1552,7 @@ Obj FuncZ2(Obj self, Obj p, Obj d) ErrorMayQuit("Z:

must be a prime", 0, 0); /* make the root */ - return NEW_FFE( ff, (q == 2) ? 1 : 2 ); + return NEW_FFE(ff, (q == 2) ? 1 : 2); } } } @@ -1610,7 +1618,7 @@ static Int InitKernel ( ImportFuncFromLibrary( "TYPE_FFE", &TYPE_FFE ); ImportFuncFromLibrary( "TYPE_FFE0", &TYPE_FFE0 ); ImportFuncFromLibrary( "ZOp", &ZOp ); - InitFopyGVar( "PrimitiveRootMod", &PrimitiveRootMod ); + InitFopyGVar("PrimitiveRootMod", &PrimitiveRootMod); TypeObjFuncs[ T_FFE ] = TypeFFE; /* create the fields and integer conversion bags */ @@ -1695,7 +1703,8 @@ static Int InitLibrary ( InitGVarFuncsFromTable( GVarFuncs ); SET_HDLR_FUNC(ValGVar(GVarName("Z")), 2, FuncZ2); - AssGVar(GVarName("MAXSIZE_GF_INTERNAL"),INTOBJ_INT(SIZE_LARGEST_INTERNAL_FF)); + + ExportAsConstantGVar(MAXSIZE_GF_INTERNAL); /* return success */ return 0; diff --git a/src/finfield.h b/src/finfield.h index a2d19408cf..39d592b52b 100644 --- a/src/finfield.h +++ b/src/finfield.h @@ -12,7 +12,7 @@ ** ** Finite fields are an important domain in computational group theory ** because the classical matrix groups are defined over those finite fields. -** The GAP kernel supports elements of finite fields up to some fixed size +** The GAP kernel supports elements of finite fields up to some fixed size ** limit, typically 2^16 on 32 bit systems and 2^24 on 64 bit systems. ** To change the limits, edit etc/ffgen.c. To access the current limits use ** MAXSIZE_GF_INTERNAL. Support for larger fields is implemented by the @@ -27,8 +27,8 @@ ** The least significant 3 bits of such an immediate object are always 010, ** flagging the object as an object of a small finite field. ** -** The next group of FIELD_BITS_FFE bits represent the small finite field -** where the element lies. They are simply an index into a global table of +** The next group of FIELD_BITS_FFE bits represent the small finite field +** where the element lies. They are simply an index into a global table of ** small finite fields, which is constructed at build time. ** ** The most significant VAL_BITS_FFE bits represent the value of the element. @@ -57,6 +57,7 @@ #define GAP_FINFIELD_H #include "system.h" +#include "objects.h" #include "ffdata.h" /**************************************************************************** @@ -72,7 +73,6 @@ */ - /**************************************************************************** ** *F CHAR_FF() . . . . . . . . . . . characteristic of small finite field @@ -123,24 +123,6 @@ extern Obj SuccFF; - -/**************************************************************************** -** -*F TYPE_FF() . . . . . . . . . . . . . . . type of a small finite field -** -** 'TYPE_FF' returns the type of elements of the small finite field . -** 'TYPE_FF0' returns the type of the zero of -** -** Note that 'TYPE_FF' and TypeFF0 are macros, so do not call them -** with arguments that have side effects. -*/ -#define TYPE_FF(ff) (ELM_PLIST( TypeFF, ff )) -#define TYPE_FF0(ff) (ELM_PLIST( TypeFF0, ff )) - -extern Obj TypeFF; -extern Obj TypeFF0; - - /**************************************************************************** ** *T FFV . . . . . . . . type of the values of elements of small finite fields @@ -152,7 +134,7 @@ extern Obj TypeFF0; ** logarithm of the element with respect to the root plus one. ** ** Depending on the configuration, this type may be a UInt2 or UInt4. -** This type is actually defined in gen/ffdata.h ffgen +** This type is actually defined in gen/ffdata.h by etc/ffgen.c */ /**************************************************************************** @@ -171,16 +153,17 @@ extern Obj TypeFF0; ** otherwise we have $a * b ~ z^{(a+b-2)-(o-1)} = z^{(a+b-o)-1} ~ a+b-o$ */ -static inline FFV PROD_FFV(FFV a, FFV b, const FFV *f) { +static inline FFV PROD_FFV(FFV a, FFV b, const FFV * f) +{ GAP_ASSERT(a <= f[0]); GAP_ASSERT(b <= f[0]); if (a == 0 || b == 0) return 0; UInt q1 = f[0]; - if (a - 1 <= q1-b) - return a+b-1; + if (a - 1 <= q1 - b) + return a + b - 1; else - return a+b-1-q1; + return a + b - 1 - q1; } @@ -202,7 +185,8 @@ static inline FFV PROD_FFV(FFV a, FFV b, const FFV *f) { ** $a + b ~ z^{b-1}+z^{a-1} = z^{b-1} * (z^{(a-1)-(b-1)}+1) ~ b * f[a-b+1]$. */ -static inline FFV SUM_FFV( FFV a, FFV b, const FFV *f) { +static inline FFV SUM_FFV(FFV a, FFV b, const FFV * f) +{ GAP_ASSERT(a <= f[0]); GAP_ASSERT(b <= f[0]); if (a == 0) @@ -214,11 +198,10 @@ static inline FFV SUM_FFV( FFV a, FFV b, const FFV *f) { a = b; b = t; } - return PROD_FFV(b, f[a - b + 1], f); + return PROD_FFV(b, f[a - b + 1], f); } - /**************************************************************************** ** *F NEG_FFV(,) . . . . . . . . . . . . negative of finite field value @@ -234,21 +217,21 @@ static inline FFV SUM_FFV( FFV a, FFV b, const FFV *f) { ** $-a ~ -1 * z^{a-1} = z^{a+(o-1)/2-1} = z^{a+(o-1)/2-1-(o-1)} ~ a-(o-1)/2$ */ -static inline FFV NEG_FFV( FFV a, const FFV *f) { +static inline FFV NEG_FFV(FFV a, const FFV * f) +{ GAP_ASSERT(a <= f[0]); UInt q1 = f[0]; if (a == 0) return 0; if (q1 % 2) return a; - if (a <= q1/2) - return a + q1/2; + if (a <= q1 / 2) + return a + q1 / 2; else - return a - q1/2; + return a - q1 / 2; } - /**************************************************************************** ** *F QUO_FFV(,,) . . . . . . . . . . quotient of finite field values @@ -266,15 +249,16 @@ static inline FFV NEG_FFV( FFV a, const FFV *f) { ** otherwise we have $a / b ~ z^{a-b+1-1} = z^{a-b+(o-1)} ~ a-b+o$. */ -static inline FFV QUO_FFV(FFV a, FFV b, const FFV *f) { +static inline FFV QUO_FFV(FFV a, FFV b, const FFV * f) +{ GAP_ASSERT(a <= f[0]); GAP_ASSERT(b <= f[0]); if (a == 0) return 0; if (b <= a) - return a-b+1; + return a - b + 1; else - return a+1+f[0]-b; + return a + 1 + f[0] - b; } @@ -298,16 +282,17 @@ static inline FFV QUO_FFV(FFV a, FFV b, const FFV *f) { ** */ -static inline FFV POW_FFV(FFV a, UInt n, const FFV *f) { - GAP_ASSERT(a <= f[0]); - GAP_ASSERT(n <= f[0]); - GAP_STATIC_ASSERT(sizeof(UInt) >= 2*sizeof(FFV), - "Overflow possibility in POW_FFV" ); - if (!n) - return 1; - if (!a) - return 0; - return ((((UInt)a - 1)* n) % f[0]) + 1; +static inline FFV POW_FFV(FFV a, UInt n, const FFV * f) +{ + GAP_ASSERT(a <= f[0]); + GAP_ASSERT(n <= f[0]); + GAP_STATIC_ASSERT(sizeof(UInt) >= 2 * sizeof(FFV), + "Overflow possibility in POW_FFV"); + if (!n) + return 1; + if (!a) + return 0; + return ((((UInt)a - 1) * n) % f[0]) + 1; } @@ -320,9 +305,10 @@ static inline FFV POW_FFV(FFV a, UInt n, const FFV *f) { ** */ -static inline FF FLD_FFE(Obj ffe) { +static inline FF FLD_FFE(Obj ffe) +{ GAP_ASSERT(IS_FFE(ffe)); - return (FF)((UInt)(ffe) >> 3) & ((1 << FIELD_BITS_FFE)-1); + return (FF)((UInt)(ffe) >> 3) & ((1 << FIELD_BITS_FFE) - 1); }