Changeset 0b937c in git


Ignore:
Timestamp:
Jan 31, 2003, 10:09:46 AM (21 years ago)
Author:
Hans Schönemann <hannes@…>
Branches:
(u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
Children:
6a874ee99f6ab05d5981f0dc589bc510d18d6f6c
Parents:
cd22d1a27db3332385586c32609b3ccce07f4c94
Message:
*hannes: NV_OPS, NV_MAX_PRIME


git-svn-id: file:///usr/local/Singular/svn/trunk@6454 2c84dea3-7e68-4137-9b89-c4e89433aadc
Location:
Singular
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/modulop.cc

    rcd22d1a r0b937c  
    22*  Computer Algebra System SINGULAR     *
    33****************************************/
    4 /* $Id: modulop.cc,v 1.26 2001-08-27 14:47:12 Singular Exp $ */
     4/* $Id: modulop.cc,v 1.27 2003-01-31 09:09:46 Singular Exp $ */
    55/*
    66* ABSTRACT: numbers modulo p (<=32003)
     
    2424int npMapPrime;
    2525
     26#ifdef HAVE_DIV_MOD
     27CARDINAL *npInvTable=NULL;
     28#endif
     29
     30#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
    2631CARDINAL *npExpTable=NULL;
    2732CARDINAL *npLogTable=NULL;
     33#endif
    2834
    2935
     
    3440}
    3541
    36 unsigned 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 }
     42//unsigned long npMultMod(unsigned long a, unsigned long b)
     43//{
     44//  unsigned long c = a*b;
     45//  c = c % npPrimeM;
     46//  assume(c == (unsigned long) npMultM((number) a, (number) b));
     47//  return c;
     48//}
    4349
    4450number npMult (number a,number b)
     
    4753    return (number)0;
    4854  else
    49   {
    5055    return npMultM(a,b);
    51   }
    5256}
    5357
     
    96100}
    97101
     102#ifdef HAVE_DIV_MOD
     103#if 1 //ifdef HAVE_NTL // in ntl.a
     104extern void XGCD(long& d, long& s, long& t, long a, long b);
     105#else
     106void XGCD(long& d, long& s, long& t, long a, long b)
     107{
     108   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
     109
     110   long aneg = 0, bneg = 0;
     111
     112   if (a < 0) {
     113      a = -a;
     114      aneg = 1;
     115   }
     116
     117   if (b < 0) {
     118      b = -b;
     119      bneg = 1;
     120   }
     121
     122   u1=1; v1=0;
     123   u2=0; v2=1;
     124   u = a; v = b;
     125
     126   while (v != 0) {
     127      q = u / v;
     128      r = u % v;
     129      u = v;
     130      v = r;
     131      u0 = u2;
     132      v0 = v2;
     133      u2 =  u1 - q*u2;
     134      v2 = v1- q*v2;
     135      u1 = u0;
     136      v1 = v0;
     137   }
     138
     139   if (aneg)
     140      u1 = -u1;
     141
     142   if (bneg)
     143      v1 = -v1;
     144
     145   d = u;
     146   s = u1;
     147   t = v1;
     148}
     149#endif
     150
     151long InvMod(long a)
     152{
     153   long d, s, t;
     154
     155   XGCD(d, s, t, a, npPrimeM);
     156   assume (d == 1);
     157   if (s < 0)
     158      return s + npPrimeM;
     159   else
     160      return s;
     161}
     162#endif
     163
     164inline number npInversM (number c)
     165{
     166#ifndef HAVE_DIV_MOD
     167  return (number)npExpTable[npPminus1M - npLogTable[(int)c]];
     168#else
     169  CARDINAL inv=npInvTable[(int)c];
     170  if (inv==0)
     171  {
     172    inv=InvMod((long)c);
     173    npInvTable[(int)c]=inv;
     174  }
     175  return (number)inv;
     176#endif
     177}
     178
    98179number npDiv (number a,number b)
    99180{
    100181  if ((int)a==0)
    101182    return (number)0;
     183#ifndef HAVE_DIV_MOD
    102184  else if ((int)b==0)
    103185  {
     
    112194    return (number)npExpTable[s];
    113195  }
    114 }
    115 
     196#else
     197  number inv=npInversM(b);
     198  return npMultM(a,inv);
     199#endif
     200}
    116201number  npInvers (number c)
    117202{
     
    121206    return (number)0;
    122207  }
    123   return (number)npExpTable[npPminus1M - npLogTable[(int)c]];
     208  return npInversM(c);
    124209}
    125210
     
    195280    s = npEati(s, &n);
    196281  }
    197   *a = npDiv((number)z,(number)n);
     282  if (n == 1)
     283    *a = (number)z;
     284  else
     285#ifdef NV_OPS
     286    if (npPrimeM>NV_MAX_PRIME)
     287      *a = nvDiv((number)z,(number)n);
     288    else
     289#endif   
     290      *a = npDiv((number)z,(number)n);
    198291  return s;
    199292}
     
    216309
    217310//  if (c==npPrimeM) return;
    218 //  if (npPrimeM > 1)
    219 //  {
    220 //    omFreeSize( (ADDRESS)npExpTable,npPrimeM*sizeof(CARDINAL) );
    221 //    omFreeSize( (ADDRESS)npLogTable,npPrimeM*sizeof(CARDINAL) );
    222 //  }
    223311  if ((c>1) || (c<(-1)))
    224312  {
     
    226314    else     npPrimeM = -c;
    227315    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));
     316#ifdef HAVE_DIV_MOD
     317    npInvTable=r->cf->npInvTable;
     318#endif
     319#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
    234320    npExpTable=r->cf->npExpTable;
    235321    npLogTable=r->cf->npLogTable;
    236322    npGen = npExpTable[1];
     323#endif
    237324  }
    238325  else
    239326  {
    240327    npPrimeM=0;
     328#ifdef HAVE_DIV_MOD
     329    npInvTable=NULL;
     330#endif
     331#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
    241332    npExpTable=NULL;
    242333    npLogTable=NULL;
     334#endif
    243335  }
    244336}
     
    253345    else     r->cf->npPrimeM = -c;
    254346    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)
     347#ifdef NV_OPS
     348    if (r->cf->npPrimeM <=NV_MAX_PRIME)
     349#endif
    260350    {
    261       w = 1;
    262       loop
     351#if !defined(HAVE_DIV_MOD) || !defined(HAVE_MULT_MOD)
     352      r->cf->npExpTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
     353      r->cf->npLogTable=(CARDINAL *)omAlloc( r->cf->npPrimeM*sizeof(CARDINAL) );
     354      r->cf->npExpTable[0] = 1;
     355      r->cf->npLogTable[0] = 0;
     356      if (r->cf->npPrimeM > 2)
    263357      {
    264         r->cf->npLogTable[1] = 0;
    265         w++;
    266         i = 0;
     358        w = 1;
    267359        loop
    268360        {
    269           i++;
    270           r->cf->npExpTable[i] = (int)(((long)w * (long)r->cf->npExpTable[i-1])
     361          r->cf->npLogTable[1] = 0;
     362          w++;
     363          i = 0;
     364          loop
     365          {
     366            i++;
     367            r->cf->npExpTable[i] =(int)(((long)w * (long)r->cf->npExpTable[i-1])
    271368                                 % r->cf->npPrimeM);
    272           r->cf->npLogTable[r->cf->npExpTable[i]] = i;
    273           if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1))
     369            r->cf->npLogTable[r->cf->npExpTable[i]] = i;
     370            if (/*(i == npPrimeM - 1 ) ||*/ (r->cf->npExpTable[i] == 1))
     371              break;
     372          }
     373          if (i == r->cf->npPrimeM - 1)
    274374            break;
    275375        }
    276         if (i == r->cf->npPrimeM - 1)
    277           break;
    278376      }
    279     }
    280     else
    281     {
    282       r->cf->npExpTable[1] = 1;
    283       r->cf->npLogTable[1] = 0;
     377      else
     378      {
     379        r->cf->npExpTable[1] = 1;
     380        r->cf->npLogTable[1] = 0;
     381      }
     382#endif
     383#ifdef HAVE_DIV_MOD
     384      r->cf->npInvTable=(CARDINAL*)omAlloc0( r->cf->npPrimeM*sizeof(CARDINAL) );
     385#endif
    284386    }
    285387  }
     
    348450#if defined(LDEBUG)
    349451  res->debug=123456;
     452#endif
     453#ifndef NL_OLDCOPY
     454  res->ref=1;
    350455#endif
    351456  dest = &(res->z);
     
    412517  return NULL;      /* default */
    413518}
     519
     520// -----------------------------------------------------------
     521//  operation for very large primes (32003< p < 2^31-1)
     522// ----------------------------------------------------------
     523#ifdef NV_OPS
     524
     525number nvMult (number a,number b)
     526{
     527  if (((int)a == 0) || ((int)b == 0))
     528    return (number)0;
     529  else
     530    return nvMultM(a,b);
     531}
     532
     533long nvInvMod(long a)
     534{
     535   long  s, t;
     536
     537   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
     538
     539   u1=1; v1=0;
     540   u2=0; v2=1;
     541   u = a; v = npPrimeM;
     542
     543   while (v != 0) {
     544      q = u / v;
     545      r = u % v;
     546      u = v;
     547      v = r;
     548      u0 = u2;
     549      v0 = v2;
     550      u2 =  u1 - q*u2;
     551      v2 = v1- q*v2;
     552      u1 = u0;
     553      v1 = v0;
     554   }
     555
     556   s = u1;
     557   //t = v1;
     558   if (s < 0)
     559      return s + npPrimeM;
     560   else
     561      return s;
     562}
     563
     564inline number nvInversM (number c)
     565{
     566  long inv=InvMod((long)c);
     567  return (number)inv;
     568}
     569
     570number nvDiv (number a,number b)
     571{
     572  if ((int)a==0)
     573    return (number)0;
     574  else if ((int)b==0)
     575  {
     576    WerrorS("div by 0");
     577    return (number)0;
     578  }
     579  else
     580  {
     581    number inv=nvInversM(b);
     582    return nvMultM(a,inv);
     583  }
     584}
     585number  nvInvers (number c)
     586{
     587  if ((int)c==0)
     588  {
     589    WerrorS("1/0");
     590    return (number)0;
     591  }
     592  return nvInversM(c);
     593}
     594#endif
  • Singular/modulop.h

    rcd22d1a r0b937c  
    44*  Computer Algebra System SINGULAR     *
    55****************************************/
    6 /* $Id: modulop.h,v 1.16 2001-10-09 16:36:09 Singular Exp $ */
     6/* $Id: modulop.h,v 1.17 2003-01-31 09:09:46 Singular Exp $ */
    77/*
    88* ABSTRACT: numbers modulo p (<=32003)
     
    1010#include "structs.h"
    1111
     12// defines are in struct.h
    1213// define if a*b is with mod instead of tables
    13 #define HAVE_MULT_MOD
     14//#define HAVE_MULT_MOD
     15// define if a/b is with mod instead of tables
     16//#define HAVE_DIV_MOD
     17// define if an if should be used
     18//#define HAVE_GENERIC_ADD
     19
     20// enable large primes (32003 < p < 2^31-)
     21#define NV_OPS
     22#define NV_MAX_PRIME 32003
    1423
    1524extern int npPrimeM;
     
    4655/*-------specials for spolys, do NOT use otherwise--------------------------*/
    4756/* for npMultM, npSubM, npNegM, npEqualM : */
     57#ifdef HAVE_DIV_MOD
     58extern CARDINAL *npInvTable;
     59#else
     60#ifndef HAVE_MULT_MOD
    4861extern int npPminus1M;
    4962extern CARDINAL *npExpTable;
    5063extern CARDINAL *npLogTable;
     64#endif
     65#endif
    5166
     67#if 0
     68inline number npMultM(number a, number b)
     69// return (a*b)%n
     70{
     71   double ab;
     72   long q, res;
     73
     74   ab = ((double) ((int)a)) * ((double) ((int)b));
     75   q  = (long) (ab/((double) npPrimeM));  // q could be off by (+/-) 1
     76   res = (long) (ab - ((double) q)*((double) npPrimeM));
     77   res += (res >> 31) & npPrimeM;
     78   res -= npPrimeM;
     79   res += (res >> 31) & npPrimeM;
     80   return (number)res;
     81}
     82#endif
    5283#ifdef HAVE_MULT_MOD
    53 inline number npMultM(number a, number b)
     84static inline number npMultM(number a, number b)
    5485{
    55   return (number)
     86  return (number) 
    5687    ((((unsigned long) a)*((unsigned long) b)) % ((unsigned long) npPrimeM));
    5788}
    5889#else
    59 inline number npMultM(number a, number b)
     90static inline number npMultM(number a, number b)
    6091{
    6192  int x = npLogTable[(int)a]+npLogTable[(int)b];
     
    84115}
    85116#endif
    86 
    87 inline number npAddM(number a, number b)
     117#ifdef HAVE_GENERIC_ADD
     118static inline number npAddM(number a, number b)
    88119{
    89120  int r = (int)a + (int)b;
    90121  return (number)(r >= npPrimeM ? r - npPrimeM : r);
    91122}
     123static inline number npSubM(number a, number b)
     124{
     125  return (number)((int)a<(int)b ?
     126                       npPrimeM-(int)b+(int)a : (int)a-(int)b);
     127}
     128#else
     129static inline number npAddM(number a, number b)
     130{
     131   int res = (int)a + (int)b;
     132   res -= npPrimeM;
     133   res += (res >> 31) & npPrimeM;
     134   return (number)res;
     135}
     136static inline number npSubM(number a, number b)
     137{
     138   int res = (int)a - (int)b;
     139   res += (res >> 31) & npPrimeM;
     140   return (number)res;
     141}
     142#endif
    92143
    93 inline BOOLEAN npIsZeroM (number  a)
     144static inline BOOLEAN npIsZeroM (number  a)
    94145{
    95146  return 0 == (int)a;
     
    103154*/
    104155
    105 #define npSubM(a,b)    (number)((int)a<(int)b ?\
    106                        npPrimeM-(int)b+(int)a : (int)a-(int)b)
    107 
    108156#define npNegM(A)      (number)(npPrimeM-(int)(A))
    109157#define npEqualM(A,B)  ((int)A==(int)B)
    110 #define npIsZeroM(a)   (0 == (int)a)
     158
     159
     160#ifdef NV_OPS
     161static inline number nvMultM(number a, number b)
     162{
     163  return (number)
     164    ((((unsigned long long) a)*((unsigned long long) b)) % ((unsigned long long) npPrimeM));
     165}
     166number  nvMult        (number a, number b);
     167number  nvDiv         (number a, number b);
     168number  nvInvers      (number c);
    111169#endif
    112170
     171#endif
Note: See TracChangeset for help on using the changeset viewer.