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