source: git/kernel/rmodulo2m.cc @ 18ff4c

spielwiese
Last change on this file since 18ff4c was 2a329d, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: do really nothing, if HAVE_RING2TOM is not defined git-svn-id: file:///usr/local/Singular/svn/trunk@10165 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: rmodulo2m.cc,v 1.13 2007-07-04 13:51:02 Singular Exp $ */
5/*
6* ABSTRACT: numbers modulo 2^m
7*/
8
9#include <string.h>
10#include "mod2.h"
11
12#ifdef HAVE_RING2TOM
13#include <mylimits.h>
14#include "structs.h"
15#include "febase.h"
16#include "omalloc.h"
17#include "numbers.h"
18#include "longrat.h"
19#include "mpr_complex.h"
20#include "ring.h"
21#include "rmodulo2m.h"
22
23int nr2mExp;
24NATNUMBER nr2mModul;
25
26/*
27 * Multiply two numbers
28 */
29number nr2mMult (number a,number b)
30{
31  if (((NATNUMBER)a == 0) || ((NATNUMBER)b == 0))
32    return (number)0;
33  else
34    return nr2mMultM(a,b);
35}
36
37/*
38 * Give the smallest non unit k, such that a * x = k = b * y has a solution
39 */
40number nr2mLcm (number a,number b,ring r)
41{
42  NATNUMBER res = 0;
43  if ((NATNUMBER) a == 0) a = (number) 1;
44  if ((NATNUMBER) b == 0) b = (number) 1;
45  while ((NATNUMBER) a % 2 == 0)
46  {
47    a = (number) ((NATNUMBER) a / 2);
48    if ((NATNUMBER) b % 2 == 0) b = (number) ((NATNUMBER) b / 2);
49    res++;
50  }
51  while ((NATNUMBER) b % 2 == 0)
52  {
53    b = (number) ((NATNUMBER) b / 2);
54    res++;
55  }
56  return (number) (1L << res);  // (2**res)
57}
58
59/*
60 * Give the largest non unit k, such that a = x * k, b = y * k has
61 * a solution.
62 */
63number nr2mGcd (number a,number b,ring r)
64{
65  NATNUMBER res = 0;
66  if ((NATNUMBER) a == 0 && (NATNUMBER) b == 0) return (number) 1;
67  while ((NATNUMBER) a % 2 == 0 && (NATNUMBER) b % 2 == 0)
68  {
69    a = (number) ((NATNUMBER) a / 2);
70    b = (number) ((NATNUMBER) b / 2);
71    res++;
72  }
73//  if ((NATNUMBER) b % 2 == 0)
74//  {
75//    return (number) ((1L << res));// * (NATNUMBER) a);  // (2**res)*a    a ist Einheit
76//  }
77//  else
78//  {
79    return (number) ((1L << res));// * (NATNUMBER) b);  // (2**res)*b    b ist Einheit
80//  }
81}
82
83/*
84 * Give the largest non unit k, such that a = x * k, b = y * k has
85 * a solution.
86 */
87number nr2mExtGcd (number a, number b, number *s, number *t)
88{
89  NATNUMBER res = 0;
90  if ((NATNUMBER) a == 0 && (NATNUMBER) b == 0) return (number) 1;
91  while ((NATNUMBER) a % 2 == 0 && (NATNUMBER) b % 2 == 0)
92  {
93    a = (number) ((NATNUMBER) a / 2);
94    b = (number) ((NATNUMBER) b / 2);
95    res++;
96  }
97  if ((NATNUMBER) b % 2 == 0)
98  {
99    *t = NULL;
100    *s = nr2mInvers(a);
101    return (number) ((1L << res));// * (NATNUMBER) a);  // (2**res)*a    a ist Einheit
102  }
103  else
104  {
105    *s = NULL;
106    *t = nr2mInvers(b);
107    return (number) ((1L << res));// * (NATNUMBER) b);  // (2**res)*b    b ist Einheit
108  }
109}
110
111void nr2mPower (number a, int i, number * result)
112{
113  if (i==0)
114  {
115    //npInit(1,result);
116    *(NATNUMBER *)result = 1;
117  }
118  else if (i==1)
119  {
120    *result = a;
121  }
122  else
123  {
124    nr2mPower(a,i-1,result);
125    *result = nr2mMultM(a,*result);
126  }
127}
128
129/*
130 * create a number from int
131 */
132number nr2mInit (int i)
133{
134  long ii = i;
135  while (ii < 0) ii += nr2mModul;
136  while ((ii>1) && (ii >= nr2mModul)) ii -= nr2mModul;
137  return (number) ii;
138}
139
140/*
141 * convert a number to int (-p/2 .. p/2)
142 */
143int nr2mInt(number &n)
144{
145  if ((NATNUMBER)n > (nr2mModul >>1)) return (int)((NATNUMBER)n - nr2mModul);
146  else return (int)((NATNUMBER)n);
147}
148
149number nr2mAdd (number a, number b)
150{
151  return nr2mAddM(a,b);
152}
153
154number nr2mSub (number a, number b)
155{
156  return nr2mSubM(a,b);
157}
158
159BOOLEAN nr2mIsUnit (number a)
160{
161  return ((NATNUMBER) a % 2 == 1);
162}
163
164number  nr2mGetUnit (number k)
165{
166  if (k == NULL) 
167    return (number) 1;
168  NATNUMBER tmp = (NATNUMBER) k;
169  while (tmp % 2 == 0)
170    tmp = tmp / 2;
171  return (number) tmp;
172}
173
174BOOLEAN nr2mIsZero (number  a)
175{
176  return 0 == (NATNUMBER)a;
177}
178
179BOOLEAN nr2mIsOne (number a)
180{
181  return 1 == (NATNUMBER)a;
182}
183
184BOOLEAN nr2mIsMOne (number a)
185{
186  return nr2mModul == (NATNUMBER)a + 1;
187}
188
189BOOLEAN nr2mEqual (number a,number b)
190{
191  return nr2mEqualM(a,b);
192}
193
194BOOLEAN nr2mGreater (number a,number b)
195{
196  return nr2mDivBy(a, b);
197}
198
199BOOLEAN nr2mDivBy (number a,number b)
200{
201  if ((NATNUMBER) a == 0) return TRUE;
202  if ((NATNUMBER) b == 0) return FALSE;
203  while ((NATNUMBER) a % 2 == 0 && (NATNUMBER) b % 2 == 0)
204  {
205    a = (number) ((NATNUMBER) a / 2);
206    b = (number) ((NATNUMBER) b / 2);
207}
208  return ((NATNUMBER) b % 2 == 1);
209}
210
211int nr2mComp(number as, number bs)
212{
213  NATNUMBER a = (NATNUMBER) as;
214  NATNUMBER b = (NATNUMBER) bs;
215  assume(a != 0 && b != 0);
216  while (a % 2 == 0 && b % 2 == 0)
217  {
218    a = a / 2;
219    b = b / 2;
220  }
221  if (a % 2 == 0)
222  {
223    return -1;
224  }
225  else
226  {
227    if (b % 2 == 1)
228    {
229      return 0;
230    }
231    else
232    {
233      return 1;
234    }
235  }
236}
237
238BOOLEAN nr2mGreaterZero (number k)
239{
240  return ((NATNUMBER) k !=0) && ((NATNUMBER) k <= (nr2mModul>>1));
241}
242
243//#ifdef HAVE_DIV_MOD
244#if 1 //ifdef HAVE_NTL // in ntl.a
245//extern void XGCD(long& d, long& s, long& t, long a, long b);
246#include <NTL/ZZ.h>
247#ifdef NTL_CLIENT
248NTL_CLIENT
249#endif
250#else
251void XGCD(long& d, long& s, long& t, long a, long b)
252{
253   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
254
255   long aneg = 0, bneg = 0;
256
257   if (a < 0) {
258      a = -a;
259      aneg = 1;
260   }
261
262   if (b < 0) {
263      b = -b;
264      bneg = 1;
265   }
266
267   u1=1; v1=0;
268   u2=0; v2=1;
269   u = a; v = b;
270
271   while (v != 0) {
272      q = u / v;
273      r = u % v;
274      u = v;
275      v = r;
276      u0 = u2;
277      v0 = v2;
278      u2 =  u1 - q*u2;
279      v2 = v1- q*v2;
280      u1 = u0;
281      v1 = v0;
282   }
283
284   if (aneg)
285      u1 = -u1;
286
287   if (bneg)
288      v1 = -v1;
289
290   d = u;
291   s = u1;
292   t = v1;
293}
294#endif
295
296NATNUMBER InvMod(NATNUMBER a)
297{
298   long d, s, t;
299
300   XGCD(d, s, t, a, nr2mModul);
301   assume (d == 1);
302   if (s < 0)
303      return s + nr2mModul;
304   else
305      return s;
306}
307//#endif
308
309inline number nr2mInversM (number c)
310{
311  // Table !!!
312  NATNUMBER inv;
313  inv = InvMod((NATNUMBER)c);
314  return (number) inv;
315}
316
317number nr2mDiv (number a,number b)
318{
319  if ((NATNUMBER)a==0)
320    return (number)0;
321  else if ((NATNUMBER)b%2==0)
322  {
323    if ((NATNUMBER)b != 0)
324    {
325      while ((NATNUMBER) b%2 == 0 && (NATNUMBER) a%2 == 0)
326      {
327        a = (number) ((NATNUMBER) a / 2);
328        b = (number) ((NATNUMBER) b / 2);
329      }
330    }
331    if ((NATNUMBER) b%2 == 0)
332    {
333      WerrorS("div by zero divisor");
334      return (number)0;
335    }
336  }
337  return (number) nr2mMult(a, nr2mInversM(b));
338}
339
340number nr2mIntDiv (number a,number b)
341{
342  if ((NATNUMBER)a==0)
343  {
344    if ((NATNUMBER)b==0)
345      return (number) 1;
346    if ((NATNUMBER)b==1)
347      return (number) 0;
348    return (number) (nr2mModul / (NATNUMBER) b);
349  }
350  else
351  {
352    if ((NATNUMBER)b==0)
353      return (number) 0;
354    return (number) ((NATNUMBER) a / (NATNUMBER) b);
355  }
356}
357
358number  nr2mInvers (number c)
359{
360  if ((NATNUMBER)c%2==0)
361  {
362    WerrorS("division by zero divisor");
363    return (number)0;
364  }
365  return nr2mInversM(c);
366}
367
368number nr2mNeg (number c)
369{
370  if ((NATNUMBER)c==0) return c;
371  return nr2mNegM(c);
372}
373
374nMapFunc nr2mSetMap(ring src, ring dst)
375{
376  return NULL;      /* default */
377}
378
379
380/*
381 * set the exponent (allocate and init tables) (TODO)
382 */
383
384void nr2mSetExp(int m, ring r)
385{
386  if (m>1)
387  {
388    nr2mExp = m;
389    nr2mModul = 2;
390    for (int i = 1; i < m; i++) {
391      nr2mModul = nr2mModul * 2;
392    }
393  }
394  else
395  {
396    nr2mExp=0;
397    nr2mModul=0;
398  }
399//  PrintS("Modul: ");
400//  Print("%d\n", nr2mModul);
401}
402
403void nr2mInitExp(int m, ring r)
404{
405  int i, w;
406
407  if (m>1)
408  {
409    nr2mExp = m;
410    nr2mModul = 2;
411    for (int i = 1; i < m; i++) {
412      nr2mModul = nr2mModul * 2;
413
414    }
415  }
416  else
417  {
418    WarnS("nInitExp failed");
419  }
420}
421
422#ifdef LDEBUG
423BOOLEAN nr2mDBTest (number a, char *f, int l)
424{
425  if (((NATNUMBER)a<0) || ((NATNUMBER)a>nr2mModul))
426  {
427    return FALSE;
428  }
429  return TRUE;
430}
431#endif
432
433void nr2mWrite (number &a)
434{
435  if ((NATNUMBER)a > (nr2mModul >>1)) StringAppend("-%d",(int)(nr2mModul-((NATNUMBER)a)));
436  else                          StringAppend("%d",(int)((NATNUMBER)a));
437}
438
439char* nr2mEati(char *s, int *i)
440{
441
442  if (((*s) >= '0') && ((*s) <= '9'))
443  {
444    (*i) = 0;
445    do
446    {
447      (*i) *= 10;
448      (*i) += *s++ - '0';
449      if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) % nr2mModul;
450    }
451    while (((*s) >= '0') && ((*s) <= '9'));
452    if ((*i) >= nr2mModul) (*i) = (*i) % nr2mModul;
453  }
454  else (*i) = 1;
455  return s;
456}
457
458char * nr2mRead (char *s, number *a)
459{
460  int z;
461  int n=1;
462
463  s = nr2mEati(s, &z);
464  if ((*s) == '/')
465  {
466    s++;
467    s = nr2mEati(s, &n);
468  }
469  if (n == 1)
470    *a = (number)z;
471  else
472      *a = nr2mDiv((number)z,(number)n);
473  return s;
474}
475#endif
Note: See TracBrowser for help on using the repository browser.