source: git/Singular/modulop.cc @ 48aa42

fieker-DuValspielwiese
Last change on this file since 48aa42 was cf42ab1, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: ring changes don't have complete any more git-svn-id: file:///usr/local/Singular/svn/trunk@4817 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: modulop.cc,v 1.22 2000-12-06 11:03:20 Singular 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//     memcpy(npExpTable,r->cf->npExpTable,npPrimeM*sizeof(CARDINAL));
232//     memcpy(npLogTable,r->cf->npLogTable,npPrimeM*sizeof(CARDINAL));
233    npExpTable=r->cf->npExpTable;
234    npLogTable=r->cf->npLogTable;
235    npGen = npExpTable[1];
236  }
237  else
238  {
239    npPrimeM=0;
240    npExpTable=NULL;
241    npLogTable=NULL;
242  }
243}
244
245void npInitChar(int c, ring r)
246{
247  int i, w;
248
249  if ((c>1) || (c<(-1)))
250  {
251    if (c>1) r->cf->npPrimeM = c;
252    else     r->cf->npPrimeM = -c;
253    r->cf->npPminus1M = r->cf->npPrimeM - 1;
254    r->cf->npExpTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
255    r->cf->npLogTable= (CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
256    r->cf->npExpTable[0] = 1;
257    r->cf->npLogTable[0] = 0;
258    if (r->cf->npPrimeM > 2)
259    {
260      w = 1;
261      loop
262      {
263        r->cf->npLogTable[1] = 0;
264        w++;
265        i = 0;
266        loop
267        {
268          i++;
269          r->cf->npExpTable[i] = (int)(((long)w * (long)r->cf->npExpTable[i-1])
270                                 % r->cf->npPrimeM);
271          r->cf->npLogTable[r->cf->npExpTable[i]] = i;
272          if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1))
273            break;
274        }
275        if (i == r->cf->npPrimeM - 1)
276          break;
277      }
278    }
279    else
280    {
281      r->cf->npExpTable[1] = 1;
282      r->cf->npLogTable[1] = 0;
283    }
284  }
285  else
286  {
287    WarnS("nInitChar failed");
288  }
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
320BOOLEAN npSetMap(ring r)
321{
322  if (rField_is_Q(r))
323  {
324    nMap = npMap0;   /*Q -> Z/p*/
325    return TRUE;
326  }
327  if ( rField_is_Zp(r) )
328  {
329    if (rChar(r) == npPrimeM)
330    {
331      nMap = ndCopy;  /* Z/p -> Z/p*/
332      return TRUE;
333    }
334    else
335    {
336      npMapPrime=rChar(r);
337      nMap = npMapP; /* Z/p' -> Z/p */
338      return TRUE;
339    }
340  }
341  return FALSE;      /* default */
342}
Note: See TracBrowser for help on using the repository browser.