modulop.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: numbers modulo p (<=32003)
6 */
7 
8 #include <misc/auxiliary.h>
9 #include <omalloc/omalloc.h>
10 
11 #include <factory/factory.h>
12 
13 #include <misc/mylimits.h>
14 #include <misc/sirandom.h>
15 
16 #include <reporter/reporter.h>
17 
18 #include <coeffs/coeffs.h>
19 #include <coeffs/numbers.h>
20 #include <coeffs/mpr_complex.h>
21 
22 #include "longrat.h"
23 #include "modulop.h"
24 
25 #include <string.h>
26 
27 /// Our Type!
28 static const n_coeffType ID = n_Zp;
29 
30 BOOLEAN npGreaterZero (number k, const coeffs r);
31 number npMult (number a, number b, const coeffs r);
32 number npInit (long i, const coeffs r);
33 long npInt (number &n, const coeffs r);
34 number npAdd (number a, number b,const coeffs r);
35 number npSub (number a, number b,const coeffs r);
36 void npPower (number a, int i, number * result,const coeffs r);
37 BOOLEAN npIsZero (number a,const coeffs r);
38 BOOLEAN npIsOne (number a,const coeffs r);
39 BOOLEAN npIsMOne (number a,const coeffs r);
40 number npDiv (number a, number b,const coeffs r);
41 number npNeg (number c,const coeffs r);
42 number npInvers (number c,const coeffs r);
43 BOOLEAN npGreater (number a, number b,const coeffs r);
44 BOOLEAN npEqual (number a, number b,const coeffs r);
45 void npWrite (number &a, const coeffs r);
46 void npCoeffWrite (const coeffs r, BOOLEAN details);
47 const char * npRead (const char *s, number *a,const coeffs r);
48 #ifdef LDEBUG
49 BOOLEAN npDBTest (number a, const char *f, const int l, const coeffs r);
50 #define npTest(A,r) npDBTest(A,__FILE__,__LINE__, r)
51 #else
52 #define npTest(A,r) (0)
53 #endif
54 
55 //int npGetChar();
56 
57 nMapFunc npSetMap(const coeffs src, const coeffs dst);
58 number npMapP(number from, const coeffs src, const coeffs r);
59 
60 // extern int npGen; // obsolete
61 
62 // int npGen=0;
63 
64 /*-------specials for spolys, do NOT use otherwise--------------------------*/
65 /* for npMultM, npSubM, npNegM, npEqualM : */
66 #ifdef HAVE_DIV_MOD
67 extern unsigned short *npInvTable;
68 #else
69 #ifndef HAVE_MULT_MOD
70 extern long npPminus1M;
71 extern unsigned short *npExpTable;
72 extern unsigned short *npLogTable;
73 #endif
74 #endif
75 
76 #ifdef NV_OPS
77 #pragma GCC diagnostic ignored "-Wlong-long"
78 static inline number nvMultM(number a, number b, const coeffs r)
79 {
80  assume( getCoeffType(r) == ID );
81 
82 #if SIZEOF_LONG == 4
83 #define ULONG64 (unsigned long long)(unsigned long)
84 #else
85 #define ULONG64 (unsigned long)
86 #endif
87  return (number)
88  (unsigned long)((ULONG64 a)*(ULONG64 b) % (ULONG64 r->ch));
89 }
90 number nvMult (number a, number b, const coeffs r);
91 number nvDiv (number a, number b, const coeffs r);
92 number nvInvers (number c, const coeffs r);
93 //void nvPower (number a, int i, number * result, const coeffs r);
94 #endif
95 
96 
97 
98 
99 BOOLEAN npGreaterZero (number k, const coeffs r)
100 {
101  n_Test(k, r);
102 
103  int h = (int)((long) k);
104  return ((int)h !=0) && (h <= (r->ch>>1));
105 }
106 
107 //unsigned long npMultMod(unsigned long a, unsigned long b, int npPrimeM)
108 //{
109 // unsigned long c = a*b;
110 // c = c % npPrimeM;
111 // assume(c == (unsigned long) npMultM((number) a, (number) b, npPrimeM));
112 // return c;
113 //}
114 
115 number npMult (number a,number b, const coeffs r)
116 {
117  n_Test(a, r);
118  n_Test(b, r);
119 
120  if (((long)a == 0) || ((long)b == 0))
121  return (number)0;
122  number c = npMultM(a,b, r);
123  n_Test(c, r);
124  return c;
125 }
126 
127 /*2
128 * create a number from int
129 */
130 number npInit (long i, const coeffs r)
131 {
132  long ii=i % (long)r->ch;
133  if (ii < 0L) ii += (long)r->ch;
134 
135  number c = (number)ii;
136  n_Test(c, r);
137  return c;
138 
139 }
140 
141 
142 /*2
143  * convert a number to an int in (-p/2 .. p/2]
144  */
145 long npInt(number &n, const coeffs r)
146 {
147  n_Test(n, r);
148 
149  if ((long)n > (((long)r->ch) >>1)) return ((long)n -((long)r->ch));
150  else return ((long)n);
151 }
152 
153 number npAdd (number a, number b, const coeffs r)
154 {
155  n_Test(a, r);
156  n_Test(b, r);
157 
158  number c = npAddM(a,b, r);
159 
160  n_Test(c, r);
161 
162  return c;
163 }
164 
165 number npSub (number a, number b, const coeffs r)
166 {
167  n_Test(a, r);
168  n_Test(b, r);
169 
170  number c = npSubM(a,b,r);
171 
172  n_Test(c, r);
173 
174  return c;
175 }
176 
177 BOOLEAN npIsZero (number a, const coeffs r)
178 {
179  n_Test(a, r);
180 
181  return 0 == (long)a;
182 }
183 
184 BOOLEAN npIsOne (number a, const coeffs r)
185 {
186  n_Test(a, r);
187 
188  return 1 == (long)a;
189 }
190 
191 BOOLEAN npIsMOne (number a, const coeffs r)
192 {
193  n_Test(a, r);
194 
195  return ((r->npPminus1M == (long)a)&&((long)1!=(long)a));
196 }
197 
198 #ifdef HAVE_DIV_MOD
199 
200 #ifdef USE_NTL_XGCD
201 
202 //ifdef HAVE_NTL // in ntl.a
203 //extern void XGCD(long& d, long& s, long& t, long a, long b);
204 #include <NTL/ZZ.h>
205 #ifdef NTL_CLIENT
206 NTL_CLIENT
207 #endif
208 
209 #endif
210 
211 long InvMod(long a, const coeffs R)
212 {
213  long d, s, t;
214 
215 #ifdef USE_NTL_XGCD
216  XGCD(d, s, t, a, R->ch);
217  assume (d == 1);
218 #else
219  long u, v, u0, v0, u1, v1, u2, v2, q, r;
220 
221  assume(a>0);
222  u1=1; u2=0;
223  u = a; v = R->ch;
224 
225  while (v != 0)
226  {
227  q = u / v;
228  r = u % v;
229  u = v;
230  v = r;
231  u0 = u2;
232  u2 = u1 - q*u2;
233  u1 = u0;
234  }
235 
236  assume(u==1);
237  s = u1;
238 #endif
239  if (s < 0)
240  return s + R->ch;
241  else
242  return s;
243 }
244 #endif
245 
246 inline number npInversM (number c, const coeffs r)
247 {
248  n_Test(c, r);
249 #ifndef HAVE_DIV_MOD
250  number d = (number)(long)r->npExpTable[r->npPminus1M - r->npLogTable[(long)c]];
251 #else
252  long inv=(long)r->npInvTable[(long)c];
253  if (inv==0)
254  {
255  inv=InvMod((long)c,r);
256  r->npInvTable[(long)c]=inv;
257  }
258  number d = (number)inv;
259 #endif
260  n_Test(d, r);
261  return d;
262 
263 }
264 
265 number npDiv (number a,number b, const coeffs r)
266 {
267  n_Test(a, r);
268  n_Test(b, r);
269 
270 //#ifdef NV_OPS
271 // if (r->ch>NV_MAX_PRIME)
272 // return nvDiv(a,b);
273 //#endif
274  if ((long)a==0)
275  return (number)0;
276  number d;
277 
278 #ifndef HAVE_DIV_MOD
279  if ((long)b==0)
280  {
281  WerrorS(nDivBy0);
282  return (number)0;
283  }
284 
285  int s = r->npLogTable[(long)a] - r->npLogTable[(long)b];
286  if (s < 0)
287  s += r->npPminus1M;
288  d = (number)(long)r->npExpTable[s];
289 #else
290  number inv=npInversM(b,r);
291  d = npMultM(a,inv,r);
292 #endif
293 
294  n_Test(d, r);
295  return d;
296 
297 }
298 number npInvers (number c, const coeffs r)
299 {
300  n_Test(c, r);
301 
302  if ((long)c==0)
303  {
304  WerrorS("1/0");
305  return (number)0;
306  }
307  number d = npInversM(c,r);
308 
309  n_Test(d, r);
310  return d;
311 
312 }
313 
314 number npNeg (number c, const coeffs r)
315 {
316  n_Test(c, r);
317 
318  if ((long)c==0) return c;
319 
320 #if 0
321  number d = npNegM(c,r);
322  n_Test(d, r);
323  return d;
324 #else
325  c = npNegM(c,r);
326  n_Test(c, r);
327  return c;
328 #endif
329 }
330 
331 BOOLEAN npGreater (number a,number b, const coeffs r)
332 {
333  n_Test(a, r);
334  n_Test(b, r);
335 
336  //return (long)a != (long)b;
337  return (long)a > (long)b;
338 }
339 
340 BOOLEAN npEqual (number a,number b, const coeffs r)
341 {
342  n_Test(a, r);
343  n_Test(b, r);
344 
345 // return (long)a == (long)b;
346 
347  return npEqualM(a,b,r);
348 }
349 
350 void npWrite (number &a, const coeffs r)
351 {
352  n_Test(a, r);
353 
354  if ((long)a>(((long)r->ch) >>1)) StringAppend("-%d",(int)(((long)r->ch)-((long)a)));
355  else StringAppend("%d",(int)((long)a));
356 }
357 
358 #if 0
359 void npPower (number a, int i, number * result, const coeffs r)
360 {
361  n_Test(a, r);
362 
363  if (i==0)
364  {
365  //npInit(1,result);
366  *(long *)result = 1;
367  }
368  else if (i==1)
369  {
370  *result = a;
371  }
372  else
373  {
374  npPower(a,i-1,result,r);
375  *result = npMultM(a,*result,r);
376  }
377 }
378 #endif
379 
380 static const char* npEati(const char *s, int *i, const coeffs r)
381 {
382 
383  if (((*s) >= '0') && ((*s) <= '9'))
384  {
385  unsigned long ii=0L;
386  do
387  {
388  ii *= 10;
389  ii += *s++ - '0';
390  if (ii >= (MAX_INT_VAL / 10)) ii = ii % r->ch;
391  }
392  while (((*s) >= '0') && ((*s) <= '9'));
393  if (ii >= (unsigned long)r->ch) ii = ii % r->ch;
394  *i=(int)ii;
395  }
396  else (*i) = 1;
397  return s;
398 }
399 
400 const char * npRead (const char *s, number *a, const coeffs r)
401 {
402  int z;
403  int n=1;
404 
405  s = npEati(s, &z, r);
406  if ((*s) == '/')
407  {
408  s++;
409  s = npEati(s, &n, r);
410  }
411  if (n == 1)
412  *a = (number)(long)z;
413  else
414  {
415  if ((z==0)&&(n==0)) WerrorS(nDivBy0);
416  else
417  {
418 #ifdef NV_OPS
419  if (r->ch>NV_MAX_PRIME)
420  *a = nvDiv((number)(long)z,(number)(long)n,r);
421  else
422 #endif
423  *a = npDiv((number)(long)z,(number)(long)n,r);
424  }
425  }
426  n_Test(*a, r);
427  return s;
428 }
429 
430 /*2
431 * set the charcteristic (allocate and init tables)
432 */
433 
435 {
436  #ifdef HAVE_DIV_MOD
437  if (r->npInvTable!=NULL)
438  omFreeSize( (void *)r->npInvTable, r->ch*sizeof(unsigned short) );
439  r->npInvTable=NULL;
440  #else
441  if (r->npExpTable!=NULL)
442  {
443  omFreeSize( (void *)r->npExpTable, r->ch*sizeof(unsigned short) );
444  omFreeSize( (void *)r->npLogTable, r->ch*sizeof(unsigned short) );
445  r->npExpTable=NULL; r->npLogTable=NULL;
446  }
447  #endif
448 }
449 
450 static BOOLEAN npCoeffsEqual(const coeffs r, n_coeffType n, void * parameter)
451 {
452  /* test, if r is an instance of nInitCoeffs(n,parameter) */
453  return (n==n_Zp) && (r->ch==(int)(long)parameter);
454 }
455 CanonicalForm npConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
456 {
457  if (setChar) setCharacteristic( r->ch );
458  CanonicalForm term(npInt( n,r ));
459  return term;
460 }
461 
462 number npConvFactoryNSingN( const CanonicalForm n, const coeffs r)
463 {
464  if (n.isImm())
465  {
466  return npInit(n.intval(),r);
467  }
468  else
469  {
470  assume(0);
471  return NULL;
472  }
473 }
474 
475 static char* npCoeffString(const coeffs r)
476 {
477  char *s=(char*)omAlloc(11);
478  snprintf(s,11,"%d",r->ch);
479  return s;
480 }
481 
482 static void npWriteFd(number n, FILE* f, const coeffs r)
483 {
484  fprintf(f,"%d ",(int)(long)n);
485 }
486 
487 static number npReadFd(s_buff f, const coeffs r)
488 {
489  // read int
490  int dd;
491  dd=s_readint(f);
492  return (number)(long)dd;
493 }
494 
495 static number npRandom(siRandProc p, number, number, const coeffs cf)
496 {
497  return npInit(p(),cf);
498 }
499 
501 {
502  assume( getCoeffType(r) == ID );
503  const int c = (int) (long) p;
504 
505  assume( c > 0 );
506 
507  int i, w;
508 
509  r->is_field=TRUE;
510  r->is_domain=TRUE;
511  r->rep=n_rep_int;
512 
513  r->ch = c;
514  r->npPminus1M = c /*r->ch*/ - 1;
515 
516  //r->cfInitChar=npInitChar;
517  r->cfKillChar=npKillChar;
518  r->nCoeffIsEqual=npCoeffsEqual;
519  r->cfCoeffString=npCoeffString;
520 
521  r->cfMult = npMult;
522  r->cfSub = npSub;
523  r->cfAdd = npAdd;
524  r->cfDiv = npDiv;
525  r->cfInit = npInit;
526  //r->cfSize = ndSize;
527  r->cfInt = npInt;
528  #ifdef HAVE_RINGS
529  //r->cfDivComp = NULL; // only for ring stuff
530  //r->cfIsUnit = NULL; // only for ring stuff
531  //r->cfGetUnit = NULL; // only for ring stuff
532  //r->cfExtGcd = NULL; // only for ring stuff
533  // r->cfDivBy = NULL; // only for ring stuff
534  #endif
535  r->cfInpNeg = npNeg;
536  r->cfInvers= npInvers;
537  //r->cfCopy = ndCopy;
538  //r->cfRePart = ndCopy;
539  //r->cfImPart = ndReturn0;
540  r->cfWriteLong = npWrite;
541  r->cfRead = npRead;
542  //r->cfNormalize=ndNormalize;
543  r->cfGreater = npGreater;
544  r->cfEqual = npEqual;
545  r->cfIsZero = npIsZero;
546  r->cfIsOne = npIsOne;
547  r->cfIsMOne = npIsMOne;
548  r->cfGreaterZero = npGreaterZero;
549  //r->cfPower = npPower;
550  //r->cfGetDenom = ndGetDenom;
551  //r->cfGetNumerator = ndGetNumerator;
552  //r->cfGcd = ndGcd;
553  //r->cfLcm = ndGcd;
554  //r->cfDelete= ndDelete;
555  r->cfSetMap = npSetMap;
556  //r->cfName = ndName;
557  //r->cfInpMult=ndInpMult;
558 #ifdef NV_OPS
559  if (c>NV_MAX_PRIME)
560  {
561  r->cfMult = nvMult;
562  r->cfDiv = nvDiv;
563  r->cfExactDiv= nvDiv;
564  r->cfInvers= nvInvers;
565  //r->cfPower= nvPower;
566  }
567 #endif
568  r->cfCoeffWrite=npCoeffWrite;
569 #ifdef LDEBUG
570  // debug stuff
571  r->cfDBTest=npDBTest;
572 #endif
573 
574  r->convSingNFactoryN=npConvSingNFactoryN;
575  r->convFactoryNSingN=npConvFactoryNSingN;
576 
577  r->cfRandom=npRandom;
578 
579  // io via ssi
580  r->cfWriteFd=npWriteFd;
581  r->cfReadFd=npReadFd;
582 
583  // the variables:
584  r->nNULL = (number)0;
585  r->type = n_Zp;
586  r->ch = c;
587  r->has_simple_Alloc=TRUE;
588  r->has_simple_Inverse=TRUE;
589 
590  // the tables
591 #ifdef NV_OPS
592  if (r->ch <=NV_MAX_PRIME)
593 #endif
594  {
595 #if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
596  r->npExpTable=(unsigned short *)omAlloc( r->ch*sizeof(unsigned short) );
597  r->npLogTable=(unsigned short *)omAlloc( r->ch*sizeof(unsigned short) );
598  r->npExpTable[0] = 1;
599  r->npLogTable[0] = 0;
600  if (r->ch > 2)
601  {
602  w = 1;
603  loop
604  {
605  r->npLogTable[1] = 0;
606  w++;
607  i = 0;
608  loop
609  {
610  i++;
611  r->npExpTable[i] =(int)(((long)w * (long)r->npExpTable[i-1]) % r->ch);
612  r->npLogTable[r->npExpTable[i]] = i;
613  if /*(i == r->ch - 1 ) ||*/ (/*(*/ r->npExpTable[i] == 1 /*)*/)
614  break;
615  }
616  if (i == r->ch - 1)
617  break;
618  }
619  }
620  else
621  {
622  r->npExpTable[1] = 1;
623  r->npLogTable[1] = 0;
624  }
625 #endif
626 #ifdef HAVE_DIV_MOD
627  r->npInvTable=(unsigned short*)omAlloc0( r->ch*sizeof(unsigned short) );
628 #endif
629  }
630  return FALSE;
631 }
632 
633 #ifdef LDEBUG
634 BOOLEAN npDBTest (number a, const char *f, const int l, const coeffs r)
635 {
636  if (((long)a<0) || ((long)a>r->ch))
637  {
638  Print("wrong mod p number %ld at %s,%d\n",(long)a,f,l);
639  return FALSE;
640  }
641  return TRUE;
642 }
643 #endif
644 
645 number npMapP(number from, const coeffs src, const coeffs dst_r)
646 {
647  long i = (long)from;
648  if (i>src->ch/2)
649  {
650  i-=src->ch;
651  while (i < 0) i+=dst_r->ch;
652  }
653  i%=dst_r->ch;
654  return (number)i;
655 }
656 
657 static number npMapLongR(number from, const coeffs /*src*/, const coeffs dst_r)
658 {
659  gmp_float *ff=(gmp_float*)from;
660  mpf_t *f=ff->_mpfp();
661  number res;
662  mpz_ptr dest,ndest;
663  int size,i;
664  int e,al,bl;
665  long iz;
666  mp_ptr qp,dd,nn;
667 
668  size = (*f)[0]._mp_size;
669  if (size == 0)
670  return npInit(0,dst_r);
671  if(size<0)
672  size = -size;
673 
674  qp = (*f)[0]._mp_d;
675  while(qp[0]==0)
676  {
677  qp++;
678  size--;
679  }
680 
681  if(dst_r->ch>2)
682  e=(*f)[0]._mp_exp-size;
683  else
684  e=0;
685  res = ALLOC_RNUMBER();
686 #if defined(LDEBUG)
687  res->debug=123456;
688 #endif
689  dest = res->z;
690 
691  long in=0;
692  if (e<0)
693  {
694  al = dest->_mp_size = size;
695  if (al<2) al = 2;
696  dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
697  for (i=0;i<size;i++) dd[i] = qp[i];
698  bl = 1-e;
699  nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
700  nn[bl-1] = 1;
701  for (i=bl-2;i>=0;i--) nn[i] = 0;
702  ndest = res->n;
703  ndest->_mp_d = nn;
704  ndest->_mp_alloc = ndest->_mp_size = bl;
705  res->s = 0;
706  in=mpz_fdiv_ui(ndest,dst_r->ch);
707  mpz_clear(ndest);
708  }
709  else
710  {
711  al = dest->_mp_size = size+e;
712  if (al<2) al = 2;
713  dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
714  for (i=0;i<size;i++) dd[i+e] = qp[i];
715  for (i=0;i<e;i++) dd[i] = 0;
716  res->s = 3;
717  }
718 
719  dest->_mp_d = dd;
720  dest->_mp_alloc = al;
721  iz=mpz_fdiv_ui(dest,dst_r->ch);
722  mpz_clear(dest);
723  if(res->s==0)
724  iz=(long)npDiv((number)iz,(number)in,dst_r);
725  FREE_RNUMBER(res); // Q!?
726  return (number)iz;
727 }
728 
729 #ifdef HAVE_RINGS
730 /*2
731 * convert from a GMP integer
732 */
733 number npMapGMP(number from, const coeffs /*src*/, const coeffs dst)
734 {
735  mpz_ptr erg = (mpz_ptr) omAlloc(sizeof(mpz_t)); // evtl. spaeter mit bin
736  mpz_init(erg);
737 
738  mpz_mod_ui(erg, (mpz_ptr) from, dst->ch);
739  number r = (number) mpz_get_si(erg);
740 
741  mpz_clear(erg);
742  omFree((void *) erg);
743  return (number) r;
744 }
745 
746 number npMapZ(number from, const coeffs src, const coeffs dst)
747 {
748  if (SR_HDL(from) & SR_INT)
749  {
750  long f_i=SR_TO_INT(from);
751  return npInit(f_i,dst);
752  }
753  return npMapGMP(from,src,dst);
754 }
755 
756 /*2
757 * convert from an machine long
758 */
759 number npMapMachineInt(number from, const coeffs /*src*/,const coeffs dst)
760 {
761  long i = (long) (((unsigned long) from) % dst->ch);
762  return (number) i;
763 }
764 #endif
765 
766 number npMapCanonicalForm (number a, const coeffs /*src*/, const coeffs dst)
767 {
768  setCharacteristic (dst ->ch);
770  return (number) (f.intval());
771 }
772 
773 nMapFunc npSetMap(const coeffs src, const coeffs dst)
774 {
775 #ifdef HAVE_RINGS
776  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
777  {
778  return npMapMachineInt;
779  }
780  if (src->rep==n_rep_gmp) //nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src))
781  {
782  return npMapGMP;
783  }
784  if (src->rep==n_rep_gap_gmp) //nCoeff_is_Ring_Z(src)
785  {
786  return npMapZ;
787  }
788 #endif
789  if (src->rep==n_rep_gap_rat) /* Q, Z */
790  {
791  return nlModP; // npMap0; // FIXME? TODO? // extern number nlModP(number q, const coeffs Q, const coeffs Zp); // Map q \in QQ \to Zp // FIXME!
792  }
793  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src) )
794  {
795  if (n_GetChar(src) == n_GetChar(dst))
796  {
797  return ndCopyMap;
798  }
799  else
800  {
801  return npMapP;
802  }
803  }
804  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
805  {
806  return npMapLongR;
807  }
808  if (nCoeff_is_CF (src))
809  {
810  return npMapCanonicalForm;
811  }
812  return NULL; /* default */
813 }
814 
815 // -----------------------------------------------------------
816 // operation for very large primes (32003< p < 2^31-1)
817 // ----------------------------------------------------------
818 #ifdef NV_OPS
819 
820 number nvMult (number a,number b, const coeffs r)
821 {
822  //if (((long)a == 0) || ((long)b == 0))
823  // return (number)0;
824  //else
825  return nvMultM(a,b,r);
826 }
827 
828 void nvInpMult(number &a, number b, const coeffs r)
829 {
830  number n=nvMultM(a,b,r);
831  a=n;
832 }
833 
834 
835 inline long nvInvMod(long a, const coeffs R)
836 {
837 #ifdef HAVE_DIV_MOD
838  return InvMod(a, R);
839 #else
840 /// TODO: use "long InvMod(long a, const coeffs R)"?!
841 
842  long s;
843 
844  long u, u0, u1, u2, q, r; // v0, v1, v2,
845 
846  u1=1; // v1=0;
847  u2=0; // v2=1;
848  u = a;
849 
850  long v = R->ch;
851 
852  while (v != 0)
853  {
854  q = u / v;
855  r = u % v;
856  u = v;
857  v = r;
858  u0 = u2;
859 // v0 = v2;
860  u2 = u1 - q*u2;
861 // v2 = v1 - q*v2;
862  u1 = u0;
863 // v1 = v0;
864  }
865 
866  s = u1;
867  //t = v1;
868  if (s < 0)
869  return s + R->ch;
870  else
871  return s;
872 #endif
873 }
874 
875 inline number nvInversM (number c, const coeffs r)
876 {
877  long inv=nvInvMod((long)c,r);
878  return (number)inv;
879 }
880 
881 number nvDiv (number a,number b, const coeffs r)
882 {
883  if ((long)a==0)
884  return (number)0;
885  else if ((long)b==0)
886  {
887  WerrorS(nDivBy0);
888  return (number)0;
889  }
890  else
891  {
892  number inv=nvInversM(b,r);
893  return nvMultM(a,inv,r);
894  }
895 }
896 number nvInvers (number c, const coeffs r)
897 {
898  if ((long)c==0)
899  {
900  WerrorS(nDivBy0);
901  return (number)0;
902  }
903  return nvInversM(c,r);
904 }
905 #if 0
906 void nvPower (number a, int i, number * result, const coeffs r)
907 {
908  if (i==0)
909  {
910  //npInit(1,result);
911  *(long *)result = 1;
912  }
913  else if (i==1)
914  {
915  *result = a;
916  }
917  else
918  {
919  nvPower(a,i-1,result,r);
920  *result = nvMultM(a,*result,r);
921  }
922 }
923 #endif
924 #endif
925 
926 void npCoeffWrite (const coeffs r, BOOLEAN /*details*/)
927 {
928  Print("// characteristic : %d\n",r->ch);
929 }
930 
const const intvec const intvec const ring _currRing const const intvec const intvec const ring _currRing int
Definition: gb_hack.h:53
const CanonicalForm int s
Definition: facAbsFact.cc:55
const poly a
Definition: syzextra.cc:212
#define Print
Definition: emacs.cc:83
unsigned short * npExpTable
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition: coeffs.h:816
static number npMultM(number a, number b, const coeffs r)
Definition: modulop.h:49
number npInit(long i, const coeffs r)
Definition: modulop.cc:130
long npInt(number &n, const coeffs r)
Definition: modulop.cc:145
Definition: int_poly.h:36
loop
Definition: myNF.cc:98
#define FALSE
Definition: auxiliary.h:140
number npMapZ(number from, const coeffs src, const coeffs dst)
Definition: modulop.cc:746
mpf_t * _mpfp()
Definition: mpr_complex.h:134
return P p
Definition: myNF.cc:203
number nvInvers(number c, const coeffs r)
Definition: modulop.cc:896
f
Definition: cfModGcd.cc:4022
number ndCopyMap(number a, const coeffs aRing, const coeffs r)
Definition: numbers.cc:228
static FORCE_INLINE BOOLEAN nCoeff_is_long_R(const coeffs r)
Definition: coeffs.h:887
void npPower(number a, int i, number *result, const coeffs r)
number npInvers(number c, const coeffs r)
Definition: modulop.cc:298
#define npEqualM(A, B, r)
Definition: modulop.h:132
number nvMult(number a, number b, const coeffs r)
Definition: modulop.cc:820
long nvInvMod(long a, const coeffs R)
Definition: modulop.cc:835
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
{p < 2^31}
Definition: coeffs.h:29
const CanonicalForm CFMap CFMap int &both_non_zero int n
Definition: cfEzgcd.cc:52
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
Definition: coeffs.h:739
(), see rinteger.h, new impl.
Definition: coeffs.h:110
number npAdd(number a, number b, const coeffs r)
Definition: modulop.cc:153
void nvInpMult(number &a, number b, const coeffs r)
Definition: modulop.cc:828
number npMapP(number from, const coeffs src, const coeffs r)
Definition: modulop.cc:645
static FORCE_INLINE int n_GetChar(const coeffs r)
Return the characteristic of the coeff. domain.
Definition: coeffs.h:444
factory's main class
Definition: canonicalform.h:72
#define TRUE
Definition: auxiliary.h:144
number npDiv(number a, number b, const coeffs r)
Definition: modulop.cc:265
#define FREE_RNUMBER(x)
Definition: coeffs.h:84
void WerrorS(const char *s)
Definition: feFopen.cc:23
int k
Definition: cfEzgcd.cc:93
static number npReadFd(s_buff f, const coeffs r)
Definition: modulop.cc:487
BOOLEAN npEqual(number a, number b, const coeffs r)
Definition: modulop.cc:340
BOOLEAN npInitChar(coeffs r, void *p)
Definition: modulop.cc:500
long intval() const
conversion functions
#define omAlloc(size)
Definition: omAllocDecl.h:210
long npPminus1M
BOOLEAN npDBTest(number a, const char *f, const int l, const coeffs r)
Definition: modulop.cc:634
void setCharacteristic(int c)
Definition: cf_char.cc:23
int int kStrategy strat if(h==NULL) return NULL
virtual class for internal CanonicalForm's
Definition: int_cf.h:35
static void npWriteFd(number n, FILE *f, const coeffs r)
Definition: modulop.cc:482
static number npNegM(number a, const coeffs r)
Definition: modulop.h:111
number npInversM(number c, const coeffs r)
Definition: modulop.cc:246
static number npSubM(number a, number b, const coeffs r)
Definition: modulop.h:82
static number npRandom(siRandProc p, number, number, const coeffs cf)
Definition: modulop.cc:495
poly res
Definition: myNF.cc:322
number npMapMachineInt(number from, const coeffs, const coeffs dst)
Definition: modulop.cc:759
BOOLEAN npGreater(number a, number b, const coeffs r)
Definition: modulop.cc:331
number nvDiv(number a, number b, const coeffs r)
Definition: modulop.cc:881
unsigned short * npLogTable
const ring r
Definition: syzextra.cc:208
BOOLEAN npIsMOne(number a, const coeffs r)
Definition: modulop.cc:191
Coefficient rings, fields and other domains suitable for Singular polynomials.
void npCoeffWrite(const coeffs r, BOOLEAN details)
Definition: modulop.cc:926
static FORCE_INLINE BOOLEAN nCoeff_is_CF(const coeffs r)
Definition: coeffs.h:893
int s_readint(s_buff F)
Definition: s_buff.cc:120
static const n_coeffType ID
Our Type!
Definition: modulop.cc:28
#define omFree(addr)
Definition: omAllocDecl.h:261
#define assume(x)
Definition: mod2.h:405
The main handler for Singular numbers which are suitable for Singular polynomials.
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:71
BOOLEAN npGreaterZero(number k, const coeffs r)
Definition: modulop.cc:99
number nlModP(number q, const coeffs Q, const coeffs Zp)
Definition: longrat.cc:1355
const int MAX_INT_VAL
Definition: mylimits.h:12
static const char * npEati(const char *s, int *i, const coeffs r)
Definition: modulop.cc:380
#define n_Test(a, r)
BOOLEAN n_Test(number a, const coeffs r)
Definition: coeffs.h:918
static number npAddM(number a, number b, const coeffs r)
Definition: modulop.h:77
All the auxiliary stuff.
const char *const nDivBy0
Definition: numbers.h:83
#define StringAppend
Definition: emacs.cc:82
int i
Definition: cfEzgcd.cc:123
nMapFunc npSetMap(const coeffs src, const coeffs dst)
Definition: modulop.cc:773
(mpz_ptr), see rmodulon,h
Definition: coeffs.h:113
static number npMapLongR(number from, const coeffs, const coeffs dst_r)
Definition: modulop.cc:657
static char * npCoeffString(const coeffs r)
Definition: modulop.cc:475
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421
int(* siRandProc)()
Definition: sirandom.h:9
void npWrite(number &a, const coeffs r)
Definition: modulop.cc:350
number npSub(number a, number b, const coeffs r)
Definition: modulop.cc:165
number npConvFactoryNSingN(const CanonicalForm n, const coeffs r)
Definition: modulop.cc:462
#define NV_MAX_PRIME
Definition: modulop.h:21
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
#define SR_TO_INT(SR)
Definition: longrat.h:67
(number), see longrat.h
Definition: coeffs.h:109
bool isImm() const
Definition: canonicalform.h:97
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:37
n_coeffType
Definition: coeffs.h:26
CanonicalForm cf
Definition: cfModGcd.cc:4024
unsigned long InvMod(unsigned long a, const coeffs r)
Definition: rmodulo2m.cc:529
#define NULL
Definition: omList.c:10
#define ULONG64
(gmp_float), see
Definition: coeffs.h:115
number npNeg(number c, const coeffs r)
Definition: modulop.cc:314
#define R
Definition: sirandom.c:26
#define SR_INT
Definition: longrat.h:65
const CanonicalForm & w
Definition: facAbsFact.cc:55
#define ALLOC_RNUMBER()
Definition: coeffs.h:85
number npMult(number a, number b, const coeffs r)
Definition: modulop.cc:115
CanonicalForm npConvSingNFactoryN(number n, BOOLEAN setChar, const coeffs r)
Definition: modulop.cc:455
static BOOLEAN npCoeffsEqual(const coeffs r, n_coeffType n, void *parameter)
Definition: modulop.cc:450
number nvInversM(number c, const coeffs r)
Definition: modulop.cc:875
(int), see modulop.h
Definition: coeffs.h:108
#define SR_HDL(A)
Definition: tgb.cc:35
void npKillChar(coeffs r)
Definition: modulop.cc:434
const char * npRead(const char *s, number *a, const coeffs r)
Definition: modulop.cc:400
static Poly * h
Definition: janet.cc:978
int BOOLEAN
Definition: auxiliary.h:131
const poly b
Definition: syzextra.cc:213
BOOLEAN npIsOne(number a, const coeffs r)
Definition: modulop.cc:184
number npMapGMP(number from, const coeffs, const coeffs dst)
Definition: modulop.cc:733
BOOLEAN npIsZero(number a, const coeffs r)
Definition: modulop.cc:177
#define omAlloc0(size)
Definition: omAllocDecl.h:211
int l
Definition: cfEzgcd.cc:94
return result
Definition: facAbsBiFact.cc:76
static number nvMultM(number a, number b, const coeffs r)
Definition: modulop.cc:78
number npMapCanonicalForm(number a, const coeffs, const coeffs dst)
Definition: modulop.cc:766