Show
Ignore:
Timestamp:
06/05/08 14:58:48 (7 months ago)
Author:
pernet
Message:

Update the randiter:
* add the non-zero randiter class (following LinBox? structure)
* modify finite fields accordingly
* Update implementation of finite fields to fix bugs, improve efficiency and readability
* minor tweeks

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • include/fflas-ffpack/modular-int.h

    r62 r66  
    1818#include <sys/time.h> 
    1919#include "fflas-ffpack/modular-randiter.h" 
     20#include "fflas-ffpack/nonzero-randiter.h" 
    2021template< class Element > 
    2122class Modular; 
     
    2627        typedef unsigned long long uint64; 
    2728        typedef unsigned long FieldInt; 
    28  
     29         
    2930protected: 
    3031         
    31                 int modulus; 
    32  
    33                 double modulusinv; 
    34                  
    35          
    36                 int _two64; 
     32        int modulus; 
     33        double modulusinv; 
     34        int _two64; 
    3735                 
    3836        public:         
    3937                 
    40                 typedef int Element; 
    41                 typedef ModularRandIter<int> RandIter; 
    42  
    43                 const bool balanced; 
    44  
    45                  
    46                 Modular (int value)  : modulus(value), balanced(false) { 
    47                         modulusinv = 1 / ((double) value);  
    48                         _two64 = (int) ((uint64) (-1) % (uint64) value); 
    49                         _two64 += 1; 
    50                         if (_two64 >= value) _two64 -= value; 
    51                 } 
    52  
    53                 Modular(const Modular<int>& mf) : modulus(mf.modulus),modulusinv(mf.modulusinv),_two64(mf._two64), balanced(false){} 
    54  
    55                 const Modular &operator=(const Modular<int> &F) { 
    56                         modulus = F.modulus; 
    57                         modulusinv = F.modulusinv; 
    58                         _two64 = F._two64; 
    59                         return *this; 
    60                 } 
    61  
    62          
    63                 FieldInt &cardinality (FieldInt &c) const{  
    64                         return c = modulus; 
    65                 } 
    66  
    67                 FieldInt &characteristic (FieldInt &c) const { 
    68                         return c = modulus;  
    69                 } 
    70  
    71                 FieldInt &convert (FieldInt &x, const Element &y) const {  
    72                         return x = y; 
    73                 } 
     38        typedef int Element; 
     39        typedef ModularRandIter<int> RandIter; 
     40        typedef NonzeroRandIter<Modular<int>,RandIter> NonZeroRandIter; 
     41         
     42        const bool balanced; 
     43         
     44         
     45        Modular (int value)  : modulus(value), balanced(false) { 
     46                modulusinv = 1 / ((double) value);  
     47                _two64 = (int) ((uint64) (-1) % (uint64) value); 
     48                _two64 += 1; 
     49                if (_two64 >= value) _two64 -= value; 
     50        } 
     51         
     52        Modular(const Modular<int>& mf) : modulus(mf.modulus),modulusinv(mf.modulusinv),_two64(mf._two64), balanced(false){} 
     53         
     54        const Modular &operator=(const Modular<int> &F) { 
     55                modulus = F.modulus; 
     56                modulusinv = F.modulusinv; 
     57                _two64 = F._two64; 
     58                return *this; 
     59        } 
     60 
     61         
     62        FieldInt &cardinality (FieldInt &c) const{  
     63                return c = modulus; 
     64        } 
     65 
     66        FieldInt &characteristic (FieldInt &c) const { 
     67                return c = modulus;  
     68        } 
     69 
     70        FieldInt &convert (FieldInt &x, const Element &y) const {  
     71                return x = y; 
     72        } 
    7473        Element &convert (Element &x, const Element &y) const {  
    7574                return x = y; 
    7675        } 
    7776 
    78                 double & convert (double &x, const Element &y) const {  
    79                         return x = (double) y; 
    80                 } 
     77        double & convert (double &x, const Element &y) const {  
     78                return x = (double) y; 
     79        } 
    8180 
    8281        float & convert (float &x, const Element &y) const {  
     
    8483        } 
    8584                 
    86                 std::ostream &write (std::ostream &os) const { 
    87                         return os << "int mod " << modulus; 
     85        std::ostream &write (std::ostream &os) const { 
     86                return os << "int mod " << modulus; 
     87        } 
     88                 
     89        std::istream &read (std::istream &is) { 
     90                is >> modulus;  
     91                modulusinv = 1 /((double) modulus ); 
     92                _two64 = (int) ((uint64) (-1) % (uint64) modulus); 
     93                _two64 += 1; 
     94                if (_two64 >= modulus) _two64 -= modulus; 
     95                         
     96                return is; 
     97        } 
     98                 
     99        std::ostream &write (std::ostream &os, const Element &x) const { 
     100                return os << x; 
     101        } 
     102 
     103        std::istream &read (std::istream &is, Element &x) const { 
     104                FieldInt tmp; 
     105                is >> tmp; 
     106                init(x,tmp);  
     107                return is; 
     108        } 
     109                 
     110 
     111        template<class Element1> 
     112        Element &init (Element & x, const Element1 &y) const { 
     113                x = y % modulus; 
     114                if (x < 0) x += modulus; 
     115                return x; 
     116        } 
     117 
     118        Element &init (Element &x, const double &y) const  {  
     119                double z = fmod(y, (double)modulus); 
     120                if (z < 0) z += (double)modulus; 
     121                z += 0.5; 
     122                return x = static_cast<long>(z); //rounds towards 0 
     123        } 
     124        Element &init (Element &x, const float  &y) const  {  
     125                float z = fmod(y, (float)modulus); 
     126                if (z < 0) z += (float)modulus; 
     127                z += 0.5; 
     128                return x = static_cast<long>(z); //rounds towards 0 
     129        } 
     130 
     131        Element &init (Element &x, const FieldInt &y) const  { 
     132                x = y % modulus; 
     133                if (x < 0) x += modulus; 
     134                return x; 
     135        } 
     136 
     137        inline Element& init(Element& x, int y =0) const { 
     138                x = y % modulus; 
     139                if ( x < 0 ) x += modulus; 
     140                return x; 
     141        } 
     142 
     143        inline Element& init(Element& x, long y) const { 
     144                x = y % modulus; 
     145                if ( x < 0 ) x += modulus;  
     146                return x; 
     147        } 
     148                 
     149        inline Element& assign(Element& x, const Element& y) const { 
     150                return x = y; 
     151        } 
     152                                                                         
     153                 
     154        inline bool areEqual (const Element &x, const Element &y) const { 
     155                return x == y; 
     156        } 
     157 
     158        inline  bool isZero (const Element &x) const { 
     159                return x == 0;  
     160        } 
     161                 
     162        inline bool isOne (const Element &x) const { 
     163                return x == 1;  
     164        } 
     165 
     166        inline Element &add (Element &x, const Element &y, const Element &z) const { 
     167                x = y + z; 
     168                if ( x >= modulus ) x -= modulus; 
     169                return x; 
     170        } 
     171  
     172        inline Element &sub (Element &x, const Element &y, const Element &z) const { 
     173                x = y - z; 
     174                if (x < 0) x += modulus; 
     175                return x; 
     176        } 
     177                 
     178        inline Element &mul (Element &x, const Element &y, const Element &z) const { 
     179                int q; 
     180 
     181                q  = (int) ((((double) y)*((double) z)) * modulusinv);  // q could be off by (+/-) 1 
     182                x = (int) (y*z - q*modulus); 
     183                         
     184                         
     185                if (x >= modulus) 
     186                        x -= modulus; 
     187                else if (x < 0) 
     188                        x += modulus; 
     189 
     190                return x; 
     191        } 
     192  
     193        inline Element &div (Element &x, const Element &y, const Element &z) const { 
     194                Element temp; 
     195                inv (temp, z); 
     196                return mul (x, y, temp); 
     197        } 
     198  
     199        inline Element &neg (Element &x, const Element &y) const { 
     200                if(y == 0) return x=0; 
     201                else return x = modulus-y; 
     202        } 
     203  
     204        inline Element &inv (Element &x, const Element &y) const { 
     205                int d, t;                        
     206                XGCD(d, x, t, y, modulus); 
     207                if (x < 0) 
     208                        x += modulus; 
     209                return x;                
     210                                                               
     211        } 
     212 
     213        inline Element &axpy (Element &r,  
     214                              const Element &a,  
     215                              const Element &x,  
     216                              const Element &y) const { 
     217                int q; 
     218                         
     219                q  = (int) (((((double) a) * ((double) x)) + (double)y) * modulusinv);  // q could be off by (+/-) 1 
     220                r = (int) (a * x + y - q*modulus); 
     221                         
     222                         
     223                if (r >= modulus) 
     224                        r -= modulus; 
     225                else if (r < 0) 
     226                        r += modulus; 
     227 
     228                return r; 
     229 
     230        } 
     231 
     232        inline Element &addin (Element &x, const Element &y) const { 
     233                x += y; 
     234                if (  x >= modulus ) x -= modulus; 
     235                return x; 
     236        } 
     237  
     238        inline Element &subin (Element &x, const Element &y) const { 
     239                x -= y; 
     240                if (x < 0) x += modulus; 
     241                return x; 
     242        } 
     243  
     244        inline Element &mulin (Element &x, const Element &y) const { 
     245                return mul(x,x,y); 
     246        } 
     247  
     248        inline Element &divin (Element &x, const Element &y) const { 
     249                return div(x,x,y); 
     250        } 
     251  
     252        inline Element &negin (Element &x) const { 
     253                if (x == 0) return x;  
     254                else return x = modulus - x;  
     255        } 
     256  
     257        inline Element &invin (Element &x) const { 
     258                return inv (x, x); 
     259        } 
     260 
     261        inline Element &axpyin (Element &r, const Element &a, const Element &x) const { 
     262                int q; 
     263                         
     264                q  = (int) (((((double) a) * ((double) x)) + (double) r) * modulusinv);  // q could be off by (+/-) 1 
     265                r = (int) (a * x + r - q*modulus); 
     266                         
     267                         
     268                if (r >= modulus) 
     269                        r -= modulus; 
     270                else if (r < 0) 
     271                        r += modulus; 
     272 
     273                return r; 
     274        } 
     275 
     276private: 
     277 
     278        static void XGCD(int& d, int& s, int& t, int a, int b) { 
     279                int  u, v, u0, v0, u1, v1, u2, v2, q, r; 
     280                         
     281                int aneg = 0, bneg = 0; 
     282                         
     283                if (a < 0) { 
     284                        a = -a; 
     285                        aneg = 1; 
    88286                } 
    89                  
    90                 std::istream &read (std::istream &is) { 
    91                         is >> modulus;  
    92                         modulusinv = 1 /((double) modulus ); 
    93                         _two64 = (int) ((uint64) (-1) % (uint64) modulus); 
    94                         _two64 += 1; 
    95                         if (_two64 >= modulus) _two64 -= modulus; 
    96                          
    97                         return is; 
     287                         
     288                if (b < 0) { 
     289                        b = -b; 
     290                        bneg = 1; 
    98291                } 
    99                  
    100                 std::ostream &write (std::ostream &os, const Element &x) const { 
    101                         return os << x; 
     292                         
     293                u1 = 1; v1 = 0; 
     294                u2 = 0; v2 = 1; 
     295                u = a; v = b; 
     296                         
     297                while (v != 0) { 
     298                        q = u / v; 
     299                        r = u % v; 
     300                        u = v; 
     301                        v = r; 
     302                        u0 = u2; 
     303                        v0 = v2; 
     304                        u2 =  u1 - q*u2; 
     305                        v2 = v1- q*v2; 
     306                        u1 = u0; 
     307                        v1 = v0; 
    102308                } 
    103  
    104                 std::istream &read (std::istream &is, Element &x) const { 
    105                         FieldInt tmp; 
    106                         is >> tmp; 
    107                         init(x,tmp);  
    108                         return is; 
    109                 } 
    110                  
    111  
    112                 template<class Element1> 
    113                 Element &init (Element & x, const Element1 &y) const { 
    114                         x = y % modulus; 
    115                         if (x < 0) x += modulus; 
    116                         return x; 
    117                 } 
    118  
    119                 Element &init (Element &x, const double &y) const  {  
    120                   double z = fmod(y, (double)modulus); 
    121                   if (z < 0) z += (double)modulus; 
    122                   z += 0.5; 
    123                   return x = static_cast<long>(z); //rounds towards 0 
    124                 } 
    125                 Element &init (Element &x, const float  &y) const  {  
    126                         float z = fmod(y, (float)modulus); 
    127                   if (z < 0) z += (float)modulus; 
    128                   z += 0.5; 
    129                   return x = static_cast<long>(z); //rounds towards 0 
    130                 } 
    131  
    132                 Element &init (Element &x, const FieldInt &y) const  { 
    133                         x = y % modulus; 
    134                         if (x < 0) x += modulus; 
    135                         return x; 
    136                 } 
    137  
    138                 inline Element& init(Element& x, int y =0) const { 
    139                         x = y % modulus; 
    140                         if ( x < 0 ) x += modulus; 
    141                         return x; 
    142                 } 
    143  
    144                 inline Element& init(Element& x, long y) const { 
    145                         x = y % modulus; 
    146                         if ( x < 0 ) x += modulus;  
    147                         return x; 
    148                 } 
    149                  
    150                 inline Element& assign(Element& x, const Element& y) const { 
    151                         return x = y; 
    152                 } 
    153                                                                          
    154                  
    155                 inline bool areEqual (const Element &x, const Element &y) const { 
    156                         return x == y; 
    157                 } 
    158  
    159                 inline  bool isZero (const Element &x) const { 
    160                         return x == 0;  
    161                 } 
    162                  
    163                 inline bool isOne (const Element &x) const { 
    164                         return x == 1;  
    165                 } 
    166  
    167                 inline Element &add (Element &x, const Element &y, const Element &z) const { 
    168                         x = y + z; 
    169                         if ( x >= modulus ) x -= modulus; 
    170                         return x; 
    171                 } 
    172   
    173                 inline Element &sub (Element &x, const Element &y, const Element &z) const { 
    174                         x = y - z; 
    175                         if (x < 0) x += modulus; 
    176                         return x; 
    177                 } 
    178                  
    179                 inline Element &mul (Element &x, const Element &y, const Element &z) const { 
    180                         int q; 
    181  
    182                         q  = (int) ((((double) y)*((double) z)) * modulusinv);  // q could be off by (+/-) 1 
    183                         x = (int) (y*z - q*modulus); 
    184                          
    185                          
    186                         if (x >= modulus) 
    187                                 x -= modulus; 
    188                         else if (x < 0) 
    189                                 x += modulus; 
    190  
    191                         return x; 
    192                 } 
    193   
    194                 inline Element &div (Element &x, const Element &y, const Element &z) const { 
    195                         Element temp; 
    196                         inv (temp, z); 
    197                         return mul (x, y, temp); 
    198                 } 
    199   
    200                 inline Element &neg (Element &x, const Element &y) const { 
    201                         if(y == 0) return x=0; 
    202                         else return x = modulus-y; 
    203                 } 
    204   
    205                 inline Element &inv (Element &x, const Element &y) const { 
    206                         int d, t;                        
    207                         XGCD(d, x, t, y, modulus); 
    208                         if (x < 0) 
    209                                 x += modulus; 
    210                         return x;                
    211                                                                
    212                 } 
    213  
    214                 inline Element &axpy (Element &r,  
    215                                       const Element &a,  
    216                                       const Element &x,  
    217                                       const Element &y) const { 
    218                         int q; 
    219                          
    220                         q  = (int) (((((double) a) * ((double) x)) + (double)y) * modulusinv);  // q could be off by (+/-) 1 
    221                         r = (int) (a * x + y - q*modulus); 
    222                          
    223                          
    224                         if (r >= modulus) 
    225                                 r -= modulus; 
    226                         else if (r < 0) 
    227                                 r += modulus; 
    228  
    229                         return r; 
    230  
    231                 } 
    232  
    233                 inline Element &addin (Element &x, const Element &y) const { 
    234                         x += y; 
    235                         if (  x >= modulus ) x -= modulus; 
    236                         return x; 
    237                 } 
    238   
    239                 inline Element &subin (Element &x, const Element &y) const { 
    240                         x -= y; 
    241                         if (x < 0) x += modulus; 
    242                         return x; 
    243                 } 
    244   
    245                 inline Element &mulin (Element &x, const Element &y) const { 
    246                         return mul(x,x,y); 
    247                 } 
    248   
    249                 inline Element &divin (Element &x, const Element &y) const { 
    250                         return div(x,x,y); 
    251                 } 
    252   
    253                 inline Element &negin (Element &x) const { 
    254                         if (x == 0) return x;  
    255                         else return x = modulus - x;  
    256                 } 
    257   
    258                 inline Element &invin (Element &x) const { 
    259                         return inv (x, x); 
    260                 } 
    261  
    262                 inline Element &axpyin (Element &r, const Element &a, const Element &x) const { 
    263                         int q; 
    264                          
    265                         q  = (int) (((((double) a) * ((double) x)) + (double) r) * modulusinv);  // q could be off by (+/-) 1 
    266                         r = (int) (a * x + r - q*modulus); 
    267                          
    268                          
    269                         if (r >= modulus) 
    270                                 r -= modulus; 
    271                         else if (r < 0) 
    272                                 r += modulus; 
    273  
    274                         return r; 
    275                 } 
    276  
    277                 private: 
    278  
    279                 static void XGCD(int& d, int& s, int& t, int a, int b) { 
    280                         int  u, v, u0, v0, u1, v1, u2, v2, q, r; 
    281                          
    282                         int aneg = 0, bneg = 0; 
    283                          
    284                         if (a < 0) { 
    285                                 a = -a; 
    286                                 aneg = 1; 
    287                         } 
    288                          
    289                         if (b < 0) { 
    290                                 b = -b; 
    291                                 bneg = 1; 
    292                         } 
    293                          
    294                         u1 = 1; v1 = 0; 
    295                         u2 = 0; v2 = 1; 
    296                         u = a; v = b; 
    297                          
    298                         while (v != 0) { 
    299                                 q = u / v; 
    300                                 r = u % v; 
    301                                 u = v; 
    302                                 v = r; 
    303                                 u0 = u2; 
    304                                 v0 = v2; 
    305                                 u2 =  u1 - q*u2; 
    306                                 v2 = v1- q*v2; 
    307                                 u1 = u0; 
    308                                 v1 = v0; 
    309                         } 
    310                          
    311                         if (aneg) 
    312                                 u1 = -u1; 
    313                          
    314                         if (bneg) 
    315                                 v1 = -v1; 
    316                          
    317                         d = u; 
    318                         s = u1; 
    319                         t = v1; 
    320                 } 
    321                  
    322         }; 
     309                         
     310                if (aneg) 
     311                        u1 = -u1; 
     312                         
     313                if (bneg) 
     314                        v1 = -v1; 
     315                         
     316                d = u; 
     317                s = u1; 
     318                t = v1; 
     319        } 
     320                 
     321}; 
    323322 
    324323