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