source: git/libpolys/coeffs/rintegers.cc @ b39b313

spielwiese
Last change on this file since b39b313 was b39b313, checked in by Janko Boehm <boehm@…>, 11 years ago
Fix for integer std
  • Property mode set to 100644
File size: 9.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: numbers modulo n
6*/
7#include "config.h"
8#include <misc/auxiliary.h>
9
10#ifdef HAVE_RINGS
11
12#include <string.h>
13#include <misc/mylimits.h>
14#include <coeffs/coeffs.h>
15#include <reporter/reporter.h>
16#include <omalloc/omalloc.h>
17#include <coeffs/numbers.h>
18#include <coeffs/longrat.h>
19#include <coeffs/mpr_complex.h>
20#include <coeffs/rintegers.h>
21#include "si_gmp.h"
22
23/// Our Type!
24static const n_coeffType ID = n_Z;
25
26omBin gmp_nrz_bin = omGetSpecBin(sizeof(mpz_t));
27
28/*
29 * Multiply two numbers
30 */
31number nrzMult (number a, number b, const coeffs)
32{
33  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
34  mpz_init(erg);
35  mpz_mul(erg, (int_number) a, (int_number) b);
36  return (number) erg;
37}
38
39/*
40 * Give the smallest non unit k, such that a * x = k = b * y has a solution
41 */
42number nrzLcm (number a,number b,const coeffs)
43{
44  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
45  mpz_init(erg);
46  mpz_lcm(erg, (int_number) a, (int_number) b);
47  return (number) erg;
48}
49
50/*
51 * Give the largest non unit k, such that a = x * k, b = y * k has
52 * a solution.
53 */
54number nrzGcd (number a,number b,const coeffs)
55{
56  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
57  mpz_init(erg);
58  mpz_gcd(erg, (int_number) a, (int_number) b);
59  return (number) erg;
60}
61
62/*
63 * Give the largest non unit k, such that a = x * k, b = y * k has
64 * a solution and r, s, s.t. k = s*a + t*b
65 */
66number  nrzExtGcd (number a, number b, number *s, number *t, const coeffs)
67{
68  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
69  int_number bs = (int_number) omAllocBin(gmp_nrz_bin);
70  int_number bt = (int_number) omAllocBin(gmp_nrz_bin);
71  mpz_init(erg);
72  mpz_init(bs);
73  mpz_init(bt);
74  mpz_gcdext(erg, bs, bt, (int_number) a, (int_number) b);
75  *s = (number) bs;
76  *t = (number) bt;
77  return (number) erg;
78}
79
80void nrzPower (number a, int i, number * result, const coeffs)
81{
82  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
83  mpz_init(erg);
84  mpz_pow_ui(erg, (int_number) a, i);
85  *result = (number) erg;
86}
87
88/*
89 * create a number from int
90 */
91number nrzInit (long i, const coeffs)
92{
93  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
94  mpz_init_set_si(erg, i);
95  return (number) erg;
96}
97
98void nrzDelete(number *a, const coeffs)
99{
100  if (*a == NULL) return;
101  mpz_clear((int_number) *a);
102  omFreeBin((ADDRESS) *a, gmp_nrz_bin);
103  *a = NULL;
104}
105
106number nrzCopy(number a, const coeffs)
107{
108  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
109  mpz_init_set(erg, (int_number) a);
110  return (number) erg;
111}
112
113#if 0
114number nrzCopyMap(number a, const coeffs /*src*/, const coeffs dst)
115{
116  return nrzCopy(a,dst);
117}
118#endif
119
120int nrzSize(number a, const coeffs)
121{
122  if (a == NULL) return 0;
123  return sizeof(mpz_t);
124}
125
126/*
127 * convert a number to int
128 */
129int nrzInt(number &n, const coeffs)
130{
131  return (int) mpz_get_si( (int_number)n);
132}
133
134number nrzAdd (number a, number b, const coeffs)
135{
136  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
137  mpz_init(erg);
138  mpz_add(erg, (int_number) a, (int_number) b);
139  return (number) erg;
140}
141
142number nrzSub (number a, number b, const coeffs)
143{
144  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
145  mpz_init(erg);
146  mpz_sub(erg, (int_number) a, (int_number) b);
147  return (number) erg;
148}
149
150number  nrzGetUnit (number, const coeffs r)
151{
152  return nrzInit(1, r);
153}
154
155BOOLEAN nrzIsUnit (number a, const coeffs)
156{
157  return 0 == mpz_cmpabs_ui((int_number) a, 1);
158}
159
160BOOLEAN nrzIsZero (number  a, const coeffs)
161{
162  return 0 == mpz_cmpabs_ui((int_number) a, 0);
163}
164
165BOOLEAN nrzIsOne (number a, const coeffs)
166{
167  return (a!=NULL) && (0 == mpz_cmp_si((int_number) a, 1));
168}
169
170BOOLEAN nrzIsMOne (number a, const coeffs)
171{
172  return (a!=NULL) && (0 == mpz_cmp_si((int_number) a, -1));
173}
174
175BOOLEAN nrzEqual (number a,number b, const coeffs)
176{
177  return 0 == mpz_cmp((int_number) a, (int_number) b);
178}
179
180BOOLEAN nrzGreater (number a,number b, const coeffs)
181{
182  return 0 < mpz_cmp((int_number) a, (int_number) b);
183}
184
185BOOLEAN nrzGreaterZero (number k, const coeffs)
186{
187  return 0 < mpz_cmp_si((int_number) k, 0);
188}
189
190int nrzDivComp(number a, number b, const coeffs r)
191{
192  if (nrzDivBy(a, b, r))
193  {
194    if (nrzDivBy(b, a, r)) return 2;
195    return -1;
196  }
197  if (nrzDivBy(b, a, r)) return 1;
198  return 0;
199}
200
201BOOLEAN nrzDivBy (number a,number b, const coeffs)
202{
203  return mpz_divisible_p((int_number) a, (int_number) b) != 0;
204}
205
206number nrzDiv (number a,number b, const coeffs R)
207{
208  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
209  mpz_init(erg);
210  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
211  mpz_init(r);
212  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
213  if (!nrzIsZero((number) r, R))
214  {
215    WerrorS("Division by non divisible element.");
216    WerrorS("Result is without remainder.");
217  }
218  mpz_clear(r);
219  omFreeBin(r, gmp_nrz_bin);
220  return (number) erg;
221}
222
223number nrzIntDiv (number a,number b, const coeffs)
224{
225  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
226  mpz_init(erg);
227  mpz_tdiv_q(erg, (int_number) a, (int_number) b);
228  return (number) erg;
229}
230
231number nrzIntMod (number a,number b, const coeffs)
232{
233  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
234  mpz_init(erg);
235  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
236  mpz_init(r);
237  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
238  mpz_clear(erg);
239  return (number) r;
240}
241
242number  nrzInvers (number c, const coeffs r)
243{
244  if (!nrzIsUnit((number) c, r))
245  {
246    WerrorS("Non invertible element.");
247    return (number)0; //TODO
248  }
249  return nrzCopy(c,r);
250}
251
252number nrzNeg (number c, const coeffs)
253{
254// nNeg inplace !!!
255  mpz_mul_si((int_number) c, (int_number) c, -1);
256  return c;
257}
258
259number nrzMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
260{
261  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
262  mpz_init_set_ui(erg, (NATNUMBER) from);
263  return (number) erg;
264}
265
266number nrzMapZp(number from, const coeffs /*src*/, const coeffs /*dst*/)
267{
268  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
269  mpz_init_set_si(erg, (long) from);
270  return (number) erg;
271}
272
273number nrzMapQ(number from, const coeffs src, const coeffs /*dst*/)
274{
275  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
276  mpz_init(erg);
277  nlGMP(from, (number) erg, src);
278  return (number) erg;
279}
280
281nMapFunc nrzSetMap(const coeffs src, const coeffs /*dst*/)
282{
283  /* dst = currRing */
284  if (nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_ModN(src) || nCoeff_is_Ring_PtoM(src))
285  {
286    return ndCopyMap; //nrzCopyMap;
287  }
288  if (nCoeff_is_Ring_2toM(src))
289  {
290    return nrzMapMachineInt;
291  }
292  if (nCoeff_is_Zp(src))
293  {
294    return nrzMapZp;
295  }
296  if (nCoeff_is_Q(src))
297  {
298    return nrzMapQ;
299  }
300  return NULL;      // default
301}
302
303
304/*
305 * set the exponent (allocate and init tables) (TODO)
306 */
307
308void nrzSetExp(int, coeffs)
309{
310}
311
312void nrzInitExp(int, coeffs)
313{
314}
315
316#ifdef LDEBUG
317BOOLEAN nrzDBTest (number, const char *, const int, const coeffs)
318{
319  return TRUE;//TODO
320}
321#endif
322
323void nrzWrite (number &a, const coeffs)
324{
325  char *s,*z;
326  if (a==NULL)
327  {
328    StringAppendS("o");
329  }
330  else
331  {
332    int l=mpz_sizeinbase((int_number) a, 10) + 2;
333    s=(char*)omAlloc(l);
334    z=mpz_get_str(s,10,(int_number) a);
335    StringAppendS(z);
336    omFreeSize((ADDRESS)s,l);
337  }
338}
339
340/*2
341* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
342*/
343static const char * nlEatLongC(char *s, mpz_ptr i)
344{
345  const char * start=s;
346
347  if (*s<'0' || *s>'9')
348  {
349    mpz_set_si(i,1);
350    return s;
351  }
352  while (*s >= '0' && *s <= '9') s++;
353  if (*s=='\0')
354  {
355    mpz_set_str(i,start,10);
356  }
357  else
358  {
359    char c=*s;
360    *s='\0';
361    mpz_set_str(i,start,10);
362    *s=c;
363  }
364  return s;
365}
366
367const char * nrzRead (const char *s, number *a, const coeffs)
368{
369  int_number z = (int_number) omAllocBin(gmp_nrz_bin);
370  {
371    mpz_init(z);
372    s = nlEatLongC((char *) s, z);
373  }
374  *a = (number) z;
375  return s;
376}
377
378void    nrzCoeffWrite  (const coeffs, BOOLEAN /*details*/)
379{
380  PrintS("//   coeff. ring is : Integers\n");
381}
382
383
384BOOLEAN nrzInitChar(coeffs r,  void *)
385{
386  assume( getCoeffType(r) == ID );
387  r->nCoeffIsEqual = ndCoeffIsEqual;
388  r->cfKillChar = ndKillChar;
389  r->cfMult  = nrzMult;
390  r->cfSub   = nrzSub;
391  r->cfAdd   = nrzAdd;
392  r->cfDiv   = nrzDiv;
393  r->cfIntDiv= nrzDiv;
394  r->cfIntMod= nrzIntMod;
395  r->cfExactDiv= nrzDiv;
396  r->cfInit = nrzInit;
397  r->cfSize  = nrzSize;
398  r->cfInt  = nrzInt;
399  //#ifdef HAVE_RINGS
400  r->cfDivComp = nrzDivComp; // only for ring stuff
401  r->cfIsUnit = nrzIsUnit; // only for ring stuff
402  r->cfGetUnit = nrzGetUnit; // only for ring stuff
403  r->cfExtGcd = nrzExtGcd; // only for ring stuff
404  r->cfDivBy = nrzDivBy; // only for ring stuff
405  r->cfInit_bigint = nrzMapQ;
406  //#endif
407  r->cfNeg   = nrzNeg;
408  r->cfInvers= nrzInvers;
409  r->cfCopy  = nrzCopy;
410  r->cfWriteLong = nrzWrite;
411  r->cfRead = nrzRead;
412  r->cfGreater = nrzGreater;
413  r->cfEqual = nrzEqual;
414  r->cfIsZero = nrzIsZero;
415  r->cfIsOne = nrzIsOne;
416  r->cfIsMOne = nrzIsMOne;
417  r->cfGreaterZero = nrzGreaterZero;
418  r->cfPower = nrzPower;
419  r->cfGcd  = nrzGcd;
420  r->cfLcm  = nrzLcm;
421  r->cfDelete= nrzDelete;
422  r->cfSetMap = nrzSetMap;
423  r->cfCoeffWrite = nrzCoeffWrite;
424  // debug stuff
425
426#ifdef LDEBUG
427  r->cfDBTest=nrzDBTest;
428#endif
429
430  r->nNULL = 0;
431  r->ch = 0;
432  r->has_simple_Alloc=FALSE;
433  r->has_simple_Inverse=FALSE;
434  return FALSE;
435}
436
437#endif
Note: See TracBrowser for help on using the repository browser.