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