source: git/Singular/ffields.cc @ 9235af

fieker-DuValspielwiese
Last change on this file since 9235af was 685aa6e, checked in by Hans Schönemann <hannes@…>, 25 years ago
*hannes: make gcc happy git-svn-id: file:///usr/local/Singular/svn/trunk@3642 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ffields.cc,v 1.22 1999-09-22 13:28:43 Singular Exp $ */
5/*
6* ABSTRACT: finite fields with a none-prime number of elements (via tables)
7*/
8
9#include <limits.h>
10#include <string.h>
11#include "mod2.h"
12#include "tok.h"
13#include "febase.h"
14#include "mmemory.h"
15#include "numbers.h"
16#include "ring.h"
17#include "ffields.h"
18
19int nfCharQ=0;  /* the number of elemts: q*/
20int nfM1;       /*representation of -1*/
21static int nfCharP=0;  /* the characteristic: p*/
22static int nfCharQ1=0; /* q-1 */
23CARDINAL *nfPlus1Table=NULL; /* the table i=log(z^i) -> log(z^i+1) */
24char * nfParameter;          /*  the name of the primitive element */
25/* the q's from the table 'fftable' */
26short fftable[]={
27    4,  8, 16, 32, 64, 128, 256, 512,1024,2048,4096,8192,16384,
28/*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*/
29    9, 27, 81,243,729,2187, 6561,19683,
30/*3^2 3^3 3^4 3^5 3^6  3^7  3^8   3^9*/
31   25,125,625,3125,15625,
32/*5^2 5^3 5^4 5^5  5^6*/
33   49,343,2401,16807,
34/*7^2 7^3  7^4 7^5*/
35   121,1331, 14641,
36/*11^2 11^3  11^4*/
37  169, 2197, 28561,
38/*13^2 13^3  13^4*/
39  289, 4913,
40/*17^2 17^3*/
41  361, 6859,
42/*19^2 19^3*/
43  529, 12167,
44/*23^2 23^3*/
45  841, 24389,
46/*29^2 29^3*/
47  961, 29791,
48/*31^2 31^3*/
49  1369,
50/*37^2*/
51  1681,
52/*41^2*/
53  1849,
54/*43^2*/
55  2209,
56/*47^2*/
57  2809,
58/*53^2*/
59  3481,
60/*59^2*/
61  3721,
62/*61^2*/
63  4489,
64/*67^2*/
65  5041,
66/*71^2*/
67  5329,
68/*73^2*/
69  6241,
70/*79^2*/
71  6889,
72/*83^2*/
73  7921,
74/*89^2*/
75  9409,
76/*97^2*/
77  10201,
78/*101^2*/
79  10609,
80/*103^2*/
81  11449,
82/*107^2*/
83  11881,
84/*109^2*/
85  12769,
86/*113^2*/
87  16129,
88/*127^2*/
89  17161,
90/*131^2*/
91  18769,
92/*137^2*/
93  19321,
94/*139^2*/
95  22201,
96/*149^2*/
97  22801,
98/*151^2*/
99  24649,
100/*157^2*/
101  26569,
102/*163^2*/
103  27889,
104/*167^2*/
105  29929,
106/*173^2*/
107  32041,
108/*179^2*/
109  32761,
110/*181^2*/
111  0 };
112
113/*1
114* numbers in GF(p^n):
115* let nfCharQ=q=nfCharP^n=p^n
116* GF(q)\{0} will be generated by powers of an element Z
117* Z^i will be represented by the int i, 1 by the int 0, 0 by the int q=nfChar
118*/
119
120#ifdef LDEBUG
121/*2
122* debugging: is a a valid representation of a number ?
123*/
124BOOLEAN nfDBTest (number a, char *f, int l)
125{
126  if (((int)a<0) || ((int)a>nfCharQ))
127  {
128    Print("wrong %d in %s:%d\n",(int)a,f,l);
129    return FALSE;
130  }
131  int i=0;
132  do
133  {
134    if (nfPlus1Table[i]>nfCharQ)
135    {
136      Print("wrong table %d=%d in %s:%d\n",i,nfPlus1Table[i],f,l);
137      return FALSE;
138    }
139    i++;
140  } while (i<nfCharQ);
141  return TRUE;
142}
143#define nfTest(N) nfDBTest(N,__FILE__,__LINE__)
144#endif
145
146/*2
147* k >= 0 ?
148*/
149BOOLEAN nfGreaterZero (number k)
150{
151#ifdef LDEBUG
152  nfTest(k);
153#endif
154  return !nfIsZero(k) && !nfIsMOne(k);
155}
156
157/*2
158* a*b
159*/
160number nfMult (number a,number b)
161{
162#ifdef LDEBUG
163  nfTest(a);
164  nfTest(b);
165#endif
166  if (((int)a == nfCharQ) || ((int)b == nfCharQ))
167    return (number)nfCharQ;
168  /*else*/
169  int i=(int)a+(int)b;
170  if (i>=nfCharQ1) i-=nfCharQ1;
171#ifdef LDEBUG
172  nfTest((number)i);
173#endif
174  return (number)i;
175}
176
177/*2
178* int -> number
179*/
180number nfInit (int i)
181{
182  while (i <  0)    i += nfCharP;
183  while (i >= nfCharP) i -= nfCharP;
184  if (i==0) return (number)nfCharQ;
185  int c=0;
186  while (i>1)
187  {
188    c=nfPlus1Table[c];
189    i--;
190  }
191#ifdef LDEBUG
192  nfTest((number)c);
193#endif
194  return (number)c;
195}
196
197/*
198* the generating element `z`
199*/
200number nfPar (int i)
201{
202  return (number)1;
203}
204
205/*2
206* the degree of the "alg. number"
207*/
208int nfParDeg(number n)
209{
210#ifdef LDEBUG
211  nfTest(n);
212#endif
213  if(nfCharQ == (int)n) return -1;
214  return (int)n;
215}
216
217/*2
218* number -> int
219*/
220int nfInt (number &n)
221{
222  return 0;
223}
224
225/*2
226* copy a number
227*/
228number nfCopy (number  k)
229{
230#ifdef LDEBUG
231  nfTest(k);
232#endif
233  return k;
234}
235
236/*2
237* a + b
238*/
239number nfAdd (number a, number b)
240{
241/*4 z^a+z^b=z^b*(z^(a-b)+1), if a>=b; *
242*          =z^a*(z^(b-a)+1)  if a<b  */
243#ifdef LDEBUG
244  nfTest(a);
245  nfTest(b);
246#endif
247  if (nfCharQ == (int)a) return b;
248  if (nfCharQ == (int)b) return a;
249  int zb,zab,r;
250  if ((int)a >= (int)b)
251  {
252    zb = (int)b;
253    zab = (int)a-(int)b;
254  }
255  else
256  {
257    zb = (int)a;
258    zab = (int)b-(int)a;
259  }
260#ifdef LDEBUG
261  nfTest((number)zab);
262#endif
263  if (nfPlus1Table[zab]==nfCharQ) r=nfCharQ; /*if z^(a-b)+1 =0*/
264  else
265  {
266    r= zb+nfPlus1Table[zab];
267    if(r>=nfCharQ1) r-=nfCharQ1;
268  }
269#ifdef LDEBUG
270  nfTest((number)r);
271#endif
272  return (number)r;
273}
274
275/*2
276* a - b
277*/
278number nfSub (number a, number b)
279{
280  number mb = nfNeg(b);
281  return nfAdd(a,mb);
282}
283
284/*2
285* a == 0 ?
286*/
287BOOLEAN nfIsZero (number  a)
288{
289#ifdef LDEBUG
290  nfTest(a);
291#endif
292  return nfCharQ == (int)a;
293}
294
295/*2
296* a == 1 ?
297*/
298BOOLEAN nfIsOne (number a)
299{
300#ifdef LDEBUG
301  nfTest(a);
302#endif
303  return 0 == (int)a;
304}
305
306/*2
307* a == -1 ?
308*/
309BOOLEAN nfIsMOne (number a)
310{
311#ifdef LDEBUG
312  nfTest(a);
313#endif
314  if (0 == (int)a) return FALSE; /* special handling of char 2*/
315  return nfM1 == (int)a;
316}
317
318/*2
319* a / b
320*/
321number nfDiv (number a,number b)
322{
323#ifdef LDEBUG
324  nfTest(b);
325#endif
326  if ((int)b==nfCharQ)
327  {
328    WerrorS("div. by 0");
329    return (number)nfCharQ;
330  }
331#ifdef LDEBUG
332  nfTest(a);
333#endif
334  if ((int)a==nfCharQ)
335    return (number)nfCharQ;
336  /*else*/
337  int s = (int)a - (int)b;
338  if (s < 0)
339    s += nfCharQ1;
340#ifdef LDEBUG
341  nfTest((number)s);
342#endif
343  return (number)s;
344}
345
346/*2
347* 1 / c
348*/
349number  nfInvers (number c)
350{
351#ifdef LDEBUG
352  nfTest(c);
353#endif
354  if ((int)c==nfCharQ)
355  {
356    WerrorS("div. 1/0");
357    return (number)nfCharQ;
358  }
359#ifdef LDEBUG
360  nfTest(((number)(nfCharQ1-(int)c)));
361#endif
362  return (number)(nfCharQ1-(int)c);
363}
364
365/*2
366* -c
367*/
368number nfNeg (number c)
369{
370/*4 -z^c=z^c*(-1)=z^c*nfM1*/
371#ifdef LDEBUG
372  nfTest(c);
373#endif
374  if (nfCharQ == (int)c) return c;
375  int i=(int)c+nfM1;
376  if (i>=nfCharQ1) i-=nfCharQ1;
377#ifdef LDEBUG
378  nfTest((number)i);
379#endif
380  return (number)i;
381}
382
383/*2
384* a > b ?
385*/
386BOOLEAN nfGreater (number a,number b)
387{
388#ifdef LDEBUG
389  nfTest(a);
390  nfTest(b);
391#endif
392  return (int)a != (int)b;
393}
394
395/*2
396* a == b ?
397*/
398BOOLEAN nfEqual (number a,number b)
399{
400#ifdef LDEBUG
401  nfTest(a);
402  nfTest(b);
403#endif
404  return (int)a == (int)b;
405}
406
407/*2
408* write via StringAppend
409*/
410void nfWrite (number &a)
411{
412#ifdef LDEBUG
413  nfTest(a);
414#endif
415  if ((int)a==nfCharQ)  StringAppendS("0");
416  else if ((int)a==0)   StringAppendS("1");
417  else if (nfIsMOne(a))   StringAppendS("-1");
418  else
419  {
420    StringAppendS(nfParameter);
421    if ((int)a!=1)
422    {
423      if(pShortOut==0)  StringAppendS("^");
424      StringAppend("%d",(int)a);
425    }
426  }
427}
428
429/*2
430*
431*/
432char * nfName(number a)
433{
434#ifdef LDEBUG
435  nfTest(a);
436#endif
437  char *s;
438  if (((int)a==nfCharQ) || ((int)a==0)) return NULL;
439  else if ((int)a==1)
440  {
441    return mstrdup(nfParameter);
442  }
443  else
444  {
445    s=(char *)AllocL(4+strlen(nfParameter));
446    sprintf(s,"%s%d",nfParameter,(int)a);
447  }
448  return s;
449}
450/*2
451* c ^ i with i>=0
452*/
453void nfPower (number a, int i, number * result)
454{
455#ifdef LDEBUG
456  nfTest(a);
457#endif
458  if (i==0)
459  {
460    //*result=nfInit(1);
461    *result = (number)0;
462  }
463  else if (i==1)
464  {
465    //*result = nfCopy(a);
466    *result = a;
467  }
468  else
469  {
470    nfPower(a,i-1,result);
471    *result = nfMult(a,*result);
472  }
473#ifdef LDEBUG
474  nfTest(*result);
475#endif
476}
477
478/*4
479* read an integer (with reduction mod p)
480*/
481static char* nfEati(char *s, int *i)
482{
483  if (*s >= '0' && *s <= '9')
484  {
485    *i = 0;
486    do
487    {
488      *i *= 10;
489      *i += *s++ - '0';
490      if (*i > (MAX_INT_VAL / 10)) *i = *i % nfCharP;
491    }
492    while (*s >= '0' && *s <= '9');
493    if (*i >= nfCharP) *i = *i % nfCharP;
494  }
495  else *i = 1;
496  return s;
497}
498
499/*2
500* read a number
501*/
502char * nfRead (char *s, number *a)
503{
504  int i;
505  number z;
506  number n;
507
508  s = nfEati(s, &i);
509  z=nfInit(i);
510  *a=z;
511  if (*s == '/')
512  {
513    s++;
514    s = nfEati(s, &i);
515    n=nfInit(i);
516    *a = nfDiv(z,n);
517  }
518  if (strncmp(s,nfParameter,strlen(nfParameter))==0)
519  {
520    s+=strlen(nfParameter);
521    if ((*s >= '0') && (*s <= '9'))
522    {
523      s=eati(s,&i);
524      while (i>=nfCharQ1) i-=nfCharQ1;
525    }
526    else
527      i=1;
528    z=(number)i;
529    *a=nfMult(*a,z);
530  }
531#ifdef LDEBUG
532  nfTest(*a);
533#endif
534  return s;
535}
536
537#ifdef HAVE_FACTORY
538int gf_tab_numdigits62 ( int q );
539int convertback62 ( char * p, int n );
540#else
541static int gf_tab_numdigits62 ( int q )
542{
543    if ( q < 62 )          return 1;
544    else  if ( q < 62*62 ) return 2;
545    /*else*/               return 3;
546}
547
548static int convback62 ( char c )
549{
550    if ( c >= '0' && c <= '9' )
551        return int(c) - int('0');
552    else  if ( c >= 'A' && c <= 'Z' )
553        return int(c) - int('A') + 10;
554    else
555        return int(c) - int('a') + 36;
556}
557
558static int convertback62 ( char * p, int n )
559{
560    int r = 0;
561    for ( int j = 0; j < n; j++ )
562        r = r * 62 + convback62( p[j] );
563    return r;
564}
565#endif
566
567int nfMinPoly[16];
568
569void nfShowMipo()
570{
571  int i=nfMinPoly[0];
572  int j=0;
573  loop
574  {
575    j++;
576    if (nfMinPoly[j]!=0)
577      StringAppend("%d*%s^%d",nfMinPoly[j],nfParameter,i);
578    i--;
579    if(i<0) break;
580    if (nfMinPoly[j]!=0)
581      StringAppendS("+");
582  }
583}
584
585static void nfReadMipo(char *s)
586{
587  const char *l=strchr(s,';')+1;
588  char *n;
589  int i=strtol(l,&n,10);
590  l=n;
591  int j=1;
592  nfMinPoly[0]=i;
593  while(i>=0)
594  {
595    nfMinPoly[j]=strtol(l,&n,10);
596    if (l==n) break;
597    l=n;
598    j++;
599    i--;
600  }
601  if (i>=0)
602  {
603    WerrorS("error in reading minpoly from gftables");
604  }
605}
606
607/*2
608* init global variables from files 'gftables/%d'
609*/
610void nfSetChar(int c, char **param)
611{
612  //Print("GF(%d)\n",c);
613  nfParameter=param[0];
614  if ((c==nfCharQ)||(c==-nfCharQ))
615    /*this field is already set*/  return;
616  int i=0;
617  while ((fftable[i]!=c) && (fftable[i]!=0)) i++;
618  if (fftable[i]==0)
619    return;
620  if (nfCharQ > 1)
621  {
622    Free( (ADDRESS)nfPlus1Table,nfCharQ*sizeof(CARDINAL) );
623    nfPlus1Table=NULL;
624  }
625  if ((c>1) || (c<0))
626  {
627    if (c>1) nfCharQ = c;
628    else     nfCharQ = -c;
629    char buf[100];
630#ifdef macintosh
631    sprintf(buf,"gftables:%d",nfCharQ);
632#else
633    sprintf(buf,"gftables/%d",nfCharQ);
634#endif
635    FILE * fp = feFopen(buf,"r",NULL,TRUE);
636    if (fp==NULL)
637    {
638      return;
639    }
640    if(!fgets( buf, sizeof(buf), fp)) return;
641    if(strcmp(buf,"@@ factory GF(q) table @@\n")!=0)
642    {
643      goto err;
644    }
645    if(!fgets( buf, sizeof(buf), fp))
646    {
647      goto err;
648    }
649    int q;
650    sscanf(buf,"%d %d",&nfCharP,&q);
651    nfReadMipo(buf);
652    nfCharQ1=nfCharQ-1;
653    //Print("nfCharQ=%d,nfCharQ1=%d,mipo=>>%s<<\n",nfCharQ,nfCharQ1,buf);
654    nfPlus1Table= (CARDINAL *)Alloc( (nfCharQ)*sizeof(CARDINAL) );
655    int digs = gf_tab_numdigits62( nfCharQ );
656    char * bufptr;
657    int i = 1;
658    int k;
659    while ( i < nfCharQ )
660    {
661      fgets( buf, sizeof(buf), fp);
662      //( strlen( buffer ) == (size_t)digs * 30, "illegal table" );
663      bufptr = buf;
664      k = 0;
665      while ( (i < nfCharQ) && (k < 30) )
666      {
667        nfPlus1Table[i] = convertback62( bufptr, digs );
668        if(nfPlus1Table[i]>nfCharQ)
669        {
670          Print("wrong entry %d: %d(%c%c%c)\n",i,nfPlus1Table[i],bufptr[0],bufptr[1],bufptr[2]);
671        }
672        bufptr += digs;
673        if (nfPlus1Table[i]==nfCharQ)
674        {
675          if(i==nfCharQ1)
676          {
677            nfM1=0;
678          }
679          else
680          {
681            nfM1=i;
682          }
683        }
684        i++; k++;
685      }
686    }
687    nfPlus1Table[0]=nfPlus1Table[nfCharQ1];
688  }
689  else
690    nfCharQ=0;
691#ifdef LDEBUG
692  nfTest((number)0);
693#endif
694  return;
695err:
696  Werror("illegal GF-table %d",nfCharQ);
697}
698
699/*2
700* map Z/p -> GF(p,n)
701*/
702number nfMapP(number c)
703{
704  return nfInit((int)c);
705}
706
707/*2
708* set map function nMap ... -> GF(p,n)
709*/
710BOOLEAN nfSetMap(ring r)
711{
712  if (rField_is_GF(r,nfCharQ))
713  {
714    nMap=nfCopy;   /* GF(p,n) -> GF(p,n) */
715    return TRUE;
716  }
717  if (rField_is_Zp(r,nfCharP))
718  {
719    nMap=nfMapP;    /* Z/p -> GF(p,n) */
720    return TRUE;
721  }
722  return FALSE;     /* default */
723}
Note: See TracBrowser for help on using the repository browser.