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