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