longrat.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 /*
5 * ABSTRACT: computation with long rational numbers (Hubert Grassmann)
6 */
7 
8 #include "misc/auxiliary.h"
9 
10 #include "factory/factory.h"
11 
12 #include "misc/sirandom.h"
13 #include "misc/prime.h"
14 #include "reporter/reporter.h"
15 
16 #include "coeffs/coeffs.h"
17 #include "coeffs/numbers.h"
18 #include "coeffs/rmodulon.h" // ZnmInfo
19 #include "coeffs/longrat.h"
20 #include "coeffs/shortfl.h"
21 #include "coeffs/modulop.h"
22 #include "coeffs/mpr_complex.h"
23 
24 #include <string.h>
25 #include <float.h>
26 
27 // allow inlining only from p_Numbers.h and if ! LDEBUG
28 #if defined(DO_LINLINE) && defined(P_NUMBERS_H) && !defined(LDEBUG)
29 #define LINLINE static FORCE_INLINE
30 #else
31 #define LINLINE
32 #undef DO_LINLINE
33 #endif // DO_LINLINE
34 
35 LINLINE BOOLEAN nlEqual(number a, number b, const coeffs r);
36 LINLINE number nlInit(long i, const coeffs r);
37 LINLINE BOOLEAN nlIsOne(number a, const coeffs r);
38 LINLINE BOOLEAN nlIsZero(number za, const coeffs r);
39 LINLINE number nlCopy(number a, const coeffs r);
40 LINLINE number nl_Copy(number a, const coeffs r);
41 LINLINE void nlDelete(number *a, const coeffs r);
42 LINLINE number nlNeg(number za, const coeffs r);
43 LINLINE number nlAdd(number la, number li, const coeffs r);
44 LINLINE number nlSub(number la, number li, const coeffs r);
45 LINLINE number nlMult(number a, number b, const coeffs r);
46 LINLINE void nlInpAdd(number &a, number b, const coeffs r);
47 LINLINE void nlInpMult(number &a, number b, const coeffs r);
48 
49 number nlRInit (long i);
50 
51 
52 // number nlInitMPZ(mpz_t m, const coeffs r);
53 // void nlMPZ(mpz_t m, number &n, const coeffs r);
54 
55 void nlNormalize(number &x, const coeffs r);
56 
57 number nlGcd(number a, number b, const coeffs r);
58 number nlExtGcd(number a, number b, number *s, number *t, const coeffs);
59 number nlNormalizeHelper(number a, number b, const coeffs r); /*special routine !*/
60 BOOLEAN nlGreater(number a, number b, const coeffs r);
61 BOOLEAN nlIsMOne(number a, const coeffs r);
62 long nlInt(number &n, const coeffs r);
63 number nlBigInt(number &n);
64 
65 #ifdef HAVE_RINGS
66 number nlMapGMP(number from, const coeffs src, const coeffs dst);
67 #endif
68 
69 BOOLEAN nlGreaterZero(number za, const coeffs r);
70 number nlInvers(number a, const coeffs r);
71 number nlDiv(number a, number b, const coeffs r);
72 number nlExactDiv(number a, number b, const coeffs r);
73 number nlIntDiv(number a, number b, const coeffs r);
74 number nlIntMod(number a, number b, const coeffs r);
75 void nlPower(number x, int exp, number *lu, const coeffs r);
76 const char * nlRead (const char *s, number *a, const coeffs r);
77 void nlWrite(number a, const coeffs r);
78 
79 void nlCoeffWrite(const coeffs r, BOOLEAN details);
80 number nlFarey(number nN, number nP, const coeffs CF);
81 
82 #ifdef LDEBUG
83 BOOLEAN nlDBTest(number a, const char *f, const int l);
84 #endif
85 
86 nMapFunc nlSetMap(const coeffs src, const coeffs dst);
87 
88 // in-place operations
89 void nlInpIntDiv(number &a, number b, const coeffs r);
90 
91 #ifdef LDEBUG
92 #define nlTest(a, r) nlDBTest(a,__FILE__,__LINE__, r)
93 BOOLEAN nlDBTest(number a, const char *f,int l, const coeffs r);
94 #else
95 #define nlTest(a, r) do {} while (0)
96 #endif
97 
98 
99 // 64 bit version:
100 //#if SIZEOF_LONG == 8
101 #if 0
102 #define MAX_NUM_SIZE 60
103 #define POW_2_28 (1L<<60)
104 #define POW_2_28_32 (1L<<28)
105 #define LONG long
106 #else
107 #define MAX_NUM_SIZE 28
108 #define POW_2_28 (1L<<28)
109 #define POW_2_28_32 (1L<<28)
110 #define LONG int
111 #endif
112 
113 
114 static inline number nlShort3(number x) // assume x->s==3
115 {
116  assume(x->s==3);
117  if (mpz_sgn1(x->z)==0)
118  {
119  mpz_clear(x->z);
120  FREE_RNUMBER(x);
121  return INT_TO_SR(0);
122  }
123  if (mpz_size1(x->z)<=MP_SMALL)
124  {
125  LONG ui=mpz_get_si(x->z);
126  if ((((ui<<3)>>3)==ui)
127  && (mpz_cmp_si(x->z,(long)ui)==0))
128  {
129  mpz_clear(x->z);
130  FREE_RNUMBER(x);
131  return INT_TO_SR(ui);
132  }
133  }
134  return x;
135 }
136 
137 #ifndef LONGRAT_CC
138 #define LONGRAT_CC
139 
140 #ifndef BYTES_PER_MP_LIMB
141 #define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
142 #endif
143 
144 //#define SR_HDL(A) ((long)(A))
145 /*#define SR_INT 1L*/
146 /*#define INT_TO_SR(INT) ((number) (((long)INT << 2) + SR_INT))*/
147 // #define SR_TO_INT(SR) (((long)SR) >> 2)
148 
149 #define MP_SMALL 1
150 //#define mpz_isNeg(A) (mpz_sgn1(A)<0)
151 #define mpz_isNeg(A) ((A)->_mp_size<0)
152 #define mpz_limb_size(A) ((A)->_mp_size)
153 #define mpz_limb_d(A) ((A)->_mp_d)
154 
155 void _nlDelete_NoImm(number *a);
156 
157 /***************************************************************
158  *
159  * Routines which are never inlined by p_Numbers.h
160  *
161  *******************************************************************/
162 #ifndef P_NUMBERS_H
163 
164 number nlShort3_noinline(number x) // assume x->s==3
165 {
166  return nlShort3(x);
167 }
168 
169 
170 #if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
171 void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
172 {
173  if (si>=0)
174  mpz_mul_ui(r,s,si);
175  else
176  {
177  mpz_mul_ui(r,s,-si);
178  mpz_neg(r,r);
179  }
180 }
181 #endif
182 
183 static number nlMapP(number from, const coeffs src, const coeffs dst)
184 {
185  assume( getCoeffType(src) == n_Zp );
186 
187  number to = nlInit(npInt(from,src), dst); // FIXME? TODO? // extern long npInt (number &n, const coeffs r);
188 
189  return to;
190 }
191 
192 static number nlMapLongR(number from, const coeffs src, const coeffs dst);
193 static number nlMapR(number from, const coeffs src, const coeffs dst);
194 
195 
196 #ifdef HAVE_RINGS
197 /*2
198 * convert from a GMP integer
199 */
200 number nlMapGMP(number from, const coeffs /*src*/, const coeffs /*dst*/)
201 {
202  number z=ALLOC_RNUMBER();
203 #if defined(LDEBUG)
204  z->debug=123456;
205 #endif
206  mpz_init_set(z->z,(mpz_ptr) from);
207  z->s = 3;
208  z=nlShort3(z);
209  return z;
210 }
211 
212 number nlMapZ(number from, const coeffs src, const coeffs dst)
213 {
214  if (SR_HDL(from) & SR_INT)
215  {
216  return from;
217  }
218  return nlMapGMP(from,src,dst);
219 }
220 
221 /*2
222 * convert from an machine long
223 */
224 number nlMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
225 {
226  number z=ALLOC_RNUMBER();
227 #if defined(LDEBUG)
228  z->debug=123456;
229 #endif
230  mpz_init_set_ui(z->z,(unsigned long) from);
231  z->s = 3;
232  z=nlShort3(z);
233  return z;
234 }
235 #endif
236 
237 
238 #ifdef LDEBUG
239 BOOLEAN nlDBTest(number a, const char *f,const int l, const coeffs /*r*/)
240 {
241  if (a==NULL)
242  {
243  Print("!!longrat: NULL in %s:%d\n",f,l);
244  return FALSE;
245  }
246  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
247  if ((((long)a)&3L)==3L)
248  {
249  Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
250  return FALSE;
251  }
252  if ((((long)a)&3L)==1L)
253  {
254  if (((((LONG)(long)a)<<1)>>1)!=((LONG)(long)a))
255  {
256  Print(" !!longrat:arith:%lx in %s:%d\n",(long)a, f,l);
257  return FALSE;
258  }
259  return TRUE;
260  }
261  /* TODO: If next line is active, then computations in algebraic field
262  extensions over Q will throw a lot of assume violations although
263  everything is computed correctly and no seg fault appears.
264  Maybe the test is not appropriate in this case. */
265  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
266  if (a->debug!=123456)
267  {
268  Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
269  a->debug=123456;
270  return FALSE;
271  }
272  if ((a->s<0)||(a->s>4))
273  {
274  Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
275  return FALSE;
276  }
277  /* TODO: If next line is active, then computations in algebraic field
278  extensions over Q will throw a lot of assume violations although
279  everything is computed correctly and no seg fault appears.
280  Maybe the test is not appropriate in this case. */
281  //omCheckAddrSize(a->z[0]._mp_d,a->z[0]._mp_alloc*BYTES_PER_MP_LIMB);
282  if (a->z[0]._mp_alloc==0)
283  Print("!!longrat:z->alloc=0 in %s:%d\n",f,l);
284 
285  if (a->s<2)
286  {
287  if ((a->n[0]._mp_d[0]==0)&&(a->n[0]._mp_alloc<=1))
288  {
289  Print("!!longrat: n==0 in %s:%d\n",f,l);
290  return FALSE;
291  }
292  /* TODO: If next line is active, then computations in algebraic field
293  extensions over Q will throw a lot of assume violations although
294  everything is computed correctly and no seg fault appears.
295  Maybe the test is not appropriate in this case. */
296  //omCheckIf(omCheckAddrSize(a->n[0]._mp_d,a->n[0]._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
297  if (a->z[0]._mp_alloc==0)
298  Print("!!longrat:n->alloc=0 in %s:%d\n",f,l);
299  if ((mpz_size1(a->n) ==1) && (mpz_cmp_si(a->n,1L)==0))
300  {
301  Print("!!longrat:integer as rational in %s:%d\n",f,l);
302  mpz_clear(a->n); a->s=3;
303  return FALSE;
304  }
305  else if (mpz_isNeg(a->n))
306  {
307  Print("!!longrat:div. by negative in %s:%d\n",f,l);
308  mpz_neg(a->z,a->z);
309  mpz_neg(a->n,a->n);
310  return FALSE;
311  }
312  return TRUE;
313  }
314  //if (a->s==2)
315  //{
316  // Print("!!longrat:s=2 in %s:%d\n",f,l);
317  // return FALSE;
318  //}
319  if (mpz_size1(a->z)>MP_SMALL) return TRUE;
320  LONG ui=(LONG)mpz_get_si(a->z);
321  if ((((ui<<3)>>3)==ui)
322  && (mpz_cmp_si(a->z,(long)ui)==0))
323  {
324  Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
325  return FALSE;
326  }
327  return TRUE;
328 }
329 #endif
330 
331 static CanonicalForm nlConvSingNFactoryN( number n, const BOOLEAN setChar, const coeffs /*r*/ )
332 {
333  if (setChar) setCharacteristic( 0 );
334 
336  if ( SR_HDL(n) & SR_INT )
337  {
338  long nn=SR_TO_INT(n);
339  term = nn;
340  }
341  else
342  {
343  if ( n->s == 3 )
344  {
345  mpz_t dummy;
346  long lz=mpz_get_si(n->z);
347  if (mpz_cmp_si(n->z,lz)==0) term=lz;
348  else
349  {
350  mpz_init_set( dummy,n->z );
351  term = make_cf( dummy );
352  }
353  }
354  else
355  {
356  // assume s==0 or s==1
357  mpz_t num, den;
358  On(SW_RATIONAL);
359  mpz_init_set( num, n->z );
360  mpz_init_set( den, n->n );
361  term = make_cf( num, den, ( n->s != 1 ));
362  }
363  }
364  return term;
365 }
366 
367 number nlRInit (long i);
368 
369 static number nlConvFactoryNSingN( const CanonicalForm f, const coeffs r)
370 {
371  if (f.isImm())
372  {
373  return nlInit(f.intval(),r);
374  }
375  else
376  {
377  number z = ALLOC_RNUMBER();
378 #if defined(LDEBUG)
379  z->debug=123456;
380 #endif
381  gmp_numerator( f, z->z );
382  if ( f.den().isOne() )
383  {
384  z->s = 3;
385  z=nlShort3(z);
386  }
387  else
388  {
389  gmp_denominator( f, z->n );
390  z->s = 1;
391  }
392  return z;
393  }
394 }
395 
396 static number nlMapR(number from, const coeffs src, const coeffs dst)
397 {
398  assume( getCoeffType(src) == n_R );
399 
400  double f=nrFloat(from); // FIXME? TODO? // extern float nrFloat(number n);
401  if (f==0.0) return INT_TO_SR(0);
402  int f_sign=1;
403  if (f<0.0)
404  {
405  f_sign=-1;
406  f=-f;
407  }
408  int i=0;
409  mpz_t h1;
410  mpz_init_set_ui(h1,1);
411  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
412  {
413  f*=FLT_RADIX;
414  mpz_mul_ui(h1,h1,FLT_RADIX);
415  i++;
416  }
417  number re=nlRInit(1);
418  mpz_set_d(re->z,f);
419  memcpy(&(re->n),&h1,sizeof(h1));
420  re->s=0; /* not normalized */
421  if(f_sign==-1) re=nlNeg(re,dst);
422  nlNormalize(re,dst);
423  return re;
424 }
425 
426 static number nlMapLongR(number from, const coeffs src, const coeffs dst)
427 {
428  assume( getCoeffType(src) == n_long_R );
429 
430  gmp_float *ff=(gmp_float*)from;
431  mpf_t *f=ff->_mpfp();
432  number res;
433  mpz_ptr dest,ndest;
434  int size, i,negative;
435  int e,al,bl;
436  mp_ptr qp,dd,nn;
437 
438  size = (*f)[0]._mp_size;
439  if (size == 0)
440  return INT_TO_SR(0);
441  if(size<0)
442  {
443  negative = 1;
444  size = -size;
445  }
446  else
447  negative = 0;
448 
449  qp = (*f)[0]._mp_d;
450  while(qp[0]==0)
451  {
452  qp++;
453  size--;
454  }
455 
456  e=(*f)[0]._mp_exp-size;
457  res = ALLOC_RNUMBER();
458 #if defined(LDEBUG)
459  res->debug=123456;
460 #endif
461  dest = res->z;
462 
463  void* (*allocfunc) (size_t);
464  mp_get_memory_functions (&allocfunc,NULL, NULL);
465  if (e<0)
466  {
467  al = dest->_mp_size = size;
468  if (al<2) al = 2;
469  dd = (mp_ptr)allocfunc(sizeof(mp_limb_t)*al);
470  for (i=0;i<size;i++) dd[i] = qp[i];
471  bl = 1-e;
472  nn = (mp_ptr)allocfunc(sizeof(mp_limb_t)*bl);
473  nn[bl-1] = 1;
474  ndest = res->n;
475  ndest->_mp_d = nn;
476  ndest->_mp_alloc = ndest->_mp_size = bl;
477  res->s = 0;
478  }
479  else
480  {
481  al = dest->_mp_size = size+e;
482  if (al<2) al = 2;
483  dd = (mp_ptr)allocfunc(sizeof(mp_limb_t)*al);
484  for (i=0;i<size;i++) dd[i+e] = qp[i];
485  for (i=0;i<e;i++) dd[i] = 0;
486  res->s = 3;
487  }
488 
489  dest->_mp_d = dd;
490  dest->_mp_alloc = al;
491  if (negative) mpz_neg(dest,dest);
492 
493  if (res->s==0)
494  nlNormalize(res,dst);
495  else if (mpz_size1(res->z)<=MP_SMALL)
496  {
497  // res is new, res->ref is 1
498  res=nlShort3(res);
499  }
500  nlTest(res, dst);
501  return res;
502 }
503 
504 //static number nlMapLongR(number from)
505 //{
506 // gmp_float *ff=(gmp_float*)from;
507 // const mpf_t *f=ff->mpfp();
508 // int f_size=ABS((*f)[0]._mp_size);
509 // if (f_size==0)
510 // return nlInit(0);
511 // int f_sign=1;
512 // number work=ngcCopy(from);
513 // if (!ngcGreaterZero(work))
514 // {
515 // f_sign=-1;
516 // work=ngcNeg(work);
517 // }
518 // int i=0;
519 // mpz_t h1;
520 // mpz_init_set_ui(h1,1);
521 // while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
522 // {
523 // f*=FLT_RADIX;
524 // mpz_mul_ui(h1,h1,FLT_RADIX);
525 // i++;
526 // }
527 // number r=nlRInit(1);
528 // mpz_set_d(&(r->z),f);
529 // memcpy(&(r->n),&h1,sizeof(h1));
530 // r->s=0; /* not normalized */
531 // nlNormalize(r);
532 // return r;
533 //
534 //
535 // number r=nlRInit(1);
536 // int f_shift=f_size+(*f)[0]._mp_exp;
537 // if ( f_shift > 0)
538 // {
539 // r->s=0;
540 // mpz_init(&r->n);
541 // mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
542 // mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
543 // // now r->z has enough space
544 // memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
545 // nlNormalize(r);
546 // }
547 // else
548 // {
549 // r->s=3;
550 // if (f_shift==0)
551 // {
552 // mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
553 // // now r->z has enough space
554 // memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
555 // }
556 // else /* f_shift < 0 */
557 // {
558 // mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
559 // // now r->z has enough space
560 // memcpy(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
561 // f_size*BYTES_PER_MP_LIMB);
562 // }
563 // }
564 // if ((*f)[0]._mp_size<0);
565 // r=nlNeg(r);
566 // return r;
567 //}
568 
569 int nlSize(number a, const coeffs)
570 {
571  if (a==INT_TO_SR(0))
572  return 0; /* rational 0*/
573  if (SR_HDL(a) & SR_INT)
574  return 1; /* immediate int */
575  int s=a->z[0]._mp_alloc;
576 // while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
577 //#if SIZEOF_LONG == 8
578 // if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
579 // else s *=2;
580 //#endif
581 // s++;
582  if (a->s<2)
583  {
584  int d=a->n[0]._mp_alloc;
585 // while ((d>0) && (a->n._mp_d[d]==0L)) d--;
586 //#if SIZEOF_LONG == 8
587 // if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
588 // else d *=2;
589 //#endif
590  s+=d;
591  }
592  return s;
593 }
594 
595 /*2
596 * convert number to int
597 */
598 long nlInt(number &i, const coeffs r)
599 {
600  nlTest(i, r);
601  nlNormalize(i,r);
602  if (SR_HDL(i) & SR_INT)
603  {
604  return SR_TO_INT(i);
605  }
606  if (i->s==3)
607  {
608  if(mpz_size1(i->z)>MP_SMALL) return 0;
609  long ul=mpz_get_si(i->z);
610  if (mpz_cmp_si(i->z,ul)!=0) return 0;
611  return ul;
612  }
613  mpz_t tmp;
614  long ul;
615  mpz_init(tmp);
616  mpz_tdiv_q(tmp,i->z,i->n);
617  if(mpz_size1(tmp)>MP_SMALL) ul=0;
618  else
619  {
620  ul=mpz_get_si(tmp);
621  if (mpz_cmp_si(tmp,ul)!=0) ul=0;
622  }
623  mpz_clear(tmp);
624  return ul;
625 }
626 
627 /*2
628 * convert number to bigint
629 */
630 number nlBigInt(number &i, const coeffs r)
631 {
632  nlTest(i, r);
633  nlNormalize(i,r);
634  if (SR_HDL(i) & SR_INT) return (i);
635  if (i->s==3)
636  {
637  return nlCopy(i,r);
638  }
639  number tmp=nlRInit(1);
640  mpz_tdiv_q(tmp->z,i->z,i->n);
641  tmp=nlShort3(tmp);
642  return tmp;
643 }
644 
645 /*
646 * 1/a
647 */
648 number nlInvers(number a, const coeffs r)
649 {
650  nlTest(a, r);
651  number n;
652  if (SR_HDL(a) & SR_INT)
653  {
654  if ((a==INT_TO_SR(1L)) || (a==INT_TO_SR(-1L)))
655  {
656  return a;
657  }
658  if (nlIsZero(a,r))
659  {
660  WerrorS(nDivBy0);
661  return INT_TO_SR(0);
662  }
663  n=ALLOC_RNUMBER();
664 #if defined(LDEBUG)
665  n->debug=123456;
666 #endif
667  n->s=1;
668  if (((long)a)>0L)
669  {
670  mpz_init_set_ui(n->z,1L);
671  mpz_init_set_si(n->n,(long)SR_TO_INT(a));
672  }
673  else
674  {
675  mpz_init_set_si(n->z,-1L);
676  mpz_init_set_si(n->n,(long)-SR_TO_INT(a));
677  }
678  nlTest(n, r);
679  return n;
680  }
681  n=ALLOC_RNUMBER();
682 #if defined(LDEBUG)
683  n->debug=123456;
684 #endif
685  {
686  mpz_init_set(n->n,a->z);
687  switch (a->s)
688  {
689  case 0:
690  case 1:
691  n->s=a->s;
692  mpz_init_set(n->z,a->n);
693  if (mpz_isNeg(n->n)) /* && n->s<2*/
694  {
695  mpz_neg(n->z,n->z);
696  mpz_neg(n->n,n->n);
697  }
698  if (mpz_cmp_ui(n->n,1L)==0)
699  {
700  mpz_clear(n->n);
701  n->s=3;
702  n=nlShort3(n);
703  }
704  break;
705  case 3:
706  // i.e. |a| > 2^...
707  n->s=1;
708  if (mpz_isNeg(n->n)) /* && n->s<2*/
709  {
710  mpz_neg(n->n,n->n);
711  mpz_init_set_si(n->z,-1L);
712  }
713  else
714  {
715  mpz_init_set_ui(n->z,1L);
716  }
717  break;
718  }
719  }
720  nlTest(n, r);
721  return n;
722 }
723 
724 
725 /*2
726 * u := a / b in Z, if b | a (else undefined)
727 */
728 number nlExactDiv(number a, number b, const coeffs r)
729 {
730  if (b==INT_TO_SR(0))
731  {
732  WerrorS(nDivBy0);
733  return INT_TO_SR(0);
734  }
735  if (a==INT_TO_SR(0))
736  return INT_TO_SR(0);
737  number u;
738  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
739  {
740  /* the small int -(1<<28) divided by -1 is the large int (1<<28) */
741  if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
742  {
743  return nlRInit(POW_2_28);
744  }
745  long aa=SR_TO_INT(a);
746  long bb=SR_TO_INT(b);
747  return INT_TO_SR(aa/bb);
748  }
749  number aa=NULL;
750  number bb=NULL;
751  if (SR_HDL(a) & SR_INT)
752  {
753  aa=nlRInit(SR_TO_INT(a));
754  a=aa;
755  }
756  if (SR_HDL(b) & SR_INT)
757  {
758  bb=nlRInit(SR_TO_INT(b));
759  b=bb;
760  }
761  u=ALLOC_RNUMBER();
762 #if defined(LDEBUG)
763  u->debug=123456;
764 #endif
765  mpz_init(u->z);
766  /* u=a/b */
767  u->s = 3;
768  assume(a->s==3);
769  assume(b->s==3);
770  mpz_divexact(u->z,a->z,b->z);
771  if (aa!=NULL)
772  {
773  mpz_clear(aa->z);
774 #if defined(LDEBUG)
775  aa->debug=654324;
776 #endif
777  FREE_RNUMBER(aa); // omFreeBin((void *)aa, rnumber_bin);
778  }
779  if (bb!=NULL)
780  {
781  mpz_clear(bb->z);
782 #if defined(LDEBUG)
783  bb->debug=654324;
784 #endif
785  FREE_RNUMBER(bb); // omFreeBin((void *)bb, rnumber_bin);
786  }
787  u=nlShort3(u);
788  nlTest(u, r);
789  return u;
790 }
791 
792 /*2
793 * u := a / b in Z
794 */
795 number nlIntDiv (number a, number b, const coeffs r)
796 {
797  if (b==INT_TO_SR(0))
798  {
799  WerrorS(nDivBy0);
800  return INT_TO_SR(0);
801  }
802  if (a==INT_TO_SR(0))
803  return INT_TO_SR(0);
804  number u;
805  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
806  {
807  /* the small int -(1<<28) divided by -1 is the large int (1<<28) */
808  if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
809  {
810  return nlRInit(POW_2_28);
811  }
812  LONG aa=SR_TO_INT(a);
813  LONG bb=SR_TO_INT(b);
814  LONG rr=aa%bb;
815  if (rr<0) rr+=ABS(bb);
816  LONG cc=(aa-rr)/bb;
817  return INT_TO_SR(cc);
818  }
819  number aa=NULL;
820  if (SR_HDL(a) & SR_INT)
821  {
822  /* the small int -(1<<28) divided by 2^28 is 1 */
823  if (a==INT_TO_SR(-(POW_2_28)))
824  {
825  if(mpz_cmp_si(b->z,(POW_2_28))==0)
826  {
827  return INT_TO_SR(-1);
828  }
829  }
830  aa=nlRInit(SR_TO_INT(a));
831  a=aa;
832  }
833  number bb=NULL;
834  if (SR_HDL(b) & SR_INT)
835  {
836  bb=nlRInit(SR_TO_INT(b));
837  b=bb;
838  }
839  u=ALLOC_RNUMBER();
840 #if defined(LDEBUG)
841  u->debug=123456;
842 #endif
843  assume(a->s==3);
844  assume(b->s==3);
845  mpz_init_set(u->z,a->z);
846  /* u=u/b */
847  u->s = 3;
848  number rr=nlIntMod(a,b,r);
849  if (SR_HDL(rr) & SR_INT) mpz_sub_ui(u->z,u->z,SR_TO_INT(rr));
850  else mpz_sub(u->z,u->z,rr->z);
851  mpz_divexact(u->z,u->z,b->z);
852  if (aa!=NULL)
853  {
854  mpz_clear(aa->z);
855 #if defined(LDEBUG)
856  aa->debug=654324;
857 #endif
858  FREE_RNUMBER(aa);
859  }
860  if (bb!=NULL)
861  {
862  mpz_clear(bb->z);
863 #if defined(LDEBUG)
864  bb->debug=654324;
865 #endif
866  FREE_RNUMBER(bb);
867  }
868  u=nlShort3(u);
869  nlTest(u,r);
870  return u;
871 }
872 
873 /*2
874 * u := a mod b in Z, u>=0
875 */
876 number nlIntMod (number a, number b, const coeffs r)
877 {
878  if (b==INT_TO_SR(0))
879  {
880  WerrorS(nDivBy0);
881  return INT_TO_SR(0);
882  }
883  if (a==INT_TO_SR(0))
884  return INT_TO_SR(0);
885  number u;
886  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
887  {
888  LONG aa=SR_TO_INT(a);
889  LONG bb=SR_TO_INT(b);
890  LONG c=aa % bb;
891  if (c<0) c+=ABS(bb);
892  return INT_TO_SR(c);
893  }
894  if (SR_HDL(a) & SR_INT)
895  {
896  LONG ai=SR_TO_INT(a);
897  mpz_t aa;
898  mpz_init_set_si(aa, ai);
899  u=ALLOC_RNUMBER();
900 #if defined(LDEBUG)
901  u->debug=123456;
902 #endif
903  u->s = 3;
904  mpz_init(u->z);
905  mpz_mod(u->z, aa, b->z);
906  mpz_clear(aa);
907  u=nlShort3(u);
908  nlTest(u,r);
909  return u;
910  }
911  number bb=NULL;
912  if (SR_HDL(b) & SR_INT)
913  {
914  bb=nlRInit(SR_TO_INT(b));
915  b=bb;
916  }
917  u=ALLOC_RNUMBER();
918 #if defined(LDEBUG)
919  u->debug=123456;
920 #endif
921  mpz_init(u->z);
922  u->s = 3;
923  mpz_mod(u->z, a->z, b->z);
924  if (bb!=NULL)
925  {
926  mpz_clear(bb->z);
927 #if defined(LDEBUG)
928  bb->debug=654324;
929 #endif
930  FREE_RNUMBER(bb);
931  }
932  u=nlShort3(u);
933  nlTest(u,r);
934  return u;
935 }
936 
937 BOOLEAN nlDivBy (number a,number b, const coeffs)
938 {
939  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
940  {
941  return ((SR_TO_INT(a) % SR_TO_INT(b))==0);
942  }
943  if (SR_HDL(b) & SR_INT)
944  {
945  return (mpz_divisible_ui_p(a->z,SR_TO_INT(b))!=0);
946  }
947  if (SR_HDL(a) & SR_INT) return FALSE;
948  return mpz_divisible_p(a->z, b->z) != 0;
949 }
950 
951 int nlDivComp(number a, number b, const coeffs r)
952 {
953  if (nlDivBy(a, b, r))
954  {
955  if (nlDivBy(b, a, r)) return 2;
956  return -1;
957  }
958  if (nlDivBy(b, a, r)) return 1;
959  return 0;
960 }
961 
962 number nlGetUnit (number n, const coeffs cf)
963 {
964  if (nlGreaterZero(n,cf)) return INT_TO_SR(1);
965  else return INT_TO_SR(-1);
966 }
967 
968 coeffs nlQuot1(number c, const coeffs r)
969 {
970  long ch = r->cfInt(c, r);
971  int p=IsPrime(ch);
972  coeffs rr=NULL;
973  if (((long)p)==ch)
974  {
975  rr = nInitChar(n_Zp,(void*)ch);
976  }
977  #ifdef HAVE_RINGS
978  else
979  {
980  mpz_t dummy;
981  mpz_init_set_ui(dummy, ch);
982  ZnmInfo info;
983  info.base = dummy;
984  info.exp = (unsigned long) 1;
985  rr = nInitChar(n_Zn, (void*)&info);
986  mpz_clear(dummy);
987  }
988  #endif
989  return(rr);
990 }
991 
992 
993 BOOLEAN nlIsUnit (number a, const coeffs)
994 {
995  return ((SR_HDL(a) & SR_INT) && (ABS(SR_TO_INT(a))==1));
996 }
997 
998 
999 /*2
1000 * u := a / b
1001 */
1002 number nlDiv (number a, number b, const coeffs r)
1003 {
1004  if (nlIsZero(b,r))
1005  {
1006  WerrorS(nDivBy0);
1007  return INT_TO_SR(0);
1008  }
1009  number u;
1010 // ---------- short / short ------------------------------------
1011  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1012  {
1013  LONG i=SR_TO_INT(a);
1014  LONG j=SR_TO_INT(b);
1015  if (j==1L) return a;
1016  if ((i==-POW_2_28) && (j== -1L))
1017  {
1018  return nlRInit(POW_2_28);
1019  }
1020  LONG r=i%j;
1021  if (r==0)
1022  {
1023  return INT_TO_SR(i/j);
1024  }
1025  u=ALLOC_RNUMBER();
1026  u->s=0;
1027  #if defined(LDEBUG)
1028  u->debug=123456;
1029  #endif
1030  mpz_init_set_si(u->z,(long)i);
1031  mpz_init_set_si(u->n,(long)j);
1032  }
1033  else
1034  {
1035  u=ALLOC_RNUMBER();
1036  u->s=0;
1037  #if defined(LDEBUG)
1038  u->debug=123456;
1039  #endif
1040  mpz_init(u->z);
1041 // ---------- short / long ------------------------------------
1042  if (SR_HDL(a) & SR_INT)
1043  {
1044  // short a / (z/n) -> (a*n)/z
1045  if (b->s<2)
1046  {
1047  mpz_mul_si(u->z,b->n,SR_TO_INT(a));
1048  }
1049  else
1050  // short a / long z -> a/z
1051  {
1052  mpz_set_si(u->z,SR_TO_INT(a));
1053  }
1054  if (mpz_cmp(u->z,b->z)==0)
1055  {
1056  mpz_clear(u->z);
1057  FREE_RNUMBER(u);
1058  return INT_TO_SR(1);
1059  }
1060  mpz_init_set(u->n,b->z);
1061  }
1062 // ---------- long / short ------------------------------------
1063  else if (SR_HDL(b) & SR_INT)
1064  {
1065  mpz_set(u->z,a->z);
1066  // (z/n) / b -> z/(n*b)
1067  if (a->s<2)
1068  {
1069  mpz_init_set(u->n,a->n);
1070  if (((long)b)>0L)
1071  mpz_mul_ui(u->n,u->n,SR_TO_INT(b));
1072  else
1073  {
1074  mpz_mul_ui(u->n,u->n,-SR_TO_INT(b));
1075  mpz_neg(u->z,u->z);
1076  }
1077  }
1078  else
1079  // long z / short b -> z/b
1080  {
1081  //mpz_set(u->z,a->z);
1082  mpz_init_set_si(u->n,SR_TO_INT(b));
1083  }
1084  }
1085 // ---------- long / long ------------------------------------
1086  else
1087  {
1088  mpz_set(u->z,a->z);
1089  mpz_init_set(u->n,b->z);
1090  if (a->s<2) mpz_mul(u->n,u->n,a->n);
1091  if (b->s<2) mpz_mul(u->z,u->z,b->n);
1092  }
1093  }
1094  if (mpz_isNeg(u->n))
1095  {
1096  mpz_neg(u->z,u->z);
1097  mpz_neg(u->n,u->n);
1098  }
1099  if (mpz_cmp_si(u->n,1L)==0)
1100  {
1101  mpz_clear(u->n);
1102  u->s=3;
1103  u=nlShort3(u);
1104  }
1105  nlTest(u, r);
1106  return u;
1107 }
1108 
1109 /*2
1110 * u:= x ^ exp
1111 */
1112 void nlPower (number x,int exp,number * u, const coeffs r)
1113 {
1114  *u = INT_TO_SR(0); // 0^e, e!=0
1115  if (exp==0)
1116  *u= INT_TO_SR(1);
1117  else if (!nlIsZero(x,r))
1118  {
1119  nlTest(x, r);
1120  number aa=NULL;
1121  if (SR_HDL(x) & SR_INT)
1122  {
1123  aa=nlRInit(SR_TO_INT(x));
1124  x=aa;
1125  }
1126  else if (x->s==0)
1127  nlNormalize(x,r);
1128  *u=ALLOC_RNUMBER();
1129 #if defined(LDEBUG)
1130  (*u)->debug=123456;
1131 #endif
1132  mpz_init((*u)->z);
1133  mpz_pow_ui((*u)->z,x->z,(unsigned long)exp);
1134  if (x->s<2)
1135  {
1136  if (mpz_cmp_si(x->n,1L)==0)
1137  {
1138  x->s=3;
1139  mpz_clear(x->n);
1140  }
1141  else
1142  {
1143  mpz_init((*u)->n);
1144  mpz_pow_ui((*u)->n,x->n,(unsigned long)exp);
1145  }
1146  }
1147  (*u)->s = x->s;
1148  if ((*u)->s==3) *u=nlShort3(*u);
1149  if (aa!=NULL)
1150  {
1151  mpz_clear(aa->z);
1152  FREE_RNUMBER(aa);
1153  }
1154  }
1155 #ifdef LDEBUG
1156  if (exp<0) Print("nlPower: neg. exp. %d\n",exp);
1157  nlTest(*u, r);
1158 #endif
1159 }
1160 
1161 
1162 /*2
1163 * za >= 0 ?
1164 */
1165 BOOLEAN nlGreaterZero (number a, const coeffs r)
1166 {
1167  nlTest(a, r);
1168  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1L /* represents number(0) */;
1169  return (!mpz_isNeg(a->z));
1170 }
1171 
1172 /*2
1173 * a > b ?
1174 */
1175 BOOLEAN nlGreater (number a, number b, const coeffs r)
1176 {
1177  nlTest(a, r);
1178  nlTest(b, r);
1179  number re;
1180  BOOLEAN rr;
1181  re=nlSub(a,b,r);
1182  rr=(!nlIsZero(re,r)) && (nlGreaterZero(re,r));
1183  nlDelete(&re,r);
1184  return rr;
1185 }
1186 
1187 /*2
1188 * a == -1 ?
1189 */
1190 BOOLEAN nlIsMOne (number a, const coeffs r)
1191 {
1192 #ifdef LDEBUG
1193  if (a==NULL) return FALSE;
1194  nlTest(a, r);
1195 #endif
1196  return (a==INT_TO_SR(-1L));
1197 }
1198 
1199 /*2
1200 * result =gcd(a,b)
1201 */
1202 number nlGcd(number a, number b, const coeffs r)
1203 {
1204  number result;
1205  nlTest(a, r);
1206  nlTest(b, r);
1207  //nlNormalize(a);
1208  //nlNormalize(b);
1209  if ((a==INT_TO_SR(1L))||(a==INT_TO_SR(-1L))
1210  || (b==INT_TO_SR(1L))||(b==INT_TO_SR(-1L)))
1211  return INT_TO_SR(1L);
1212  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1213  return nlCopy(b,r);
1214  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1215  return nlCopy(a,r);
1216  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1217  {
1218  long i=SR_TO_INT(a);
1219  long j=SR_TO_INT(b);
1220  if((i==0L)||(j==0L))
1221  return INT_TO_SR(1);
1222  long l;
1223  i=ABS(i);
1224  j=ABS(j);
1225  do
1226  {
1227  l=i%j;
1228  i=j;
1229  j=l;
1230  } while (l!=0L);
1231  if (i==POW_2_28)
1232  result=nlRInit(POW_2_28);
1233  else
1234  result=INT_TO_SR(i);
1235  nlTest(result,r);
1236  return result;
1237  }
1238  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1239  || ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1240  if (SR_HDL(a) & SR_INT)
1241  {
1242  LONG aa=ABS(SR_TO_INT(a));
1243  unsigned long t=mpz_gcd_ui(NULL,b->z,(long)aa);
1244  if (t==POW_2_28)
1245  result=nlRInit(POW_2_28);
1246  else
1247  result=INT_TO_SR(t);
1248  }
1249  else
1250  if (SR_HDL(b) & SR_INT)
1251  {
1252  LONG bb=ABS(SR_TO_INT(b));
1253  unsigned long t=mpz_gcd_ui(NULL,a->z,(long)bb);
1254  if (t==POW_2_28)
1255  result=nlRInit(POW_2_28);
1256  else
1257  result=INT_TO_SR(t);
1258  }
1259  else
1260  {
1261  result=ALLOC0_RNUMBER();
1262  result->s = 3;
1263  #ifdef LDEBUG
1264  result->debug=123456;
1265  #endif
1266  mpz_init(result->z);
1267  mpz_gcd(result->z,a->z,b->z);
1268  result=nlShort3(result);
1269  }
1270  nlTest(result, r);
1271  return result;
1272 }
1273 static int int_extgcd(int a, int b, int * u, int* x, int * v, int* y)
1274 {
1275  int q, r;
1276  if (a==0)
1277  {
1278  *u = 0;
1279  *v = 1;
1280  *x = -1;
1281  *y = 0;
1282  return b;
1283  }
1284  if (b==0)
1285  {
1286  *u = 1;
1287  *v = 0;
1288  *x = 0;
1289  *y = 1;
1290  return a;
1291  }
1292  *u=1;
1293  *v=0;
1294  *x=0;
1295  *y=1;
1296  do
1297  {
1298  q = a/b;
1299  r = a%b;
1300  assume (q*b+r == a);
1301  a = b;
1302  b = r;
1303 
1304  r = -(*v)*q+(*u);
1305  (*u) =(*v);
1306  (*v) = r;
1307 
1308  r = -(*y)*q+(*x);
1309  (*x) = (*y);
1310  (*y) = r;
1311  } while (b);
1312 
1313  return a;
1314 }
1315 
1316 //number nlGcd_dummy(number a, number b, const coeffs r)
1317 //{
1318 // extern char my_yylinebuf[80];
1319 // Print("nlGcd in >>%s<<\n",my_yylinebuf);
1320 // return nlGcd(a,b,r);;
1321 //}
1322 
1323 number nlShort1(number x) // assume x->s==0/1
1324 {
1325  assume(x->s<2);
1326  if (mpz_sgn1(x->z)==0)
1327  {
1328  _nlDelete_NoImm(&x);
1329  return INT_TO_SR(0);
1330  }
1331  if (x->s<2)
1332  {
1333  if (mpz_cmp(x->z,x->n)==0)
1334  {
1335  _nlDelete_NoImm(&x);
1336  return INT_TO_SR(1);
1337  }
1338  }
1339  return x;
1340 }
1341 /*2
1342 * simplify x
1343 */
1344 void nlNormalize (number &x, const coeffs r)
1345 {
1346  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1347  return;
1348  if (x->s==3)
1349  {
1350  x=nlShort3_noinline(x);
1351  nlTest(x,r);
1352  return;
1353  }
1354  else if (x->s==0)
1355  {
1356  if (mpz_cmp_si(x->n,1L)==0)
1357  {
1358  mpz_clear(x->n);
1359  x->s=3;
1360  x=nlShort3(x);
1361  }
1362  else
1363  {
1364  mpz_t gcd;
1365  mpz_init(gcd);
1366  mpz_gcd(gcd,x->z,x->n);
1367  x->s=1;
1368  if (mpz_cmp_si(gcd,1L)!=0)
1369  {
1370  mpz_divexact(x->z,x->z,gcd);
1371  mpz_divexact(x->n,x->n,gcd);
1372  if (mpz_cmp_si(x->n,1L)==0)
1373  {
1374  mpz_clear(x->n);
1375  x->s=3;
1376  x=nlShort3_noinline(x);
1377  }
1378  }
1379  mpz_clear(gcd);
1380  }
1381  }
1382  nlTest(x, r);
1383 }
1384 
1385 /*2
1386 * returns in result->z the lcm(a->z,b->n)
1387 */
1388 number nlNormalizeHelper(number a, number b, const coeffs r)
1389 {
1390  number result;
1391  nlTest(a, r);
1392  nlTest(b, r);
1393  if ((SR_HDL(b) & SR_INT)
1394  || (b->s==3))
1395  {
1396  // b is 1/(b->n) => b->n is 1 => result is a
1397  return nlCopy(a,r);
1398  }
1399  result=ALLOC_RNUMBER();
1400 #if defined(LDEBUG)
1401  result->debug=123456;
1402 #endif
1403  result->s=3;
1404  mpz_t gcd;
1405  mpz_init(gcd);
1406  mpz_init(result->z);
1407  if (SR_HDL(a) & SR_INT)
1408  mpz_gcd_ui(gcd,b->n,ABS(SR_TO_INT(a)));
1409  else
1410  mpz_gcd(gcd,a->z,b->n);
1411  if (mpz_cmp_si(gcd,1L)!=0)
1412  {
1413  mpz_t bt;
1414  mpz_init(bt);
1415  mpz_divexact(bt,b->n,gcd);
1416  if (SR_HDL(a) & SR_INT)
1417  mpz_mul_si(result->z,bt,SR_TO_INT(a));
1418  else
1419  mpz_mul(result->z,bt,a->z);
1420  mpz_clear(bt);
1421  }
1422  else
1423  if (SR_HDL(a) & SR_INT)
1424  mpz_mul_si(result->z,b->n,SR_TO_INT(a));
1425  else
1426  mpz_mul(result->z,b->n,a->z);
1427  mpz_clear(gcd);
1428  result=nlShort3(result);
1429  nlTest(result, r);
1430  return result;
1431 }
1432 
1433 // Map q \in QQ or ZZ \to Zp or an extension of it
1434 // src = Q or Z, dst = Zp (or an extension of Zp)
1435 number nlModP(number q, const coeffs /*Q*/, const coeffs Zp)
1436 {
1437  const int p = n_GetChar(Zp);
1438  assume( p > 0 );
1439 
1440  const long P = p;
1441  assume( P > 0 );
1442 
1443  // embedded long within q => only long numerator has to be converted
1444  // to int (modulo char.)
1445  if (SR_HDL(q) & SR_INT)
1446  {
1447  long i = SR_TO_INT(q);
1448  return n_Init( i, Zp );
1449  }
1450 
1451  const unsigned long PP = p;
1452 
1453  // numerator modulo char. should fit into int
1454  number z = n_Init( static_cast<long>(mpz_fdiv_ui(q->z, PP)), Zp );
1455 
1456  // denominator != 1?
1457  if (q->s!=3)
1458  {
1459  // denominator modulo char. should fit into int
1460  number n = n_Init( static_cast<long>(mpz_fdiv_ui(q->n, PP)), Zp );
1461 
1462  number res = n_Div( z, n, Zp );
1463 
1464  n_Delete(&z, Zp);
1465  n_Delete(&n, Zp);
1466 
1467  return res;
1468  }
1469 
1470  return z;
1471 }
1472 
1473 #ifdef HAVE_RINGS
1474 /*2
1475 * convert number i (from Q) to GMP and warn if denom != 1
1476 */
1477 void nlGMP(number &i, mpz_t n, const coeffs r)
1478 {
1479  // Hier brauche ich einfach die GMP Zahl
1480  nlTest(i, r);
1481  nlNormalize(i, r);
1482  if (SR_HDL(i) & SR_INT)
1483  {
1484  mpz_set_si(n, SR_TO_INT(i));
1485  return;
1486  }
1487  if (i->s!=3)
1488  {
1489  WarnS("Omitted denominator during coefficient mapping !");
1490  }
1491  mpz_set(n, i->z);
1492 }
1493 #endif
1494 
1495 /*2
1496 * acces to denominator, other 1 for integers
1497 */
1498 number nlGetDenom(number &n, const coeffs r)
1499 {
1500  if (!(SR_HDL(n) & SR_INT))
1501  {
1502  if (n->s==0)
1503  {
1504  nlNormalize(n,r);
1505  }
1506  if (!(SR_HDL(n) & SR_INT))
1507  {
1508  if (n->s!=3)
1509  {
1510  number u=ALLOC_RNUMBER();
1511  u->s=3;
1512 #if defined(LDEBUG)
1513  u->debug=123456;
1514 #endif
1515  mpz_init_set(u->z,n->n);
1516  u=nlShort3_noinline(u);
1517  return u;
1518  }
1519  }
1520  }
1521  return INT_TO_SR(1);
1522 }
1523 
1524 /*2
1525 * acces to Nominator, nlCopy(n) for integers
1526 */
1527 number nlGetNumerator(number &n, const coeffs r)
1528 {
1529  if (!(SR_HDL(n) & SR_INT))
1530  {
1531  if (n->s==0)
1532  {
1533  nlNormalize(n,r);
1534  }
1535  if (!(SR_HDL(n) & SR_INT))
1536  {
1537  number u=ALLOC_RNUMBER();
1538 #if defined(LDEBUG)
1539  u->debug=123456;
1540 #endif
1541  u->s=3;
1542  mpz_init_set(u->z,n->z);
1543  if (n->s!=3)
1544  {
1545  u=nlShort3_noinline(u);
1546  }
1547  return u;
1548  }
1549  }
1550  return n; // imm. int
1551 }
1552 
1553 /***************************************************************
1554  *
1555  * routines which are needed by Inline(d) routines
1556  *
1557  *******************************************************************/
1559 {
1560  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1561 // long - short
1562  BOOLEAN bo;
1563  if (SR_HDL(b) & SR_INT)
1564  {
1565  if (a->s!=0) return FALSE;
1566  number n=b; b=a; a=n;
1567  }
1568 // short - long
1569  if (SR_HDL(a) & SR_INT)
1570  {
1571  if (b->s!=0)
1572  return FALSE;
1573  if ((((long)a) > 0L) && (mpz_isNeg(b->z)))
1574  return FALSE;
1575  if ((((long)a) < 0L) && (!mpz_isNeg(b->z)))
1576  return FALSE;
1577  mpz_t bb;
1578  mpz_init(bb);
1579  mpz_mul_si(bb,b->n,(long)SR_TO_INT(a));
1580  bo=(mpz_cmp(bb,b->z)==0);
1581  mpz_clear(bb);
1582  return bo;
1583  }
1584 // long - long
1585  if (((a->s==1) && (b->s==3))
1586  || ((b->s==1) && (a->s==3)))
1587  return FALSE;
1588  if (mpz_isNeg(a->z)&&(!mpz_isNeg(b->z)))
1589  return FALSE;
1590  if (mpz_isNeg(b->z)&&(!mpz_isNeg(a->z)))
1591  return FALSE;
1592  mpz_t aa;
1593  mpz_t bb;
1594  mpz_init_set(aa,a->z);
1595  mpz_init_set(bb,b->z);
1596  if (a->s<2) mpz_mul(bb,bb,a->n);
1597  if (b->s<2) mpz_mul(aa,aa,b->n);
1598  bo=(mpz_cmp(aa,bb)==0);
1599  mpz_clear(aa);
1600  mpz_clear(bb);
1601  return bo;
1602 }
1603 
1604 // copy not immediate number a
1605 number _nlCopy_NoImm(number a)
1606 {
1607  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
1608  //nlTest(a, r);
1609  number b=ALLOC_RNUMBER();
1610 #if defined(LDEBUG)
1611  b->debug=123456;
1612 #endif
1613  switch (a->s)
1614  {
1615  case 0:
1616  case 1:
1617  mpz_init_set(b->n,a->n);
1618  case 3:
1619  mpz_init_set(b->z,a->z);
1620  break;
1621  }
1622  b->s = a->s;
1623  return b;
1624 }
1625 
1626 void _nlDelete_NoImm(number *a)
1627 {
1628  {
1629  switch ((*a)->s)
1630  {
1631  case 0:
1632  case 1:
1633  mpz_clear((*a)->n);
1634  case 3:
1635  mpz_clear((*a)->z);
1636 #ifdef LDEBUG
1637  (*a)->s=2;
1638 #endif
1639  }
1640  #ifdef LDEBUG
1641  memset(*a,0,sizeof(**a));
1642  #endif
1643  FREE_RNUMBER(*a); // omFreeBin((void *) *a, rnumber_bin);
1644  }
1645 }
1646 
1647 number _nlNeg_NoImm(number a)
1648 {
1649  {
1650  mpz_neg(a->z,a->z);
1651  if (a->s==3)
1652  {
1653  a=nlShort3(a);
1654  }
1655  }
1656  return a;
1657 }
1658 
1659 // conditio to use nlNormalize_Gcd in intermediate computations:
1660 #define GCD_NORM_COND(OLD,NEW) (mpz_size1(NEW->z)>mpz_size1(OLD->z))
1661 
1662 static void nlNormalize_Gcd(number &x)
1663 {
1664  mpz_t gcd;
1665  mpz_init(gcd);
1666  mpz_gcd(gcd,x->z,x->n);
1667  x->s=1;
1668  if (mpz_cmp_si(gcd,1L)!=0)
1669  {
1670  mpz_divexact(x->z,x->z,gcd);
1671  mpz_divexact(x->n,x->n,gcd);
1672  if (mpz_cmp_si(x->n,1L)==0)
1673  {
1674  mpz_clear(x->n);
1675  x->s=3;
1676  x=nlShort3_noinline(x);
1677  }
1678  }
1679  mpz_clear(gcd);
1680 }
1681 
1682 number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
1683 {
1684  number u=ALLOC_RNUMBER();
1685 #if defined(LDEBUG)
1686  u->debug=123456;
1687 #endif
1688  mpz_init(u->z);
1689  if (SR_HDL(b) & SR_INT)
1690  {
1691  number x=a;
1692  a=b;
1693  b=x;
1694  }
1695  if (SR_HDL(a) & SR_INT)
1696  {
1697  switch (b->s)
1698  {
1699  case 0:
1700  case 1:/* a:short, b:1 */
1701  {
1702  mpz_t x;
1703  mpz_init(x);
1704  mpz_mul_si(x,b->n,SR_TO_INT(a));
1705  mpz_add(u->z,b->z,x);
1706  mpz_clear(x);
1707  if (mpz_sgn1(u->z)==0)
1708  {
1709  mpz_clear(u->z);
1710  FREE_RNUMBER(u);
1711  return INT_TO_SR(0);
1712  }
1713  if (mpz_cmp(u->z,b->n)==0)
1714  {
1715  mpz_clear(u->z);
1716  FREE_RNUMBER(u);
1717  return INT_TO_SR(1);
1718  }
1719  mpz_init_set(u->n,b->n);
1720  u->s = 0;
1721  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
1722  break;
1723  }
1724  case 3:
1725  {
1726  if (((long)a)>0L)
1727  mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1728  else
1729  mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1730  u->s = 3;
1731  u=nlShort3(u);
1732  break;
1733  }
1734  }
1735  }
1736  else
1737  {
1738  switch (a->s)
1739  {
1740  case 0:
1741  case 1:
1742  {
1743  switch(b->s)
1744  {
1745  case 0:
1746  case 1:
1747  {
1748  mpz_t x;
1749  mpz_init(x);
1750 
1751  mpz_mul(x,b->z,a->n);
1752  mpz_mul(u->z,a->z,b->n);
1753  mpz_add(u->z,u->z,x);
1754  mpz_clear(x);
1755 
1756  if (mpz_sgn1(u->z)==0)
1757  {
1758  mpz_clear(u->z);
1759  FREE_RNUMBER(u);
1760  return INT_TO_SR(0);
1761  }
1762  mpz_init(u->n);
1763  mpz_mul(u->n,a->n,b->n);
1764  if (mpz_cmp(u->z,u->n)==0)
1765  {
1766  mpz_clear(u->z);
1767  mpz_clear(u->n);
1768  FREE_RNUMBER(u);
1769  return INT_TO_SR(1);
1770  }
1771  u->s = 0;
1772  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
1773  break;
1774  }
1775  case 3: /* a:1 b:3 */
1776  {
1777  mpz_mul(u->z,b->z,a->n);
1778  mpz_add(u->z,u->z,a->z);
1779  if (mpz_sgn1(u->z)==0)
1780  {
1781  mpz_clear(u->z);
1782  FREE_RNUMBER(u);
1783  return INT_TO_SR(0);
1784  }
1785  if (mpz_cmp(u->z,a->n)==0)
1786  {
1787  mpz_clear(u->z);
1788  FREE_RNUMBER(u);
1789  return INT_TO_SR(1);
1790  }
1791  mpz_init_set(u->n,a->n);
1792  u->s = 0;
1793  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
1794  break;
1795  }
1796  } /*switch (b->s) */
1797  break;
1798  }
1799  case 3:
1800  {
1801  switch(b->s)
1802  {
1803  case 0:
1804  case 1:/* a:3, b:1 */
1805  {
1806  mpz_mul(u->z,a->z,b->n);
1807  mpz_add(u->z,u->z,b->z);
1808  if (mpz_sgn1(u->z)==0)
1809  {
1810  mpz_clear(u->z);
1811  FREE_RNUMBER(u);
1812  return INT_TO_SR(0);
1813  }
1814  if (mpz_cmp(u->z,b->n)==0)
1815  {
1816  mpz_clear(u->z);
1817  FREE_RNUMBER(u);
1818  return INT_TO_SR(1);
1819  }
1820  mpz_init_set(u->n,b->n);
1821  u->s = 0;
1822  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
1823  break;
1824  }
1825  case 3:
1826  {
1827  mpz_add(u->z,a->z,b->z);
1828  u->s = 3;
1829  u=nlShort3(u);
1830  break;
1831  }
1832  }
1833  break;
1834  }
1835  }
1836  }
1837  return u;
1838 }
1839 
1840 void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
1841 {
1842  if (SR_HDL(b) & SR_INT)
1843  {
1844  switch (a->s)
1845  {
1846  case 0:
1847  case 1:/* b:short, a:1 */
1848  {
1849  mpz_t x;
1850  mpz_init(x);
1851  mpz_mul_si(x,a->n,SR_TO_INT(b));
1852  mpz_add(a->z,a->z,x);
1853  mpz_clear(x);
1854  nlNormalize_Gcd(a);
1855  break;
1856  }
1857  case 3:
1858  {
1859  if (((long)b)>0L)
1860  mpz_add_ui(a->z,a->z,SR_TO_INT(b));
1861  else
1862  mpz_sub_ui(a->z,a->z,-SR_TO_INT(b));
1863  a->s = 3;
1864  a=nlShort3_noinline(a);
1865  break;
1866  }
1867  }
1868  return;
1869  }
1870  else if (SR_HDL(a) & SR_INT)
1871  {
1872  number u=ALLOC_RNUMBER();
1873  #if defined(LDEBUG)
1874  u->debug=123456;
1875  #endif
1876  mpz_init(u->z);
1877  switch (b->s)
1878  {
1879  case 0:
1880  case 1:/* a:short, b:1 */
1881  {
1882  mpz_t x;
1883  mpz_init(x);
1884 
1885  mpz_mul_si(x,b->n,SR_TO_INT(a));
1886  mpz_add(u->z,b->z,x);
1887  mpz_clear(x);
1888  // result cannot be 0, if coeffs are normalized
1889  mpz_init_set(u->n,b->n);
1890  u->s=0;
1891  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
1892  else { u=nlShort1(u); }
1893  break;
1894  }
1895  case 3:
1896  {
1897  if (((long)a)>0L)
1898  mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1899  else
1900  mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1901  // result cannot be 0, if coeffs are normalized
1902  u->s = 3;
1903  u=nlShort3_noinline(u);
1904  break;
1905  }
1906  }
1907  a=u;
1908  }
1909  else
1910  {
1911  switch (a->s)
1912  {
1913  case 0:
1914  case 1:
1915  {
1916  switch(b->s)
1917  {
1918  case 0:
1919  case 1: /* a:1 b:1 */
1920  {
1921  mpz_t x;
1922  mpz_t y;
1923  mpz_init(x);
1924  mpz_init(y);
1925  mpz_mul(x,b->z,a->n);
1926  mpz_mul(y,a->z,b->n);
1927  mpz_add(a->z,x,y);
1928  mpz_clear(x);
1929  mpz_clear(y);
1930  mpz_mul(a->n,a->n,b->n);
1931  a->s=0;
1932  if (GCD_NORM_COND(b,a)) { nlNormalize_Gcd(a); }
1933  else { a=nlShort1(a);}
1934  break;
1935  }
1936  case 3: /* a:1 b:3 */
1937  {
1938  mpz_t x;
1939  mpz_init(x);
1940  mpz_mul(x,b->z,a->n);
1941  mpz_add(a->z,a->z,x);
1942  mpz_clear(x);
1943  a->s=0;
1944  if (GCD_NORM_COND(b,a)) { nlNormalize_Gcd(a); }
1945  else { a=nlShort1(a);}
1946  break;
1947  }
1948  } /*switch (b->s) */
1949  break;
1950  }
1951  case 3:
1952  {
1953  switch(b->s)
1954  {
1955  case 0:
1956  case 1:/* a:3, b:1 */
1957  {
1958  mpz_t x;
1959  mpz_init(x);
1960  mpz_mul(x,a->z,b->n);
1961  mpz_add(a->z,b->z,x);
1962  mpz_clear(x);
1963  mpz_init_set(a->n,b->n);
1964  a->s=0;
1965  if (GCD_NORM_COND(b,a)) { nlNormalize_Gcd(a); }
1966  else { a=nlShort1(a);}
1967  break;
1968  }
1969  case 3:
1970  {
1971  mpz_add(a->z,a->z,b->z);
1972  a->s = 3;
1973  a=nlShort3_noinline(a);
1974  break;
1975  }
1976  }
1977  break;
1978  }
1979  }
1980  }
1981 }
1982 
1983 number _nlSub_aNoImm_OR_bNoImm(number a, number b)
1984 {
1985  number u=ALLOC_RNUMBER();
1986 #if defined(LDEBUG)
1987  u->debug=123456;
1988 #endif
1989  mpz_init(u->z);
1990  if (SR_HDL(a) & SR_INT)
1991  {
1992  switch (b->s)
1993  {
1994  case 0:
1995  case 1:/* a:short, b:1 */
1996  {
1997  mpz_t x;
1998  mpz_init(x);
1999  mpz_mul_si(x,b->n,SR_TO_INT(a));
2000  mpz_sub(u->z,x,b->z);
2001  mpz_clear(x);
2002  if (mpz_sgn1(u->z)==0)
2003  {
2004  mpz_clear(u->z);
2005  FREE_RNUMBER(u);
2006  return INT_TO_SR(0);
2007  }
2008  if (mpz_cmp(u->z,b->n)==0)
2009  {
2010  mpz_clear(u->z);
2011  FREE_RNUMBER(u);
2012  return INT_TO_SR(1);
2013  }
2014  mpz_init_set(u->n,b->n);
2015  u->s=0;
2016  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
2017  break;
2018  }
2019  case 3:
2020  {
2021  if (((long)a)>0L)
2022  {
2023  mpz_sub_ui(u->z,b->z,SR_TO_INT(a));
2024  mpz_neg(u->z,u->z);
2025  }
2026  else
2027  {
2028  mpz_add_ui(u->z,b->z,-SR_TO_INT(a));
2029  mpz_neg(u->z,u->z);
2030  }
2031  u->s = 3;
2032  u=nlShort3(u);
2033  break;
2034  }
2035  }
2036  }
2037  else if (SR_HDL(b) & SR_INT)
2038  {
2039  switch (a->s)
2040  {
2041  case 0:
2042  case 1:/* b:short, a:1 */
2043  {
2044  mpz_t x;
2045  mpz_init(x);
2046  mpz_mul_si(x,a->n,SR_TO_INT(b));
2047  mpz_sub(u->z,a->z,x);
2048  mpz_clear(x);
2049  if (mpz_sgn1(u->z)==0)
2050  {
2051  mpz_clear(u->z);
2052  FREE_RNUMBER(u);
2053  return INT_TO_SR(0);
2054  }
2055  if (mpz_cmp(u->z,a->n)==0)
2056  {
2057  mpz_clear(u->z);
2058  FREE_RNUMBER(u);
2059  return INT_TO_SR(1);
2060  }
2061  mpz_init_set(u->n,a->n);
2062  u->s=0;
2063  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
2064  break;
2065  }
2066  case 3:
2067  {
2068  if (((long)b)>0L)
2069  {
2070  mpz_sub_ui(u->z,a->z,SR_TO_INT(b));
2071  }
2072  else
2073  {
2074  mpz_add_ui(u->z,a->z,-SR_TO_INT(b));
2075  }
2076  u->s = 3;
2077  u=nlShort3(u);
2078  break;
2079  }
2080  }
2081  }
2082  else
2083  {
2084  switch (a->s)
2085  {
2086  case 0:
2087  case 1:
2088  {
2089  switch(b->s)
2090  {
2091  case 0:
2092  case 1:
2093  {
2094  mpz_t x;
2095  mpz_t y;
2096  mpz_init(x);
2097  mpz_init(y);
2098  mpz_mul(x,b->z,a->n);
2099  mpz_mul(y,a->z,b->n);
2100  mpz_sub(u->z,y,x);
2101  mpz_clear(x);
2102  mpz_clear(y);
2103  if (mpz_sgn1(u->z)==0)
2104  {
2105  mpz_clear(u->z);
2106  FREE_RNUMBER(u);
2107  return INT_TO_SR(0);
2108  }
2109  mpz_init(u->n);
2110  mpz_mul(u->n,a->n,b->n);
2111  if (mpz_cmp(u->z,u->n)==0)
2112  {
2113  mpz_clear(u->z);
2114  mpz_clear(u->n);
2115  FREE_RNUMBER(u);
2116  return INT_TO_SR(1);
2117  }
2118  u->s=0;
2119  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
2120  break;
2121  }
2122  case 3: /* a:1, b:3 */
2123  {
2124  mpz_t x;
2125  mpz_init(x);
2126  mpz_mul(x,b->z,a->n);
2127  mpz_sub(u->z,a->z,x);
2128  mpz_clear(x);
2129  if (mpz_sgn1(u->z)==0)
2130  {
2131  mpz_clear(u->z);
2132  FREE_RNUMBER(u);
2133  return INT_TO_SR(0);
2134  }
2135  if (mpz_cmp(u->z,a->n)==0)
2136  {
2137  mpz_clear(u->z);
2138  FREE_RNUMBER(u);
2139  return INT_TO_SR(1);
2140  }
2141  mpz_init_set(u->n,a->n);
2142  u->s=0;
2143  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
2144  break;
2145  }
2146  }
2147  break;
2148  }
2149  case 3:
2150  {
2151  switch(b->s)
2152  {
2153  case 0:
2154  case 1: /* a:3, b:1 */
2155  {
2156  mpz_t x;
2157  mpz_init(x);
2158  mpz_mul(x,a->z,b->n);
2159  mpz_sub(u->z,x,b->z);
2160  mpz_clear(x);
2161  if (mpz_sgn1(u->z)==0)
2162  {
2163  mpz_clear(u->z);
2164  FREE_RNUMBER(u);
2165  return INT_TO_SR(0);
2166  }
2167  if (mpz_cmp(u->z,b->n)==0)
2168  {
2169  mpz_clear(u->z);
2170  FREE_RNUMBER(u);
2171  return INT_TO_SR(1);
2172  }
2173  mpz_init_set(u->n,b->n);
2174  u->s=0;
2175  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
2176  break;
2177  }
2178  case 3: /* a:3 , b:3 */
2179  {
2180  mpz_sub(u->z,a->z,b->z);
2181  u->s = 3;
2182  u=nlShort3(u);
2183  break;
2184  }
2185  }
2186  break;
2187  }
2188  }
2189  }
2190  return u;
2191 }
2192 
2193 // a and b are intermediate, but a*b not
2194 number _nlMult_aImm_bImm_rNoImm(number a, number b)
2195 {
2196  number u=ALLOC_RNUMBER();
2197 #if defined(LDEBUG)
2198  u->debug=123456;
2199 #endif
2200  u->s=3;
2201  mpz_init_set_si(u->z,SR_TO_INT(a));
2202  mpz_mul_si(u->z,u->z,SR_TO_INT(b));
2203  return u;
2204 }
2205 
2206 // a or b are not immediate
2207 number _nlMult_aNoImm_OR_bNoImm(number a, number b)
2208 {
2209  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
2210  number u=ALLOC_RNUMBER();
2211 #if defined(LDEBUG)
2212  u->debug=123456;
2213 #endif
2214  mpz_init(u->z);
2215  if (SR_HDL(b) & SR_INT)
2216  {
2217  number x=a;
2218  a=b;
2219  b=x;
2220  }
2221  if (SR_HDL(a) & SR_INT)
2222  {
2223  u->s=b->s;
2224  if (u->s==1) u->s=0;
2225  if (((long)a)>0L)
2226  {
2227  mpz_mul_ui(u->z,b->z,(unsigned long)SR_TO_INT(a));
2228  }
2229  else
2230  {
2231  if (a==INT_TO_SR(-1))
2232  {
2233  mpz_set(u->z,b->z);
2234  mpz_neg(u->z,u->z);
2235  u->s=b->s;
2236  }
2237  else
2238  {
2239  mpz_mul_ui(u->z,b->z,(unsigned long)-SR_TO_INT(a));
2240  mpz_neg(u->z,u->z);
2241  }
2242  }
2243  if (u->s<2)
2244  {
2245  if (mpz_cmp(u->z,b->n)==0)
2246  {
2247  mpz_clear(u->z);
2248  FREE_RNUMBER(u);
2249  return INT_TO_SR(1);
2250  }
2251  mpz_init_set(u->n,b->n);
2252  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
2253  }
2254  else //u->s==3
2255  {
2256  u=nlShort3(u);
2257  }
2258  }
2259  else
2260  {
2261  mpz_mul(u->z,a->z,b->z);
2262  u->s = 0;
2263  if(a->s==3)
2264  {
2265  if(b->s==3)
2266  {
2267  u->s = 3;
2268  }
2269  else
2270  {
2271  if (mpz_cmp(u->z,b->n)==0)
2272  {
2273  mpz_clear(u->z);
2274  FREE_RNUMBER(u);
2275  return INT_TO_SR(1);
2276  }
2277  mpz_init_set(u->n,b->n);
2278  if (GCD_NORM_COND(b,u)) { nlNormalize_Gcd(u); }
2279  }
2280  }
2281  else
2282  {
2283  if(b->s==3)
2284  {
2285  if (mpz_cmp(u->z,a->n)==0)
2286  {
2287  mpz_clear(u->z);
2288  FREE_RNUMBER(u);
2289  return INT_TO_SR(1);
2290  }
2291  mpz_init_set(u->n,a->n);
2292  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
2293  }
2294  else
2295  {
2296  mpz_init(u->n);
2297  mpz_mul(u->n,a->n,b->n);
2298  if (mpz_cmp(u->z,u->n)==0)
2299  {
2300  mpz_clear(u->z);
2301  mpz_clear(u->n);
2302  FREE_RNUMBER(u);
2303  return INT_TO_SR(1);
2304  }
2305  if (GCD_NORM_COND(a,u)) { nlNormalize_Gcd(u); }
2306  }
2307  }
2308  }
2309  return u;
2310 }
2311 
2312 /*2
2313 * copy a to b for mapping
2314 */
2315 number nlCopyMap(number a, const coeffs /*src*/, const coeffs /*dst*/)
2316 {
2317  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2318  {
2319  return a;
2320  }
2321  return _nlCopy_NoImm(a);
2322 }
2323 
2324 nMapFunc nlSetMap(const coeffs src, const coeffs /*dst*/)
2325 {
2326  if (src->rep==n_rep_gap_rat) /*Q, coeffs_BIGINT */
2327  {
2328  return ndCopyMap;
2329  }
2330  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
2331  {
2332  return nlMapP;
2333  }
2334  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
2335  {
2336  return nlMapR;
2337  }
2338  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
2339  {
2340  return nlMapLongR; /* long R -> Q */
2341  }
2342 #ifdef HAVE_RINGS
2343  if (src->rep==n_rep_gmp) // nCoeff_is_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Zn(src))
2344  {
2345  return nlMapGMP;
2346  }
2347  if (src->rep==n_rep_gap_gmp)
2348  {
2349  return nlMapZ;
2350  }
2351  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
2352  {
2353  return nlMapMachineInt;
2354  }
2355 #endif
2356  return NULL;
2357 }
2358 /*2
2359 * z := i
2360 */
2361 number nlRInit (long i)
2362 {
2363  number z=ALLOC_RNUMBER();
2364 #if defined(LDEBUG)
2365  z->debug=123456;
2366 #endif
2367  mpz_init_set_si(z->z,i);
2368  z->s = 3;
2369  return z;
2370 }
2371 
2372 /*2
2373 * z := i/j
2374 */
2375 number nlInit2 (int i, int j, const coeffs r)
2376 {
2377  number z=ALLOC_RNUMBER();
2378 #if defined(LDEBUG)
2379  z->debug=123456;
2380 #endif
2381  mpz_init_set_si(z->z,(long)i);
2382  mpz_init_set_si(z->n,(long)j);
2383  z->s = 0;
2384  nlNormalize(z,r);
2385  return z;
2386 }
2387 
2388 number nlInit2gmp (mpz_t i, mpz_t j, const coeffs r)
2389 {
2390  number z=ALLOC_RNUMBER();
2391 #if defined(LDEBUG)
2392  z->debug=123456;
2393 #endif
2394  mpz_init_set(z->z,i);
2395  mpz_init_set(z->n,j);
2396  z->s = 0;
2397  nlNormalize(z,r);
2398  return z;
2399 }
2400 
2401 #else // DO_LINLINE
2402 
2403 // declare immedate routines
2404 number nlRInit (long i);
2405 BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2406 number _nlCopy_NoImm(number a);
2407 number _nlNeg_NoImm(number a);
2408 number _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2409 void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b);
2410 number _nlSub_aNoImm_OR_bNoImm(number a, number b);
2411 number _nlMult_aNoImm_OR_bNoImm(number a, number b);
2412 number _nlMult_aImm_bImm_rNoImm(number a, number b);
2413 
2414 #endif
2415 
2416 /***************************************************************
2417  *
2418  * Routines which might be inlined by p_Numbers.h
2419  *
2420  *******************************************************************/
2421 #if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2422 
2423 // routines which are always inlined/static
2424 
2425 /*2
2426 * a = b ?
2427 */
2428 LINLINE BOOLEAN nlEqual (number a, number b, const coeffs r)
2429 {
2430  nlTest(a, r);
2431  nlTest(b, r);
2432 // short - short
2433  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2434  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2435 }
2436 
2437 LINLINE number nlInit (long i, const coeffs r)
2438 {
2439  number n;
2440  #if MAX_NUM_SIZE == 60
2441  if (((i << 3) >> 3) == i) n=INT_TO_SR(i);
2442  else n=nlRInit(i);
2443  #else
2444  LONG ii=(LONG)i;
2445  if ( ((((long)ii)==i) && ((ii << 3) >> 3) == ii )) n=INT_TO_SR(ii);
2446  else n=nlRInit(i);
2447  #endif
2448  nlTest(n, r);
2449  return n;
2450 }
2451 
2452 /*2
2453 * a == 1 ?
2454 */
2455 LINLINE BOOLEAN nlIsOne (number a, const coeffs r)
2456 {
2457 #ifdef LDEBUG
2458  if (a==NULL) return FALSE;
2459  nlTest(a, r);
2460 #endif
2461  return (a==INT_TO_SR(1));
2462 }
2463 
2464 LINLINE BOOLEAN nlIsZero (number a, const coeffs)
2465 {
2466  #if 0
2467  if (a==INT_TO_SR(0)) return TRUE;
2468  if ((SR_HDL(a) & SR_INT)||(a==NULL)) return FALSE;
2469  if (mpz_cmp_si(a->z,0L)==0)
2470  {
2471  printf("gmp-0 in nlIsZero\n");
2472  dErrorBreak();
2473  return TRUE;
2474  }
2475  return FALSE;
2476  #else
2477  return (a==NULL)|| (a==INT_TO_SR(0));
2478  #endif
2479 }
2480 
2481 /*2
2482 * copy a to b
2483 */
2484 LINLINE number nlCopy(number a, const coeffs)
2485 {
2486  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2487  {
2488  return a;
2489  }
2490  return _nlCopy_NoImm(a);
2491 }
2492 
2493 
2494 /*2
2495 * delete a
2496 */
2497 LINLINE void nlDelete (number * a, const coeffs r)
2498 {
2499  if (*a!=NULL)
2500  {
2501  nlTest(*a, r);
2502  if ((SR_HDL(*a) & SR_INT)==0)
2503  {
2504  _nlDelete_NoImm(a);
2505  }
2506  *a=NULL;
2507  }
2508 }
2509 
2510 /*2
2511 * za:= - za
2512 */
2513 LINLINE number nlNeg (number a, const coeffs R)
2514 {
2515  nlTest(a, R);
2516  if(SR_HDL(a) &SR_INT)
2517  {
2518  LONG r=SR_TO_INT(a);
2519  if (r==(-(POW_2_28))) a=nlRInit(POW_2_28);
2520  else a=INT_TO_SR(-r);
2521  return a;
2522  }
2523  a = _nlNeg_NoImm(a);
2524  nlTest(a, R);
2525  return a;
2526 
2527 }
2528 
2529 /*2
2530 * u:= a + b
2531 */
2532 LINLINE number nlAdd (number a, number b, const coeffs R)
2533 {
2534  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2535  {
2536  LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2537  if ( ((r << 1) >> 1) == r )
2538  return (number)(long)r;
2539  else
2540  return nlRInit(SR_TO_INT(r));
2541  }
2542  number u = _nlAdd_aNoImm_OR_bNoImm(a, b);
2543  nlTest(u, R);
2544  return u;
2545 }
2546 
2547 number nlShort1(number a);
2548 number nlShort3_noinline(number x);
2549 
2550 LINLINE void nlInpAdd(number &a, number b, const coeffs r)
2551 {
2552  // a=a+b
2553  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2554  {
2555  LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2556  if ( ((r << 1) >> 1) == r )
2557  a=(number)(long)r;
2558  else
2559  a=nlRInit(SR_TO_INT(r));
2560  }
2561  else
2562  {
2564  nlTest(a,r);
2565  }
2566 }
2567 
2568 LINLINE number nlMult (number a, number b, const coeffs R)
2569 {
2570  nlTest(a, R);
2571  nlTest(b, R);
2572  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2573  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2574  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2575  {
2576  LONG r=(LONG)((unsigned LONG)(SR_HDL(a)-1L))*((unsigned LONG)(SR_HDL(b)>>1));
2577  if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1L))
2578  {
2579  number u=((number) ((r>>1)+SR_INT));
2580  if (((((LONG)SR_HDL(u))<<1)>>1)==SR_HDL(u)) return (u);
2581  return nlRInit(SR_HDL(u)>>2);
2582  }
2583  number u = _nlMult_aImm_bImm_rNoImm(a, b);
2584  nlTest(u, R);
2585  return u;
2586 
2587  }
2588  number u = _nlMult_aNoImm_OR_bNoImm(a, b);
2589  nlTest(u, R);
2590  return u;
2591 
2592 }
2593 
2594 
2595 /*2
2596 * u:= a - b
2597 */
2598 LINLINE number nlSub (number a, number b, const coeffs r)
2599 {
2600  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2601  {
2602  LONG r=SR_HDL(a)-SR_HDL(b)+1;
2603  if ( ((r << 1) >> 1) == r )
2604  {
2605  return (number)(long)r;
2606  }
2607  else
2608  return nlRInit(SR_TO_INT(r));
2609  }
2610  number u = _nlSub_aNoImm_OR_bNoImm(a, b);
2611  nlTest(u, r);
2612  return u;
2613 
2614 }
2615 
2616 LINLINE void nlInpMult(number &a, number b, const coeffs r)
2617 {
2618  number aa=a;
2619  if (((SR_HDL(b)|SR_HDL(aa))&SR_INT))
2620  {
2621  number n=nlMult(aa,b,r);
2622  nlDelete(&a,r);
2623  a=n;
2624  }
2625  else
2626  {
2627  mpz_mul(aa->z,a->z,b->z);
2628  if (aa->s==3)
2629  {
2630  if(b->s!=3)
2631  {
2632  mpz_init_set(a->n,b->n);
2633  a->s=0;
2634  }
2635  }
2636  else
2637  {
2638  if(b->s!=3)
2639  {
2640  mpz_mul(a->n,a->n,b->n);
2641  }
2642  a->s=0;
2643  }
2644  }
2645 }
2646 #endif // DO_LINLINE
2647 
2648 #ifndef P_NUMBERS_H
2649 
2650 static void nlMPZ(mpz_t m, number &n, const coeffs r)
2651 {
2652  nlTest(n, r);
2653  nlNormalize(n, r);
2654  if (SR_HDL(n) & SR_INT) mpz_init_set_si(m, SR_TO_INT(n)); /* n fits in an int */
2655  else mpz_init_set(m, (mpz_ptr)n->z);
2656 }
2657 
2658 
2659 static number nlInitMPZ(mpz_t m, const coeffs)
2660 {
2661  number z = ALLOC_RNUMBER();
2662  z->s = 3;
2663  #ifdef LDEBUG
2664  z->debug=123456;
2665  #endif
2666  mpz_init_set(z->z, m);
2667  z=nlShort3(z);
2668  return z;
2669 }
2670 
2671 number nlXExtGcd (number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
2672 {
2673  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2674  {
2675  int uu, vv, x, y;
2676  int g = int_extgcd(SR_TO_INT(a), SR_TO_INT(b), &uu, &vv, &x, &y);
2677  *s = INT_TO_SR(uu);
2678  *t = INT_TO_SR(vv);
2679  *u = INT_TO_SR(x);
2680  *v = INT_TO_SR(y);
2681  return INT_TO_SR(g);
2682  }
2683  else
2684  {
2685  mpz_t aa, bb;
2686  if (SR_HDL(a) & SR_INT)
2687  {
2688  mpz_init_set_si(aa, SR_TO_INT(a));
2689  }
2690  else
2691  {
2692  mpz_init_set(aa, a->z);
2693  }
2694  if (SR_HDL(b) & SR_INT)
2695  {
2696  mpz_init_set_si(bb, SR_TO_INT(b));
2697  }
2698  else
2699  {
2700  mpz_init_set(bb, b->z);
2701  }
2702  mpz_t erg; mpz_t bs; mpz_t bt;
2703  mpz_init(erg);
2704  mpz_init(bs);
2705  mpz_init(bt);
2706 
2707  mpz_gcdext(erg, bs, bt, aa, bb);
2708 
2709  mpz_div(aa, aa, erg);
2710  *u=nlInitMPZ(bb,r);
2711  *u=nlNeg(*u,r);
2712  *v=nlInitMPZ(aa,r);
2713 
2714  mpz_clear(aa);
2715  mpz_clear(bb);
2716 
2717  *s = nlInitMPZ(bs,r);
2718  *t = nlInitMPZ(bt,r);
2719  return nlInitMPZ(erg,r);
2720  }
2721 }
2722 
2723 number nlQuotRem (number a, number b, number * r, const coeffs R)
2724 {
2725  assume(SR_TO_INT(b)!=0);
2726  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2727  {
2728  if (r!=NULL)
2729  *r = INT_TO_SR(SR_TO_INT(a) % SR_TO_INT(b));
2730  return INT_TO_SR(SR_TO_INT(a)/SR_TO_INT(b));
2731  }
2732  else if (SR_HDL(a) & SR_INT)
2733  {
2734  // -2^xx / 2^xx
2735  if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
2736  {
2737  if (r!=NULL) *r=INT_TO_SR(0);
2738  return nlRInit(POW_2_28);
2739  }
2740  //a is small, b is not, so q=0, r=a
2741  if (r!=NULL)
2742  *r = a;
2743  return INT_TO_SR(0);
2744  }
2745  else if (SR_HDL(b) & SR_INT)
2746  {
2747  unsigned long rr;
2748  mpz_t qq;
2749  mpz_init(qq);
2750  mpz_t rrr;
2751  mpz_init(rrr);
2752  rr = mpz_divmod_ui(qq, rrr, a->z, (unsigned long)ABS(SR_TO_INT(b)));
2753  mpz_clear(rrr);
2754 
2755  if (r!=NULL)
2756  *r = INT_TO_SR(rr);
2757  if (SR_TO_INT(b)<0)
2758  {
2759  mpz_neg(qq, qq);
2760  }
2761  return nlInitMPZ(qq,R);
2762  }
2763  mpz_t qq,rr;
2764  mpz_init(qq);
2765  mpz_init(rr);
2766  mpz_divmod(qq, rr, a->z, b->z);
2767  if (r!=NULL)
2768  *r = nlInitMPZ(rr,R);
2769  else
2770  {
2771  mpz_clear(rr);
2772  }
2773  return nlInitMPZ(qq,R);
2774 }
2775 
2776 void nlInpGcd(number &a, number b, const coeffs r)
2777 {
2778  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2779  {
2780  number n=nlGcd(a,b,r);
2781  nlDelete(&a,r);
2782  a=n;
2783  }
2784  else
2785  {
2786  mpz_gcd(a->z,a->z,b->z);
2787  a=nlShort3_noinline(a);
2788  }
2789 }
2790 
2791 void nlInpIntDiv(number &a, number b, const coeffs r)
2792 {
2793  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2794  {
2795  number n=nlIntDiv(a,b, r);
2796  nlDelete(&a,r);
2797  a=n;
2798  }
2799  else
2800  {
2801  number rr=nlIntMod(a,b,r);
2802  if (SR_HDL(rr) & SR_INT) mpz_sub_ui(a->z,a->z,SR_TO_INT(rr));
2803  else mpz_sub(a->z,a->z,rr->z);
2804  mpz_divexact(a->z,a->z,b->z);
2805  a=nlShort3_noinline(a);
2806  }
2807 }
2808 
2809 number nlFarey(number nN, number nP, const coeffs r)
2810 {
2811  mpz_t A,B,C,D,E,N,P,tmp;
2812  if (SR_HDL(nP) & SR_INT) mpz_init_set_si(P,SR_TO_INT(nP));
2813  else mpz_init_set(P,nP->z);
2814  const mp_bitcnt_t bits=2*(mpz_size1(P)+1)*GMP_LIMB_BITS;
2815  mpz_init2(N,bits);
2816  if (SR_HDL(nN) & SR_INT) mpz_set_si(N,SR_TO_INT(nN));
2817  else mpz_set(N,nN->z);
2818  assume(!mpz_isNeg(P));
2819  if (mpz_isNeg(N)) mpz_add(N,N,P);
2820  mpz_init2(A,bits); mpz_set_ui(A,0L);
2821  mpz_init2(B,bits); mpz_set_ui(B,1L);
2822  mpz_init2(C,bits); mpz_set_ui(C,0L);
2823  mpz_init2(D,bits);
2824  mpz_init2(E,bits); mpz_set(E,P);
2825  mpz_init2(tmp,bits);
2826  number z=INT_TO_SR(0);
2827  while(mpz_sgn1(N)!=0)
2828  {
2829  mpz_mul(tmp,N,N);
2830  mpz_add(tmp,tmp,tmp);
2831  if (mpz_cmp(tmp,P)<0)
2832  {
2833  if (mpz_isNeg(B))
2834  {
2835  mpz_neg(B,B);
2836  mpz_neg(N,N);
2837  }
2838  // check for gcd(N,B)==1
2839  mpz_gcd(tmp,N,B);
2840  if (mpz_cmp_ui(tmp,1)==0)
2841  {
2842  // return N/B
2843  z=ALLOC_RNUMBER();
2844  #ifdef LDEBUG
2845  z->debug=123456;
2846  #endif
2847  mpz_init_set(z->z,N);
2848  mpz_init_set(z->n,B);
2849  z->s = 0;
2850  nlNormalize(z,r);
2851  }
2852  else
2853  {
2854  // return nN (the input) instead of "fail"
2855  z=nlCopy(nN,r);
2856  }
2857  break;
2858  }
2859  //mpz_mod(D,E,N);
2860  //mpz_div(tmp,E,N);
2861  mpz_divmod(tmp,D,E,N);
2862  mpz_mul(tmp,tmp,B);
2863  mpz_sub(C,A,tmp);
2864  mpz_set(E,N);
2865  mpz_set(N,D);
2866  mpz_set(A,B);
2867  mpz_set(B,C);
2868  }
2869  mpz_clear(tmp);
2870  mpz_clear(A);
2871  mpz_clear(B);
2872  mpz_clear(C);
2873  mpz_clear(D);
2874  mpz_clear(E);
2875  mpz_clear(N);
2876  mpz_clear(P);
2877  return z;
2878 }
2879 
2880 number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
2881 {
2882  mpz_ptr aa,bb;
2883  *s=ALLOC_RNUMBER();
2884  mpz_init((*s)->z); (*s)->s=3;
2885  (*t)=ALLOC_RNUMBER();
2886  mpz_init((*t)->z); (*t)->s=3;
2887  number g=ALLOC_RNUMBER();
2888  mpz_init(g->z); g->s=3;
2889  #ifdef LDEBUG
2890  g->debug=123456;
2891  (*s)->debug=123456;
2892  (*t)->debug=123456;
2893  #endif
2894  if (SR_HDL(a) & SR_INT)
2895  {
2896  aa=(mpz_ptr)omAlloc(sizeof(mpz_t));
2897  mpz_init_set_si(aa,SR_TO_INT(a));
2898  }
2899  else
2900  {
2901  aa=a->z;
2902  }
2903  if (SR_HDL(b) & SR_INT)
2904  {
2905  bb=(mpz_ptr)omAlloc(sizeof(mpz_t));
2906  mpz_init_set_si(bb,SR_TO_INT(b));
2907  }
2908  else
2909  {
2910  bb=b->z;
2911  }
2912  mpz_gcdext(g->z,(*s)->z,(*t)->z,aa,bb);
2913  g=nlShort3(g);
2914  (*s)=nlShort3((*s));
2915  (*t)=nlShort3((*t));
2916  if (SR_HDL(a) & SR_INT)
2917  {
2918  mpz_clear(aa);
2919  omFreeSize(aa, sizeof(mpz_t));
2920  }
2921  if (SR_HDL(b) & SR_INT)
2922  {
2923  mpz_clear(bb);
2924  omFreeSize(bb, sizeof(mpz_t));
2925  }
2926  return g;
2927 }
2928 
2929 void nlCoeffWrite (const coeffs r, BOOLEAN /*details*/)
2930 {
2931  if (r->is_field)
2932  PrintS("QQ");
2933  else
2934  PrintS("ZZ");
2935 }
2936 
2938 number nlChineseRemainderSym(number *x, number *q,int rl, BOOLEAN sym, CFArray &inv_cache,const coeffs CF)
2939 // elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
2940 {
2941  setCharacteristic( 0 ); // only in char 0
2942  Off(SW_RATIONAL);
2943  CFArray X(rl), Q(rl);
2944  int i;
2945  for(i=rl-1;i>=0;i--)
2946  {
2947  X[i]=CF->convSingNFactoryN(x[i],FALSE,CF); // may be larger MAX_INT
2948  Q[i]=CF->convSingNFactoryN(q[i],FALSE,CF); // may be larger MAX_INT
2949  }
2950  CanonicalForm xnew,qnew;
2951  if (n_SwitchChinRem)
2952  chineseRemainder(X,Q,xnew,qnew);
2953  else
2954  chineseRemainderCached(X,Q,xnew,qnew,inv_cache);
2955  number n=CF->convFactoryNSingN(xnew,CF);
2956  if (sym)
2957  {
2958  number p=CF->convFactoryNSingN(qnew,CF);
2959  number p2;
2960  if (getCoeffType(CF) == n_Q) p2=nlIntDiv(p,nlInit(2, CF),CF);
2961  else p2=CF->cfDiv(p,CF->cfInit(2, CF),CF);
2962  if (CF->cfGreater(n,p2,CF))
2963  {
2964  number n2=CF->cfSub(n,p,CF);
2965  CF->cfDelete(&n,CF);
2966  n=n2;
2967  }
2968  CF->cfDelete(&p2,CF);
2969  CF->cfDelete(&p,CF);
2970  }
2971  CF->cfNormalize(n,CF);
2972  return n;
2973 }
2974 #if 0
2975 number nlChineseRemainder(number *x, number *q,int rl, const coeffs C)
2976 {
2977  CFArray inv(rl);
2978  return nlChineseRemainderSym(x,q,rl,TRUE,inv,C);
2979 }
2980 #endif
2981 
2982 static void nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
2983 {
2984  assume(cf != NULL);
2985 
2986  numberCollectionEnumerator.Reset();
2987 
2988  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
2989  {
2990  c = nlInit(1, cf);
2991  return;
2992  }
2993 
2994  // all coeffs are given by integers!!!
2995 
2996  // part 1, find a small candidate for gcd
2997  number cand1,cand;
2998  int s1,s;
2999  s=2147483647; // max. int
3000 
3001  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
3002 
3003  int normalcount = 0;
3004  do
3005  {
3006  number& n = numberCollectionEnumerator.Current();
3007  nlNormalize(n, cf); ++normalcount;
3008  cand1 = n;
3009 
3010  if (SR_HDL(cand1)&SR_INT) { cand=cand1; break; }
3011  assume(cand1->s==3); // all coeffs should be integers // ==0?!! after printing
3012  s1=mpz_size1(cand1->z);
3013  if (s>s1)
3014  {
3015  cand=cand1;
3016  s=s1;
3017  }
3018  } while (numberCollectionEnumerator.MoveNext() );
3019 
3020 // assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
3021 
3022  cand=nlCopy(cand,cf);
3023  // part 2: compute gcd(cand,all coeffs)
3024 
3025  numberCollectionEnumerator.Reset();
3026 
3027  while (numberCollectionEnumerator.MoveNext() )
3028  {
3029  number& n = numberCollectionEnumerator.Current();
3030 
3031  if( (--normalcount) <= 0)
3032  nlNormalize(n, cf);
3033 
3034  nlInpGcd(cand, n, cf);
3035  assume( nlGreaterZero(cand,cf) );
3036 
3037  if(nlIsOne(cand,cf))
3038  {
3039  c = cand;
3040 
3041  if(!lc_is_pos)
3042  {
3043  // make the leading coeff positive
3044  c = nlNeg(c, cf);
3045  numberCollectionEnumerator.Reset();
3046 
3047  while (numberCollectionEnumerator.MoveNext() )
3048  {
3049  number& nn = numberCollectionEnumerator.Current();
3050  nn = nlNeg(nn, cf);
3051  }
3052  }
3053  return;
3054  }
3055  }
3056 
3057  // part3: all coeffs = all coeffs / cand
3058  if (!lc_is_pos)
3059  cand = nlNeg(cand,cf);
3060 
3061  c = cand;
3062  numberCollectionEnumerator.Reset();
3063 
3064  while (numberCollectionEnumerator.MoveNext() )
3065  {
3066  number& n = numberCollectionEnumerator.Current();
3067  number t=nlIntDiv(n, cand, cf); // simple integer exact division, no ratios to remain
3068  nlDelete(&n, cf);
3069  n = t;
3070  }
3071 }
3072 
3073 static void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
3074 {
3075  assume(cf != NULL);
3076 
3077  numberCollectionEnumerator.Reset();
3078 
3079  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
3080  {
3081  c = nlInit(1, cf);
3082 // assume( n_GreaterZero(c, cf) );
3083  return;
3084  }
3085 
3086  // all coeffs are given by integers after returning from this routine
3087 
3088  // part 1, collect product of all denominators /gcds
3089  number cand;
3090  cand=ALLOC_RNUMBER();
3091 #if defined(LDEBUG)
3092  cand->debug=123456;
3093 #endif
3094  cand->s=3;
3095 
3096  int s=0;
3097 
3098  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
3099 
3100  do
3101  {
3102  number& cand1 = numberCollectionEnumerator.Current();
3103 
3104  if (!(SR_HDL(cand1)&SR_INT))
3105  {
3106  nlNormalize(cand1, cf);
3107  if ((!(SR_HDL(cand1)&SR_INT)) // not a short int
3108  && (cand1->s==1)) // and is a normalised rational
3109  {
3110  if (s==0) // first denom, we meet
3111  {
3112  mpz_init_set(cand->z, cand1->n); // cand->z = cand1->n
3113  s=1;
3114  }
3115  else // we have already something
3116  {
3117  mpz_lcm(cand->z, cand->z, cand1->n);
3118  }
3119  }
3120  }
3121  }
3122  while (numberCollectionEnumerator.MoveNext() );
3123 
3124 
3125  if (s==0) // nothing to do, all coeffs are already integers
3126  {
3127 // mpz_clear(tmp);
3128  FREE_RNUMBER(cand);
3129  if (lc_is_pos)
3130  c=nlInit(1,cf);
3131  else
3132  {
3133  // make the leading coeff positive
3134  c=nlInit(-1,cf);
3135 
3136  // TODO: incorporate the following into the loop below?
3137  numberCollectionEnumerator.Reset();
3138  while (numberCollectionEnumerator.MoveNext() )
3139  {
3140  number& n = numberCollectionEnumerator.Current();
3141  n = nlNeg(n, cf);
3142  }
3143  }
3144 // assume( n_GreaterZero(c, cf) );
3145  return;
3146  }
3147 
3148  cand = nlShort3(cand);
3149 
3150  // part2: all coeffs = all coeffs * cand
3151  // make the lead coeff positive
3152  numberCollectionEnumerator.Reset();
3153 
3154  if (!lc_is_pos)
3155  cand = nlNeg(cand, cf);
3156 
3157  c = cand;
3158 
3159  while (numberCollectionEnumerator.MoveNext() )
3160  {
3161  number &n = numberCollectionEnumerator.Current();
3162  nlInpMult(n, cand, cf);
3163  }
3164 
3165 }
3166 
3167 char * nlCoeffName(const coeffs r)
3168 {
3169  if (r->cfDiv==nlDiv) return (char*)"QQ";
3170  else return (char*)"ZZ";
3171 }
3172 
3173 static char* nlCoeffString(const coeffs r)
3174 {
3175  //return omStrDup(nlCoeffName(r));
3176  if (r->cfDiv==nlDiv) return omStrDup("QQ");
3177  else return omStrDup("ZZ");
3178 }
3179 
3180 void nlWriteFd(number n, const ssiInfo* d, const coeffs)
3181 {
3182  if(SR_HDL(n) & SR_INT)
3183  {
3184  #if SIZEOF_LONG == 4
3185  fprintf(d->f_write,"4 %ld ",SR_TO_INT(n));
3186  #else
3187  long nn=SR_TO_INT(n);
3188  if ((nn<POW_2_28_32)&&(nn>= -POW_2_28_32))
3189  {
3190  int nnn=(int)nn;
3191  fprintf(d->f_write,"4 %d ",nnn);
3192  }
3193  else
3194  {
3195  mpz_t tmp;
3196  mpz_init_set_si(tmp,nn);
3197  fputs("8 ",d->f_write);
3198  mpz_out_str (d->f_write,SSI_BASE, tmp);
3199  fputc(' ',d->f_write);
3200  mpz_clear(tmp);
3201  }
3202  #endif
3203  }
3204  else if (n->s<2)
3205  {
3206  //gmp_fprintf(f,"%d %Zd %Zd ",n->s,n->z,n->n);
3207  fprintf(d->f_write,"%d ",n->s+5);
3208  mpz_out_str (d->f_write,SSI_BASE, n->z);
3209  fputc(' ',d->f_write);
3210  mpz_out_str (d->f_write,SSI_BASE, n->n);
3211  fputc(' ',d->f_write);
3212 
3213  //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
3214  }
3215  else /*n->s==3*/
3216  {
3217  //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
3218  fputs("8 ",d->f_write);
3219  mpz_out_str (d->f_write,SSI_BASE, n->z);
3220  fputc(' ',d->f_write);
3221 
3222  //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
3223  }
3224 }
3225 
3226 number nlReadFd(const ssiInfo *d, const coeffs)
3227 {
3228  int sub_type=-1;
3229  sub_type=s_readint(d->f_read);
3230  switch(sub_type)
3231  {
3232  case 0:
3233  case 1:
3234  {// read mpz_t, mpz_t
3235  number n=nlRInit(0);
3236  mpz_init(n->n);
3237  s_readmpz(d->f_read,n->z);
3238  s_readmpz(d->f_read,n->n);
3239  n->s=sub_type;
3240  return n;
3241  }
3242 
3243  case 3:
3244  {// read mpz_t
3245  number n=nlRInit(0);
3246  s_readmpz(d->f_read,n->z);
3247  n->s=3; /*sub_type*/
3248  #if SIZEOF_LONG == 8
3249  n=nlShort3(n);
3250  #endif
3251  return n;
3252  }
3253  case 4:
3254  {
3255  LONG dd=s_readlong(d->f_read);
3256  //#if SIZEOF_LONG == 8
3257  return INT_TO_SR(dd);
3258  //#else
3259  //return nlInit(dd,NULL);
3260  //#endif
3261  }
3262  case 5:
3263  case 6:
3264  {// read raw mpz_t, mpz_t
3265  number n=nlRInit(0);
3266  mpz_init(n->n);
3267  s_readmpz_base (d->f_read,n->z, SSI_BASE);
3268  s_readmpz_base (d->f_read,n->n, SSI_BASE);
3269  n->s=sub_type-5;
3270  return n;
3271  }
3272  case 8:
3273  {// read raw mpz_t
3274  number n=nlRInit(0);
3275  s_readmpz_base (d->f_read,n->z, SSI_BASE);
3276  n->s=sub_type=3; /*subtype-5*/
3277  #if SIZEOF_LONG == 8
3278  n=nlShort3(n);
3279  #endif
3280  return n;
3281  }
3282 
3283  default: Werror("error in reading number: invalid subtype %d",sub_type);
3284  return NULL;
3285  }
3286  return NULL;
3287 }
3288 
3290 {
3291  /* test, if r is an instance of nInitCoeffs(n,parameter) */
3292  /* if parameter is not needed */
3293  if (n==r->type)
3294  {
3295  if ((p==NULL)&&(r->cfDiv==nlDiv)) return TRUE;
3296  if ((p!=NULL)&&(r->cfDiv!=nlDiv)) return TRUE;
3297  }
3298  return FALSE;
3299 }
3300 
3301 static number nlLcm(number a,number b,const coeffs r)
3302 {
3303  number g=nlGcd(a,b,r);
3304  number n1=nlMult(a,b,r);
3305  number n2=nlIntDiv(n1,g,r);
3306  nlDelete(&g,r);
3307  nlDelete(&n1,r);
3308  return n2;
3309 }
3310 
3311 static number nlRandom(siRandProc p, number v2, number, const coeffs cf)
3312 {
3313  number a=nlInit(p(),cf);
3314  if (v2!=NULL)
3315  {
3316  number b=nlInit(p(),cf);
3317  number c=nlDiv(a,b,cf);
3318  nlDelete(&b,cf);
3319  nlDelete(&a,cf);
3320  a=c;
3321  }
3322  return a;
3323 }
3324 
3326 {
3327  r->is_domain=TRUE;
3328  r->rep=n_rep_gap_rat;
3329 
3330  r->nCoeffIsEqual=nlCoeffIsEqual;
3331  //r->cfKillChar = ndKillChar; /* dummy */
3332  r->cfCoeffString=nlCoeffString;
3333  r->cfCoeffName=nlCoeffName;
3334 
3335  r->cfInitMPZ = nlInitMPZ;
3336  r->cfMPZ = nlMPZ;
3337 
3338  r->cfMult = nlMult;
3339  r->cfSub = nlSub;
3340  r->cfAdd = nlAdd;
3341  r->cfExactDiv= nlExactDiv;
3342  if (p==NULL) /* Q */
3343  {
3344  r->is_field=TRUE;
3345  r->cfDiv = nlDiv;
3346  //r->cfGcd = ndGcd_dummy;
3347  r->cfSubringGcd = nlGcd;
3348  }
3349  else /* Z: coeffs_BIGINT */
3350  {
3351  r->is_field=FALSE;
3352  r->cfDiv = nlIntDiv;
3353  r->cfIntMod= nlIntMod;
3354  r->cfGcd = nlGcd;
3355  r->cfDivBy=nlDivBy;
3356  r->cfDivComp = nlDivComp;
3357  r->cfIsUnit = nlIsUnit;
3358  r->cfGetUnit = nlGetUnit;
3359  r->cfQuot1 = nlQuot1;
3360  r->cfLcm = nlLcm;
3361  r->cfXExtGcd=nlXExtGcd;
3362  r->cfQuotRem=nlQuotRem;
3363  }
3364  r->cfInit = nlInit;
3365  r->cfSize = nlSize;
3366  r->cfInt = nlInt;
3367 
3368  r->cfChineseRemainder=nlChineseRemainderSym;
3369  r->cfFarey=nlFarey;
3370  r->cfInpNeg = nlNeg;
3371  r->cfInvers= nlInvers;
3372  r->cfCopy = nlCopy;
3373  r->cfRePart = nlCopy;
3374  //r->cfImPart = ndReturn0;
3375  r->cfWriteLong = nlWrite;
3376  r->cfRead = nlRead;
3377  r->cfNormalize=nlNormalize;
3378  r->cfGreater = nlGreater;
3379  r->cfEqual = nlEqual;
3380  r->cfIsZero = nlIsZero;
3381  r->cfIsOne = nlIsOne;
3382  r->cfIsMOne = nlIsMOne;
3383  r->cfGreaterZero = nlGreaterZero;
3384  r->cfPower = nlPower;
3385  r->cfGetDenom = nlGetDenom;
3386  r->cfGetNumerator = nlGetNumerator;
3387  r->cfExtGcd = nlExtGcd; // only for ring stuff and Z
3388  r->cfNormalizeHelper = nlNormalizeHelper;
3389  r->cfDelete= nlDelete;
3390  r->cfSetMap = nlSetMap;
3391  //r->cfName = ndName;
3392  r->cfInpMult=nlInpMult;
3393  r->cfInpAdd=nlInpAdd;
3394  r->cfCoeffWrite=nlCoeffWrite;
3395 
3396  r->cfClearContent = nlClearContent;
3397  r->cfClearDenominators = nlClearDenominators;
3398 
3399 #ifdef LDEBUG
3400  // debug stuff
3401  r->cfDBTest=nlDBTest;
3402 #endif
3403  r->convSingNFactoryN=nlConvSingNFactoryN;
3404  r->convFactoryNSingN=nlConvFactoryNSingN;
3405 
3406  r->cfRandom=nlRandom;
3407 
3408  // io via ssi
3409  r->cfWriteFd=nlWriteFd;
3410  r->cfReadFd=nlReadFd;
3411 
3412  //r->type = n_Q;
3413  r->ch = 0;
3414  r->has_simple_Alloc=FALSE;
3415  r->has_simple_Inverse=FALSE;
3416 
3417  // variables for this type of coeffs:
3418  // (none)
3419  return FALSE;
3420 }
3421 #if 0
3422 number nlMod(number a, number b)
3423 {
3424  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
3425  {
3426  int bi=SR_TO_INT(b);
3427  int ai=SR_TO_INT(a);
3428  int bb=ABS(bi);
3429  int c=ai%bb;
3430  if (c<0) c+=bb;
3431  return (INT_TO_SR(c));
3432  }
3433  number al;
3434  number bl;
3435  if (SR_HDL(a))&SR_INT)
3436  al=nlRInit(SR_TO_INT(a));
3437  else
3438  al=nlCopy(a);
3439  if (SR_HDL(b))&SR_INT)
3440  bl=nlRInit(SR_TO_INT(b));
3441  else
3442  bl=nlCopy(b);
3443  number r=nlRInit(0);
3444  mpz_mod(r->z,al->z,bl->z);
3445  nlDelete(&al);
3446  nlDelete(&bl);
3447  if (mpz_size1(&r->z)<=MP_SMALL)
3448  {
3449  LONG ui=(int)mpz_get_si(&r->z);
3450  if ((((ui<<3)>>3)==ui)
3451  && (mpz_cmp_si(x->z,(long)ui)==0))
3452  {
3453  mpz_clear(&r->z);
3454  FREE_RNUMBER(r); // omFreeBin((void *)r, rnumber_bin);
3455  r=INT_TO_SR(ui);
3456  }
3457  }
3458  return r;
3459 }
3460 #endif
3461 #endif // not P_NUMBERS_H
3462 #endif // LONGRAT_CC
mpz_ptr base
Definition: rmodulon.h:18
mpz_t z
Definition: longrat.h:49
long intval() const
conversion functions
Definition: s_buff.h:20
STATIC_VAR jList * Q
Definition: janet.cc:30
LINLINE number nlSub(number la, number li, const coeffs r)
Definition: longrat.cc:2598
static void nlClearDenominators(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition: longrat.cc:3073
const CanonicalForm int s
Definition: facAbsFact.cc:55
const CanonicalForm int const CFList const Variable & y
Definition: facAbsFact.cc:57
int j
Definition: facHensel.cc:105
CF_NO_INLINE bool isOne() const
CF_INLINE bool CanonicalForm::isOne, isZero () const.
Definition: cf_inline.cc:354
void mpz_mul_si(mpz_ptr r, mpz_srcptr s, long int si)
Definition: longrat.cc:171
#define omCheckAddrSize(addr, size)
Definition: omAllocDecl.h:327
#define D(A)
Definition: gentable.cc:131
#define INT_TO_SR(INT)
Definition: longrat.h:67
BOOLEAN nlCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
Definition: longrat.cc:3289
#define Print
Definition: emacs.cc:80
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition: coeffs.h:822
static int int_extgcd(int a, int b, int *u, int *x, int *v, int *y)
Definition: longrat.cc:1273
char * nlCoeffName(const coeffs r)
Definition: longrat.cc:3167
void Off(int sw)
switches
#define mpz_sgn1(A)
Definition: si_gmp.h:13
gmp_float exp(const gmp_float &a)
Definition: mpr_complex.cc:357
CanonicalForm num(const CanonicalForm &f)
long npInt(number &n, const coeffs r)
Definition: modulop.cc:127
Definition: int_poly.h:33
static number nlConvFactoryNSingN(const CanonicalForm f, const coeffs r)
Definition: longrat.cc:369
BOOLEAN nlGreaterZero(number za, const coeffs r)
Definition: longrat.cc:1165
number nlModP(number q, const coeffs, const coeffs Zp)
Definition: longrat.cc:1435
#define FALSE
Definition: auxiliary.h:96
static void nlMPZ(mpz_t m, number &n, const coeffs r)
Definition: longrat.cc:2650
mpf_t * _mpfp()
Definition: mpr_complex.h:134
number _nlMult_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:2207
number nlShort1(number x)
Definition: longrat.cc:1323
number nlNormalizeHelper(number a, number b, const coeffs r)
Definition: longrat.cc:1388
number ndCopyMap(number a, const coeffs aRing, const coeffs r)
Definition: numbers.cc:251
bool isImm() const
static FORCE_INLINE BOOLEAN nCoeff_is_long_R(const coeffs r)
Definition: coeffs.h:913
LINLINE void nlInpAdd(number &a, number b, const coeffs r)
Definition: longrat.cc:2550
number nlGetDenom(number &n, const coeffs r)
Definition: longrat.cc:1498
void nlWrite(number a, const coeffs r)
Definition: longrat0.cc:90
int nlSize(number a, const coeffs)
Definition: longrat.cc:569
rational (GMP) numbers
Definition: coeffs.h:31
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition: coeffs.h:538
static FORCE_INLINE BOOLEAN nCoeff_is_R(const coeffs r)
Definition: coeffs.h:858
#define omCheckIf(cond, test)
Definition: omAllocDecl.h:323
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
LINLINE number nlAdd(number la, number li, const coeffs r)
Definition: longrat.cc:2532
{p < 2^31}
Definition: coeffs.h:30
void nlInpGcd(number &a, number b, const coeffs r)
Definition: longrat.cc:2776
BOOLEAN nlIsMOne(number a, const coeffs r)
Definition: longrat.cc:1190
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
Definition: coeffs.h:746
(), see rinteger.h, new impl.
Definition: coeffs.h:112
void nlCoeffWrite(const coeffs r, BOOLEAN details)
Definition: longrat.cc:2929
number nlIntDiv(number a, number b, const coeffs r)
Definition: longrat.cc:795
number nlGetUnit(number n, const coeffs cf)
Definition: longrat.cc:962
static FORCE_INLINE int n_GetChar(const coeffs r)
Return the characteristic of the coeff. domain.
Definition: coeffs.h:444
number nlGcd(number a, number b, const coeffs r)
Definition: longrat.cc:1202
factory&#39;s main class
Definition: canonicalform.h:77
#define TRUE
Definition: auxiliary.h:100
coeffs nlQuot1(number c, const coeffs r)
Definition: longrat.cc:968
#define POW_2_28
Definition: longrat.cc:108
#define VAR
Definition: globaldefs.h:5
number nlRInit(long i)
Definition: longrat.cc:2361
#define FREE_RNUMBER(x)
Definition: coeffs.h:86
number nlInit2(int i, int j, const coeffs r)
create a rational i/j (implicitly) over Q NOTE: make sure to use correct Q in debug mode ...
Definition: longrat.cc:2375
g
Definition: cfModGcd.cc:4031
const char * nlRead(const char *s, number *a, const coeffs r)
Definition: longrat0.cc:31
void WerrorS(const char *s)
Definition: feFopen.cc:24
bool negative(N n)
Definition: ValueTraits.h:119
void s_readmpz_base(s_buff F, mpz_ptr a, int base)
Definition: s_buff.cc:209
CanonicalForm make_cf(const mpz_ptr n)
Definition: singext.cc:66
number nlIntMod(number a, number b, const coeffs r)
Definition: longrat.cc:876
#define POW_2_28_32
Definition: longrat.cc:109
number nlInit2gmp(mpz_t i, mpz_t j, const coeffs r)
create a rational i/j (implicitly) over Q NOTE: make sure to use correct Q in debug mode ...
Definition: longrat.cc:2388
#define WarnS
Definition: emacs.cc:78
BOOLEAN nlInitChar(coeffs r, void *p)
Definition: longrat.cc:3325
#define omAlloc(size)
Definition: omAllocDecl.h:210
void nlWriteFd(number n, const ssiInfo *d, const coeffs)
Definition: longrat.cc:3180
void setCharacteristic(int c)
Definition: cf_char.cc:23
BOOLEAN nlGreater(number a, number b, const coeffs r)
Definition: longrat.cc:1175
LINLINE number nl_Copy(number a, const coeffs r)
static number nlInitMPZ(mpz_t m, const coeffs)
Definition: longrat.cc:2659
real floating point (GMP) numbers
Definition: coeffs.h:34
number nlMapZ(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:212
LINLINE BOOLEAN nlIsOne(number a, const coeffs r)
Definition: longrat.cc:2455
virtual void Reset()=0
Sets the enumerator to its initial position: -1, which is before the first element in the collection...
single prescision (6,6) real numbers
Definition: coeffs.h:32
#define MP_SMALL
Definition: longrat.cc:149
CanonicalForm b
Definition: cfModGcd.cc:4044
static number nlLcm(number a, number b, const coeffs r)
Definition: longrat.cc:3301
mpz_t n
Definition: longrat.h:50
s_buff f_read
Definition: s_buff.h:22
static number nlMapP(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:183
LINLINE number nlNeg(number za, const coeffs r)
Definition: longrat.cc:2513
number nlXExtGcd(number a, number b, number *s, number *t, number *u, number *v, const coeffs r)
Definition: longrat.cc:2671
Coefficient rings, fields and other domains suitable for Singular polynomials.
void s_readmpz(s_buff F, mpz_t a)
Definition: s_buff.cc:184
CanonicalForm res
Definition: facAbsFact.cc:64
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:48
int s_readint(s_buff F)
Definition: s_buff.cc:112
number nlDiv(number a, number b, const coeffs r)
Definition: longrat.cc:1002
number nlReadFd(const ssiInfo *d, const coeffs)
Definition: longrat.cc:3226
LINLINE number nlMult(number a, number b, const coeffs r)
Definition: longrat.cc:2568
number nlInvers(number a, const coeffs r)
Definition: longrat.cc:648
number _nlCopy_NoImm(number a)
Definition: longrat.cc:1605
#define assume(x)
Definition: mod2.h:390
void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
Definition: longrat.cc:1840
The main handler for Singular numbers which are suitable for Singular polynomials.
Templated enumerator interface for simple iteration over a generic collection of T&#39;s.
Definition: Enumerator.h:124
int nlDivComp(number a, number b, const coeffs r)
Definition: longrat.cc:951
LINLINE void nlInpMult(number &a, number b, const coeffs r)
Definition: longrat.cc:2616
const ExtensionInfo & info
< [in] sqrfree poly
#define A
Definition: sirandom.c:24
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
void _nlDelete_NoImm(number *a)
Definition: longrat.cc:1626
virtual reference Current()=0
Gets the current element in the collection (read and write).
#define LINLINE
Definition: longrat.cc:31
static number nlMapLongR(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:426
static const int SW_RATIONAL
set to 1 for computations over Q
Definition: cf_defs.h:29
All the auxiliary stuff.
int m
Definition: cfEzgcd.cc:121
#define mpz_isNeg(A)
Definition: longrat.cc:151
const char *const nDivBy0
Definition: numbers.h:88
void On(int sw)
switches
LINLINE BOOLEAN nlEqual(number a, number b, const coeffs r)
Definition: longrat.cc:2428
void nlPower(number x, int exp, number *lu, const coeffs r)
Definition: longrat.cc:1112
#define SSI_BASE
Definition: auxiliary.h:151
FILE * f
Definition: checklibs.c:9
int i
Definition: cfEzgcd.cc:125
void PrintS(const char *s)
Definition: reporter.cc:284
number nlQuotRem(number a, number b, number *r, const coeffs R)
Definition: longrat.cc:2723
void nlInpIntDiv(number &a, number b, const coeffs r)
Definition: longrat.cc:2791
number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
Definition: longrat.cc:2880
static int ABS(int v)
Definition: auxiliary.h:112
LINLINE BOOLEAN nlIsZero(number za, const coeffs r)
Definition: longrat.cc:2464
int IsPrime(int p)
Definition: prime.cc:61
(mpz_ptr), see rmodulon,h
Definition: coeffs.h:115
void nlGMP(number &i, mpz_t n, const coeffs r)
Definition: longrat.cc:1477
static void nlNormalize_Gcd(number &x)
Definition: longrat.cc:1662
BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1558
number nlShort3_noinline(number x)
Definition: longrat.cc:164
static void nlClearContent(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition: longrat.cc:2982
static CanonicalForm nlConvSingNFactoryN(number n, const BOOLEAN setChar, const coeffs)
Definition: longrat.cc:331
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421
int(* siRandProc)()
Definition: sirandom.h:9
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
number nlBigInt(number &n)
void chineseRemainderCached(CFArray &a, CFArray &n, CanonicalForm &xnew, CanonicalForm &prod, CFArray &inv)
Definition: cf_chinese.cc:265
#define SR_TO_INT(SR)
Definition: longrat.h:68
void gmp_numerator(const CanonicalForm &f, mpz_ptr result)
Definition: singext.cc:20
(number), see longrat.h
Definition: coeffs.h:111
void nlNormalize(number &x, const coeffs r)
Definition: longrat.cc:1344
void chineseRemainder(const CanonicalForm &x1, const CanonicalForm &q1, const CanonicalForm &x2, const CanonicalForm &q2, CanonicalForm &xnew, CanonicalForm &qnew)
void chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2...
Definition: cf_chinese.cc:52
number nlChineseRemainderSym(number *x, number *q, int rl, BOOLEAN sym, CFArray &inv_cache, const coeffs CF)
Definition: longrat.cc:2938
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:37
#define mpz_size1(A)
Definition: si_gmp.h:12
n_coeffType
Definition: coeffs.h:27
CanonicalForm cf
Definition: cfModGcd.cc:4024
number _nlNeg_NoImm(number a)
Definition: longrat.cc:1647
#define NULL
Definition: omList.c:12
static number nlShort3(number x)
Definition: longrat.cc:114
static number nlRandom(siRandProc p, number v2, number, const coeffs cf)
Definition: longrat.cc:3311
CanonicalForm den() const
den() returns the denominator of CO if CO is a rational number, 1 (from the current domain!) otherwis...
REvaluation E(1, terms.length(), IntRandom(25))
CanonicalForm den(const CanonicalForm &f)
FILE * f_write
Definition: s_buff.h:23
LINLINE void nlDelete(number *a, const coeffs r)
Definition: longrat.cc:2497
static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
return the quotient of &#39;a&#39; and &#39;b&#39;, i.e., a/b; raises an error if &#39;b&#39; is not invertible in r exceptio...
Definition: coeffs.h:615
BOOLEAN nlDivBy(number a, number b, const coeffs)
Definition: longrat.cc:937
(gmp_float), see
Definition: coeffs.h:117
b *CanonicalForm B
Definition: facBivar.cc:52
virtual bool MoveNext()=0
Advances the enumerator to the next element of the collection. returns true if the enumerator was suc...
int gcd(int a, int b)
Definition: walkSupport.cc:836
BOOLEAN nlIsUnit(number a, const coeffs)
Definition: longrat.cc:993
#define R
Definition: sirandom.c:27
long nlInt(number &n, const coeffs r)
Definition: longrat.cc:598
#define SR_INT
Definition: longrat.h:66
int exp
Definition: rmodulon.h:18
number _nlMult_aImm_bImm_rNoImm(number a, number b)
Definition: longrat.cc:2194
#define ALLOC_RNUMBER()
Definition: coeffs.h:87
nMapFunc nlSetMap(const coeffs src, const coeffs dst)
Definition: longrat.cc:2324
Variable x
Definition: cfModGcd.cc:4023
number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1682
#define GCD_NORM_COND(OLD, NEW)
Definition: longrat.cc:1660
long s_readlong(s_buff F)
Definition: s_buff.cc:140
number nlExactDiv(number a, number b, const coeffs r)
Definition: longrat.cc:728
number _nlSub_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1983
number nlMapGMP(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:200
BOOLEAN nlDBTest(number a, const char *f, const int l)
LINLINE number nlInit(long i, const coeffs r)
Definition: longrat.cc:2437
(int), see modulop.h
Definition: coeffs.h:110
#define SR_HDL(A)
Definition: tgb.cc:35
static char * nlCoeffString(const coeffs r)
Definition: longrat.cc:3173
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete &#39;p&#39;
Definition: coeffs.h:455
number nlMapMachineInt(number from, const coeffs, const coeffs)
Definition: longrat.cc:224
int p
Definition: cfModGcd.cc:4019
SI_FLOAT nrFloat(number n)
Converts a n_R number into a float. Needed by Maps.
Definition: shortfl.cc:56
number nlCopyMap(number a, const coeffs, const coeffs)
Definition: longrat.cc:2315
int BOOLEAN
Definition: auxiliary.h:87
static number nlMapR(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:396
number nlGetNumerator(number &n, const coeffs r)
Definition: longrat.cc:1527
LINLINE number nlCopy(number a, const coeffs r)
Definition: longrat.cc:2484
void dErrorBreak()
Definition: dError.cc:139
void Werror(const char *fmt,...)
Definition: reporter.cc:189
#define LONG
Definition: longrat.cc:110
return result
Definition: facAbsBiFact.cc:76
int l
Definition: cfEzgcd.cc:93
#define ALLOC0_RNUMBER()
Definition: coeffs.h:88
#define nlTest(a, r)
Definition: longrat.cc:92
const CanonicalForm const CanonicalForm const CanonicalForm const CanonicalForm & cand
Definition: cfModGcd.cc:69
number nlFarey(number nN, number nP, const coeffs CF)
Definition: longrat.cc:2809
VAR int n_SwitchChinRem
Definition: longrat.cc:2937
void gmp_denominator(const CanonicalForm &f, mpz_ptr result)
Definition: singext.cc:40
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:349
(float), see shortfl.h
Definition: coeffs.h:116
#define omStrDup(s)
Definition: omAllocDecl.h:263