source: git/Singular/modulop.cc @ 4ecee2

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