source: git/coeffs/rintegers.cc @ 1f855e

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