source: git/kernel/rintegers.cc @ 3a0e1a

spielwiese
Last change on this file since 3a0e1a was 3231f3, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: nrzIntMod git-svn-id: file:///usr/local/Singular/svn/trunk@11889 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: rintegers.cc,v 1.23 2009-06-09 18:10:44 Singular Exp $ */
5/*
6* ABSTRACT: numbers modulo n
7*/
8
9#include <string.h>
10#include "mod2.h"
11#include <mylimits.h>
12#include "structs.h"
13#include "febase.h"
14#include "omalloc.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "mpr_complex.h"
18#include "ring.h"
19#include "rintegers.h"
20#include "si_gmp.h"
21
22#ifdef HAVE_RINGS
23
24omBin gmp_nrz_bin = omGetSpecBin(sizeof(MP_INT));
25
26/*
27 * Multiply two numbers
28 */
29number nrzMult (number a, number b)
30{
31  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
32  mpz_init(erg);
33  mpz_mul(erg, (int_number) a, (int_number) b);
34  return (number) erg;
35}
36
37/*
38 * Give the smallest non unit k, such that a * x = k = b * y has a solution
39 */
40number nrzLcm (number a,number b,ring r)
41{
42  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
43  mpz_init(erg);
44  mpz_lcm(erg, (int_number) a, (int_number) 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.
51 */
52number nrzGcd (number a,number b,ring r)
53{
54  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
55  mpz_init(erg);
56  mpz_gcd(erg, (int_number) a, (int_number) b);
57  return (number) erg;
58}
59
60/*
61 * Give the largest non unit k, such that a = x * k, b = y * k has
62 * a solution and r, s, s.t. k = s*a + t*b
63 */
64number  nrzExtGcd (number a, number b, number *s, number *t)
65{
66  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
67  int_number bs = (int_number) omAllocBin(gmp_nrz_bin);
68  int_number bt = (int_number) omAllocBin(gmp_nrz_bin);
69  mpz_init(erg);
70  mpz_init(bs);
71  mpz_init(bt);
72  mpz_gcdext(erg, bs, bt, (int_number) a, (int_number) b);
73  *s = (number) bs;
74  *t = (number) bt;
75  return (number) erg;
76}
77
78void nrzPower (number a, int i, number * result)
79{
80  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
81  mpz_init(erg);
82  mpz_pow_ui(erg, (int_number) a, i);
83  *result = (number) erg;
84}
85
86/*
87 * create a number from int
88 */
89number nrzInit (int i)
90{
91  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
92  mpz_init_set_si(erg, i);
93  return (number) erg;
94}
95
96void nrzDelete(number *a, const ring r)
97{
98  if (*a == NULL) return;
99  mpz_clear((int_number) *a);
100  omFreeBin((ADDRESS) *a, gmp_nrz_bin);
101  *a = NULL;
102}
103
104number nrzCopy(number a)
105{
106  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
107  mpz_init_set(erg, (int_number) a);
108  return (number) erg;
109}
110
111number cfrzCopy(number a, const ring r)
112{
113  return nrzCopy(a);
114}
115
116int nrzSize(number a)
117{
118  if (a == NULL) return 0;
119  return sizeof(MP_INT);
120}
121
122/*
123 * convert a number to int (-p/2 .. p/2)
124 */
125int nrzInt(number &n)
126{
127  return (int) mpz_get_si( (int_number) &n);
128}
129
130number nrzAdd (number a, number b)
131{
132  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
133  mpz_init(erg);
134  mpz_add(erg, (int_number) a, (int_number) b);
135  return (number) erg;
136}
137
138number nrzSub (number a, number b)
139{
140  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
141  mpz_init(erg);
142  mpz_sub(erg, (int_number) a, (int_number) b);
143  return (number) erg;
144}
145
146number  nrzGetUnit (number a)
147{
148  return nrzInit(1);
149}
150
151BOOLEAN nrzIsUnit (number a)
152{
153  return 0 == mpz_cmpabs_ui((int_number) a, 1);
154}
155
156BOOLEAN nrzIsZero (number  a)
157{
158  return 0 == mpz_cmpabs_ui((int_number) a, 0);
159}
160
161BOOLEAN nrzIsOne (number a)
162{
163  return 0 == mpz_cmp_si((int_number) a, 1);
164}
165
166BOOLEAN nrzIsMOne (number a)
167{
168  return 0 == mpz_cmp_si((int_number) a, -1);
169}
170
171BOOLEAN nrzEqual (number a,number b)
172{
173  return 0 == mpz_cmp((int_number) a, (int_number) b);
174}
175
176BOOLEAN nrzGreater (number a,number b)
177{
178  return 0 < mpz_cmp((int_number) a, (int_number) b);
179}
180
181BOOLEAN nrzGreaterZero (number k)
182{
183  return 0 < mpz_cmp_si((int_number) k, 0);
184}
185
186int nrzDivComp(number a, number b)
187{
188  if (nrzEqual(a, b)) return 0;
189  if (nrzDivBy(a, b)) return -1;
190  if (nrzDivBy(b, a)) return 1;
191  return 2;
192}
193
194BOOLEAN nrzDivBy (number a,number b)
195{
196  return mpz_divisible_p((int_number) a, (int_number) b) != 0;
197}
198
199number nrzDiv (number a,number b)
200{
201  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
202  mpz_init(erg);
203  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
204  mpz_init(r);
205  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
206  if (!nrzIsZero((number) r))
207  {
208    WarnS("Division by non divisible element.");
209    WarnS("Result is without remainder.");
210  }
211  mpz_clear(r);
212  omFreeBin(r, gmp_nrz_bin);
213  return (number) erg;
214}
215
216number nrzIntDiv (number a,number b)
217{
218  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
219  mpz_init(erg);
220  mpz_tdiv_q(erg, (int_number) a, (int_number) b);
221  return (number) erg;
222}
223
224number nrzIntMod (number a,number b)
225{
226  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
227  mpz_init(erg);
228  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
229  mpz_init(r);
230  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
231  mpz_clear(erg);
232  return (number) r;
233}
234
235number  nrzInvers (number c)
236{
237  if (!nrzIsUnit((number) c))
238  {
239    WarnS("Non invertible element.");
240    return (number)0; //TODO
241  }
242  return nrzCopy(c);
243}
244
245number nrzNeg (number c)
246{
247// nNeg inplace !!!
248  mpz_mul_si((int_number) c, (int_number) c, -1);
249  return c;
250}
251
252number nrzMapMachineInt(number from)
253{
254  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
255  mpz_init_set_ui(erg, (NATNUMBER) from);
256  return (number) erg;
257}
258
259number nrzMapZp(number from)
260{
261  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
262  mpz_init_set_si(erg, (long) from);
263  return (number) erg;
264}
265
266number nrzMapQ(number from)
267{
268  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
269  mpz_init(erg);
270  nlGMP(from, (number) erg);
271  return (number) erg;
272}
273
274nMapFunc nrzSetMap(ring src, ring dst)
275{
276  /* dst = currRing */
277  if (rField_is_Ring_Z(src) || rField_is_Ring_ModN(src) || rField_is_Ring_PtoM(src))
278  {
279    return nrzCopy;
280  }
281  if (rField_is_Ring_2toM(src))
282  {
283    return nrzMapMachineInt;
284  }
285  if (rField_is_Zp(src))
286  {
287    return nrzMapZp;
288  }
289  if (rField_is_Q(src))
290  {
291    return nrzMapQ;
292  }
293  return NULL;      // default
294}
295
296
297/*
298 * set the exponent (allocate and init tables) (TODO)
299 */
300
301void nrzSetExp(int m, ring r)
302{
303}
304
305void nrzInitExp(int m, ring r)
306{
307}
308
309#ifdef LDEBUG
310//BOOLEAN nrzDBTest (number a, const char *f, const int l)
311//{
312//  return TRUE;//TODO
313//}
314#endif
315
316void nrzWrite (number &a)
317{
318  char *s,*z;
319  if (a==NULL)
320  {
321    StringAppendS("o");
322  }
323  else
324  {
325    int l=mpz_sizeinbase((int_number) a, 10) + 2;
326    s=(char*)omAlloc(l);
327    z=mpz_get_str(s,10,(int_number) a);
328    StringAppendS(z);
329    omFreeSize((ADDRESS)s,l);
330  }
331}
332
333/*2
334* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
335*/
336static const char * nlEatLongC(char *s, MP_INT *i)
337{
338  const char * start=s;
339
340  if (*s<'0' || *s>'9')
341  {
342    mpz_set_si(i,1);
343    return s;
344  }
345  while (*s >= '0' && *s <= '9') s++;
346  if (*s=='\0')
347  {
348    mpz_set_str(i,start,10);
349  }
350  else
351  {
352    char c=*s;
353    *s='\0';
354    mpz_set_str(i,start,10);
355    *s=c;
356  }
357  return s;
358}
359
360const char * nrzRead (const char *s, number *a)
361{
362  int_number z = (int_number) omAllocBin(gmp_nrz_bin);
363  {
364    mpz_init(z);
365    s = nlEatLongC((char *) s, z);
366  }
367  *a = (number) z;
368  return s;
369}
370#endif
Note: See TracBrowser for help on using the repository browser.