source: git/Singular/modulop.cc @ c98410

fieker-DuValspielwiese
Last change on this file since c98410 was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: modulop.cc,v 1.26 2001-08-27 14:47:12 Singular Exp $ */
5/*
6* ABSTRACT: numbers modulo p (<=32003)
7*/
8
9#include <string.h>
10#include "mod2.h"
11#include <mylimits.h>
12#include "tok.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 "modulop.h"
20
21int npPrimeM=0;
22int npGen=0;
23int npPminus1M=0;
24int npMapPrime;
25
26CARDINAL *npExpTable=NULL;
27CARDINAL *npLogTable=NULL;
28
29
30BOOLEAN npGreaterZero (number k)
31{
32  int h = (int) k;
33  return ((int)h !=0) && (h <= (npPrimeM>>1));
34}
35
36unsigned long npMultMod(unsigned long a, unsigned long b)
37{
38  unsigned long c = a*b;
39  c = c % npPrimeM;
40  assume(c == (unsigned long) npMultM((number) a, (number) b));
41  return c;
42}
43
44number npMult (number a,number b)
45{
46  if (((int)a == 0) || ((int)b == 0))
47    return (number)0;
48  else
49  {
50    return npMultM(a,b);
51  }
52}
53
54/*2
55* create a number from int
56*/
57number npInit (int i)
58{
59  while (i <  0)                   i += npPrimeM;
60  while ((i>1) && (i >= npPrimeM)) i -= npPrimeM;
61  return (number)i;
62}
63
64/*2
65* convert a number to int (-p/2 .. p/2)
66*/
67int npInt(number &n)
68{
69  if ((int)n > (npPrimeM >>1)) return ((int)n -npPrimeM);
70  else                     return (int)n;
71}
72
73number npAdd (number a, number b)
74{
75  return npAddM(a,b);
76}
77
78number npSub (number a, number b)
79{
80  return npSubM(a,b);
81}
82
83BOOLEAN npIsZero (number  a)
84{
85  return 0 == (int)a;
86}
87
88BOOLEAN npIsOne (number a)
89{
90  return 1 == (int)a;
91}
92
93BOOLEAN npIsMOne (number a)
94{
95  return ((npPminus1M == (int)a)&&(1!=(int)a));
96}
97
98number npDiv (number a,number b)
99{
100  if ((int)a==0)
101    return (number)0;
102  else if ((int)b==0)
103  {
104    WerrorS("div by 0");
105    return (number)0;
106  }
107  else
108  {
109    int s = npLogTable[(int)a] - npLogTable[(int)b];
110    if (s < 0)
111      s += npPminus1M;
112    return (number)npExpTable[s];
113  }
114}
115
116number  npInvers (number c)
117{
118  if ((int)c==0)
119  {
120    WerrorS("1/0");
121    return (number)0;
122  }
123  return (number)npExpTable[npPminus1M - npLogTable[(int)c]];
124}
125
126number npNeg (number c)
127{
128  if ((int)c==0) return c;
129  return npNegM(c);
130}
131
132BOOLEAN npGreater (number a,number b)
133{
134  return (int)a != (int)b;
135}
136
137BOOLEAN npEqual (number a,number b)
138{
139//  return (int)a == (int)b;
140  return npEqualM(a,b);
141}
142
143void npWrite (number &a)
144{
145  if ((int)a > (npPrimeM >>1)) StringAppend("-%d",npPrimeM-((int)a));
146  else                     StringAppend("%d",(int)a);
147}
148
149void npPower (number a, int i, number * result)
150{
151  if (i==0)
152  {
153    //npInit(1,result);
154    *(int *)result = 1;
155  }
156  else if (i==1)
157  {
158    *result = a;
159  }
160  else
161  {
162    npPower(a,i-1,result);
163    *result = npMultM(a,*result);
164  }
165}
166
167char* npEati(char *s, int *i)
168{
169
170  if (((*s) >= '0') && ((*s) <= '9'))
171  {
172    (*i) = 0;
173    do
174    {
175      (*i) *= 10;
176      (*i) += *s++ - '0';
177      if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) % npPrimeM;
178    }
179    while (((*s) >= '0') && ((*s) <= '9'));
180    if ((*i) >= npPrimeM) (*i) = (*i) % npPrimeM;
181  }
182  else (*i) = 1;
183  return s;
184}
185
186char * npRead (char *s, number *a)
187{
188  int z;
189  int n=1;
190
191  s = npEati(s, &z);
192  if ((*s) == '/')
193  {
194    s++;
195    s = npEati(s, &n);
196  }
197  *a = npDiv((number)z,(number)n);
198  return s;
199}
200
201/*2
202* the last used charcteristic
203*/
204//int npGetChar()
205//{
206//  return npPrimeM;
207//}
208
209/*2
210* set the charcteristic (allocate and init tables)
211*/
212
213void npSetChar(int c, ring r)
214{
215//  int i, w;
216
217//  if (c==npPrimeM) return;
218//  if (npPrimeM > 1)
219//  {
220//    omFreeSize( (ADDRESS)npExpTable,npPrimeM*sizeof(CARDINAL) );
221//    omFreeSize( (ADDRESS)npLogTable,npPrimeM*sizeof(CARDINAL) );
222//  }
223  if ((c>1) || (c<(-1)))
224  {
225    if (c>1) npPrimeM = c;
226    else     npPrimeM = -c;
227    npPminus1M = npPrimeM - 1;
228//    npExpTable= (CARDINAL *)omAlloc( npPrimeM*sizeof(CARDINAL) );
229//     npLogTable= (CARDINAL *)omAlloc( npPrimeM*sizeof(CARDINAL) );
230//     omMarkAsStaticAddr(npExpTable);
231//     omMarkAsStaticAddr(npLogTable);
232//     memcpy(npExpTable,r->cf->npExpTable,npPrimeM*sizeof(CARDINAL));
233//     memcpy(npLogTable,r->cf->npLogTable,npPrimeM*sizeof(CARDINAL));
234    npExpTable=r->cf->npExpTable;
235    npLogTable=r->cf->npLogTable;
236    npGen = npExpTable[1];
237  }
238  else
239  {
240    npPrimeM=0;
241    npExpTable=NULL;
242    npLogTable=NULL;
243  }
244}
245
246void npInitChar(int c, ring r)
247{
248  int i, w;
249
250  if ((c>1) || (c<(-1)))
251  {
252    if (c>1) r->cf->npPrimeM = c;
253    else     r->cf->npPrimeM = -c;
254    r->cf->npPminus1M = r->cf->npPrimeM - 1;
255    r->cf->npExpTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
256    r->cf->npLogTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
257    r->cf->npExpTable[0] = 1;
258    r->cf->npLogTable[0] = 0;
259    if (r->cf->npPrimeM > 2)
260    {
261      w = 1;
262      loop
263      {
264        r->cf->npLogTable[1] = 0;
265        w++;
266        i = 0;
267        loop
268        {
269          i++;
270          r->cf->npExpTable[i] = (int)(((long)w * (long)r->cf->npExpTable[i-1])
271                                 % r->cf->npPrimeM);
272          r->cf->npLogTable[r->cf->npExpTable[i]] = i;
273          if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1))
274            break;
275        }
276        if (i == r->cf->npPrimeM - 1)
277          break;
278      }
279    }
280    else
281    {
282      r->cf->npExpTable[1] = 1;
283      r->cf->npLogTable[1] = 0;
284    }
285  }
286  else
287  {
288    WarnS("nInitChar failed");
289  }
290}
291
292#ifdef LDEBUG
293BOOLEAN npDBTest (number a, char *f, int l)
294{
295  if (((int)a<0) || ((int)a>npPrimeM))
296  {
297    return FALSE;
298  }
299  return TRUE;
300}
301#endif
302
303number npMap0(number from)
304{
305  return npInit(nlModP(from,npPrimeM));
306}
307
308number npMapP(number from)
309{
310  int i = (int)from;
311  if (i>npMapPrime/2)
312  {
313    i-=npMapPrime;
314    while (i < 0) i+=npPrimeM;
315  }
316  i%=npPrimeM;
317  return (number)i;
318}
319
320static number npMapLongR(number from)
321{
322  gmp_float *ff=(gmp_float*)from;
323  mpf_t *f=ff->_mpfp();
324  number res;
325  lint *dest,*ndest;
326  int size,i;
327  int e,al,bl,iz,in;
328  mp_ptr qp,dd,nn;
329
330  size = (*f)[0]._mp_size;
331  if (size == 0)
332    return npInit(0);
333  if(size<0)
334    size = -size;
335
336  qp = (*f)[0]._mp_d;
337  while(qp[0]==0)
338  {
339    qp++;
340    size--;
341  }
342
343  if(npPrimeM>2)
344    e=(*f)[0]._mp_exp-size;
345  else
346    e=0;
347  res = (number)omAllocBin(rnumber_bin);
348#if defined(LDEBUG)
349  res->debug=123456;
350#endif
351  dest = &(res->z);
352
353  if (e<0)
354  {
355    al = dest->_mp_size = size;
356    if (al<2) al = 2;
357    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
358    for (i=0;i<size;i++) dd[i] = qp[i];
359    bl = 1-e;
360    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
361    nn[bl-1] = 1;
362    for (i=bl-2;i>=0;i--) nn[i] = 0;
363    ndest = &(res->n);
364    ndest->_mp_d = nn;
365    ndest->_mp_alloc = ndest->_mp_size = bl;
366    res->s = 0;
367    in=mpz_mmod_ui(NULL,ndest,npPrimeM);
368    mpz_clear(ndest);
369  }
370  else
371  {
372    al = dest->_mp_size = size+e;
373    if (al<2) al = 2;
374    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
375    for (i=0;i<size;i++) dd[i+e] = qp[i];
376    for (i=0;i<e;i++) dd[i] = 0;
377    res->s = 3;
378  }
379
380  dest->_mp_d = dd;
381  dest->_mp_alloc = al;
382  iz=mpz_mmod_ui(NULL,dest,npPrimeM);
383  mpz_clear(dest);
384  omFreeBin((ADDRESS)res, rnumber_bin);
385  if(res->s==0)
386    iz=(int)npDiv((number)iz,(number)in);
387  return (number)iz;
388}
389
390nMapFunc npSetMap(ring src, ring dst)
391{
392  if (rField_is_Q(src))
393  {
394    return npMap0;
395  }
396  if ( rField_is_Zp(src) )
397  {
398    if (rChar(src) == rChar(dst))
399    {
400      return ndCopy;
401    }
402    else
403    {
404      npMapPrime=rChar(src);
405      return npMapP;
406    }
407  }
408  if (rField_is_long_R(src))
409  {
410    return npMapLongR;
411  }
412  return NULL;      /* default */
413}
Note: See TracBrowser for help on using the repository browser.