1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /*
5 * ABSTRACT: numbers (integers)
6 */
7 
8 
9 #ifdef HAVE_RINGS
10 #if SI_INTEGER_VARIANT == 2
11 
12 #include "coeffs/si_gmp.h"
13 
14 /*
15  * Multiply two numbers
16  */
nrzMult(number a,number b,const coeffs)17 static number nrzMult (number a, number b, const coeffs)
18 {
19   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
20   mpz_init(erg);
21   mpz_mul(erg, (mpz_ptr) a, (mpz_ptr) b);
22   return (number) erg;
23 }
24 
25 /*
26  * Give the smallest non unit k, such that a * x = k = b * y has a solution
27  */
nrzLcm(number a,number b,const coeffs)28 static number nrzLcm (number a,number b,const coeffs)
29 {
30   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
31   mpz_init(erg);
32   mpz_lcm(erg, (mpz_ptr) a, (mpz_ptr) b);
33   return (number) erg;
34 }
35 
36 /*
37  * Give the largest non unit k, such that a = x * k, b = y * k has
38  * a solution.
39  */
nrzGcd(number a,number b,const coeffs)40 static number nrzGcd (number a,number b,const coeffs)
41 {
42   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
43   mpz_init(erg);
44   mpz_gcd(erg, (mpz_ptr) a, (mpz_ptr) b);
45   return (number) erg;
46 }
47 
48 /*
49  * Give the largest non unit k, such that a = x * k, b = y * k has
50  * a solution and r, s, s.t. k = s*a + t*b
51  */
nrzExtGcd(number a,number b,number * s,number * t,const coeffs)52 static number nrzExtGcd (number a, number b, number *s, number *t, const coeffs)
53 {
54   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
55   mpz_ptr bs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
56   mpz_ptr bt = (mpz_ptr) omAllocBin(gmp_nrz_bin);
57   mpz_init(erg);
58   mpz_init(bs);
59   mpz_init(bt);
60   mpz_gcdext(erg, bs, bt, (mpz_ptr) a, (mpz_ptr) b);
61   *s = (number) bs;
62   *t = (number) bt;
63   return (number) erg;
64 }
65 
nrzXExtGcd(number a,number b,number * s,number * t,number * u,number * v,const coeffs)66 static number nrzXExtGcd (number a, number b, number *s, number *t, number *u, number *v, const coeffs )
67 {
68   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
69   mpz_ptr bs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
70   mpz_ptr bt = (mpz_ptr) omAllocBin(gmp_nrz_bin);
71   mpz_init(erg);
72   mpz_init(bs);
73   mpz_init(bt);
74 
75   mpz_gcdext(erg, bs, bt, (mpz_ptr)a, (mpz_ptr)b);
76 
77   mpz_ptr bu = (mpz_ptr) omAllocBin(gmp_nrz_bin);
78   mpz_ptr bv = (mpz_ptr) omAllocBin(gmp_nrz_bin);
79 
80   mpz_init_set(bu, (mpz_ptr) b);
81   mpz_init_set(bv, (mpz_ptr) a);
82 
83   assume(mpz_cmp_si(erg, 0));
84 
85   mpz_div(bu, bu, erg);
86   mpz_div(bv, bv, erg);
87 
88   mpz_mul_si(bu, bu, -1);
89   *u = (number) bu;
90   *v = (number) bv;
91 
92   *s = (number) bs;
93   *t = (number) bt;
94   return (number) erg;
95 }
96 
nrzPower(number a,int i,number * result,const coeffs)97 static void nrzPower (number a, int i, number * result, const coeffs)
98 {
99   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
100   mpz_init(erg);
101   mpz_pow_ui(erg, (mpz_ptr) a, i);
102   *result = (number) erg;
103 }
104 
105 /*
106  * create a number from int
107  */
nrzInit(long i,const coeffs)108 number nrzInit (long i, const coeffs)
109 {
110   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
111   mpz_init_set_si(erg, i);
112   return (number) erg;
113 }
114 
nrzDelete(number * a,const coeffs)115 void nrzDelete(number *a, const coeffs)
116 {
117   if (*a != NULL)
118   {
119     mpz_clear((mpz_ptr) *a);
120     omFreeBin((ADDRESS) *a, gmp_nrz_bin);
121     *a = NULL;
122   }
123 }
124 
nrzCopy(number a,const coeffs)125 static number nrzCopy(number a, const coeffs)
126 {
127   if (a==NULL) return NULL;
128   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
129   mpz_init_set(erg, (mpz_ptr) a);
130   return (number) erg;
131 }
132 
133 #if 0
134 number nrzCopyMap(number a, const coeffs /*src*/, const coeffs dst)
135 {
136   return nrzCopy(a,dst);
137 }
138 #endif
139 
nrzSize(number a,const coeffs)140 int nrzSize(number a, const coeffs)
141 {
142   mpz_ptr p=(mpz_ptr)a;
143   int s=p->_mp_alloc;
144   if (s==1) s=(mpz_cmp_ui(p,0)!=0);
145   return s;
146 
147 }
148 
149 /*
150  * convert a number to int
151  */
nrzInt(number & n,const coeffs)152 static long nrzInt(number &n, const coeffs)
153 {
154   return mpz_get_si( (mpz_ptr)n);
155 }
156 
nrzAdd(number a,number b,const coeffs)157 static number nrzAdd (number a, number b, const coeffs)
158 {
159   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
160   mpz_init(erg);
161   mpz_add(erg, (mpz_ptr) a, (mpz_ptr) b);
162   return (number) erg;
163 }
164 
nrzSub(number a,number b,const coeffs)165 static number nrzSub (number a, number b, const coeffs)
166 {
167   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
168   mpz_init(erg);
169   mpz_sub(erg, (mpz_ptr) a, (mpz_ptr) b);
170   return (number) erg;
171 }
172 
nrzGetUnit(number,const coeffs r)173 static number nrzGetUnit (number, const coeffs r)
174 {
175   return nrzInit(1, r);
176 }
177 
nrzIsUnit(number a,const coeffs)178 static BOOLEAN nrzIsUnit (number a, const coeffs)
179 {
180   return 0 == mpz_cmpabs_ui((mpz_ptr) a, 1);
181 }
182 
nrzIsZero(number a,const coeffs)183 static BOOLEAN nrzIsZero (number  a, const coeffs)
184 {
185   return 0 == mpz_cmpabs_ui((mpz_ptr) a, 0);
186 }
187 
nrzIsOne(number a,const coeffs)188 static BOOLEAN nrzIsOne (number a, const coeffs)
189 {
190   return (0 == mpz_cmp_ui((mpz_ptr) a, 1));
191 }
192 
nrzIsMOne(number a,const coeffs)193 static BOOLEAN nrzIsMOne (number a, const coeffs)
194 {
195   return (0 == mpz_cmp_si((mpz_ptr) a, -1));
196 }
197 
nrzEqual(number a,number b,const coeffs)198 static BOOLEAN nrzEqual (number a,number b, const coeffs)
199 {
200   return 0 == mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
201 }
202 
nrzGreater(number a,number b,const coeffs)203 static BOOLEAN nrzGreater (number a,number b, const coeffs)
204 {
205   return 0 < mpz_cmp((mpz_ptr) a, (mpz_ptr) b);
206 }
207 
nrzGreaterZero(number k,const coeffs)208 static BOOLEAN nrzGreaterZero (number k, const coeffs)
209 {
210   return 0 < mpz_sgn1((mpz_ptr) k);
211 }
212 
nrzDivBy(number a,number b,const coeffs)213 static BOOLEAN nrzDivBy (number a,number b, const coeffs)
214 {
215   return mpz_divisible_p((mpz_ptr) a, (mpz_ptr) b) != 0;
216 }
217 
nrzDivComp(number a,number b,const coeffs r)218 static int nrzDivComp(number a, number b, const coeffs r)
219 {
220   if (nrzDivBy(a, b, r))
221   {
222     if (nrzDivBy(b, a, r)) return 2;
223     return -1;
224   }
225   if (nrzDivBy(b, a, r)) return 1;
226   return 0;
227 }
228 
nrzDiv(number a,number b,const coeffs r)229 static number nrzDiv (number a,number b, const coeffs r)
230 {
231   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
232   mpz_init(erg);
233   if (nrzIsZero(b,r))
234   {
235     WerrorS(nDivBy0);
236   }
237   else
238   {
239     mpz_ptr r = (mpz_ptr) omAllocBin(gmp_nrz_bin);
240     mpz_init(r);
241     mpz_tdiv_qr(erg, r, (mpz_ptr) a, (mpz_ptr) b);
242     mpz_clear(r);
243     omFreeBin(r, gmp_nrz_bin);
244   }
245   return (number) erg;
246 }
247 
nrzExactDiv(number a,number b,const coeffs r)248 static number nrzExactDiv (number a,number b, const coeffs r)
249 {
250   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
251   mpz_init(erg);
252   if (nrzIsZero(b,r))
253   {
254     WerrorS(nDivBy0);
255   }
256   else
257   {
258     mpz_tdiv_q(erg, (mpz_ptr) a, (mpz_ptr) b);
259   }
260   return (number) erg;
261 }
262 
nrzEucNorm(number a,const coeffs)263 static number nrzEucNorm (number a, const coeffs )
264 {
265   mpz_ptr abs = (mpz_ptr) omAllocBin(gmp_nrz_bin);
266   mpz_init(abs);
267   mpz_abs(abs, (mpz_ptr)a);
268 
269   return (number) abs;
270 }
271 
nrzSmallestQuotRem(number a,number b,number * r,const coeffs)272 static number nrzSmallestQuotRem (number a, number b, number * r, const coeffs )
273 {
274   mpz_ptr qq = (mpz_ptr) omAllocBin(gmp_nrz_bin);
275   mpz_init(qq);
276   mpz_ptr rr = (mpz_ptr) omAllocBin(gmp_nrz_bin);
277   mpz_init(rr);
278   int gsign = mpz_sgn((mpz_ptr) b);
279   mpz_t gg, ghalf;
280   mpz_init(gg);
281   mpz_init(ghalf);
282   mpz_abs(gg, (mpz_ptr) b);
283   mpz_fdiv_qr(qq, rr, (mpz_ptr) a, gg);
284   mpz_tdiv_q_2exp(ghalf, gg, 1);
285   if (mpz_cmp(rr, ghalf) > 0)  // r > ghalf
286     {
287       mpz_sub(rr, rr, gg);
288       mpz_add_ui(qq, qq, 1);
289     }
290   if (gsign < 0) mpz_neg(qq, qq);
291 
292   mpz_clear(gg);
293   mpz_clear(ghalf);
294   if (r==NULL)
295   {
296     mpz_clear(rr);
297     omFreeBin(rr,gmp_nrz_bin);
298   }
299   else
300   {
301     *r=(number)rr;
302   }
303   return (number) qq;
304 }
305 
nrzQuotRem(number a,number b,number * r,const coeffs)306 static number nrzQuotRem (number a, number b, number * r, const coeffs )
307 {
308   mpz_ptr qq = (mpz_ptr) omAllocBin(gmp_nrz_bin);
309   mpz_init(qq);
310   mpz_ptr rr = (mpz_ptr) omAllocBin(gmp_nrz_bin);
311   mpz_init(rr);
312   mpz_tdiv_qr(qq, rr, (mpz_ptr) a, (mpz_ptr) b);
313   if (r==NULL)
314   {
315     mpz_clear(rr);
316     omFreeBin(rr,gmp_nrz_bin);
317   }
318   else
319   {
320     *r=(number)rr;
321   }
322   return (number) qq;
323 }
324 
nrzIntMod(number a,number b,const coeffs)325 static number nrzIntMod (number a,number b, const coeffs)
326 {
327   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
328   mpz_init(erg);
329   mpz_ptr r = (mpz_ptr) omAllocBin(gmp_nrz_bin);
330   mpz_init(r);
331   mpz_tdiv_qr(erg, r, (mpz_ptr) a, (mpz_ptr) b);
332   mpz_clear(erg);
333   omFreeBin(erg, gmp_nrz_bin);
334   return (number) r;
335 }
336 
nrzInvers(number c,const coeffs r)337 static number  nrzInvers (number c, const coeffs r)
338 {
339   if (!nrzIsUnit((number) c, r))
340   {
341     WerrorS("Non invertible element.");
342     return nrzInit(0,r);
343   }
344   return nrzCopy(c,r);
345 }
346 
nrzNeg(number c,const coeffs)347 static number nrzNeg (number c, const coeffs)
348 {
349 // nNeg inplace !!!
350   mpz_mul_si((mpz_ptr) c, (mpz_ptr) c, -1);
351   return c;
352 }
353 
nrzMapMachineInt(number from,const coeffs,const coeffs)354 static number nrzMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
355 {
356   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
357   mpz_init_set_ui(erg, (unsigned long) from);
358   return (number) erg;
359 }
360 
nrzMapZp(number from,const coeffs,const coeffs)361 static number nrzMapZp(number from, const coeffs /*src*/, const coeffs /*dst*/)
362 {
363   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
364   mpz_init_set_si(erg, (long) from);
365   return (number) erg;
366 }
367 
nrzMapQ(number from,const coeffs src,const coeffs)368 static number nrzMapQ(number from, const coeffs src, const coeffs /*dst*/)
369 {
370   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
371   mpz_init(erg);
372   nlMPZ(erg, from, src);
373   return (number) erg;
374 }
375 
nrzSetMap(const coeffs src,const coeffs)376 static nMapFunc nrzSetMap(const coeffs src, const coeffs /*dst*/)
377 {
378   /* dst = currRing */
379   /* dst = nrn */
380   if ((src->rep==n_rep_gmp)
381   && (nCoeff_is_Z(src) || nCoeff_is_Zn(src) || nCoeff_is_Ring_PtoM(src)))
382   {
383     return ndCopyMap; //nrzCopyMap;
384   }
385   if ((src->rep==n_rep_gap_gmp) /*&& nCoeff_is_Z(src)*/)
386   {
387     return ndCopyMap; //nrzCopyMap;
388   }
389   if (nCoeff_is_Ring_2toM(src))
390   {
391     return nrzMapMachineInt;
392   }
393   if (nCoeff_is_Zp(src))
394   {
395     return nrzMapZp;
396   }
397   if (getCoeffType(src)==n_Q /*nCoeff_is_Q(src) or coeffs_BIGINT*/)
398   {
399     return nrzMapQ;
400   }
401   return NULL;      // default
402 }
403 
404 /*
405  * set the exponent (allocate and init tables) (TODO)
406  */
407 
nrzSetExp(int,coeffs)408 void nrzSetExp(int, coeffs)
409 {
410 }
411 
nrzInitExp(int,coeffs)412 void nrzInitExp(int, coeffs)
413 {
414 }
415 
416 #ifdef LDEBUG
nrzDBTest(number,const char *,const int,const coeffs)417 static BOOLEAN nrzDBTest (number, const char *, const int, const coeffs)
418 {
419   return TRUE;//TODO
420 }
421 #endif
422 
nrzWrite(number a,const coeffs)423 void nrzWrite (number a, const coeffs)
424 {
425   char *s,*z;
426   if (a==NULL)
427   {
428     StringAppendS("o");
429   }
430   else
431   {
432     int l=mpz_sizeinbase((mpz_ptr) a, 10) + 2;
433     s=(char*)omAlloc(l);
434     z=mpz_get_str(s,10,(mpz_ptr) a);
435     StringAppendS(z);
436     omFreeSize((ADDRESS)s,l);
437   }
438 }
439 
440 /*2
441 * extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
442 */
nlEatLongC(char * s,mpz_ptr i)443 static const char * nlEatLongC(char *s, mpz_ptr i)
444 {
445   const char * start=s;
446 
447   if (*s<'0' || *s>'9')
448   {
449     mpz_set_ui(i,1);
450     return s;
451   }
452   while (*s >= '0' && *s <= '9') s++;
453   if (*s=='\0')
454   {
455     mpz_set_str(i,start,10);
456   }
457   else
458   {
459     char c=*s;
460     *s='\0';
461     mpz_set_str(i,start,10);
462     *s=c;
463   }
464   return s;
465 }
466 
467 
nrzConvSingNFactoryN(number n,BOOLEAN setChar,const coeffs)468 static CanonicalForm nrzConvSingNFactoryN(number n, BOOLEAN setChar, const coeffs /*r*/)
469 {
470   if (setChar) setCharacteristic( 0 );
471 
472   CanonicalForm term;
473   mpz_t num;
474   mpz_init_set(num, *((mpz_t*)n));
475   term = make_cf(num);
476   return term;
477 }
478 
nrzConvFactoryNSingN(const CanonicalForm n,const coeffs r)479 static number nrzConvFactoryNSingN(const CanonicalForm n, const coeffs r)
480 {
481   if (n.isImm())
482     return nrzInit(n.intval(),r);
483   else
484   {
485     mpz_ptr m = (mpz_ptr) omAllocBin(gmp_nrz_bin);
486     gmp_numerator(n,m);
487     if (!n.den().isOne())
488     {
489       WarnS("denominator is not 1 in factory");
490     }
491     return (number) m;
492   }
493 }
494 
nrzRead(const char * s,number * a,const coeffs)495 static const char * nrzRead (const char *s, number *a, const coeffs)
496 {
497   mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
498   {
499     mpz_init(z);
500     s = nlEatLongC((char *) s, z);
501   }
502   *a = (number) z;
503   return s;
504 }
505 
nrzQuot1(number c,const coeffs r)506 static coeffs nrzQuot1(number c, const coeffs r)
507 {
508     long ch = r->cfInt(c, r);
509     mpz_t dummy;
510     mpz_init_set_ui(dummy, ch);
511     ZnmInfo info;
512     info.base = dummy;
513     info.exp = (unsigned long) 1;
514     coeffs rr = nInitChar(n_Zn, (void*)&info);
515     mpz_clear(dummy);
516     return(rr);
517 }
518 
nrzInitMPZ(mpz_t m,const coeffs)519 static number nrzInitMPZ(mpz_t m, const coeffs)
520 {
521   mpz_ptr z = (mpz_ptr) omAllocBin(gmp_nrz_bin);
522   mpz_init_set(z, m);
523   return (number)z;
524 }
525 
nrzMPZ(mpz_t res,number & a,const coeffs)526 static void nrzMPZ(mpz_t res, number &a, const coeffs)
527 {
528   mpz_init_set(res, (mpz_ptr) a);
529 }
530 
nrzFarey(number r,number N,const coeffs R)531 static number nrzFarey(number r, number N, const coeffs R)
532 {
533   number a0 = nrzCopy(N, R);
534   number b0 = nrzInit(0, R);
535   number a1 = nrzCopy(r, R);
536   number b1 = nrzInit(1, R);
537   number two = nrzInit(2, R);
538 #if 0
539   PrintS("Farey start with ");
540   n_Print(r, R);
541   PrintS(" mod ");
542   n_Print(N, R);
543   PrintLn();
544 #endif
545   while (1)
546   {
547     number as = nrzMult(a1, a1, R);
548     n_InpMult(as, two, R);
549     if (nrzGreater(N, as, R))
550     {
551       nrzDelete(&as, R);
552       break;
553     }
554     nrzDelete(&as, R);
555     number q = nrzDiv(a0, a1, R);
556     number t = nrzMult(a1, q, R),
557            s = nrzSub(a0, t, R);
558     nrzDelete(&a0, R);
559     a0 = a1;
560     a1 = s;
561     nrzDelete(&t, R);
562 
563     t = nrzMult(b1, q, R);
564     s = nrzSub(b0, t, R);
565     nrzDelete(&b0, R);
566     b0 = b1;
567     b1 = s;
568     nrzDelete(&t, R);
569     nrzDelete(&q, R);
570   }
571   number as = nrzMult(b1, b1, R);
572   n_InpMult(as, two, R);
573   nrzDelete(&two, R);
574   if (nrzGreater(as, N, R))
575   {
576     nrzDelete(&a0, R);
577     nrzDelete(&a1, R);
578     nrzDelete(&b0, R);
579     nrzDelete(&b1, R);
580     nrzDelete(&as, R);
581     return NULL;
582   }
583   nrzDelete(&as, R);
584   nrzDelete(&a0, R);
585   nrzDelete(&b0, R);
586 
587   number a, b, ab;
588   coeffs Q = nInitChar(n_Q, 0);
589   nMapFunc f = n_SetMap(R, Q);
590   a = f(a1, R, Q);
591   b = f(b1, R, Q);
592   ab = n_Div(a, b, Q);
593   n_Delete(&a, Q);
594   n_Delete(&b, Q);
595   nKillChar(Q);
596 
597   nrzDelete(&a1, R);
598   nrzDelete(&b1, R);
599   return ab;
600 }
601 
nrzWriteFd(number n,const ssiInfo * d,const coeffs)602 void nrzWriteFd(number n, const ssiInfo* d, const coeffs)
603 {
604   mpz_out_str (d->f_write,SSI_BASE, (mpz_ptr)n);
605   fputc(' ',d->f_write);
606 }
607 
nrzReadFd(const ssiInfo * d,const coeffs)608 number nrzReadFd(const ssiInfo *d, const coeffs)
609 {
610   mpz_ptr erg = (mpz_ptr) omAllocBin(gmp_nrz_bin);
611   mpz_init(erg);
612   s_readmpz_base(d->f_read,erg,SSI_BASE);
613   return (number)erg;
614 }
615 
nrzInitChar(coeffs r,void *)616 BOOLEAN nrzInitChar(coeffs r,  void *)
617 {
618   assume( getCoeffType(r) == n_Z );
619 
620   r->is_field=FALSE;
621   r->is_domain=TRUE;
622   r->rep=n_rep_gmp;
623 
624   //r->nCoeffIsEqual = ndCoeffIsEqual;
625   r->cfCoeffName = nrzCoeffName;
626   //r->cfKillChar = ndKillChar;
627   r->cfMult  = nrzMult;
628   r->cfSub   = nrzSub;
629   r->cfAdd   = nrzAdd;
630   r->cfDiv   = nrzDiv;
631   r->cfIntMod= nrzIntMod;
632   r->cfExactDiv= nrzExactDiv;
633   r->cfInit = nrzInit;
634   r->cfInitMPZ = nrzInitMPZ;
635   r->cfMPZ = nrzMPZ;
636   r->cfSize  = nrzSize;
637   r->cfInt  = nrzInt;
638   r->cfDivComp = nrzDivComp;
639   r->cfIsUnit = nrzIsUnit;
640   r->cfGetUnit = nrzGetUnit;
641   r->cfExtGcd = nrzExtGcd;
642   r->cfXExtGcd = nrzXExtGcd;
643   r->cfDivBy = nrzDivBy;
644   r->cfEucNorm = nrzEucNorm;
645   r->cfQuotRem = nrzSmallestQuotRem;
646   r->cfInpNeg   = nrzNeg;
647   r->cfInvers= nrzInvers;
648   r->cfCopy  = nrzCopy;
649   r->cfWriteLong = nrzWrite;
650   r->cfRead = nrzRead;
651   r->cfGreater = nrzGreater;
652   r->cfEqual = nrzEqual;
653   r->cfIsZero = nrzIsZero;
654   r->cfIsOne = nrzIsOne;
655   r->cfIsMOne = nrzIsMOne;
656   r->cfGreaterZero = nrzGreaterZero;
657   r->cfPower = nrzPower;
658   r->cfGcd  = nrzGcd;
659   r->cfLcm  = nrzLcm;
660   r->cfDelete= nrzDelete;
661   r->cfSetMap = nrzSetMap;
662   r->cfQuot1 = nrzQuot1;
663   r->convSingNFactoryN=nrzConvSingNFactoryN;
664   r->convFactoryNSingN=nrzConvFactoryNSingN;
665   r->cfChineseRemainder=nlChineseRemainderSym;
666   r->cfFarey=nrzFarey;
667   r->cfWriteFd=nrzWriteFd;
668   r->cfReadFd=nrzReadFd;
669   // debug stuff
670 
671 #ifdef LDEBUG
672   r->cfDBTest=nrzDBTest;
673 #endif
674 
675   r->ch = 0;
676   r->has_simple_Alloc=FALSE;
677   r->has_simple_Inverse=FALSE;
678   return FALSE;
679 }
680 #endif
681 #endif
682