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

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