rmodulon.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: numbers modulo n
6 */
7 #include "misc/auxiliary.h"
8 
9 #include "misc/mylimits.h"
10 #include "misc/prime.h" // IsPrime
11 #include "reporter/reporter.h"
12 
13 #include "coeffs/si_gmp.h"
14 #include "coeffs/coeffs.h"
15 #include "coeffs/modulop.h"
16 #include "coeffs/rintegers.h"
17 #include "coeffs/numbers.h"
18 
19 #include "coeffs/mpr_complex.h"
20 
21 #include "coeffs/longrat.h"
22 #include "coeffs/rmodulon.h"
23 
24 #include <string.h>
25 
26 #ifdef HAVE_RINGS
27 
28 void nrnWrite (number a, const coeffs);
29 #ifdef LDEBUG
30 BOOLEAN nrnDBTest (number a, const char *f, const int l, const coeffs r);
31 #endif
32 
33 extern omBin gmp_nrz_bin;
34 
35 static void nrnCoeffWrite (const coeffs r, BOOLEAN /*details*/)
36 {
37  size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) + 2;
38  char* s = (char*) omAlloc(l);
39  s= mpz_get_str (s, 10, r->modBase);
40 
41  #ifdef TEST_ZN_AS_ZP
42  if (l<10)
43  {
44  if (nCoeff_is_Zn(r)) Print("ZZ/%s", s);
45  else if (nCoeff_is_Ring_PtoM(r)) Print("ZZ/(%s^%lu)", s, r->modExponent);
46  }
47  else
48  #endif
49  {
50  if (nCoeff_is_Zn(r)) Print("ZZ/bigint(%s)", s);
51  else if (nCoeff_is_Ring_PtoM(r)) Print("ZZ/(bigint(%s)^%lu)", s, r->modExponent);
52  }
53 
54  omFreeSize((ADDRESS)s, l);
55 }
56 
58 {
59  const char start[]="ZZ/bigint(";
60  const int start_len=strlen(start);
61  if (strncmp(s,start,start_len)==0)
62  {
63  s+=start_len;
64  mpz_t z;
65  mpz_init(z);
66  s=nEatLong(s,z);
67  ZnmInfo info;
68  info.base=z;
69  info.exp= 1;
70  while ((*s!='\0') && (*s!=')')) s++;
71  // expect ")" or ")^exp"
72  if (*s=='\0') { mpz_clear(z); return NULL; }
73  if (((*s)==')') && (*(s+1)=='^'))
74  {
75  s=s+2;
76  s=nEati(s,&(info.exp),0);
77  return nInitChar(n_Znm,(void*) &info);
78  }
79  else
80  return nInitChar(n_Zn,(void*) &info);
81  }
82  else return NULL;
83 }
84 
85 static char* nrnCoeffName_buff=NULL;
86 static char* nrnCoeffName(const coeffs r)
87 {
89  size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) + 2;
90  char* s = (char*) omAlloc(l);
91  l+=22;
92  nrnCoeffName_buff=(char*)omAlloc(l);
93  s= mpz_get_str (s, 10, r->modBase);
94  int ll;
95  if (nCoeff_is_Zn(r))
96  ll=snprintf(nrnCoeffName_buff,l,"ZZ/bigint(%s)",s);
97  else if (nCoeff_is_Ring_PtoM(r))
98  ll=snprintf(nrnCoeffName_buff,l,"ZZ/bigint(%s)^%lu",s,r->modExponent);
99  assume(ll<(int)l); // otherwise nrnCoeffName_buff too small
100  omFreeSize((ADDRESS)s, l-22);
101  return nrnCoeffName_buff;
102 }
103 
104 static BOOLEAN nrnCoeffIsEqual(const coeffs r, n_coeffType n, void * parameter)
105 {
106  /* test, if r is an instance of nInitCoeffs(n,parameter) */
107  ZnmInfo *info=(ZnmInfo*)parameter;
108  return (n==r->type) && (r->modExponent==info->exp)
109  && (mpz_cmp(r->modBase,info->base)==0);
110 }
111 
112 static char* nrnCoeffString(const coeffs r)
113 {
114  size_t l = (size_t)mpz_sizeinbase(r->modBase, 10) +2;
115  char* b = (char*) omAlloc(l);
116  b= mpz_get_str (b, 10, r->modBase);
117  char* s = (char*) omAlloc(15+l);
118  if (nCoeff_is_Zn(r)) sprintf(s,"ZZ/%s",b);
119  else /*if (nCoeff_is_Ring_PtoM(r))*/ sprintf(s,"ZZ/(bigint(%s)^%lu)",b,r->modExponent);
120  omFreeSize(b,l);
121  return s;
122 }
123 
124 static void nrnKillChar(coeffs r)
125 {
126  mpz_clear(r->modNumber);
127  mpz_clear(r->modBase);
128  omFreeBin((void *) r->modBase, gmp_nrz_bin);
129  omFreeBin((void *) r->modNumber, gmp_nrz_bin);
130 }
131 
132 static coeffs nrnQuot1(number c, const coeffs r)
133 {
134  coeffs rr;
135  long ch = r->cfInt(c, r);
136  mpz_t a,b;
137  mpz_init_set(a, r->modNumber);
138  mpz_init_set_ui(b, ch);
139  mpz_t gcd;
140  mpz_init(gcd);
141  mpz_gcd(gcd, a,b);
142  if(mpz_cmp_ui(gcd, 1) == 0)
143  {
144  WerrorS("constant in q-ideal is coprime to modulus in ground ring");
145  WerrorS("Unable to create qring!");
146  return NULL;
147  }
148  if(r->modExponent == 1)
149  {
150  ZnmInfo info;
151  info.base = gcd;
152  info.exp = (unsigned long) 1;
153  rr = nInitChar(n_Zn, (void*)&info);
154  }
155  else
156  {
157  ZnmInfo info;
158  info.base = r->modBase;
159  int kNew = 1;
160  mpz_t baseTokNew;
161  mpz_init(baseTokNew);
162  mpz_set(baseTokNew, r->modBase);
163  while(mpz_cmp(gcd, baseTokNew) > 0)
164  {
165  kNew++;
166  mpz_mul(baseTokNew, baseTokNew, r->modBase);
167  }
168  //printf("\nkNew = %i\n",kNew);
169  info.exp = kNew;
170  mpz_clear(baseTokNew);
171  rr = nInitChar(n_Znm, (void*)&info);
172  }
173  mpz_clear(gcd);
174  return(rr);
175 }
176 
177 static number nrnCopy(number a, const coeffs)
178 {
179  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
180  mpz_init_set(erg, (mpz_ptr) a);
181  return (number) erg;
182 }
183 
184 /*
185  * create a number from int
186  */
187 static number nrnInit(long i, const coeffs r)
188 {
189  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
190  mpz_init_set_si(erg, i);
191  mpz_mod(erg, erg, r->modNumber);
192  return (number) erg;
193 }
194 
195 /*
196  * convert a number to int
197  */
198 static long nrnInt(number &n, const coeffs)
199 {
200  return mpz_get_si((mpz_ptr) n);
201 }
202 
203 #if SI_INTEGER_VARIANT==2
204 #define nrnDelete nrzDelete
205 #define nrnSize nrzSize
206 #else
207 static void nrnDelete(number *a, const coeffs)
208 {
209  if (*a != NULL)
210  {
211  mpz_clear((mpz_ptr) *a);
212  omFreeBin((void *) *a, gmp_nrz_bin);
213  *a = NULL;
214  }
215 }
216 static int nrnSize(number a, const coeffs)
217 {
218  mpz_ptr p=(mpz_ptr)a;
219  int s=p->_mp_alloc;
220  if (s==1) s=(mpz_cmp_ui(p,0)!=0);
221  return s;
222 }
223 #endif
224 /*
225  * Multiply two numbers
226  */
227 static number nrnMult(number a, number b, const coeffs r)
228 {
229  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
230  mpz_init(erg);
231  mpz_mul(erg, (mpz_ptr)a, (mpz_ptr) b);
232  mpz_mod(erg, erg, r->modNumber);
233  return (number) erg;
234 }
235 
236 static void nrnPower(number a, int i, number * result, const coeffs r)
237 {
238  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
239  mpz_init(erg);
240  mpz_powm_ui(erg, (mpz_ptr)a, i, r->modNumber);
241  *result = (number) erg;
242 }
243 
244 static number nrnAdd(number a, number b, const coeffs r)
245 {
246  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
247  mpz_init(erg);
248  mpz_add(erg, (mpz_ptr)a, (mpz_ptr) b);
249  mpz_mod(erg, erg, r->modNumber);
250  return (number) erg;
251 }
252 
253 static number nrnSub(number a, number b, const coeffs r)
254 {
255  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
256  mpz_init(erg);
257  mpz_sub(erg, (mpz_ptr)a, (mpz_ptr) b);
258  mpz_mod(erg, erg, r->modNumber);
259  return (number) erg;
260 }
261 
262 static BOOLEAN nrnIsZero(number a, const coeffs)
263 {
264  return 0 == mpz_cmpabs_ui((mpz_ptr)a, 0);
265 }
266 
267 static number nrnNeg(number c, const coeffs r)
268 {
269  if( !nrnIsZero(c, r) )
270  // Attention: This method operates in-place.
271  mpz_sub((mpz_ptr)c, r->modNumber, (mpz_ptr)c);
272  return c;
273 }
274 
275 static number nrnInvers(number c, const coeffs r)
276 {
277  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
278  mpz_init(erg);
279  mpz_invert(erg, (mpz_ptr)c, r->modNumber);
280  return (number) erg;
281 }
282 
283 /*
284  * Give the largest k, such that a = x * k, b = y * k has
285  * a solution.
286  * a may be NULL, b not
287  */
288 static number nrnGcd(number a, number b, const coeffs r)
289 {
290  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
291  mpz_init_set(erg, r->modNumber);
292  if (a != NULL) mpz_gcd(erg, erg, (mpz_ptr)a);
293  mpz_gcd(erg, erg, (mpz_ptr)b);
294  if(mpz_cmp(erg,r->modNumber)==0)
295  {
296  mpz_clear(erg);
298  return nrnInit(0,r);
299  }
300  return (number)erg;
301 }
302 
303 /*
304  * Give the smallest k, such that a * x = k = b * y has a solution
305  * TODO: lcm(gcd,gcd) better than gcd(lcm) ?
306  */
307 static number nrnLcm(number a, number b, const coeffs r)
308 {
309  number erg = nrnGcd(NULL, a, r);
310  number tmp = nrnGcd(NULL, b, r);
311  mpz_lcm((mpz_ptr)erg, (mpz_ptr)erg, (mpz_ptr)tmp);
312  nrnDelete(&tmp, r);
313  return (number)erg;
314 }
315 
316 /* Not needed any more, but may have room for improvement
317  number nrnGcd3(number a,number b, number c,ring r)
318 {
319  mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
320  mpz_init(erg);
321  if (a == NULL) a = (number)r->modNumber;
322  if (b == NULL) b = (number)r->modNumber;
323  if (c == NULL) c = (number)r->modNumber;
324  mpz_gcd(erg, (mpz_ptr)a, (mpz_ptr)b);
325  mpz_gcd(erg, erg, (mpz_ptr)c);
326  mpz_gcd(erg, erg, r->modNumber);
327  return (number)erg;
328 }
329 */
330 
331 /*
332  * Give the largest k, such that a = x * k, b = y * k has
333  * a solution and r, s, s.t. k = s*a + t*b
334  * CF: careful: ExtGcd is wrong as implemented (or at least may not
335  * give you what you want:
336  * ExtGcd(5, 10 modulo 12):
337  * the gcdext will return 5 = 1*5 + 0*10
338  * however, mod 12, the gcd should be 1
339  */
340 static number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r)
341 {
342  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
343  mpz_ptr bs = (mpz_ptr)omAllocBin(gmp_nrz_bin);
344  mpz_ptr bt = (mpz_ptr)omAllocBin(gmp_nrz_bin);
345  mpz_init(erg);
346  mpz_init(bs);
347  mpz_init(bt);
348  mpz_gcdext(erg, bs, bt, (mpz_ptr)a, (mpz_ptr)b);
349  mpz_mod(bs, bs, r->modNumber);
350  mpz_mod(bt, bt, r->modNumber);
351  *s = (number)bs;
352  *t = (number)bt;
353  return (number)erg;
354 }
355 
356 static BOOLEAN nrnIsOne(number a, const coeffs)
357 {
358  return 0 == mpz_cmp_si((mpz_ptr)a, 1);
359 }
360 
361 static BOOLEAN nrnEqual(number a, number b, const coeffs)
362 {
363  return 0 == mpz_cmp((mpz_ptr)a, (mpz_ptr)b);
364 }
365 
366 static number nrnGetUnit(number k, const coeffs r)
367 {
368  if (mpz_divisible_p(r->modNumber, (mpz_ptr)k)) return nrnInit(1,r);
369 
370  mpz_ptr unit = (mpz_ptr)nrnGcd(NULL, k, r);
371  mpz_tdiv_q(unit, (mpz_ptr)k, unit);
372  mpz_ptr gcd = (mpz_ptr)nrnGcd(NULL, (number)unit, r);
373  if (!nrnIsOne((number)gcd,r))
374  {
375  mpz_ptr ctmp;
376  // tmp := unit^2
377  mpz_ptr tmp = (mpz_ptr) nrnMult((number) unit,(number) unit,r);
378  // gcd_new := gcd(tmp, 0)
379  mpz_ptr gcd_new = (mpz_ptr) nrnGcd(NULL, (number) tmp, r);
380  while (!nrnEqual((number) gcd_new,(number) gcd,r))
381  {
382  // gcd := gcd_new
383  ctmp = gcd;
384  gcd = gcd_new;
385  gcd_new = ctmp;
386  // tmp := tmp * unit
387  mpz_mul(tmp, tmp, unit);
388  mpz_mod(tmp, tmp, r->modNumber);
389  // gcd_new := gcd(tmp, 0)
390  mpz_gcd(gcd_new, tmp, r->modNumber);
391  }
392  // unit := unit + modNumber / gcd_new
393  mpz_tdiv_q(tmp, r->modNumber, gcd_new);
394  mpz_add(unit, unit, tmp);
395  mpz_mod(unit, unit, r->modNumber);
396  nrnDelete((number*) &gcd_new, r);
397  nrnDelete((number*) &tmp, r);
398  }
399  nrnDelete((number*) &gcd, r);
400  return (number)unit;
401 }
402 
403 /* XExtGcd returns a unimodular matrix ((s,t)(u,v)) sth.
404  * (a,b)^t ((st)(uv)) = (g,0)^t
405  * Beware, the ExtGcd will not necessaairly do this.
406  * Problem: if g = as+bt then (in Z/nZ) it follows NOT that
407  * 1 = (a/g)s + (b/g) t
408  * due to the zero divisors.
409  */
410 
411 //#define CF_DEB;
412 static number nrnXExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
413 {
414  number xx;
415 #ifdef CF_DEB
416  StringSetS("XExtGcd of ");
417  nrnWrite(a, r);
418  StringAppendS("\t");
419  nrnWrite(b, r);
420  StringAppendS(" modulo ");
421  nrnWrite(xx = (number)r->modNumber, r);
422  Print("%s\n", StringEndS());
423 #endif
424 
425  mpz_ptr one = (mpz_ptr)omAllocBin(gmp_nrz_bin);
426  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
427  mpz_ptr bs = (mpz_ptr)omAllocBin(gmp_nrz_bin);
428  mpz_ptr bt = (mpz_ptr)omAllocBin(gmp_nrz_bin);
429  mpz_ptr bu = (mpz_ptr)omAllocBin(gmp_nrz_bin);
430  mpz_ptr bv = (mpz_ptr)omAllocBin(gmp_nrz_bin);
431  mpz_init(erg);
432  mpz_init(one);
433  mpz_init_set(bs, (mpz_ptr) a);
434  mpz_init_set(bt, (mpz_ptr) b);
435  mpz_init(bu);
436  mpz_init(bv);
437  mpz_gcd(erg, bs, bt);
438 
439 #ifdef CF_DEB
440  StringSetS("1st gcd:");
441  nrnWrite(xx= (number)erg, r);
442 #endif
443 
444  mpz_gcd(erg, erg, r->modNumber);
445 
446  mpz_div(bs, bs, erg);
447  mpz_div(bt, bt, erg);
448 
449 #ifdef CF_DEB
450  Print("%s\n", StringEndS());
451  StringSetS("xgcd: ");
452 #endif
453 
454  mpz_gcdext(one, bu, bv, bs, bt);
455  number ui = nrnGetUnit(xx = (number) one, r);
456 #ifdef CF_DEB
457  n_Write(xx, r);
458  StringAppendS("\t");
459  n_Write(ui, r);
460  Print("%s\n", StringEndS());
461 #endif
462  nrnDelete(&xx, r);
463  if (!nrnIsOne(ui, r))
464  {
465 #ifdef CF_DEB
466  PrintS("Scaling\n");
467 #endif
468  number uii = nrnInvers(ui, r);
469  nrnDelete(&ui, r);
470  ui = uii;
471  mpz_ptr uu = (mpz_ptr)omAllocBin(gmp_nrz_bin);
472  mpz_init_set(uu, (mpz_ptr)ui);
473  mpz_mul(bu, bu, uu);
474  mpz_mul(bv, bv, uu);
475  mpz_clear(uu);
476  omFreeBin(uu, gmp_nrz_bin);
477  }
478  nrnDelete(&ui, r);
479 #ifdef CF_DEB
480  StringSetS("xgcd");
481  nrnWrite(xx= (number)bs, r);
482  StringAppendS("*");
483  nrnWrite(xx= (number)bu, r);
484  StringAppendS(" + ");
485  nrnWrite(xx= (number)bt, r);
486  StringAppendS("*");
487  nrnWrite(xx= (number)bv, r);
488  Print("%s\n", StringEndS());
489 #endif
490 
491  mpz_mod(bs, bs, r->modNumber);
492  mpz_mod(bt, bt, r->modNumber);
493  mpz_mod(bu, bu, r->modNumber);
494  mpz_mod(bv, bv, r->modNumber);
495  *s = (number)bu;
496  *t = (number)bv;
497  *u = (number)bt;
498  *u = nrnNeg(*u, r);
499  *v = (number)bs;
500  return (number)erg;
501 }
502 
503 static BOOLEAN nrnIsMOne(number a, const coeffs r)
504 {
505  if((r->ch==2) && (nrnIsOne(a,r))) return FALSE;
506  mpz_t t; mpz_init_set(t, (mpz_ptr)a);
507  mpz_add_ui(t, t, 1);
508  bool erg = (0 == mpz_cmp(t, r->modNumber));
509  mpz_clear(t);
510  return erg;
511 }
512 
513 static BOOLEAN nrnGreater(number a, number b, const coeffs)
514 {
515  return 0 < mpz_cmp((mpz_ptr)a, (mpz_ptr)b);
516 }
517 
518 static BOOLEAN nrnGreaterZero(number k, const coeffs cf)
519 {
520  if (cf->is_field)
521  {
522  if (mpz_cmp_ui(cf->modBase,2)==0)
523  {
524  return TRUE;
525  }
526  mpz_t ch2; mpz_init_set(ch2, cf->modBase);
527  mpz_sub_ui(ch2,ch2,1);
528  mpz_divexact_ui(ch2,ch2,2);
529  if (mpz_cmp(ch2,(mpz_ptr)k)<0)
530  return FALSE;
531  mpz_clear(ch2);
532  }
533  return 0 < mpz_sgn1((mpz_ptr)k);
534 }
535 
536 static BOOLEAN nrnIsUnit(number a, const coeffs r)
537 {
538  number tmp = nrnGcd(a, (number)r->modNumber, r);
539  bool res = nrnIsOne(tmp, r);
540  nrnDelete(&tmp, r);
541  return res;
542 }
543 
544 static number nrnAnn(number k, const coeffs r)
545 {
546  mpz_ptr tmp = (mpz_ptr) omAllocBin(gmp_nrz_bin);
547  mpz_init(tmp);
548  mpz_gcd(tmp, (mpz_ptr) k, r->modNumber);
549  if (mpz_cmp_si(tmp, 1)==0)
550  {
551  mpz_set_ui(tmp, 0);
552  return (number) tmp;
553  }
554  mpz_divexact(tmp, r->modNumber, tmp);
555  return (number) tmp;
556 }
557 
558 static BOOLEAN nrnDivBy(number a, number b, const coeffs r)
559 {
560  /* b divides a iff b/gcd(a, b) is a unit in the given ring: */
561  number n = nrnGcd(a, b, r);
562  mpz_tdiv_q((mpz_ptr)n, (mpz_ptr)b, (mpz_ptr)n);
563  bool result = nrnIsUnit(n, r);
564  nrnDelete(&n, NULL);
565  return result;
566 }
567 
568 static int nrnDivComp(number a, number b, const coeffs r)
569 {
570  if (nrnEqual(a, b,r)) return 2;
571  if (mpz_divisible_p((mpz_ptr) a, (mpz_ptr) b)) return -1;
572  if (mpz_divisible_p((mpz_ptr) b, (mpz_ptr) a)) return 1;
573  return 0;
574 }
575 
576 static number nrnDiv(number a, number b, const coeffs r)
577 {
578  if (r->is_field)
579  {
580  number inv=nrnInvers(b,r);
581  number erg=nrnMult(a,inv,r);
582  nrnDelete(&inv,r);
583  return erg;
584  }
585  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
586  mpz_init(erg);
587  if (mpz_divisible_p((mpz_ptr)a, (mpz_ptr)b))
588  {
589  mpz_divexact(erg, (mpz_ptr)a, (mpz_ptr)b);
590  return (number)erg;
591  }
592  else
593  {
594  mpz_ptr gcd = (mpz_ptr)nrnGcd(a, b, r);
595  mpz_divexact(erg, (mpz_ptr)b, gcd);
596  if (!nrnIsUnit((number)erg, r))
597  {
598  WerrorS("Division not possible, even by cancelling zero divisors.");
599  nrnDelete((number*) &gcd, r);
600  nrnDelete((number*) &erg, r);
601  return (number)NULL;
602  }
603  // a / gcd(a,b) * [b / gcd (a,b)]^(-1)
604  mpz_ptr tmp = (mpz_ptr)nrnInvers((number) erg,r);
605  mpz_divexact(erg, (mpz_ptr)a, gcd);
606  mpz_mul(erg, erg, tmp);
607  nrnDelete((number*) &gcd, r);
608  nrnDelete((number*) &tmp, r);
609  mpz_mod(erg, erg, r->modNumber);
610  return (number)erg;
611  }
612 }
613 
614 static number nrnMod(number a, number b, const coeffs r)
615 {
616  /*
617  We need to return the number rr which is uniquely determined by the
618  following two properties:
619  (1) 0 <= rr < |b| (with respect to '<' and '<=' performed in Z x Z)
620  (2) There exists some k in the integers Z such that a = k * b + rr.
621  Consider g := gcd(n, |b|). Note that then |b|/g is a unit in Z/n.
622  Now, there are three cases:
623  (a) g = 1
624  Then |b| is a unit in Z/n, i.e. |b| (and also b) divides a.
625  Thus rr = 0.
626  (b) g <> 1 and g divides a
627  Then a = (a/g) * (|b|/g)^(-1) * b (up to sign), i.e. again rr = 0.
628  (c) g <> 1 and g does not divide a
629  Then denote the division with remainder of a by g as this:
630  a = s * g + t. Then t = a - s * g = a - s * (|b|/g)^(-1) * |b|
631  fulfills (1) and (2), i.e. rr := t is the correct result. Hence
632  in this third case, rr is the remainder of division of a by g in Z.
633  Remark: according to mpz_mod: a,b are always non-negative
634  */
635  mpz_ptr g = (mpz_ptr)omAllocBin(gmp_nrz_bin);
636  mpz_ptr rr = (mpz_ptr)omAllocBin(gmp_nrz_bin);
637  mpz_init(g);
638  mpz_init_set_ui(rr, 0);
639  mpz_gcd(g, (mpz_ptr)r->modNumber, (mpz_ptr)b); // g is now as above
640  if (mpz_cmp_si(g, 1L) != 0) mpz_mod(rr, (mpz_ptr)a, g); // the case g <> 1
641  mpz_clear(g);
643  return (number)rr;
644 }
645 
646 static number nrnIntDiv(number a, number b, const coeffs r)
647 {
648  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
649  mpz_init(erg);
650  mpz_tdiv_q(erg, (mpz_ptr)a, (mpz_ptr)b);
651  return (number)erg;
652 }
653 
654 /* CF: note that Z/nZ has (at least) two distinct euclidean structures
655  * 1st phi(a) := (a mod n) which is just the structure directly
656  * inherited from Z
657  * 2nd phi(a) := gcd(a, n)
658  * The 1st version is probably faster as everything just comes from Z,
659  * but the 2nd version behaves nicely wrt. to quotient operations
660  * and HNF and such. In agreement with nrnMod we imlement the 2nd here
661  *
662  * For quotrem note that if b exactly divides a, then
663  * min(v_p(a), v_p(n)) >= min(v_p(b), v_p(n))
664  * so if we divide a and b by g:= gcd(a,b,n), then b becomes a
665  * unit mod n/g.
666  * Thus we 1st compute the remainder (similar to nrnMod) and then
667  * the exact quotient.
668  */
669 static number nrnQuotRem(number a, number b, number * rem, const coeffs r)
670 {
671  mpz_t g, aa, bb;
672  mpz_ptr qq = (mpz_ptr)omAllocBin(gmp_nrz_bin);
673  mpz_ptr rr = (mpz_ptr)omAllocBin(gmp_nrz_bin);
674  mpz_init(qq);
675  mpz_init(rr);
676  mpz_init(g);
677  mpz_init_set(aa, (mpz_ptr)a);
678  mpz_init_set(bb, (mpz_ptr)b);
679 
680  mpz_gcd(g, bb, r->modNumber);
681  mpz_mod(rr, aa, g);
682  mpz_sub(aa, aa, rr);
683  mpz_gcd(g, aa, g);
684  mpz_div(aa, aa, g);
685  mpz_div(bb, bb, g);
686  mpz_div(g, r->modNumber, g);
687  mpz_invert(g, bb, g);
688  mpz_mul(qq, aa, g);
689  if (rem)
690  *rem = (number)rr;
691  else {
692  mpz_clear(rr);
693  omFreeBin(rr, gmp_nrz_bin);
694  }
695  mpz_clear(g);
696  mpz_clear(aa);
697  mpz_clear(bb);
698  return (number) qq;
699 }
700 
701 /*
702  * Helper function for computing the module
703  */
704 
705 static mpz_ptr nrnMapCoef = NULL;
706 
707 static number nrnMapModN(number from, const coeffs /*src*/, const coeffs dst)
708 {
709  return nrnMult(from, (number) nrnMapCoef, dst);
710 }
711 
712 static number nrnMap2toM(number from, const coeffs /*src*/, const coeffs dst)
713 {
714  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
715  mpz_init(erg);
716  mpz_mul_ui(erg, nrnMapCoef, (unsigned long)from);
717  mpz_mod(erg, erg, dst->modNumber);
718  return (number)erg;
719 }
720 
721 static number nrnMapZp(number from, const coeffs /*src*/, const coeffs dst)
722 {
723  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
724  mpz_init(erg);
725  // TODO: use npInt(...)
726  mpz_mul_si(erg, nrnMapCoef, (unsigned long)from);
727  mpz_mod(erg, erg, dst->modNumber);
728  return (number)erg;
729 }
730 
731 number nrnMapGMP(number from, const coeffs /*src*/, const coeffs dst)
732 {
733  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
734  mpz_init(erg);
735  mpz_mod(erg, (mpz_ptr)from, dst->modNumber);
736  return (number)erg;
737 }
738 
739 static number nrnMapQ(number from, const coeffs src, const coeffs dst)
740 {
741  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
742  mpz_init(erg);
743  nlGMP(from, erg, src); // FIXME? TODO? // extern void nlGMP(number &i, number n, const coeffs r); // to be replaced with n_MPZ(erg, from, src); // ?
744  mpz_mod(erg, erg, dst->modNumber);
745  return (number)erg;
746 }
747 
748 #if SI_INTEGER_VARIANT==3
749 static number nrnMapZ(number from, const coeffs /*src*/, const coeffs dst)
750 {
751  mpz_ptr erg = (mpz_ptr)omAllocBin(gmp_nrz_bin);
752  if (n_Z_IS_SMALL(from))
753  mpz_init_set_si(erg, SR_TO_INT(from));
754  else
755  mpz_init_set(erg, (mpz_ptr) from);
756  mpz_mod(erg, erg, dst->modNumber);
757  return (number)erg;
758 }
759 #elif SI_INTEGER_VARIANT==2
760 
761 static number nrnMapZ(number from, const coeffs src, const coeffs dst)
762 {
763  if (SR_HDL(from) & SR_INT)
764  {
765  long f_i=SR_TO_INT(from);
766  return nrnInit(f_i,dst);
767  }
768  return nrnMapGMP(from,src,dst);
769 }
770 #elif SI_INTEGER_VARIANT==1
771 static number nrnMapZ(number from, const coeffs src, const coeffs dst)
772 {
773  return nrnMapQ(from,src,dst);
774 }
775 #endif
776 void nrnWrite (number a, const coeffs cf)
777 {
778  char *s,*z;
779  if (a==NULL)
780  {
781  StringAppendS("o");
782  }
783  else
784  {
785  int l=mpz_sizeinbase((mpz_ptr) a, 10) + 2;
786  s=(char*)omAlloc(l);
787  if (cf->is_field)
788  {
789  mpz_t ch2; mpz_init_set(ch2, cf->modBase);
790  mpz_sub_ui(ch2,ch2,1);
791  mpz_divexact_ui(ch2,ch2,2);
792  if ((mpz_cmp_ui(cf->modBase,2)!=0) && (mpz_cmp(ch2,(mpz_ptr)a)<0))
793  {
794  mpz_sub(ch2,(mpz_ptr)a,cf->modBase);
795  z=mpz_get_str(s,10,ch2);
796  StringAppendS(z);
797  }
798  else
799  {
800  z=mpz_get_str(s,10,(mpz_ptr) a);
801  StringAppendS(z);
802  }
803  mpz_clear(ch2);
804  }
805  else
806  {
807  z=mpz_get_str(s,10,(mpz_ptr) a);
808  StringAppendS(z);
809  }
810  omFreeSize((ADDRESS)s,l);
811  }
812 }
813 
814 nMapFunc nrnSetMap(const coeffs src, const coeffs dst)
815 {
816  /* dst = nrn */
817  if ((src->rep==n_rep_gmp) && nCoeff_is_Z(src))
818  {
819  return nrnMapZ;
820  }
821  if ((src->rep==n_rep_gap_gmp) /*&& nCoeff_is_Z(src)*/)
822  {
823  return nrnMapZ;
824  }
825  if (src->rep==n_rep_gap_rat) /*&& nCoeff_is_Q(src)) or Z*/
826  {
827  return nrnMapQ;
828  }
829  // Some type of Z/n ring / field
830  if (nCoeff_is_Zn(src) || nCoeff_is_Ring_PtoM(src) ||
831  nCoeff_is_Ring_2toM(src) || nCoeff_is_Zp(src))
832  {
833  if ( (!nCoeff_is_Zp(src))
834  && (mpz_cmp(src->modBase, dst->modBase) == 0)
835  && (src->modExponent == dst->modExponent)) return ndCopyMap;
836  else
837  {
838  mpz_ptr nrnMapModul = (mpz_ptr) omAllocBin(gmp_nrz_bin);
839  // Computing the n of Z/n
840  if (nCoeff_is_Zp(src))
841  {
842  mpz_init_set_si(nrnMapModul, src->ch);
843  }
844  else
845  {
846  mpz_init(nrnMapModul);
847  mpz_set(nrnMapModul, src->modNumber);
848  }
849  // nrnMapCoef = 1 in dst if dst is a subring of src
850  // nrnMapCoef = 0 in dst / src if src is a subring of dst
851  if (nrnMapCoef == NULL)
852  {
853  nrnMapCoef = (mpz_ptr) omAllocBin(gmp_nrz_bin);
854  mpz_init(nrnMapCoef);
855  }
856  if (mpz_divisible_p(nrnMapModul, dst->modNumber))
857  {
858  mpz_set_ui(nrnMapCoef, 1);
859  }
860  else
861  if (mpz_divisible_p(dst->modNumber,nrnMapModul))
862  {
863  mpz_divexact(nrnMapCoef, dst->modNumber, nrnMapModul);
864  mpz_ptr tmp = dst->modNumber;
865  dst->modNumber = nrnMapModul;
866  if (!nrnIsUnit((number) nrnMapCoef,dst))
867  {
868  dst->modNumber = tmp;
869  nrnDelete((number*) &nrnMapModul, dst);
870  return NULL;
871  }
872  mpz_ptr inv = (mpz_ptr) nrnInvers((number) nrnMapCoef,dst);
873  dst->modNumber = tmp;
874  mpz_mul(nrnMapCoef, nrnMapCoef, inv);
875  mpz_mod(nrnMapCoef, nrnMapCoef, dst->modNumber);
876  nrnDelete((number*) &inv, dst);
877  }
878  else
879  {
880  nrnDelete((number*) &nrnMapModul, dst);
881  return NULL;
882  }
883  nrnDelete((number*) &nrnMapModul, dst);
884  if (nCoeff_is_Ring_2toM(src))
885  return nrnMap2toM;
886  else if (nCoeff_is_Zp(src))
887  return nrnMapZp;
888  else
889  return nrnMapModN;
890  }
891  }
892  return NULL; // default
893 }
894 
895 /*
896  * set the exponent (allocate and init tables) (TODO)
897  */
898 
899 static void nrnSetExp(unsigned long m, coeffs r)
900 {
901  /* clean up former stuff */
902  if (r->modNumber != NULL) mpz_clear(r->modNumber);
903 
904  r->modExponent= m;
905  r->modNumber = (mpz_ptr)omAllocBin(gmp_nrz_bin);
906  mpz_init_set (r->modNumber, r->modBase);
907  mpz_pow_ui (r->modNumber, r->modNumber, m);
908 }
909 
910 /* We expect this ring to be Z/n^m for some m > 0 and for some n > 2 which is not a prime. */
911 static void nrnInitExp(unsigned long m, coeffs r)
912 {
913  nrnSetExp(m, r);
914  assume (r->modNumber != NULL);
915 //CF: in general, the modulus is computed somewhere. I don't want to
916 // check it's size before I construct the best ring.
917 // if (mpz_cmp_ui(r->modNumber,2) <= 0)
918 // WarnS("nrnInitExp failed (m in Z/m too small)");
919 }
920 
921 #ifdef LDEBUG
922 BOOLEAN nrnDBTest (number a, const char *f, const int l, const coeffs r)
923 {
924  if ( (mpz_sgn1((mpz_ptr) a) < 0) || (mpz_cmp((mpz_ptr) a, r->modNumber) > 0) )
925  {
926  Warn("mod-n: out of range at %s:%d\n",f,l);
927  return FALSE;
928  }
929  return TRUE;
930 }
931 #endif
932 
933 /*2
934 * extracts a long integer from s, returns the rest (COPY FROM longrat0.cc)
935 */
936 static const char * nlCPEatLongC(char *s, mpz_ptr i)
937 {
938  const char * start=s;
939  if (!(*s >= '0' && *s <= '9'))
940  {
941  mpz_init_set_ui(i, 1);
942  return s;
943  }
944  mpz_init(i);
945  while (*s >= '0' && *s <= '9') s++;
946  if (*s=='\0')
947  {
948  mpz_set_str(i,start,10);
949  }
950  else
951  {
952  char c=*s;
953  *s='\0';
954  mpz_set_str(i,start,10);
955  *s=c;
956  }
957  return s;
958 }
959 
960 static const char * nrnRead (const char *s, number *a, const coeffs r)
961 {
962  mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
963  {
964  s = nlCPEatLongC((char *)s, z);
965  }
966  mpz_mod(z, z, r->modNumber);
967  if ((*s)=='/')
968  {
969  mpz_ptr n = (mpz_ptr) omAllocBin(gmp_nrz_bin);
970  s++;
971  s=nlCPEatLongC((char*)s,n);
972  if (!nrnIsOne((number)n,r))
973  {
974  *a=nrnDiv((number)z,(number)n,r);
975  mpz_clear(z);
976  omFreeBin((void *)z, gmp_nrz_bin);
977  mpz_clear(n);
978  omFreeBin((void *)n, gmp_nrz_bin);
979  }
980  }
981  else
982  *a = (number) z;
983  return s;
984 }
985 
986 static number nrnConvFactoryNSingN( const CanonicalForm n, const coeffs r)
987 {
988  return nrnInit(n.intval(),r);
989 }
990 
991 static CanonicalForm nrnConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
992 {
993  if (setChar) setCharacteristic( r->ch );
994  return CanonicalForm(nrnInt( n,r ));
995 }
996 
997 /* for initializing function pointers */
999 {
1000  assume( (getCoeffType(r) == n_Zn) || (getCoeffType (r) == n_Znm) );
1001  ZnmInfo * info= (ZnmInfo *) p;
1002  r->modBase= (mpz_ptr)nrnCopy((number)info->base, r); //this circumvents the problem
1003  //in bigintmat.cc where we cannot create a "legal" nrn that can be freed.
1004  //If we take a copy, we can do whatever we want.
1005 
1006  nrnInitExp (info->exp, r);
1007 
1008  /* next computation may yield wrong characteristic as r->modNumber
1009  is a GMP number */
1010  r->ch = mpz_get_ui(r->modNumber);
1011 
1012  r->is_field=FALSE;
1013  r->is_domain=FALSE;
1014  r->rep=n_rep_gmp;
1015 
1016 
1017  r->cfCoeffString = nrnCoeffString;
1018 
1019  r->cfInit = nrnInit;
1020  r->cfDelete = nrnDelete;
1021  r->cfCopy = nrnCopy;
1022  r->cfSize = nrnSize;
1023  r->cfInt = nrnInt;
1024  r->cfAdd = nrnAdd;
1025  r->cfSub = nrnSub;
1026  r->cfMult = nrnMult;
1027  r->cfDiv = nrnDiv;
1028  r->cfAnn = nrnAnn;
1029  r->cfIntMod = nrnMod;
1030  r->cfExactDiv = nrnDiv;
1031  r->cfInpNeg = nrnNeg;
1032  r->cfInvers = nrnInvers;
1033  r->cfDivBy = nrnDivBy;
1034  r->cfDivComp = nrnDivComp;
1035  r->cfGreater = nrnGreater;
1036  r->cfEqual = nrnEqual;
1037  r->cfIsZero = nrnIsZero;
1038  r->cfIsOne = nrnIsOne;
1039  r->cfIsMOne = nrnIsMOne;
1040  r->cfGreaterZero = nrnGreaterZero;
1041  r->cfWriteLong = nrnWrite;
1042  r->cfRead = nrnRead;
1043  r->cfPower = nrnPower;
1044  r->cfSetMap = nrnSetMap;
1045  //r->cfNormalize = ndNormalize;
1046  r->cfLcm = nrnLcm;
1047  r->cfGcd = nrnGcd;
1048  r->cfIsUnit = nrnIsUnit;
1049  r->cfGetUnit = nrnGetUnit;
1050  r->cfExtGcd = nrnExtGcd;
1051  r->cfXExtGcd = nrnXExtGcd;
1052  r->cfQuotRem = nrnQuotRem;
1053  r->cfCoeffName = nrnCoeffName;
1054  r->cfCoeffWrite = nrnCoeffWrite;
1055  r->nCoeffIsEqual = nrnCoeffIsEqual;
1056  r->cfKillChar = nrnKillChar;
1057  r->cfQuot1 = nrnQuot1;
1058 #if SI_INTEGER_VARIANT==2
1059  r->cfWriteFd = nrzWriteFd;
1060  r->cfReadFd = nrzReadFd;
1061 #endif
1062 
1063 #ifdef LDEBUG
1064  r->cfDBTest = nrnDBTest;
1065 #endif
1066  if ((r->modExponent==1)&&(mpz_size1(r->modBase)==1))
1067  {
1068  long p=mpz_get_si(r->modBase);
1069  if ((p<=FACTORY_MAX_PRIME)&&(p==IsPrime(p))) /*factory limit: <2^29*/
1070  {
1071  r->convFactoryNSingN=nrnConvFactoryNSingN;
1072  r->convSingNFactoryN=nrnConvSingNFactoryN;
1073  }
1074  }
1075  return FALSE;
1076 }
1077 
1078 #endif
1079 /* #ifdef HAVE_RINGS */
mpz_ptr base
Definition: rmodulon.h:18
static number nrnAdd(number a, number b, const coeffs r)
Definition: rmodulon.cc:244
mpz_t z
Definition: longrat.h:49
#define omAllocBin(bin)
Definition: omAllocDecl.h:205
long intval() const
conversion functions
const CanonicalForm int s
Definition: facAbsFact.cc:55
static number nrnMapZp(number from, const coeffs, const coeffs dst)
Definition: rmodulon.cc:721
void mpz_mul_si(mpz_ptr r, mpz_srcptr s, long int si)
Definition: longrat.cc:171
void rem(unsigned long *a, unsigned long *q, unsigned long p, int &dega, int degq)
Definition: minpoly.cc:572
static BOOLEAN nrnDivBy(number a, number b, const coeffs r)
Definition: rmodulon.cc:558
omBin_t * omBin
Definition: omStructs.h:12
#define Print
Definition: emacs.cc:80
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition: coeffs.h:822
void nrzWriteFd(number n, const ssiInfo *d, const coeffs)
#define mpz_sgn1(A)
Definition: si_gmp.h:13
static number nrnGetUnit(number k, const coeffs r)
Definition: rmodulon.cc:366
static number nrnInvers(number c, const coeffs r)
Definition: rmodulon.cc:275
static void nrnInitExp(unsigned long m, coeffs r)
Definition: rmodulon.cc:911
#define FALSE
Definition: auxiliary.h:94
number ndCopyMap(number a, const coeffs aRing, const coeffs r)
Definition: numbers.cc:251
static void nrnPower(number a, int i, number *result, const coeffs r)
Definition: rmodulon.cc:236
void nrnWrite(number a, const coeffs)
Definition: rmodulon.cc:776
static const char * nlCPEatLongC(char *s, mpz_ptr i)
Definition: rmodulon.cc:936
static char * nrnCoeffName_buff
Definition: rmodulon.cc:85
static number nrnMod(number a, number b, const coeffs r)
Definition: rmodulon.cc:614
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
static BOOLEAN nrnEqual(number a, number b, const coeffs)
Definition: rmodulon.cc:361
static number nrnGcd(number a, number b, const coeffs r)
Definition: rmodulon.cc:288
char * nEati(char *s, int *i, int m)
divide by the first (leading) number and return it, i.e. make monic
Definition: numbers.cc:630
static BOOLEAN nrnIsOne(number a, const coeffs)
Definition: rmodulon.cc:356
static number nrnXExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
Definition: rmodulon.cc:412
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
Definition: coeffs.h:746
(), see rinteger.h, new impl.
Definition: coeffs.h:112
static number nrnConvFactoryNSingN(const CanonicalForm n, const coeffs r)
Definition: rmodulon.cc:986
static BOOLEAN nrnIsZero(number a, const coeffs)
Definition: rmodulon.cc:262
coeffs nrnInitCfByName(char *s, n_coeffType n)
Definition: rmodulon.cc:57
factory&#39;s main class
Definition: canonicalform.h:77
#define TRUE
Definition: auxiliary.h:98
static const char * nrnRead(const char *s, number *a, const coeffs r)
Definition: rmodulon.cc:960
static mpz_ptr nrnMapCoef
Definition: rmodulon.cc:705
static number nrnMap2toM(number from, const coeffs, const coeffs dst)
Definition: rmodulon.cc:712
void * ADDRESS
Definition: auxiliary.h:133
g
Definition: cfModGcd.cc:4031
static CanonicalForm nrnConvSingNFactoryN(number n, BOOLEAN setChar, const coeffs r)
Definition: rmodulon.cc:991
void WerrorS(const char *s)
Definition: feFopen.cc:24
int k
Definition: cfEzgcd.cc:92
char * StringEndS()
Definition: reporter.cc:151
static number nrnQuotRem(number a, number b, number *rem, const coeffs r)
Definition: rmodulon.cc:669
#define omAlloc(size)
Definition: omAllocDecl.h:210
void setCharacteristic(int c)
Definition: cf_char.cc:23
static FORCE_INLINE BOOLEAN nCoeff_is_Z(const coeffs r)
Definition: coeffs.h:838
static number nrnSub(number a, number b, const coeffs r)
Definition: rmodulon.cc:253
static number nrnAnn(number k, const coeffs r)
Definition: rmodulon.cc:544
static BOOLEAN nrnIsUnit(number a, const coeffs r)
Definition: rmodulon.cc:536
#define FACTORY_MAX_PRIME
Definition: modulop.h:30
static number nrnMapQ(number from, const coeffs src, const coeffs dst)
Definition: rmodulon.cc:739
static number nrnIntDiv(number a, number b, const coeffs r)
Definition: rmodulon.cc:646
CanonicalForm b
Definition: cfModGcd.cc:4044
mpz_t n
Definition: longrat.h:50
static char * nrnCoeffString(const coeffs r)
Definition: rmodulon.cc:112
Coefficient rings, fields and other domains suitable for Singular polynomials.
CanonicalForm res
Definition: facAbsFact.cc:64
only used if HAVE_RINGS is defined
Definition: coeffs.h:46
BOOLEAN nrnInitChar(coeffs r, void *p)
Definition: rmodulon.cc:998
#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.
void StringSetS(const char *st)
Definition: reporter.cc:128
void StringAppendS(const char *st)
Definition: reporter.cc:107
const ExtensionInfo & info
< [in] sqrfree poly
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
static number nrnLcm(number a, number b, const coeffs r)
Definition: rmodulon.cc:307
static FORCE_INLINE void n_Write(number n, const coeffs r, const BOOLEAN bShortOut=TRUE)
Definition: coeffs.h:591
BOOLEAN nrnDBTest(number a, const char *f, const int l, const coeffs r)
Definition: rmodulon.cc:922
static number nrnDiv(number a, number b, const coeffs r)
Definition: rmodulon.cc:576
static long nrnInt(number &n, const coeffs)
Definition: rmodulon.cc:198
omBin gmp_nrz_bin
Definition: rintegers.cc:24
All the auxiliary stuff.
int m
Definition: cfEzgcd.cc:121
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
Definition: coeffs.h:749
number nrnMapGMP(number from, const coeffs, const coeffs dst)
Definition: rmodulon.cc:731
FILE * f
Definition: checklibs.c:9
int i
Definition: cfEzgcd.cc:125
void PrintS(const char *s)
Definition: reporter.cc:284
#define nrnDelete
Definition: rmodulon.cc:204
static number nrnMapZ(number from, const coeffs src, const coeffs dst)
Definition: rmodulon.cc:761
int IsPrime(int p)
Definition: prime.cc:61
(mpz_ptr), see rmodulon,h
Definition: coeffs.h:115
void nlGMP(number &i, mpz_t n, const coeffs r)
Definition: longrat.cc:1477
#define nrnSize
Definition: rmodulon.cc:205
static number nrnExtGcd(number a, number b, number *s, number *t, const coeffs r)
Definition: rmodulon.cc:340
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421
static BOOLEAN nrnGreater(number a, number b, const coeffs)
Definition: rmodulon.cc:513
#define SR_TO_INT(SR)
Definition: longrat.h:68
(number), see longrat.h
Definition: coeffs.h:111
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:37
#define mpz_size1(A)
Definition: si_gmp.h:12
static BOOLEAN nrnIsMOne(number a, const coeffs r)
Definition: rmodulon.cc:503
static void nrnKillChar(coeffs r)
Definition: rmodulon.cc:124
n_coeffType
Definition: coeffs.h:27
static number nrnMapModN(number from, const coeffs, const coeffs dst)
Definition: rmodulon.cc:707
CanonicalForm cf
Definition: cfModGcd.cc:4024
#define NULL
Definition: omList.c:12
int gcd(int a, int b)
Definition: walkSupport.cc:836
static void nrnSetExp(unsigned long m, coeffs r)
Definition: rmodulon.cc:899
number nrzReadFd(const ssiInfo *d, const coeffs)
#define SR_INT
Definition: longrat.h:66
int exp
Definition: rmodulon.h:18
static BOOLEAN nrnCoeffIsEqual(const coeffs r, n_coeffType n, void *parameter)
Definition: rmodulon.cc:104
static BOOLEAN nrnGreaterZero(number k, const coeffs cf)
Definition: rmodulon.cc:518
static coeffs nrnQuot1(number c, const coeffs r)
Definition: rmodulon.cc:132
static char * nrnCoeffName(const coeffs r)
Definition: rmodulon.cc:86
static number nrnCopy(number a, const coeffs)
Definition: rmodulon.cc:177
nMapFunc nrnSetMap(const coeffs src, const coeffs dst)
Definition: rmodulon.cc:814
#define SR_HDL(A)
Definition: tgb.cc:35
static number nrnInit(long i, const coeffs r)
Definition: rmodulon.cc:187
int p
Definition: cfModGcd.cc:4019
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
static void nrnCoeffWrite(const coeffs r, BOOLEAN)
Definition: rmodulon.cc:35
char * nEatLong(char *s, mpz_ptr i)
extracts a long integer from s, returns the rest
Definition: numbers.cc:651
int BOOLEAN
Definition: auxiliary.h:85
static number nrnNeg(number c, const coeffs r)
Definition: rmodulon.cc:267
static FORCE_INLINE BOOLEAN nCoeff_is_Zn(const coeffs r)
Definition: coeffs.h:848
return result
Definition: facAbsBiFact.cc:76
int l
Definition: cfEzgcd.cc:93
static number nrnMult(number a, number b, const coeffs r)
Definition: rmodulon.cc:227
static int nrnDivComp(number a, number b, const coeffs r)
Definition: rmodulon.cc:568
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:349
#define Warn
Definition: emacs.cc:77