source: git/libpolys/coeffs/ffields.cc @ 4c6e420

fieker-DuValspielwiese
Last change on this file since 4c6e420 was c7e3d7, checked in by Hans Schoenemann <hannes@…>, 13 years ago
cfCoeffWrite introduced
  • Property mode set to 100644
File size: 16.9 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[35aab3]5/*
6* ABSTRACT: finite fields with a none-prime number of elements (via tables)
7*/
8
[18cb65]9#include <misc/auxiliary.h>
[35aab3]10#include <string.h>
[2d805a]11#include <coeffs/coeffs.h>
[18cb65]12#include <misc/mylimits.h>
13#include <omalloc/omalloc.h>
14#include <reporter/reporter.h>
[2d805a]15#include <coeffs/numbers.h>
16#include <coeffs/ffields.h>
[18cb65]17#include <resources/feFopen.h>
[a5cd69]18#include <math.h>
[d0a51ee]19
[5e3046]20
21//unsigned short *nfPlus1Table=NULL; /* the table i=log(z^i) -> log(z^i+1) */
22
[1b078e]23const double sixteenlog2= 11.09035489;
[35aab3]24/* the q's from the table 'fftable' */
[6f8225]25unsigned short fftable[]={
26    4,  8, 16, 32, 64, 128, 256, 512,1024,2048,4096,8192,16384, 32768,
27/*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*/
28    9, 27, 81,243,729,2187, 6561,19683,59049,
29/*3^2 3^3 3^4 3^5 3^6  3^7  3^8   3^9  3^10*/
[35aab3]30   25,125,625,3125,15625,
31/*5^2 5^3 5^4 5^5  5^6*/
32   49,343,2401,16807,
33/*7^2 7^3  7^4 7^5*/
34   121,1331, 14641,
35/*11^2 11^3  11^4*/
36  169, 2197, 28561,
37/*13^2 13^3  13^4*/
38  289, 4913,
39/*17^2 17^3*/
40  361, 6859,
41/*19^2 19^3*/
42  529, 12167,
43/*23^2 23^3*/
44  841, 24389,
45/*29^2 29^3*/
46  961, 29791,
47/*31^2 31^3*/
[6f8225]48  1369, 50653,
49/*37^2  37^3*/
50  1681, /*41^2*/
51  1849, /*43^2*/
52  2209, /*47^2*/
53  2809, /*53^2*/
54  3481, /*59^2*/
55  3721, /*61^2*/
56  4489, /*67^2*/
57  5041, /*71^2*/
58  5329, /*73^2*/
59  6241, /*79^2*/
60  6889, /*83^2*/
61  7921, /*89^2*/
62  9409, /*97^2*/
63  10201, /*101^2*/
64  10609, /*103^2*/
65  11449, /*107^2*/
66  11881, /*109^2*/
67  12769, /*113^2*/
68  16129, /*127^2*/
69  17161, /*131^2*/
70  18769, /*137^2*/
71  19321, /*139^2*/
72  22201, /*149^2*/
73  22801, /*151^2*/
74  24649, /*157^2*/
75  26569, /*163^2*/
76  27889, /*167^2*/
77  29929, /*173^2*/
78  32041, /*179^2*/
79  32761, /*181^2*/
80  36481, /*191^2*/
81  37249, /*193^2*/
82  38809, /*197^2*/
83  39601, /*199^2*/
84  49729, /*223^2*/
85  44521, /*211^2*/
86  51529, /*227^2*/
87  52441, /*229^2*/
88  54289, /*233^2*/
89  57121, /*239^2*/
90  58081, /*241^2*/
[85e68dd]91  63001, /*251^2*/
[35aab3]92  0 };
93
94/*1
95* numbers in GF(p^n):
96* let nfCharQ=q=nfCharP^n=p^n
97* GF(q)\{0} will be generated by powers of an element Z
98* Z^i will be represented by the int i, 1 by the int 0, 0 by the int q=nfChar
99*/
100
101#ifdef LDEBUG
102/*2
103* debugging: is a a valid representation of a number ?
104*/
[5e3046]105BOOLEAN nfDBTest (number a, const char *f, const int l, const coeffs r)
[35aab3]106{
[7f7b2a]107  assume( r->m_nfPlus1Table != NULL );
[5e3046]108  if (((long)a<0L) || ((long)a>(long)r->m_nfCharQ))
[35aab3]109  {
[7447d8]110    Print("wrong %d in %s:%d\n",(int)((long)a),f,l);
[35aab3]111    return FALSE;
112  }
113  int i=0;
114  do
115  {
[5e3046]116    if (r->m_nfPlus1Table[i]>r->m_nfCharQ)
[35aab3]117    {
[5e3046]118      Print("wrong table %d=%d in %s:%d\n",i,r->m_nfPlus1Table[i],f,l);
[35aab3]119      return FALSE;
120    }
121    i++;
[5e3046]122  } while (i<r->m_nfCharQ);
[35aab3]123  return TRUE;
124}
[5e3046]125#define nfTest(N, R) nfDBTest(N,__FILE__,__LINE__, R)
[35aab3]126#endif
127
128/*2
129* k >= 0 ?
130*/
[3510a6]131BOOLEAN nfGreaterZero (number k, const coeffs r)
[35aab3]132{
133#ifdef LDEBUG
[5e3046]134  nfTest(k, r);
[35aab3]135#endif
[3510a6]136  return !nfIsZero(k, r) && !nfIsMOne(k, r);
[35aab3]137}
138
139/*2
140* a*b
141*/
[3510a6]142number nfMult (number a,number b, const coeffs r)
[35aab3]143{
144#ifdef LDEBUG
[5e3046]145  nfTest(a, r);
146  nfTest(b, r);
[35aab3]147#endif
[5e3046]148  if (((long)a == (long)r->m_nfCharQ) || ((long)b == (long)r->m_nfCharQ))
149    return (number)(long)r->m_nfCharQ;
[35aab3]150  /*else*/
[7447d8]151  int i=(int)((long)a+(long)b);
[5e3046]152  if (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
[35aab3]153#ifdef LDEBUG
[5e3046]154  nfTest((number)(long)i, r);
[35aab3]155#endif
[1c7953]156  return (number)(long)i;
[35aab3]157}
158
159/*2
160* int -> number
161*/
[3510a6]162number nfInit (int i, const coeffs r)
[35aab3]163{
[7f7b2a]164  assume( r->m_nfPlus1Table != NULL );
[35aab3]165  // Hmm .. this is just to prevent initialization
166  // from nfInitChar to go into an infinite loop
[5e3046]167  if (i==0) return (number)(long)r->m_nfCharQ;
168  while (i <  0)    i += r->m_nfCharP;
169  while (i >= r->m_nfCharP) i -= r->m_nfCharP;
170  if (i==0) return (number)(long)r->m_nfCharQ;
[900802]171  unsigned short c=0;
[35aab3]172  while (i>1)
173  {
[5e3046]174    c=r->m_nfPlus1Table[c];
[35aab3]175    i--;
176  }
177#ifdef LDEBUG
[5e3046]178  nfTest((number)(long)c, r);
[35aab3]179#endif
[1c7953]180  return (number)(long)c;
[35aab3]181}
182
183/*
184* the generating element `z`
185*/
[3510a6]186number nfPar (int i, const coeffs r)
[35aab3]187{
188  return (number)1;
189}
190
191/*2
192* the degree of the "alg. number"
193*/
[3510a6]194int nfParDeg(number n, const coeffs r)
[35aab3]195{
196#ifdef LDEBUG
[5e3046]197  nfTest(n, r);
[35aab3]198#endif
[5e3046]199  if((long)r->m_nfCharQ == (long)n) return -1;
[7447d8]200  return (int)((long)n);
[35aab3]201}
202
203/*2
204* number -> int
205*/
[3510a6]206int nfInt (number &n, const coeffs r)
[35aab3]207{
208  return 0;
209}
210
211/*2
212* a + b
213*/
[3510a6]214number nfAdd (number a, number b, const coeffs R)
[35aab3]215{
216/*4 z^a+z^b=z^b*(z^(a-b)+1), if a>=b; *
217*          =z^a*(z^(b-a)+1)  if a<b  */
218#ifdef LDEBUG
[5e3046]219  nfTest(a, R);
220  nfTest(b, R);
[35aab3]221#endif
[5e3046]222  if ((long)R->m_nfCharQ == (long)a) return b;
223  if ((long)R->m_nfCharQ == (long)b) return a;
[7447d8]224  long zb,zab,r;
225  if ((long)a >= (long)b)
[35aab3]226  {
[7447d8]227    zb = (long)b;
228    zab = (long)a-(long)b;
[35aab3]229  }
230  else
231  {
[7447d8]232    zb = (long)a;
233    zab = (long)b-(long)a;
[35aab3]234  }
235#ifdef LDEBUG
[5e3046]236  nfTest((number)zab, R);
[35aab3]237#endif
[5e3046]238  if (R->m_nfPlus1Table[zab]==R->m_nfCharQ) r=(long)R->m_nfCharQ; /*if z^(a-b)+1 =0*/
[35aab3]239  else
240  {
[5e3046]241    r= zb+(long)R->m_nfPlus1Table[zab];
242    if(r>=(long)R->m_nfCharQ1) r-=(long)R->m_nfCharQ1;
[35aab3]243  }
244#ifdef LDEBUG
[5e3046]245  nfTest((number)r, R);
[35aab3]246#endif
247  return (number)r;
248}
249
250/*2
251* a - b
252*/
[3510a6]253number nfSub (number a, number b, const coeffs r)
[35aab3]254{
[3510a6]255  number mb = nfNeg(b, r);
256  return nfAdd(a,mb,r);
[35aab3]257}
258
259/*2
260* a == 0 ?
261*/
[3510a6]262BOOLEAN nfIsZero (number  a, const coeffs r)
[35aab3]263{
264#ifdef LDEBUG
[5e3046]265  nfTest(a, r);
[35aab3]266#endif
[5e3046]267  return (long)r->m_nfCharQ == (long)a;
[35aab3]268}
269
270/*2
271* a == 1 ?
272*/
[3510a6]273BOOLEAN nfIsOne (number a, const coeffs r)
[35aab3]274{
275#ifdef LDEBUG
[5e3046]276  nfTest(a, r);
[35aab3]277#endif
[7447d8]278  return 0L == (long)a;
[35aab3]279}
280
281/*2
282* a == -1 ?
283*/
[3510a6]284BOOLEAN nfIsMOne (number a, const coeffs r)
[35aab3]285{
286#ifdef LDEBUG
[5e3046]287  nfTest(a, r);
[35aab3]288#endif
[7447d8]289  if (0L == (long)a) return FALSE; /* special handling of char 2*/
[5e3046]290  return (long)r->m_nfM1 == (long)a;
[35aab3]291}
292
293/*2
294* a / b
295*/
[3510a6]296number nfDiv (number a,number b, const coeffs r)
[35aab3]297{
298#ifdef LDEBUG
[5e3046]299  nfTest(b, r);
[35aab3]300#endif
[5e3046]301  if ((long)b==(long)r->m_nfCharQ)
[35aab3]302  {
[b7e838]303    WerrorS(nDivBy0);
[5e3046]304    return (number)((long)r->m_nfCharQ);
[35aab3]305  }
306#ifdef LDEBUG
[5e3046]307  nfTest(a, r);
[35aab3]308#endif
[5e3046]309  if ((long)a==(long)r->m_nfCharQ)
310    return (number)((long)r->m_nfCharQ);
[35aab3]311  /*else*/
[7447d8]312  long s = (long)a - (long)b;
313  if (s < 0L)
[5e3046]314    s += (long)r->m_nfCharQ1;
[35aab3]315#ifdef LDEBUG
[5e3046]316  nfTest((number)s, r);
[35aab3]317#endif
318  return (number)s;
319}
320
321/*2
322* 1 / c
323*/
[3510a6]324number  nfInvers (number c, const coeffs r)
[35aab3]325{
326#ifdef LDEBUG
[5e3046]327  nfTest(c, r);
[35aab3]328#endif
[5e3046]329  if ((long)c==(long)r->m_nfCharQ)
[35aab3]330  {
[b7e838]331    WerrorS(nDivBy0);
[5e3046]332    return (number)((long)r->m_nfCharQ);
[35aab3]333  }
334#ifdef LDEBUG
[5e3046]335  nfTest(((number)((long)r->m_nfCharQ1-(long)c)), r);
[35aab3]336#endif
[5e3046]337  return (number)((long)r->m_nfCharQ1-(long)c);
[35aab3]338}
339
340/*2
341* -c
342*/
[3510a6]343number nfNeg (number c, const coeffs r)
[35aab3]344{
345/*4 -z^c=z^c*(-1)=z^c*nfM1*/
346#ifdef LDEBUG
[5e3046]347  nfTest(c, r);
[35aab3]348#endif
[5e3046]349  if ((long)r->m_nfCharQ == (long)c) return c;
350  long i=(long)c+(long)r->m_nfM1;
351  if (i>=(long)r->m_nfCharQ1) i-=(long)r->m_nfCharQ1;
[35aab3]352#ifdef LDEBUG
[5e3046]353  nfTest((number)i, r);
[35aab3]354#endif
355  return (number)i;
356}
357
358/*2
359* a > b ?
360*/
[3510a6]361BOOLEAN nfGreater (number a,number b, const coeffs r)
[35aab3]362{
363#ifdef LDEBUG
[5e3046]364  nfTest(a, r);
365  nfTest(b, r);
[35aab3]366#endif
[7447d8]367  return (long)a != (long)b;
[35aab3]368}
369
370/*2
371* a == b ?
372*/
[3510a6]373BOOLEAN nfEqual (number a,number b, const coeffs r)
[35aab3]374{
375#ifdef LDEBUG
[5e3046]376  nfTest(a, r);
377  nfTest(b, r);
[35aab3]378#endif
[7447d8]379  return (long)a == (long)b;
[35aab3]380}
381
382/*2
383* write via StringAppend
384*/
[3510a6]385void nfWrite (number &a, const coeffs r)
[35aab3]386{
387#ifdef LDEBUG
[5e3046]388  nfTest(a, r);
[35aab3]389#endif
[5e3046]390  if ((long)a==(long)r->m_nfCharQ)  StringAppendS("0");
[7447d8]391  else if ((long)a==0L)   StringAppendS("1");
[3510a6]392  else if (nfIsMOne(a, r))   StringAppendS("-1");
[35aab3]393  else
394  {
[dc06550]395    StringAppendS(r->m_nfParameter);
[7447d8]396    if ((long)a!=1L)
[35aab3]397    {
[493225]398      if(r->ShortOut==0)  StringAppendS("^");
[7447d8]399      StringAppend("%d",(int)((long)a));
[35aab3]400    }
401  }
402}
403
404/*2
405*
406*/
[3510a6]407char * nfName(number a, const coeffs r)
[35aab3]408{
409#ifdef LDEBUG
[5e3046]410  nfTest(a, r);
[35aab3]411#endif
412  char *s;
[dc06550]413  char *nfParameter=r->m_nfParameter;
[5e3046]414  if (((long)a==(long)r->m_nfCharQ) || ((long)a==0L)) return NULL;
[7447d8]415  else if ((long)a==1L)
[35aab3]416  {
417    return omStrDup(nfParameter);
418  }
419  else
420  {
421    s=(char *)omAlloc(4+strlen(nfParameter));
[7447d8]422    sprintf(s,"%s%d",nfParameter,(int)((long)a));
[35aab3]423  }
424  return s;
425}
426/*2
427* c ^ i with i>=0
428*/
[3510a6]429void nfPower (number a, int i, number * result, const coeffs r)
[35aab3]430{
431#ifdef LDEBUG
[5e3046]432  nfTest(a, r);
[35aab3]433#endif
434  if (i==0)
435  {
436    //*result=nfInit(1);
[7447d8]437    *result = (number)0L;
[35aab3]438  }
439  else if (i==1)
440  {
441    *result = a;
442  }
443  else
444  {
[3510a6]445    nfPower(a,i-1,result, r);
446    *result = nfMult(a,*result, r);
[35aab3]447  }
448#ifdef LDEBUG
[5e3046]449  nfTest(*result, r);
[35aab3]450#endif
451}
452
453/*4
454* read an integer (with reduction mod p)
455*/
[5e3046]456static const char* nfEati(const char *s, int *i, const coeffs r)
[35aab3]457{
458  if (*s >= '0' && *s <= '9')
459  {
460    *i = 0;
461    do
462    {
463      *i *= 10;
464      *i += *s++ - '0';
[5e3046]465      if (*i > (INT_MAX / 10)) *i = *i % r->m_nfCharP;
[35aab3]466    }
467    while (*s >= '0' && *s <= '9');
[5e3046]468    if (*i >= r->m_nfCharP) *i = *i % r->m_nfCharP;
[35aab3]469  }
470  else *i = 1;
471  return s;
472}
473
474/*2
475* read a number
476*/
[3510a6]477const char * nfRead (const char *s, number *a, const coeffs r)
[35aab3]478{
479  int i;
480  number z;
481  number n;
482
[5e3046]483  s = nfEati(s, &i, r);
[3510a6]484  z=nfInit(i, r);
[35aab3]485  *a=z;
486  if (*s == '/')
487  {
488    s++;
[5e3046]489    s = nfEati(s, &i, r);
[3510a6]490    n=nfInit(i, r);
491    *a = nfDiv(z,n,r);
[35aab3]492  }
[dc06550]493  char *nfParameter=r->m_nfParameter;
[35aab3]494  if (strncmp(s,nfParameter,strlen(nfParameter))==0)
495  {
496    s+=strlen(nfParameter);
497    if ((*s >= '0') && (*s <= '9'))
498    {
499      s=eati(s,&i);
[5e3046]500      while (i>=r->m_nfCharQ1) i-=r->m_nfCharQ1;
[35aab3]501    }
502    else
503      i=1;
[01a57b]504    z=(number)(long)i;
[3510a6]505    *a=nfMult(*a,z,r);
[35aab3]506  }
507#ifdef LDEBUG
[5e3046]508  nfTest(*a, r);
[35aab3]509#endif
510  return s;
511}
512
513#ifdef HAVE_FACTORY
514int gf_tab_numdigits62 ( int q );
515int convertback62 ( char * p, int n );
516#else
517static int gf_tab_numdigits62 ( int q )
518{
519    if ( q < 62 )          return 1;
520    else  if ( q < 62*62 ) return 2;
521    /*else*/               return 3;
522}
523
524static int convback62 ( char c )
525{
526    if ( c >= '0' && c <= '9' )
527        return int(c) - int('0');
528    else  if ( c >= 'A' && c <= 'Z' )
529        return int(c) - int('A') + 10;
530    else
531        return int(c) - int('a') + 36;
532}
533
534static int convertback62 ( char * p, int n )
535{
536    int r = 0;
537    for ( int j = 0; j < n; j++ )
538        r = r * 62 + convback62( p[j] );
539    return r;
540}
541#endif
542
543int nfMinPoly[16];
544
[d0a51ee]545void nfShowMipo(const coeffs r)
[35aab3]546{
547  int i=nfMinPoly[0];
548  int j=0;
549  loop
550  {
551    j++;
552    if (nfMinPoly[j]!=0)
[dc06550]553      StringAppend("%d*%s^%d",nfMinPoly[j],r->m_nfParameter,i);
[35aab3]554    i--;
555    if(i<0) break;
556    if (nfMinPoly[j]!=0)
557      StringAppendS("+");
558  }
559}
560
561static void nfReadMipo(char *s)
562{
563  const char *l=strchr(s,';')+1;
564  char *n;
565  int i=strtol(l,&n,10);
566  l=n;
567  int j=1;
568  nfMinPoly[0]=i;
569  while(i>=0)
570  {
571    nfMinPoly[j]=strtol(l,&n,10);
572    if (l==n) break;
573    l=n;
574    j++;
575    i--;
576  }
577  if (i>=0)
578  {
579    WerrorS("error in reading minpoly from gftables");
580  }
581}
582
583/*2
584* init global variables from files 'gftables/%d'
585*/
[5e3046]586void nfReadTable(const int c, const coeffs r)
[35aab3]587{
588  //Print("GF(%d)\n",c);
[5e3046]589  if ((c==r->m_nfCharQ)||(c==-r->m_nfCharQ))
[35aab3]590    /*this field is already set*/  return;
591  int i=0;
[1b078e]592 
593  while ((fftable[i]!=c) && (fftable[i]!=0)) 
594    i++;
595 
[35aab3]596  if (fftable[i]==0)
[1b078e]597  {
598    Werror("illegal GF-table size: %d", c);
[35aab3]599    return;
[1b078e]600  }
601
[5e3046]602  if (r->m_nfCharQ > 1)
[35aab3]603  {
[5e3046]604    omFreeSize( (ADDRESS)r->m_nfPlus1Table,r->m_nfCharQ*sizeof(unsigned short) );
605    r->m_nfPlus1Table=NULL;
[35aab3]606  }
607  if ((c>1) || (c<0))
608  {
[5e3046]609    if (c>1) r->m_nfCharQ = c;
610    else     r->m_nfCharQ = -c;
[35aab3]611    char buf[100];
[5e3046]612    sprintf(buf,"gftables/%d",r->m_nfCharQ);
[35aab3]613    FILE * fp = feFopen(buf,"r",NULL,TRUE);
614    if (fp==NULL)
615    {
616      return;
617    }
618    if(!fgets( buf, sizeof(buf), fp)) return;
619    if(strcmp(buf,"@@ factory GF(q) table @@\n")!=0)
620    {
621      goto err;
622    }
623    if(!fgets( buf, sizeof(buf), fp))
624    {
625      goto err;
626    }
627    int q;
[5e3046]628    sscanf(buf,"%d %d",&r->m_nfCharP,&q);
[35aab3]629    nfReadMipo(buf);
[5e3046]630    r->m_nfCharQ1=r->m_nfCharQ-1;
[35aab3]631    //Print("nfCharQ=%d,nfCharQ1=%d,mipo=>>%s<<\n",nfCharQ,nfCharQ1,buf);
[5e3046]632    r->m_nfPlus1Table= (unsigned short *)omAlloc( (r->m_nfCharQ)*sizeof(unsigned short) );
633    int digs = gf_tab_numdigits62( r->m_nfCharQ );
[35aab3]634    char * bufptr;
635    int i = 1;
636    int k;
[5e3046]637    while ( i < r->m_nfCharQ )
[35aab3]638    {
639      fgets( buf, sizeof(buf), fp);
640      //( strlen( buffer ) == (size_t)digs * 30, "illegal table" );
641      bufptr = buf;
642      k = 0;
[5e3046]643      while ( (i < r->m_nfCharQ) && (k < 30) )
[35aab3]644      {
[5e3046]645        r->m_nfPlus1Table[i] = convertback62( bufptr, digs );
646        if(r->m_nfPlus1Table[i]>r->m_nfCharQ)
[35aab3]647        {
[5e3046]648          Print("wrong entry %d: %d(%c%c%c)\n",i,r->m_nfPlus1Table[i],bufptr[0],bufptr[1],bufptr[2]);
[35aab3]649        }
650        bufptr += digs;
[5e3046]651        if (r->m_nfPlus1Table[i]==r->m_nfCharQ)
[35aab3]652        {
[5e3046]653          if(i==r->m_nfCharQ1)
[35aab3]654          {
[5e3046]655            r->m_nfM1=0;
[35aab3]656          }
657          else
658          {
[5e3046]659            r->m_nfM1=i;
[35aab3]660          }
661        }
662        i++; k++;
663      }
664    }
[5e3046]665    r->m_nfPlus1Table[0]=r->m_nfPlus1Table[r->m_nfCharQ1];
[35aab3]666  }
667  else
[5e3046]668    r->m_nfCharQ=0;
[35aab3]669#ifdef LDEBUG
[5e3046]670  nfTest((number)0, r);
[35aab3]671#endif
672  return;
673err:
[5e3046]674  Werror("illegal GF-table %d",r->m_nfCharQ);
[35aab3]675}
676
677/*2
678* map Z/p -> GF(p,n)
679*/
[49a64cf]680number nfMapP(number c, const coeffs, const coeffs dst)
[35aab3]681{
[d0a51ee]682  return nfInit((int)((long)c), dst);
[35aab3]683}
684
[85e68dd]685/*2
686* map GF(p,n1) -> GF(p,n2), n1 < n2, n1 | n2
687*/
688int nfMapGG_factor;
[49a64cf]689number nfMapGG(number c, const coeffs src, const coeffs)
[85e68dd]690{
691  int i=(long)c;
692  i*= nfMapGG_factor;
[5e3046]693  while (i >src->m_nfCharQ1) i-=src->m_nfCharQ1;
[85e68dd]694  return (number)((long)i);
695}
696/*2
697* map GF(p,n1) -> GF(p,n2), n1 > n2, n2 | n1
698*/
[49a64cf]699number nfMapGGrev(number c, const coeffs src, const coeffs)
[85e68dd]700{
701  int ex=(int)((long)c);
702  if ((ex % nfMapGG_factor)==0)
703    return (number)(((long)ex) / ((long)nfMapGG_factor));
704  else
[5e3046]705    return (number)(long)src->m_nfCharQ; /* 0 */
[85e68dd]706}
707
[35aab3]708/*2
709* set map function nMap ... -> GF(p,n)
710*/
[a0ce49]711nMapFunc nfSetMap(const coeffs src, const coeffs dst)
[35aab3]712{
[1cce47]713  if (nCoeff_is_GF(src,src->m_nfCharQ))
[35aab3]714  {
[d0a51ee]715    return ndCopyMap;   /* GF(p,n) -> GF(p,n) */
[35aab3]716  }
[1cce47]717  if (nCoeff_is_GF(src))
[85e68dd]718  {
[a0ce49]719    const coeffs r = dst;
[85e68dd]720    int q=src->ch;
[5e3046]721    if ((src->m_nfCharQ % q)==0) /* GF(p,n1) -> GF(p,n2), n2 > n1 */
[85e68dd]722    {
723      // check if n2 is a multiple of n1
724      int n1=1;
[5e3046]725      int qq=r->m_nfCharP;
726      while(qq!=q) { qq *= r->m_nfCharP; n1++; }
[85e68dd]727      int n2=1;
[5e3046]728      qq=r->m_nfCharP;
729      while(qq!=src->m_nfCharQ) { qq *= r->m_nfCharP; n2++; }
730      Print("map %d^%d -> %d^%d\n",r->m_nfCharP,n1,r->m_nfCharP,n2);
[85e68dd]731      if ((n2 % n1)==0)
732      {
[d0a51ee]733        int save_ch=r->ch;
[5e3046]734        nfReadTable(src->ch, r);
735        int nn=r->m_nfPlus1Table[0];
736        nfReadTable(save_ch, r);
737        nfMapGG_factor= r->m_nfPlus1Table[0] / nn;
738        Print("nfMapGG_factor=%d (%d / %d)\n",nfMapGG_factor, r->m_nfPlus1Table[0], nn);
[85e68dd]739        return nfMapGG;
740      }
741      else if ((n1 % n2)==0)
742      {
743        nfMapGG_factor= (n1/n2);
744        return nfMapGGrev;
745      }
746      else
747        return NULL;
748    }
749  }
[1cce47]750  if (nCoeff_is_Zp(src,src->m_nfCharP))
[35aab3]751  {
752    return nfMapP;    /* Z/p -> GF(p,n) */
753  }
754  return NULL;     /* default */
755}
[5e3046]756
[1cce47]757BOOLEAN nfInitChar(coeffs r,  void * parameter)
[5e3046]758{
759
760
761  //r->cfInitChar=npInitChar;
762  //r->cfKillChar=nfKillChar;
763  r->cfSetChar= NULL;
764  //r->nCoeffIsEqual=nfCoeffsEqual;
765
766  r->cfMult  = nfMult;
767  r->cfSub   = nfSub;
768  r->cfAdd   = nfAdd;
769  r->cfDiv   = nfDiv;
770  r->cfIntDiv= nfDiv;
771  //r->cfIntMod= ndIntMod;
772  r->cfExactDiv= nfDiv;
773  r->cfInit = nfInit;
774  //r->cfPar = ndPar;
775  //r->cfParDeg = ndParDeg;
776  //r->cfSize  = ndSize;
777  r->cfInt  = nfInt;
778  #ifdef HAVE_RINGS
779  //r->cfDivComp = NULL; // only for ring stuff
780  //r->cfIsUnit = NULL; // only for ring stuff
781  //r->cfGetUnit = NULL; // only for ring stuff
782  //r->cfExtGcd = NULL; // only for ring stuff
783  // r->cfDivBy = NULL; // only for ring stuff
784  #endif
785  r->cfNeg   = nfNeg;
786  r->cfInvers= nfInvers;
787  //r->cfCopy  = ndCopy;
788  //r->cfRePart = ndCopy;
789  //r->cfImPart = ndReturn0;
790  r->cfWrite = nfWrite;
791  r->cfRead = nfRead;
792  //r->cfNormalize=ndNormalize;
793  r->cfGreater = nfGreater;
794  r->cfEqual = nfEqual;
795  r->cfIsZero = nfIsZero;
796  r->cfIsOne = nfIsOne;
797  r->cfIsMOne = nfIsMOne;
798  r->cfGreaterZero = nfGreaterZero;
799  r->cfPower = nfPower;
800  //r->cfGcd  = ndGcd;
801  //r->cfLcm  = ndGcd;
802  //r->cfDelete= ndDelete;
803  r->cfSetMap = nfSetMap;
804  //r->cfName = ndName;
805  // debug stuff
[c7e3d7]806  r->cfCoeffWrite=nfCoeffWrite;
[a0ce49]807
808#ifdef LDEBUG
[5e3046]809  r->cfDBTest=nfDBTest;
[a0ce49]810#endif
[5e3046]811 
812  // the variables:
813  r->nNULL = (number)0;
[a0ce49]814  assume( r->type == n_GF );
[5e3046]815
[dc06550]816  GFInfo* p = (GFInfo *)(parameter); 
817  const char * name = p->GFPar_name;
[5e3046]818  r->m_nfCharQ = 0;
[dc06550]819  r->m_nfCharP = p->GFChar;
820  r->m_nfCharQ1 = 0;
821  r->m_nfParameter= strdup(name); //TODO use omAlloc for allocating memory and use strcpy?
822  r->m_nfPlus1Table= NULL;
[5e3046]823
824  r->has_simple_Alloc=TRUE;
825  r->has_simple_Inverse=TRUE;
[1b078e]826
827  assume (p->GFChar > 0);
828  assume (p->GFDegree > 0);
829
830  if(p->GFChar > (2<<15))
831  {
[a9f584]832    Werror("illegal characteristic");
833    return TRUE;
[1b078e]834  }
835
836  const double check= log ((double) (p->GFChar)); 
837
838  if( (p->GFDegree * check) > sixteenlog2 )
839  {
[7f7b2a]840    Werror("Sorry: illegal size: %u ^ %u", p->GFChar, p->GFDegree );
[a9f584]841    return TRUE;
[1b078e]842  }
843
844  int c = pow (p->GFChar, p->GFDegree);
845
[5e3046]846  nfReadTable(c, r);
[7f7b2a]847 
848  if( r->m_nfPlus1Table == NULL )
849  {
850    Werror("Sorry: cannot init lookup table!");
[a9f584]851    return TRUE;
[7f7b2a]852  }
853 
854 
[1b078e]855  assume (r -> m_nfCharQ > 0);
856
[5e3046]857  r->ch = r->m_nfCharP; 
[7f7b2a]858  assume( r->m_nfPlus1Table != NULL );
[a9f584]859 
860  return FALSE;
861 
[5e3046]862}
[c7e3d7]863
864void    nfCoeffWrite  (const coeffs r)
865{
866  Print("//   # ground field : %d\n",r->m_nfCharP);
867  Print("//   primitive element : %s\n", r->m_nfParameter);
868  StringSetS("//   minpoly        : ");
869  nfShowMipo(r);PrintS(StringAppendS("\n"));
870}
871
Note: See TracBrowser for help on using the repository browser.