source: git/libpolys/coeffs/rintegers2.cc @ 5f15ce

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