source: git/libpolys/coeffs/ffields.cc @ 7b8e28f

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