Index: libpolys/coeffs/ffields.cc
===================================================================
--- libpolys/coeffs/ffields.cc	(revision 014b65b05f3dcc53c2482f7290e78a289930ae54)
+++ libpolys/coeffs/ffields.cc	(revision 014b65b05f3dcc53c2482f7290e78a289930ae54)
@@ -0,0 +1,886 @@
+/****************************************
+*  Computer Algebra System SINGULAR     *
+****************************************/
+/* $Id$ */
+/*
+* ABSTRACT: finite fields with a none-prime number of elements (via tables)
+*/
+
+#include <misc/auxiliary.h>
+#include <string.h>
+#include <coeffs/coeffs.h>
+#include <misc/mylimits.h>
+#include <omalloc/omalloc.h>
+#include <reporter/reporter.h>
+#include <coeffs/numbers.h>
+#include <coeffs/ffields.h>
+#include <resources/feFopen.h>
+#include <math.h>
+
+
+//unsigned short *nfPlus1Table=NULL; /* the table i=log(z^i) -> log(z^i+1) */
+
+const double sixteenlog2= 11.09035489;
+/* the q's from the table 'fftable' */
+unsigned short fftable[]={
+    4,  8, 16, 32, 64, 128, 256, 512,1024,2048,4096,8192,16384, 32768,
+/*2^2 2^3 2^4 2^5 2^6  2^7  2^8  2^9 2^10 2^11 2^12 2^13  2^14  2^15*/
+    9, 27, 81,243,729,2187, 6561,19683,59049,
+/*3^2 3^3 3^4 3^5 3^6  3^7  3^8   3^9  3^10*/
+   25,125,625,3125,15625,
+/*5^2 5^3 5^4 5^5  5^6*/
+   49,343,2401,16807,
+/*7^2 7^3  7^4 7^5*/
+   121,1331, 14641,
+/*11^2 11^3  11^4*/
+  169, 2197, 28561,
+/*13^2 13^3  13^4*/
+  289, 4913,
+/*17^2 17^3*/
+  361, 6859,
+/*19^2 19^3*/
+  529, 12167,
+/*23^2 23^3*/
+  841, 24389,
+/*29^2 29^3*/
+  961, 29791,
+/*31^2 31^3*/
+  1369, 50653,
+/*37^2  37^3*/
+  1681, /*41^2*/
+  1849, /*43^2*/
+  2209, /*47^2*/
+  2809, /*53^2*/
+  3481, /*59^2*/
+  3721, /*61^2*/
+  4489, /*67^2*/
+  5041, /*71^2*/
+  5329, /*73^2*/
+  6241, /*79^2*/
+  6889, /*83^2*/
+  7921, /*89^2*/
+  9409, /*97^2*/
+  10201, /*101^2*/
+  10609, /*103^2*/
+  11449, /*107^2*/
+  11881, /*109^2*/
+  12769, /*113^2*/
+  16129, /*127^2*/
+  17161, /*131^2*/
+  18769, /*137^2*/
+  19321, /*139^2*/
+  22201, /*149^2*/
+  22801, /*151^2*/
+  24649, /*157^2*/
+  26569, /*163^2*/
+  27889, /*167^2*/
+  29929, /*173^2*/
+  32041, /*179^2*/
+  32761, /*181^2*/
+  36481, /*191^2*/
+  37249, /*193^2*/
+  38809, /*197^2*/
+  39601, /*199^2*/
+  49729, /*223^2*/
+  44521, /*211^2*/
+  51529, /*227^2*/
+  52441, /*229^2*/
+  54289, /*233^2*/
+  57121, /*239^2*/
+  58081, /*241^2*/
+  63001, /*251^2*/
+  0 };
+
+const char* eati(const char *s, int *i)
+{
+  int l=0;
+
+  if    (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    while (*s >= '0' && *s <= '9')
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      l++;
+      if ((l>=MAX_INT_LEN)||((*i) <0))
+      {
+        s-=l;
+        Werror("`%s` greater than %d(max. integer representation)",
+                s,INT_MAX);
+        return s;
+      }
+    }
+  }
+  else *i = 1;
+  return s;
+}
+
+/*1
+* numbers in GF(p^n):
+* let nfCharQ=q=nfCharP^n=p^n
+* GF(q)\{0} will be generated by powers of an element Z
+* Z^i will be represented by the int i, 1 by the int 0, 0 by the int q=nfChar
+*/
+
+#ifdef LDEBUG
+/*2
+* debugging: is a a valid representation of a number ?
+*/
+BOOLEAN nfDBTest (number a, const char *f, const int l, const coeffs r)
+{
+  assume( r->m_nfPlus1Table != NULL );
+  if (((long)a<0L) || ((long)a>(long)r->m_nfCharQ))
+  {
+    Print("wrong %d in %s:%d\n",(int)((long)a),f,l);
+    return FALSE;
+  }
+  int i=0;
+  do
+  {
+    if (r->m_nfPlus1Table[i]>r->m_nfCharQ)
+    {
+      Print("wrong table %d=%d in %s:%d\n",i,r->m_nfPlus1Table[i],f,l);
+      return FALSE;
+    }
+    i++;
+  } while (i<r->m_nfCharQ);
+  return TRUE;
+}
+#define nfTest(N, R) nfDBTest(N,__FILE__,__LINE__, R)
+#endif
+
+/*2
+* k >= 0 ?
+*/
+BOOLEAN nfGreaterZero (number k, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(k, r);
+#endif
+  return !nfIsZero(k, r) && !nfIsMOne(k, r);
+}
+
+/*2
+* a*b
+*/
+number nfMult (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  if (((long)a == (long)r->m_nfCharQ) || ((long)b == (long)r->m_nfCharQ))
+    return (number)(long)r->m_nfCharQ;
+  /*else*/
+  int i=(int)((long)a+(long)b);
+  if (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)(long)i, r);
+#endif
+  return (number)(long)i;
+}
+
+/*2
+* int -> number
+*/
+number nfInit (int i, const coeffs r)
+{
+  assume( r->m_nfPlus1Table != NULL );
+  // Hmm .. this is just to prevent initialization
+  // from nfInitChar to go into an infinite loop
+  if (i==0) return (number)(long)r->m_nfCharQ;
+  while (i <  0)    i += r->m_nfCharP;
+  while (i >= r->m_nfCharP) i -= r->m_nfCharP;
+  if (i==0) return (number)(long)r->m_nfCharQ;
+  unsigned short c=0;
+  while (i>1)
+  {
+    c=r->m_nfPlus1Table[c];
+    i--;
+  }
+#ifdef LDEBUG
+  nfTest((number)(long)c, r);
+#endif
+  return (number)(long)c;
+}
+
+/*
+* the generating element `z`
+*/
+number nfPar (int i, const coeffs r)
+{
+  return (number)1;
+}
+
+/*2
+* the degree of the "alg. number"
+*/
+int nfParDeg(number n, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(n, r);
+#endif
+  if((long)r->m_nfCharQ == (long)n) return -1;
+  return (int)((long)n);
+}
+
+/*2
+* number -> int
+*/
+int nfInt (number &n, const coeffs r)
+{
+  return 0;
+}
+
+/*2
+* a + b
+*/
+number nfAdd (number a, number b, const coeffs R)
+{
+/*4 z^a+z^b=z^b*(z^(a-b)+1), if a>=b; *
+*          =z^a*(z^(b-a)+1)  if a<b  */
+#ifdef LDEBUG
+  nfTest(a, R);
+  nfTest(b, R);
+#endif
+  if ((long)R->m_nfCharQ == (long)a) return b;
+  if ((long)R->m_nfCharQ == (long)b) return a;
+  long zb,zab,r;
+  if ((long)a >= (long)b)
+  {
+    zb = (long)b;
+    zab = (long)a-(long)b;
+  }
+  else
+  {
+    zb = (long)a;
+    zab = (long)b-(long)a;
+  }
+#ifdef LDEBUG
+  nfTest((number)zab, R);
+#endif
+  if (R->m_nfPlus1Table[zab]==R->m_nfCharQ) r=(long)R->m_nfCharQ; /*if z^(a-b)+1 =0*/
+  else
+  {
+    r= zb+(long)R->m_nfPlus1Table[zab];
+    if(r>=(long)R->m_nfCharQ1) r-=(long)R->m_nfCharQ1;
+  }
+#ifdef LDEBUG
+  nfTest((number)r, R);
+#endif
+  return (number)r;
+}
+
+/*2
+* a - b
+*/
+number nfSub (number a, number b, const coeffs r)
+{
+  number mb = nfNeg(b, r);
+  return nfAdd(a,mb,r);
+}
+
+/*2
+* a == 0 ?
+*/
+BOOLEAN nfIsZero (number  a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  return (long)r->m_nfCharQ == (long)a;
+}
+
+/*2
+* a == 1 ?
+*/
+BOOLEAN nfIsOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  return 0L == (long)a;
+}
+
+/*2
+* a == -1 ?
+*/
+BOOLEAN nfIsMOne (number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if (0L == (long)a) return FALSE; /* special handling of char 2*/
+  return (long)r->m_nfM1 == (long)a;
+}
+
+/*2
+* a / b
+*/
+number nfDiv (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(b, r);
+#endif
+  if ((long)b==(long)r->m_nfCharQ)
+  {
+    WerrorS(nDivBy0);
+    return (number)((long)r->m_nfCharQ);
+  }
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if ((long)a==(long)r->m_nfCharQ)
+    return (number)((long)r->m_nfCharQ);
+  /*else*/
+  long s = (long)a - (long)b;
+  if (s < 0L)
+    s += (long)r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)s, r);
+#endif
+  return (number)s;
+}
+
+/*2
+* 1 / c
+*/
+number  nfInvers (number c, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(c, r);
+#endif
+  if ((long)c==(long)r->m_nfCharQ)
+  {
+    WerrorS(nDivBy0);
+    return (number)((long)r->m_nfCharQ);
+  }
+#ifdef LDEBUG
+  nfTest(((number)((long)r->m_nfCharQ1-(long)c)), r);
+#endif
+  return (number)((long)r->m_nfCharQ1-(long)c);
+}
+
+/*2
+* -c
+*/
+number nfNeg (number c, const coeffs r)
+{
+/*4 -z^c=z^c*(-1)=z^c*nfM1*/
+#ifdef LDEBUG
+  nfTest(c, r);
+#endif
+  if ((long)r->m_nfCharQ == (long)c) return c;
+  long i=(long)c+(long)r->m_nfM1;
+  if (i>=(long)r->m_nfCharQ1) i-=(long)r->m_nfCharQ1;
+#ifdef LDEBUG
+  nfTest((number)i, r);
+#endif
+  return (number)i;
+}
+
+/*2
+* a > b ?
+*/
+BOOLEAN nfGreater (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  return (long)a != (long)b;
+}
+
+/*2
+* a == b ?
+*/
+BOOLEAN nfEqual (number a,number b, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+  nfTest(b, r);
+#endif
+  return (long)a == (long)b;
+}
+
+/*2
+* write via StringAppend
+*/
+void nfWrite (number &a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if ((long)a==(long)r->m_nfCharQ)  StringAppendS("0");
+  else if ((long)a==0L)   StringAppendS("1");
+  else if (nfIsMOne(a, r))   StringAppendS("-1");
+  else
+  {
+    StringAppendS(r->m_nfParameter);
+    if ((long)a!=1L)
+    {
+      if(r->ShortOut==0)  StringAppendS("^");
+      StringAppend("%d",(int)((long)a));
+    }
+  }
+}
+
+/*2
+*
+*/
+char * nfName(number a, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  char *s;
+  char *nfParameter=r->m_nfParameter;
+  if (((long)a==(long)r->m_nfCharQ) || ((long)a==0L)) return NULL;
+  else if ((long)a==1L)
+  {
+    return omStrDup(nfParameter);
+  }
+  else
+  {
+    s=(char *)omAlloc(4+strlen(nfParameter));
+    sprintf(s,"%s%d",nfParameter,(int)((long)a));
+  }
+  return s;
+}
+/*2
+* c ^ i with i>=0
+*/
+void nfPower (number a, int i, number * result, const coeffs r)
+{
+#ifdef LDEBUG
+  nfTest(a, r);
+#endif
+  if (i==0)
+  {
+    //*result=nfInit(1);
+    *result = (number)0L;
+  }
+  else if (i==1)
+  {
+    *result = a;
+  }
+  else
+  {
+    nfPower(a,i-1,result, r);
+    *result = nfMult(a,*result, r);
+  }
+#ifdef LDEBUG
+  nfTest(*result, r);
+#endif
+}
+
+/*4
+* read an integer (with reduction mod p)
+*/
+static const char* nfEati(const char *s, int *i, const coeffs r)
+{
+  if (*s >= '0' && *s <= '9')
+  {
+    *i = 0;
+    do
+    {
+      *i *= 10;
+      *i += *s++ - '0';
+      if (*i > (INT_MAX / 10)) *i = *i % r->m_nfCharP;
+    }
+    while (*s >= '0' && *s <= '9');
+    if (*i >= r->m_nfCharP) *i = *i % r->m_nfCharP;
+  }
+  else *i = 1;
+  return s;
+}
+
+/*2
+* read a number
+*/
+const char * nfRead (const char *s, number *a, const coeffs r)
+{
+  int i;
+  number z;
+  number n;
+
+  s = nfEati(s, &i, r);
+  z=nfInit(i, r);
+  *a=z;
+  if (*s == '/')
+  {
+    s++;
+    s = nfEati(s, &i, r);
+    n=nfInit(i, r);
+    *a = nfDiv(z,n,r);
+  }
+  char *nfParameter=r->m_nfParameter;
+  if (strncmp(s,nfParameter,strlen(nfParameter))==0)
+  {
+    s+=strlen(nfParameter);
+    if ((*s >= '0') && (*s <= '9'))
+    {
+      s=eati(s,&i);
+      while (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
+    }
+    else
+      i=1;
+    z=(number)(long)i;
+    *a=nfMult(*a,z,r);
+  }
+#ifdef LDEBUG
+  nfTest(*a, r);
+#endif
+  return s;
+}
+
+#ifdef HAVE_FACTORY
+int gf_tab_numdigits62 ( int q );
+int convertback62 ( char * p, int n );
+#else
+static int gf_tab_numdigits62 ( int q )
+{
+    if ( q < 62 )          return 1;
+    else  if ( q < 62*62 ) return 2;
+    /*else*/               return 3;
+}
+
+static int convback62 ( char c )
+{
+    if ( c >= '0' && c <= '9' )
+        return int(c) - int('0');
+    else  if ( c >= 'A' && c <= 'Z' )
+        return int(c) - int('A') + 10;
+    else
+        return int(c) - int('a') + 36;
+}
+
+static int convertback62 ( char * p, int n )
+{
+    int r = 0;
+    for ( int j = 0; j < n; j++ )
+        r = r * 62 + convback62( p[j] );
+    return r;
+}
+#endif
+
+int nfMinPoly[16];
+
+void nfShowMipo(const coeffs r)
+{
+  int i=nfMinPoly[0];
+  int j=0;
+  loop
+  {
+    j++;
+    if (nfMinPoly[j]!=0)
+      StringAppend("%d*%s^%d",nfMinPoly[j],r->m_nfParameter,i);
+    i--;
+    if(i<0) break;
+    if (nfMinPoly[j]!=0)
+      StringAppendS("+");
+  }
+}
+
+static void nfReadMipo(char *s)
+{
+  const char *l=strchr(s,';')+1;
+  char *n;
+  int i=strtol(l,&n,10);
+  l=n;
+  int j=1;
+  nfMinPoly[0]=i;
+  while(i>=0)
+  {
+    nfMinPoly[j]=strtol(l,&n,10);
+    if (l==n) break;
+    l=n;
+    j++;
+    i--;
+  }
+  if (i>=0)
+  {
+    WerrorS("error in reading minpoly from gftables");
+  }
+}
+
+/*2
+* init global variables from files 'gftables/%d'
+*/
+void nfReadTable(const int c, const coeffs r)
+{
+  //Print("GF(%d)\n",c);
+  if ((c==r->m_nfCharQ)||(c==-r->m_nfCharQ))
+    /*this field is already set*/  return;
+  int i=0;
+  
+  while ((fftable[i]!=c) && (fftable[i]!=0)) 
+    i++;
+  
+  if (fftable[i]==0)
+  {
+    Werror("illegal GF-table size: %d", c);
+    return;
+  }
+
+  if (r->m_nfCharQ > 1)
+  {
+    omFreeSize( (ADDRESS)r->m_nfPlus1Table,r->m_nfCharQ*sizeof(unsigned short) );
+    r->m_nfPlus1Table=NULL;
+  }
+  if ((c>1) || (c<0))
+  {
+    if (c>1) r->m_nfCharQ = c;
+    else     r->m_nfCharQ = -c;
+    char buf[100];
+    sprintf(buf,"gftables/%d",r->m_nfCharQ);
+    FILE * fp = feFopen(buf,"r",NULL,TRUE);
+    if (fp==NULL)
+    {
+      return;
+    }
+    if(!fgets( buf, sizeof(buf), fp)) return;
+    if(strcmp(buf,"@@ factory GF(q) table @@\n")!=0)
+    {
+      goto err;
+    }
+    if(!fgets( buf, sizeof(buf), fp))
+    {
+      goto err;
+    }
+    int q;
+    sscanf(buf,"%d %d",&r->m_nfCharP,&q);
+    nfReadMipo(buf);
+    r->m_nfCharQ1=r->m_nfCharQ-1;
+    //Print("nfCharQ=%d,nfCharQ1=%d,mipo=>>%s<<\n",nfCharQ,nfCharQ1,buf);
+    r->m_nfPlus1Table= (unsigned short *)omAlloc( (r->m_nfCharQ)*sizeof(unsigned short) );
+    int digs = gf_tab_numdigits62( r->m_nfCharQ );
+    char * bufptr;
+    int i = 1;
+    int k;
+    while ( i < r->m_nfCharQ )
+    {
+      fgets( buf, sizeof(buf), fp);
+      //( strlen( buffer ) == (size_t)digs * 30, "illegal table" );
+      bufptr = buf;
+      k = 0;
+      while ( (i < r->m_nfCharQ) && (k < 30) )
+      {
+        r->m_nfPlus1Table[i] = convertback62( bufptr, digs );
+        if(r->m_nfPlus1Table[i]>r->m_nfCharQ)
+        {
+          Print("wrong entry %d: %d(%c%c%c)\n",i,r->m_nfPlus1Table[i],bufptr[0],bufptr[1],bufptr[2]);
+        }
+        bufptr += digs;
+        if (r->m_nfPlus1Table[i]==r->m_nfCharQ)
+        {
+          if(i==r->m_nfCharQ1)
+          {
+            r->m_nfM1=0;
+          }
+          else
+          {
+            r->m_nfM1=i;
+          }
+        }
+        i++; k++;
+      }
+    }
+    r->m_nfPlus1Table[0]=r->m_nfPlus1Table[r->m_nfCharQ1];
+  }
+  else
+    r->m_nfCharQ=0;
+#ifdef LDEBUG
+  nfTest((number)0, r);
+#endif
+  return;
+err:
+  Werror("illegal GF-table %d",r->m_nfCharQ);
+}
+
+/*2
+* map Z/p -> GF(p,n)
+*/
+number nfMapP(number c, const coeffs, const coeffs dst)
+{
+  return nfInit((int)((long)c), dst);
+}
+
+/*2
+* map GF(p,n1) -> GF(p,n2), n1 < n2, n1 | n2
+*/
+int nfMapGG_factor;
+number nfMapGG(number c, const coeffs src, const coeffs)
+{
+  int i=(long)c;
+  i*= nfMapGG_factor;
+  while (i >src->m_nfCharQ1) i-=src->m_nfCharQ1;
+  return (number)((long)i);
+}
+/*2
+* map GF(p,n1) -> GF(p,n2), n1 > n2, n2 | n1
+*/
+number nfMapGGrev(number c, const coeffs src, const coeffs)
+{
+  int ex=(int)((long)c);
+  if ((ex % nfMapGG_factor)==0)
+    return (number)(((long)ex) / ((long)nfMapGG_factor));
+  else
+    return (number)(long)src->m_nfCharQ; /* 0 */
+}
+
+/*2
+* set map function nMap ... -> GF(p,n)
+*/
+nMapFunc nfSetMap(const coeffs src, const coeffs dst)
+{
+  if (nCoeff_is_GF(src,src->m_nfCharQ))
+  {
+    return ndCopyMap;   /* GF(p,n) -> GF(p,n) */
+  }
+  if (nCoeff_is_GF(src))
+  {
+    const coeffs r = dst;
+    int q=src->ch;
+    if ((src->m_nfCharQ % q)==0) /* GF(p,n1) -> GF(p,n2), n2 > n1 */
+    {
+      // check if n2 is a multiple of n1
+      int n1=1;
+      int qq=r->m_nfCharP;
+      while(qq!=q) { qq *= r->m_nfCharP; n1++; }
+      int n2=1;
+      qq=r->m_nfCharP;
+      while(qq!=src->m_nfCharQ) { qq *= r->m_nfCharP; n2++; }
+      Print("map %d^%d -> %d^%d\n",r->m_nfCharP,n1,r->m_nfCharP,n2);
+      if ((n2 % n1)==0)
+      {
+        int save_ch=r->ch;
+        nfReadTable(src->ch, r);
+        int nn=r->m_nfPlus1Table[0];
+        nfReadTable(save_ch, r);
+        nfMapGG_factor= r->m_nfPlus1Table[0] / nn;
+        Print("nfMapGG_factor=%d (%d / %d)\n",nfMapGG_factor, r->m_nfPlus1Table[0], nn);
+        return nfMapGG;
+      }
+      else if ((n1 % n2)==0)
+      {
+        nfMapGG_factor= (n1/n2);
+        return nfMapGGrev;
+      }
+      else
+        return NULL;
+    }
+  }
+  if (nCoeff_is_Zp(src,src->m_nfCharP))
+  {
+    return nfMapP;    /* Z/p -> GF(p,n) */
+  }
+  return NULL;     /* default */
+}
+
+BOOLEAN nfInitChar(coeffs r,  void * parameter)
+{
+
+
+  //r->cfInitChar=npInitChar;
+  //r->cfKillChar=nfKillChar;
+  r->cfSetChar= NULL;
+  //r->nCoeffIsEqual=nfCoeffsEqual;
+
+  r->cfMult  = nfMult;
+  r->cfSub   = nfSub;
+  r->cfAdd   = nfAdd;
+  r->cfDiv   = nfDiv;
+  r->cfIntDiv= nfDiv;
+  //r->cfIntMod= ndIntMod;
+  r->cfExactDiv= nfDiv;
+  r->cfInit = nfInit;
+  //r->cfPar = ndPar;
+  //r->cfParDeg = ndParDeg;
+  //r->cfSize  = ndSize;
+  r->cfInt  = nfInt;
+  #ifdef HAVE_RINGS
+  //r->cfDivComp = NULL; // only for ring stuff
+  //r->cfIsUnit = NULL; // only for ring stuff
+  //r->cfGetUnit = NULL; // only for ring stuff
+  //r->cfExtGcd = NULL; // only for ring stuff
+  // r->cfDivBy = NULL; // only for ring stuff
+  #endif
+  r->cfNeg   = nfNeg;
+  r->cfInvers= nfInvers;
+  //r->cfCopy  = ndCopy;
+  //r->cfRePart = ndCopy;
+  //r->cfImPart = ndReturn0;
+  r->cfWrite = nfWrite;
+  r->cfRead = nfRead;
+  //r->cfNormalize=ndNormalize;
+  r->cfGreater = nfGreater;
+  r->cfEqual = nfEqual;
+  r->cfIsZero = nfIsZero;
+  r->cfIsOne = nfIsOne;
+  r->cfIsMOne = nfIsMOne;
+  r->cfGreaterZero = nfGreaterZero;
+  r->cfPower = nfPower;
+  //r->cfGcd  = ndGcd;
+  //r->cfLcm  = ndGcd;
+  //r->cfDelete= ndDelete;
+  r->cfSetMap = nfSetMap;
+  //r->cfName = ndName;
+  // debug stuff
+
+#ifdef LDEBUG
+  r->cfDBTest=nfDBTest;
+#endif
+  
+  // the variables:
+  r->nNULL = (number)0;
+  assume( r->type == n_GF );
+
+  GFInfo* p = (GFInfo *)(parameter); 
+  const char * name = p->GFPar_name;
+  r->m_nfCharQ = 0;
+  r->m_nfCharP = p->GFChar;
+  r->m_nfCharQ1 = 0;
+  r->m_nfParameter= strdup(name); //TODO use omAlloc for allocating memory and use strcpy?
+  r->m_nfPlus1Table= NULL;
+
+  r->has_simple_Alloc=TRUE;
+  r->has_simple_Inverse=TRUE;
+
+  assume (p->GFChar > 0);
+  assume (p->GFDegree > 0);
+
+  if(p->GFChar > (2<<15))
+  {
+    Werror("illegal characteristic");
+    return TRUE;
+  }
+
+  const double check= log ((double) (p->GFChar)); 
+
+  if( (p->GFDegree * check) > sixteenlog2 )
+  {
+    Werror("Sorry: illegal size: %u ^ %u", p->GFChar, p->GFDegree );
+    return TRUE;
+  }
+
+  int c = pow (p->GFChar, p->GFDegree);
+
+  nfReadTable(c, r);
+  
+  if( r->m_nfPlus1Table == NULL )
+  {
+    Werror("Sorry: cannot init lookup table!");
+    return TRUE;
+  }
+  
+  
+  assume (r -> m_nfCharQ > 0);
+
+  r->ch = r->m_nfCharP; 
+  assume( r->m_nfPlus1Table != NULL );
+  
+  return FALSE;
+  
+}
