fast_Ring.cpp

Go to the documentation of this file.
00001 
00006 #include <cstdlib>
00007 #include <exception>
00008 #include <new>
00009 
00010 
00012 template <class TNum, class kdefs>
00013 fast_Ring<TNum,kdefs>::fast_Ring(       unsigned short _char, 
00014                                                 unsigned short _epsPrec) :      characteristic(_char),
00015                                                                                         epsilon(_epsPrec), 
00016                                                                                         generator(getGenerator())
00017 {
00018         assert(TNum::wellDefined(characteristic));
00019         assert( epsilon <= 1 );
00020         init();
00021         assert( wellDefined() );
00022 }
00023 
00024 
00025 template <class TNum, class kdefs>
00026 bool            fast_Ring<TNum,kdefs>::wellDefined()
00027 {
00028         TNum num;
00029         assert (num.wellDefined(characteristic) );
00030         return true;
00031 }
00032 
00034 template <class TNum,class kdefs>
00035 inline void     fast_Ring< TNum, kdefs>::init() 
00036 {
00037         additiveInverseTable            =NULL;
00038         multiplicationTable             =NULL;
00039         additionTable                   =NULL;
00040         multiplicativeInverseTable      =NULL;
00041         
00042         fastAdditionTable               =NULL;
00043         elementsToExponentsTab          =NULL;
00044         exponentsToElementTab           =NULL;
00045 
00046         sqrtTable               =NULL;
00047         
00048         moduloTable = NULL;
00049 
00050         try
00051         {
00052                 if (additionTable==NULL)
00053                         additionTable = createAdditionTable();
00054         
00055                 if (additiveInverseTable==NULL)
00056                         additiveInverseTable = createAdditiveInverseTable();
00057         
00058                 if (multiplicationTable==NULL)
00059                         multiplicationTable = createMultiplicationTable();
00060                 
00061         
00062                 if (multiplicativeInverseTable==NULL)
00063                         multiplicativeInverseTable = createMultiplicativeInverseTable();
00064         
00065                 if (fastAdditionTable==NULL)
00066                         fastAdditionTable = createFastAdditionTable();
00067         
00068                 if (elementsToExponentsTab==NULL)
00069                         elementsToExponentsTab = initElementsToExponentsTab(generator);
00070         
00071                 if (exponentsToElementTab==NULL)
00072                         exponentsToElementTab = initExponentsToElementTab(generator);
00073 
00074                 if (sqrtTable==NULL)
00075                         sqrtTable = createSqrtTable( );
00076 
00077                 if (moduloTable==NULL)
00078                         moduloTable=createModuloTable();
00079         }
00080         catch(std::bad_alloc &e)
00081         {
00082                 std::cerr << "Memory allocation error in fast_Ring::init() " << std::endl;
00083                 exit(0);
00084         }
00085         catch(...)
00086         {
00087                 std::cerr << "Error in creating ring operation Tables, " << std::endl;
00088                 exit(0);
00089         }
00090 }
00091 
00092 
00093 
00094 template <class TNum,class kdefs>
00095 fast_Ring<TNum,kdefs>::~fast_Ring()
00096 {
00097         if (additiveInverseTable!=NULL)                 {       delete[] additiveInverseTable;  
00098                                                                         additiveInverseTable = NULL;    }
00099 
00100         if (multiplicationTable!=NULL)          {        delete[] multiplicationTable;  
00101                                                                         multiplicationTable = NULL;     }
00102 
00103         if (additionTable!=NULL)                        {       delete[] additionTable;  
00104                                                                         additionTable = NULL;           }
00105 
00106         if (multiplicativeInverseTable!=NULL)   {        delete[] multiplicativeInverseTable;
00107                                                                          multiplicativeInverseTable = NULL;     }
00108         
00109         if ( fastAdditionTable!=NULL   )                {       delete[]        fastAdditionTable;       
00110                                                                         fastAdditionTable = NULL;               }
00111 
00112         if ( elementsToExponentsTab!=NULL )     {       delete[]        elementsToExponentsTab; 
00113                                                                         elementsToExponentsTab = NULL;  }
00114 
00115         if ( exponentsToElementTab!=NULL )              {       delete[]        exponentsToElementTab;   
00116                                                                         exponentsToElementTab = NULL;   }
00117 
00118         if ( sqrtTable!=NULL )                  {       delete[]        sqrtTable;       
00119                                                                         sqrtTable = NULL;       }
00120 
00121         if ( moduloTable!=NULL )                        {       delete[]        moduloTable;     
00122                                                                         moduloTable = NULL;     }
00123 
00124 }
00125 
00126 
00127 
00128 
00129 
00130 //----------------------Convert---------------------------------------------------
00131 
00132 
00140 template <class TNum, class kdefs>
00141 template <class TConvNum >
00142 inline  TNum fast_Ring<TNum, kdefs>::Convert(const TConvNum  src ) const
00143 {
00144         #ifdef SAFE
00145                 assert( getEpsPrecision()<=1 );
00146         #endif
00147         
00148         TNum    z;
00149         
00150         z.setX( ConvertScalar( src.getX() ) );
00151         //alternativ: 
00152         //int   currEpsPrecision = 0;
00153         //z.setValue(currEpsPrecision, ConvertScalar( a.getValue(currEpsPrecision) ) );
00154         
00155         if ( getEpsPrecision()==1 )
00156         {
00157                 z.setEps( ConvertScalar(src.getEps() ) );
00158                 //alternativ: 
00159                 //currEpsPrecision=1;
00160                 //z.setValue(currEpsPrecision, ConvertScalar( a.getValue(currEpsPrecision) ) );
00161         }
00162         return z;
00163 }
00164 
00165 template <class TNum, class kdefs>
00166 inline  TNum fast_Ring<TNum, kdefs>::Convert(const double  a) const
00167 {
00168         #ifdef SAFE
00169                 assert( getEpsPrecision()<=1 );
00170         #endif
00171         
00172         TNum    z;
00173         
00174         z.setX( ConvertScalar( a ) );
00175         
00176         return z;
00177 }
00178 
00179 template <class TNum, class kdefs>
00180 inline  TNum fast_Ring<TNum, kdefs>::Convert(const int  a) const
00181 {
00182         #ifdef SAFE
00183                 assert( getEpsPrecision()<=1 );
00184         #endif
00185         
00186         TNum    z;
00187         
00188         z.setX( ConvertScalar( a ) );
00189         
00190         return z;
00191 }
00192 
00193 /*
00194 template <class TNum, class kdefs>
00195 template < const int>
00196 inline  TNum fast_Ring<TNum, kdefs>::Convert(const int  a) const
00197 {
00198         #ifdef SAFE
00199                 assert( getEpsPrecision()<=1 );
00200         #endif
00201         
00202         TNum    z;
00203         
00204         z.setX( ConvertScalar( a ) );
00205         //alternativ: 
00206         //int   currEpsPrecision = 0;
00207         //z.setValue(currEpsPrecision, ConvertScalar( a.getValue(currEpsPrecision) ) );
00208         
00209         return z;
00210 }*/
00211 
00216 template <class TNum,class kdefs>
00217 template <class TConvNum >
00218 inline  void fast_Ring<TNum, kdefs>::ConvertInPlace( TConvNum & a) const
00219 {
00220 
00221         assert( a.getEpsPrecision()<=1 );
00222         
00223         
00224         a.setX( ConvertScalar(a.getX() ) );
00225         
00226         if ( getEpsPrecision()==1 )
00227                 a.setEps( ConvertScalar(a.getEps() ) );
00228 
00229         #ifdef SAFE
00230                 assert(a.getX()   ==  ConvertScalar(a.getX() ) );
00231                 assert(a.getEps() ==  ConvertScalar(a.getEps() ) );
00232         #endif
00233 
00234         return ;
00235 }
00236 
00238 template <class TNum, class kdefs>
00239 inline int       fast_Ring<TNum,kdefs>::ConvertScalar(const int  a) const
00240 {
00241         int res = a;
00242         while (res<0)
00243         {
00244                 res += getCharacteristic();
00245         }
00246         if ( res >= getCharacteristic() ) 
00247         {       
00248                 res %= getCharacteristic();
00249         }
00250         // Alternativ zur Modulo-Rechnung:
00251         //while (res >=getCharacteristic()<)
00252         //{
00253         //      res -= getCharacteristic();
00254         //}
00255         return res;
00256  }
00257 
00258 
00260 template <class TNum,class kdefs>
00261 inline int fast_Ring<TNum,kdefs>::ConvertScalarSpec(const int a) const
00262 {
00263         #ifdef SAFE
00264                 assert(a>=0);
00265         #endif
00266         return  a % getCharacteristic();
00267  }
00268 
00269 
00270  
00273 
00274  template <class TNum,class kdefs>
00275 inline  int fast_Ring<TNum,kdefs>::FastConvertScalar(const int  a) const
00276 {
00277         return ( a + getCharacteristic() ) % getCharacteristic();
00278  }
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 //----------------------Add---------------------------------------------------
00288 
00289 template <class TNum,class kdefs>
00290 inline TNum     fast_Ring< TNum, kdefs>::add( const TNum a, const  TNum b) const
00291 {
00292         #ifdef SAFE
00293                 assert(Convert(a)==a);
00294                 assert(Convert(b)==b);
00295         #endif
00296         return additionTable[ getPairIndex(a, b) ];
00297 }
00298 
00299 
00300 
00301 
00302 template <class TNum,class kdefs>
00303 inline TNum     fast_Ring< TNum, kdefs>::addRef( const TNum &a, const  TNum &b) const
00304 {
00305         #ifdef SAFE
00306                 assert(Convert(a)==a);
00307                 assert(Convert(b)==b);
00308         #endif
00309         return additionTable[ getPairIndexByRef(a, b) ];
00310 }
00311 
00312 
00313 
00314 
00315 
00316 //----------------------Add in place---------------------------------------------------
00317 
00318 template <class TNum,class kdefs>
00319 inline void fast_Ring< TNum, kdefs>::addInPlace(TNum& a, const TNum b) const
00320 {
00321         #ifdef SAFE
00322                 assert(Convert(a)==a);
00323                 assert(Convert(b)==b);
00324         #endif
00325 
00326         a= this->additionTable[ getPairIndex(a, b) ];
00327         return;
00328 
00329         
00330 }
00331 
00332         
00333 template <class TNum,class kdefs>
00334 inline void fast_Ring< TNum, kdefs>::addInPlaceRef(TNum& a, const TNum &b) const
00335 {
00336         #ifdef SAFE
00337                 assert(Convert(a)==a);
00338                 assert(Convert(b)==b);
00339         #endif
00340 
00341         a = this->additionTable[ getPairIndexByRef(a, b) ];
00342         return;
00343 }
00344 
00345 
00346 
00347 
00348 //----------------------Additive Inverse---------------------------------------------------
00349 
00350 
00351 template <class TNum,class kdefs>
00352 inline TNum  fast_Ring< TNum, kdefs>::addInv(const TNum a) const
00353 {
00354         #ifdef SAFE
00355                 assert(Convert(a)==a);
00356         #endif
00357         return additiveInverseTable[ getSingleIndex(a) ];
00358 }
00359 
00360 
00361 
00362 
00363 template <class TNum,class kdefs>
00364 inline TNum  fast_Ring< TNum, kdefs>::addInvRef(const TNum& a) const
00365 {
00366         #ifdef SAFE
00367                 assert(Convert(a)==a);
00368         #endif
00369         return additiveInverseTable[ getSingleIndexByRef(a) ];
00370 }
00371 
00372 
00373 
00374 template <class TNum, class kdefs>
00375 inline void     fast_Ring< TNum, kdefs>::addInvInPlace( TNum  & a) const
00376 {
00377         #ifdef SAFE
00378                 assert(Convert(a)==a);
00379         #endif
00380         a=additiveInverseTable[ getSingleIndexByRef(a) ];
00381         return;
00382 }
00383 
00384 
00385 
00386 
00387 
00388 
00389 //-------------------------------multiply-------------------------------------------
00390 
00391 
00392 
00393 
00394 
00395 template <class TNum,class kdefs>
00396 inline  TNum   fast_Ring< TNum, kdefs>::multiply(const TNum a, const TNum b) const
00397 {
00398         #ifdef SAFE
00399                 assert(Convert(a)==a);
00400                 assert(Convert(b)==b);
00401         #endif
00402 
00403         return multiplicationTable[getPairIndex(a, b)];
00404 }
00405 
00406 
00407 
00408 // inline bringt hier kaum Zeitvorteil.
00410 template <class TNum,class kdefs>
00411  inline  TNum  fast_Ring< TNum, kdefs>::multiplyRef(const TNum & a, const TNum & b) const
00412 {
00413         #ifdef SAFE
00414                 assert(Convert(a)==a);
00415                 assert(Convert(b)==b);
00416         #endif
00417 
00418         return multiplicationTable[getPairIndexByRef(a, b)];
00419 }
00420 
00421 
00422 
00423 //-------------------------------multiply in place-------------------------------------------
00424 
00425 
00426 
00427 template <class TNum,class kdefs>
00428 inline void  fast_Ring< TNum, kdefs>::multiplyInPlace(TNum &a, const TNum b) const
00429 {
00430         #ifdef SAFE
00431                 assert(Convert(a)==a);
00432                 assert(Convert(b)==b);
00433         #endif
00434         a = multiplicationTable[ getPairIndex(a, b) ];
00435 }
00436 
00437 
00438 template <class TNum,class kdefs>
00439 inline void  fast_Ring< TNum, kdefs>::multiplyInPlaceRef(TNum &a, const TNum &  b) const
00440 {
00441         #ifdef SAFE
00442                 assert(Convert(a)==a);
00443                 assert(Convert(b)==b);
00444         #endif
00445         a = multiplicationTable[ getPairIndexByRef(a, b) ];
00446 }
00447 
00448 //-------------------------------scalarmultiply-------------------------------------------
00449 
00450 
00451 
00452 
00453 
00454 template <class TNum,class kdefs>
00455 inline  TNum   
00456 fast_Ring< TNum, kdefs>::scalarMultiply(const FieldType::ElementType a, const TNum b) const
00457 {
00458         #ifdef SAFE
00459                 assert(Convert(TNum(a))==a);
00460                 assert(Convert(b)==b);
00461         #endif
00462 
00463         return multiplicationTable[getPairIndex(a, b)];
00464 }
00465 
00466 
00467 
00468 // inline bringt hier kaum Zeitvorteil.
00470 template <class TNum,class kdefs>
00471  inline  TNum  
00472 fast_Ring< TNum, kdefs>::scalarMultiplyRef(const FieldType::ElementType & a, const TNum & b) const
00473 {
00474         #ifdef SAFE
00475                 assert(Convert(TNum(a))==a);
00476                 assert(Convert(b)==b);
00477         #endif
00478 
00479         return multiplicationTable[getPairIndexByRef(a, b)];
00480 }
00481 
00482 
00483 
00484 //-------------------------------scalarmultiply in place-------------------------------------------
00485 
00486 
00487 template <class TNum,class kdefs>
00488 inline void  
00489 fast_Ring< TNum, kdefs>::scalarMultiplyInPlace(const FieldType::ElementType     a,
00490                                                                                                 TNum & b ) const
00491 {
00492         #ifdef SAFE
00493                 assert(Convert(TNum(a))==a);
00494                 assert(Convert(b)==b);
00495         #endif
00496         b = multiplicationTable[ getPairIndex(a, b) ];
00497 }
00498 
00499 
00500 template <class TNum,class kdefs>
00501 inline void  
00502 fast_Ring< TNum, kdefs>::scalarMultiplyInPlaceRef(const FieldType::ElementType & a,
00503                                                                                                  TNum &  b      ) const
00504 {
00505         #ifdef SAFE
00506                 assert(Convert(TNum(a))==a);
00507                 assert(Convert(b)==b);
00508         #endif
00509         b = multiplicationTable[ getPairIndexByRef(a, b) ];
00510 }
00511 
00512 //-------------------------------multiply by exponents-------------------------------------------
00513 
00514 
00515 template <class TNum,class kdefs>
00516 inline TNum const   fast_Ring< TNum, kdefs>::multByExp(const TNum a, const TNum b) const
00517 {
00518         if (a.isZero() || b.isZero() )
00519                 return TNum::Zero;
00520 
00521         register short res = a.getX()+b.getX();
00522         if ( res>=getCharacteristic() )
00523                 return res-getCharacteristic();
00524         return res;
00525 }
00526 
00527 
00528 
00529 template <class TNum,class kdefs>
00530 inline TNum const   fast_Ring< TNum, kdefs>::multByExpRef(const TNum & a, const TNum & b) const
00531 {
00532         if (a.isZero() || b.isZero() )
00533                 return TNum::Zero;
00534 
00535         register short res = a.getX()+b.getX();
00536         if (res>=getCharacteristic())
00537                 return res-getCharacteristic();
00538         return res;
00539 }
00540 
00541 
00542 
00543 template <class TNum,class kdefs>
00544 inline void  fast_Ring< TNum, kdefs>::multByExpInPlace( TNum & a, const TNum  b) const
00545 {
00546         if (a.isZero() || b.isZero() )
00547                  a=TNum::Zero;
00548 
00549         register short res = a.getX()+b.getX();
00550         if (res>=getCharacteristic())
00551                 a=res-getCharacteristic();
00552         a=res;
00553 }
00554 
00555 
00556 
00557 template <class TNum,class kdefs>
00558 inline void  fast_Ring< TNum, kdefs>::multByExpInPlaceRef( TNum & a, const TNum & b) const
00559 {
00560         if (a.isZero() ||b.isZero())
00561                  a=TNum::Zero;
00562 
00563         register unsigned short res = a.getX() + b.getX();
00564         if (res>getCharacteristic()-1)
00565                 a= res-getCharacteristic();
00566         return;
00567 }
00568 //-------------------------------multiplicative inverse-------------------------------------------
00569 
00570 // invers: sollte nur skalare invertieren und nicht zahlen. -
00571 //  no das ist ja ein superring und kann auch mit basicNumber rechnen :-)
00572 template <class TNum,class kdefs>
00573 inline  TNum  fast_Ring< TNum, kdefs>::multInv(const TNum  a) const
00574 {
00575         #ifdef SAFE
00576                 assert( a==Convert(a) );
00577         #endif
00578         TNum const &  res = multiplicativeInverseTable[ getSingleIndex( a)];
00579         if (res.isNotZero() ) 
00580         {
00581                 return res;
00582         }
00583         else 
00584         {
00585                 std::cerr << "Multiplicative inverse does not exist!" << std::endl;
00586                 throw "Multiplicative inverse does not exist!" ;
00587         }
00588 }
00589 
00590 // invers: sollte nur skalare invertieren und nicht zahlen.
00591 template <class TNum,class kdefs>
00592 inline  TNum  fast_Ring< TNum, kdefs>::multInvRef(const TNum & a) const
00593 {
00594         #ifdef SAFE
00595                 assert( a==Convert(a) );
00596         #endif
00597         TNum const &    res = multiplicativeInverseTable[ getSingleIndexByRef( a) ];
00598         if (res.isNotZero() ) 
00599         {
00600                 return res;
00601         }
00602         else 
00603         {
00604                 std::cerr << "Multiplicative inverse does not exist!" << std::endl;
00605                 throw "Multiplicative inverse does not exist!" ;
00606         }
00607 }
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 // invers: sollte nur skalare invertieren und nicht zahlen.
00616 template <class TNum,class kdefs>
00617 inline void fast_Ring< TNum, kdefs>::multInvInPlace( TNum & a) const
00618 {
00619         #ifdef SAFE
00620                 assert( a==Convert(a) );
00621         #endif
00622         TNum const &    res = multiplicativeInverseTable[getSingleIndex( a)];
00623         if (res.isNotZero() ) 
00624         {
00625                 a = res;
00626         }
00627         else 
00628         {
00629                 std::cerr << "Multiplicative inverse does not exist!" << std::endl;
00630                 throw "Multiplicative inverse does not exist!" ;
00631         }
00632 }
00633 
00634 
00635 
00636 
00637 //-------------------------------accMmult-------------------------------------------
00638 
00639 
00640 template <class TNum,class kdefs>
00641 inline void fast_Ring<TNum,kdefs>::accMult( TNum& a ,const TNum b , const TNum c)  const
00642 {
00643         #ifdef SAFE
00644                 assert(Convert(a)==a);
00645                 assert(Convert(b)==b);
00646                 assert(Convert(c)==c);
00647         #endif
00648         #ifdef COUNT
00649                 accMultCount=accMultCount+1;
00650         #endif
00651         a=additionTable[ getPairIndex (a, multiplicationTable[ getPairIndex(b, c)] ) ];
00652 }
00653 
00654 
00655 template <class TNum,class kdefs>
00656 inline void fast_Ring<TNum,kdefs>::accMult( TNum* a ,const TNum b , const TNum c)  const
00657 {
00658         #ifdef SAFE
00659                 assert(Convert(a)==a);
00660                 assert(Convert(b)==b);
00661                 assert(Convert(c)==c);
00662         #endif
00663         #ifdef COUNT
00664                 accMultCount=accMultCount+1;
00665         #endif
00666 
00667         *a = additionTable[ getPairIndex( *a,multiplicationTable[ getPairIndex(b, c)] ) ];
00668 }
00669 
00670 
00671 
00672 template <class TNum,class kdefs>
00673 inline void fast_Ring<TNum,kdefs>::accMultRef( TNum& a ,const TNum& b , const TNum& c)  const
00674 {
00675         #ifdef SAFE
00676                 assert(Convert(a)==a);
00677                 assert(Convert(b)==b);
00678                 assert(Convert(c)==c);
00679         #endif
00680         #ifdef COUNT
00681                 accMultCount=accMultCount+1;
00682         #endif
00683 
00684         a=additionTable[ getPairIndexByRef(a, multiplicationTable[ getPairIndex(b, c) ]) ];
00685 }
00686 
00687 
00688 
00696 template <class TNum,class kdefs>
00697 inline void 
00698 fast_Ring<TNum,kdefs>::accMultSpec( TNum* const a ,const TNum b , const TNum * const c)  const
00699 {
00700         #ifdef SAFE
00701                 assert(Convert(*a)==*a);
00702                 assert(Convert(b)==b);
00703                 assert(Convert(*c)==*c);
00704         #endif
00705 
00706         #ifdef COUNT
00707                 accMultCount=accMultCount+1;
00708         #endif 
00709 
00710         *a=additionTable[ getPairIndex(*a, multiplicationTable[ getPairIndex(b, *c)]) ];
00711 
00712         /*
00713         #if EPSPRECISION==1
00714         
00715                 register TNum tmp=multiplicationTable[getPairIndex(b, *c)];
00716                 register short a2=tmp.getX()+a->getX();
00717                 if (a2>=getCharacteristic())
00718                         a->setX(a2-getCharacteristic());
00719                 else
00720                         a->setX(a2);
00721                 a2=tmp.getEps()+a->getEps();
00722                 if (a2>=getCharacteristic())
00723                         a->setEps(a2-getCharacteristic());
00724                 else
00725                         a->setEps(a2);
00726         
00727         #else
00728                 //  on Pentiums following code has catastrophic performance: but on hoech its fast
00729                 int tmp=(*a).getX()+multiplicationTable[getPairIndex(b, *c)].getX();
00730                 if (tmp>=getCharacteristic())
00731                         (a)->setX(tmp-getCharacteristic());
00732                 else
00733                         (a)->setX(tmp);
00734         #endif*/
00735 
00736 }
00737 
00738 
00739 template <class TNum,class kdefs>
00740 inline          typename fast_Ring<TNum,kdefs>::sqrtInf_t       fast_Ring<TNum,kdefs>::sqrt     ( const TNum a)  const
00741 {
00742         #ifdef SAFE
00743                 assert(Convert(a)==a);
00744                 
00745         #endif
00746         assert( a.getEps()==0 );
00747         return  sqrtTable[ a.getX() ];
00748 }
00749 
00750 template <class TNum,class kdefs>
00751 inline          typename fast_Ring<TNum,kdefs>::sqrtInf_t               fast_Ring<TNum,kdefs>::sqrtRef  ( const TNum &a) const
00752 {
00753         #ifdef SAFE
00754                 assert(Convert(*a)==*a);
00755         #endif
00756         assert( a.getEps()==0 );
00757         return sqrtTable[ a.getX() ];
00758 }
00759 
00760 
00762 template <class TNum,class kdefs>
00763 inline void fast_Ring<TNum,kdefs>::accMultAddr( TNum* a ,const TNum* b , const TNum* c)  const
00764 {
00765         #ifdef SAFE
00766                 assert(Convert(a)==a);
00767                 assert(Convert(b)==b);
00768                 assert(Convert(c)==c);
00769         #endif
00770         *a = additionTable[getPairIndex(*a, multiplicationTable[ getPairIndex(*b, *c)]) ];
00771 }
00772 
00773 
00774 
00780 template <class TNum,class kdefs>
00781  TNum fast_Ring<TNum,kdefs>::getGenerator()
00782 {
00783         std::cerr << " getGenerator () " << std::endl;
00784         if (getEpsPrecision()>0)
00785         {
00786                 std::cerr << " Warning: getGenerator()  is not implemented for epsPrecision>0 !";
00787                 std::cerr << std::endl;
00788 
00789                 return TNum::Zero;
00790         }
00791         for (int m=1; m<getCharacteristic(); m++)
00792         {
00793                 TNum erzeuger = m;
00794                 TNum tmp = erzeuger;
00795                 assert (tmp==erzeuger);
00796 
00797                 bool erz=true;
00798 
00799                 for (int n=0; n<getCharacteristic()-1; n++)
00800                 {
00801 
00802                         tmp.setX(     (unsigned int ) 
00803                                         ( (unsigned int )tmp.getX() * (unsigned int )erzeuger.getX() )
00804                                         % getCharacteristic()
00805                                 );
00806         
00807                         if ( (tmp.getX()==erzeuger.getX()) && (n<( getCharacteristic() - 2 )) )
00808                         {
00809                                 erz=false;
00810                         }
00811                 }
00812 
00813                 if (erz)
00814                 {
00815                         tmp = erzeuger;
00816                         return erzeuger;
00817         
00818                 }
00819         }
00820         std::cerr << " Error: kein Erzeuger gefunden !  - da gibt es einen Fehler! " << std::endl;
00821         exit(0);
00822         return TNum::Zero;
00823 }
00824 
00825 
00826 
00827 
00841 template <class TNum,class kdefs>
00842  TNum * fast_Ring<TNum, kdefs>::createAdditionTable()
00843 {
00844 
00845         unsigned short i, j, k , l;  // sollte nicht unb short sein, sondern vom basistyp abhaengen
00846 
00847         TNum * tAdditionTable=0;
00848 
00849         size_t tableSize = getMaxPairIndex() + 1;
00850         std::cerr << "createAdditionTable::tableSize = " << tableSize << std::endl;
00851         tAdditionTable = new TNum[tableSize];
00852 
00853         for (i=0; i<getCharacteristic(); i++)
00854                 for (j=0; j<((getCharacteristic()-1)*getEpsPrecision())+1; j++)
00855                         for (k=0; k<getCharacteristic(); k++)
00856                                 for (l=0; l<((getCharacteristic()-1)*getEpsPrecision())+1; l++)
00857                                 {
00858                                         TNum    z1(i, j);
00859                                         TNum    z2(k, l);
00860                                         size_t index = getPairIndex(z1, z2);
00861                                         assert(index <  tableSize && index>=0);
00862 
00863                                         tAdditionTable[index].setX   (
00864                                                                                   ( (int)z1.getX() + (int)z2.getX()  )
00865                                                                                 % getCharacteristic() 
00866                                                                         );
00867 
00868                                         tAdditionTable[index].setEps ( 
00869                                                                                   ((int)z1.getEps() + (int)z2.getEps())
00870                                                                                 % getCharacteristic() 
00871                                                                         );
00872                                 }
00873         return tAdditionTable;
00874 }
00875 
00876 
00878 template <class TNum,class kdefs>
00879  TNum* fast_Ring<TNum,kdefs>::createFastAdditionTable()
00880 {
00881         TNum * tfastAdditionTable=NULL;
00882 
00883         if (getEpsPrecision()==0)
00884         {
00885 
00886                 tfastAdditionTable = new TNum[ getCharacteristic()*2 ];
00887         
00888                 for (int m=0; m<getCharacteristic(); m++)
00889                 {
00890                         tfastAdditionTable[m]=m;        
00891                 }
00892         
00893                 for (int m=0; m<getCharacteristic(); m++)
00894                 {
00895                         tfastAdditionTable[m + getCharacteristic() ]=m; 
00896                 }
00897         }
00898         return tfastAdditionTable;
00899 }
00900 
00902 template <class TNum,class kdefs>
00903  TNum*  fast_Ring<TNum,kdefs>::createAdditiveInverseTable()
00904 {
00905         int i, j; 
00906 
00907         size_t  tableSize = getMaxSingleIndex() + 1;
00908 
00909         TNum*   tadditiveInverseTable = new TNum[ tableSize ];
00910 
00911         for (i=0; i<getCharacteristic(); i++)
00912                 for (j=0; j<( ( getCharacteristic()-1 )*getEpsPrecision() )+1; j++)
00913                 {
00914                         TNum    z1(i, j);
00915 
00916                         size_t  index = getSingleIndex( z1); 
00917                         assert(index<tableSize && index>=0);
00918 
00919                         TNum    z2(     ( getCharacteristic() - i) % getCharacteristic(),
00920                                          (getCharacteristic() - j) % getCharacteristic()    );
00921 
00922                         tadditiveInverseTable[ index ] = z2;
00923                 }
00924         return tadditiveInverseTable;
00925 }
00926 
00927 
00928 
00929 
00931 template <class TNum,class kdefs>
00932 TNum * fast_Ring<TNum, kdefs>::createMultiplicationTable()
00933 {       
00934         int i, j, k, l; 
00935 
00936         TNum * tMultiplicationTable = NULL;
00937         
00938         size_t tableSize = getMaxPairIndex() + 1;
00939 
00940         tMultiplicationTable = new TNum[tableSize];
00941 
00942         for (i=0; i< getCharacteristic(); i++)
00943                 for (j=0; j<( (getCharacteristic()-1)*getEpsPrecision() )+1; j++)
00944                         for (k=0; k < getCharacteristic(); k++)
00945                                 for (l=0; l<( (getCharacteristic() - 1)* getEpsPrecision() ) + 1; l++)
00946                                 {
00947                                         TNum    z1 (i,j);
00948                                         TNum    z2 (k,l);
00949 
00950                                         size_t  index = getPairIndex(z1, z2);
00951 
00952                                         assert(index <  tableSize && index>=0 );
00953 
00954                                         TNum result;
00955 
00956                                         result.setX  (          ((int) z1.getX() * (int)z2.getX() ) 
00957                                                                 % getCharacteristic()
00958                                                         );
00959                         
00960                                         result.setEps( (   (int)z1.getX() * (int)z2.getEps() 
00961                                                                + (int)z2.getX() * (int)z1.getEps() 
00962                                                          ) % getCharacteristic()        
00963                                                         );
00964                                 
00965 
00966                                         tMultiplicationTable[ index ] = result;
00967                                 }
00968 
00969 
00970         /*for (i=0; i< getCharacteristic(); i++)
00971                         for (k=0; k < getCharacteristic(); k++)
00972                                 {
00973                                         TNum    z1 (i,0);
00974                                         TNum    z2 (k,0);
00975 
00976                                         size_t  index = getPairIndex(z1, z2);
00977 
00978                                         assert(index <  tableSize && index>=0 );
00979 
00980                                         TNum result;
00981 
00982                                         result.setX  (          ((int) z1.getX() * (int)z2.getX() ) 
00983                                                                 % getCharacteristic()
00984                                                         );
00985                         
00986                                         assert(tMultiplicationTable[ index ] == result);
00987                                 }*/
00988 
00989         return tMultiplicationTable;
00990 }
00991 
00992 
00997 template <class TNum,class kdefs>
00998  TNum* fast_Ring<TNum,kdefs>::createMultiplicativeInverseTable()
00999 {
01000         int i, j, k, l; 
01001         
01002         size_t tableSize = getMaxSingleIndex() + 1;
01003 
01004         TNum * inverses1 = new TNum[ tableSize ];
01005 
01006         for (i=0; i<getCharacteristic(); i++)
01007 
01008                 for (j=0; j<((getCharacteristic()-1)*getEpsPrecision())+1; j++)
01009                 {
01010                         TNum    z1(i, j);
01011                         size_t  index = getSingleIndex( z1 );
01012 
01013                         assert(index<tableSize && index>=0);
01014 
01015                         inverses1[ index ]  = TNum::Zero; 
01016 
01017                         for (k=0; k<getCharacteristic(); k++)
01018                                 for (l=0; l<((getCharacteristic()-1)*getEpsPrecision())+1; l++)
01019                                 {
01020                                         TNum    z2(k, l);
01021                                         TNum    z;
01022                                         z.setX(  ((int)z1.getX() * (int)z2.getX()) % getCharacteristic()  );
01023 
01024                                         z.setEps ( (  (int)z1.getX() * (int)z2.getEps() 
01025                                                      + (int)z2.getX() * (int)z1.getEps()  
01026                                                    ) % getCharacteristic()  );
01027 
01028                                         if ( z == TNum::One )
01029                                         {
01030                                                 size_t index_2 = getSingleIndex( z1);
01031                                                 assert( index_2<tableSize && index_2 >=0);
01032                                                 inverses1 [index_2 ] = z2;
01033                                                 break;
01034                                         }
01035                                 }
01036                 }
01037         return inverses1;
01038 }
01039 
01040 
01041 
01042         
01044 template <class TNum,class kdefs>
01045  TNum* fast_Ring<TNum,kdefs>::initElementsToExponentsTab(TNum erzeuger)
01046 {
01047         TNum * tElementsToExponentsTab=NULL;
01048         
01049         size_t tableSize = getMaxSingleIndex() + 1;
01050 
01051         tElementsToExponentsTab = new TNum[tableSize];
01052 
01053         tElementsToExponentsTab[0]=TNum::Zero;
01054 
01055         TNum num=erzeuger;
01056 
01057         for (int i=1; i<getCharacteristic(); i++)
01058         {
01059                 tElementsToExponentsTab[ num.getX() ] = i;
01060                 num.setX( ( (int)num.getX() * (int)erzeuger.getX() ) % getCharacteristic());
01061         }
01062         if (num!=erzeuger)
01063         {
01064                 std::cerr << "num " << num << std::endl;
01065                 std::cerr << "generator " << erzeuger << std::endl;
01066                 num = erzeuger;
01067                 for (int i=1; i<getCharacteristic(); i++)
01068                 {
01069                         std::cerr << "num " << (int)num.getX() * (int)erzeuger.getX() << std::endl;
01070                         num.setX( ( (int)num.getX() * (int)erzeuger.getX() ) % getCharacteristic());
01071                         std::cerr << "num " << num << std::endl << std::endl;
01072                 }
01073 
01074                 assert( num==erzeuger );
01075         }
01076         return tElementsToExponentsTab;
01077 }
01078 
01079 
01082 template <class TNum,class kdefs>
01083  TNum* fast_Ring<TNum,kdefs>::initExponentsToElementTab(TNum erzeuger)
01084 {
01085 
01086         TNum *  tExponentsToElementTab=NULL;
01087         
01088         long    tableSize=0;
01089 
01090         tableSize = getMaxSingleIndex() + 1;
01091 
01092         tExponentsToElementTab = new TNum[tableSize];
01093 
01094         tExponentsToElementTab[0] = TNum::Zero;
01095 
01096         TNum num = erzeuger;
01097 
01098         for (int i=1; i<getCharacteristic(); i++)
01099         {
01100                 //exponentsToElementTab[ TNum::getSingleIndex( i ) ] = num;
01101                 tExponentsToElementTab[  i  ] = num;
01102                 num.setX( ( (int)num.getX() * (int)erzeuger.getX() ) % getCharacteristic() );
01103         }
01104         assert( num==erzeuger );
01105         return tExponentsToElementTab;
01106 }
01107 
01108 
01109 template <class TNum,class kdefs>
01110 typename fast_Ring<TNum,kdefs>::FieldType::ElementType* fast_Ring<TNum,kdefs>::createModuloTable() 
01111 {
01112         ScalarType * tModuloTable=NULL;
01113         
01114 
01115          
01116          //moduloTableSize_m = 9*characteristic*characteristic+characteristic;
01117         // 
01118         moduloTableSize_m = 15*characteristic*characteristic+characteristic;
01119         tModuloTable= new ScalarType[ moduloTableSize_m ];
01120 
01121         long currPos=0;
01122         while( currPos < moduloTableSize_m )
01123         {
01124                 for (long j=0; j<characteristic;j++  )
01125                 {
01126                         tModuloTable[ currPos ] = j;
01127                         currPos++;
01128                 }
01129         }
01130         
01131         return tModuloTable;
01132 }
01133 
01134 
01135 template <class TNum,class kdefs>
01136 inline int  fast_Ring<TNum,kdefs>::getLookupModuloTableSize( ) const
01137 {
01138         return moduloTableSize_m;
01139 }
01140 
01141 
01142 template <class TNum,class kdefs>
01143 inline typename fast_Ring<TNum,kdefs>::FieldType::ElementType  fast_Ring<TNum,kdefs>::lookupModuloTable(int convertee) const
01144 {
01145         #ifdef SAFE
01146                 assert(convertee>=0 && convertee<moduloTableSize_m);
01147         #endif
01148         
01149         if (convertee>=moduloTableSize_m || convertee<0  )
01150         {
01151                 //std::cerr << "convertee " << convertee << endl;
01152                 return ConvertScalar(convertee);
01153         }
01154         //assert(convertee>=0 && convertee<moduloTableSize_m);
01155         return moduloTable[convertee];
01156 }
01157 
01158  
01159 template <class TNum,class kdefs>
01160 typename fast_Ring<TNum,kdefs>::sqrtInf_t* fast_Ring<TNum,kdefs>::createSqrtTable()
01161 {
01162 
01163         typename fast_Ring<TNum,kdefs>::sqrtInf_t *     tSqrtTable=NULL;
01164         
01165         long    tableSize=0;
01166 
01167         tableSize = getMaxSingleIndex() + 1;
01168 
01169         tSqrtTable = new typename fast_Ring<TNum,kdefs>::sqrtInf_t[tableSize];
01170 
01171         typename fast_Ring<TNum,kdefs>::sqrtInf_t entry(0,TNum::Zero);
01172 
01173         for (int i=0; i<getCharacteristic(); i++)
01174         {
01175                 tSqrtTable[ i ] = entry;
01176         }
01177 
01178         for (int i=0; i<getCharacteristic(); i++)
01179         {
01180                 int res= (i*i) % getCharacteristic();
01181                 if (tSqrtTable[  res  ].solutions==0)
01182                         tSqrtTable[  res  ].sqrt =TNum(i);
01183                 else
01184                 {
01185                         assert(  getCharacteristic()-i ==tSqrtTable[  res  ].sqrt.getX() );
01186                 }
01187                 tSqrtTable[  res  ].solutions ++;
01188                 
01189         }
01190 
01191         for (int i=0; i<getCharacteristic(); i++)
01192         {
01193                 assert( tSqrtTable[  i  ].solutions==0 ||       
01194                         tSqrtTable[  i  ].solutions==2   ||  tSqrtTable[  i  ].sqrt.getX()==0);
01195                 
01196         //      std::cerr<< "tSqrtTable["<< i <<"    ].sqrt.getX()" << (int)tSqrtTable[  i  ].sqrt.getX() << std::endl;
01197                 if (tSqrtTable[  i  ].solutions>0)
01198                         assert( (tSqrtTable[  i  ].sqrt.getX() *        tSqrtTable[  i  ].sqrt.getX() ) % getCharacteristic() == i       );
01199                 assert( tSqrtTable[  i  ].sqrt.getEps()==0);
01200         }
01201  
01202         return tSqrtTable;
01203 }
01204 
01205 
01206 
01207 
01208 //----------------------Power---------------------------------------------------
01209 
01210 template <class TNum,class kdefs>
01211 inline TNum fast_Ring<TNum,kdefs>::pow(const TNum x,unsigned int exp) const
01212 {
01213         #ifdef SAFE
01214                 assert(exp>=0);
01215         #endif
01216 
01217         
01218         if (exp==1)
01219                 return x;
01220         if (exp==0)
01221                 return TNum::One;
01222         
01223         
01224         TNum erg = x;
01225         for (; exp >1; exp--)
01226         {
01227                 multiplyInPlaceRef( erg, x ) ;                  
01228         }
01229         return erg;
01230 }
01231 
01232 
01233 
01234 template <class TNum,class kdefs>
01235 inline void fast_Ring<TNum,kdefs>::powInPlace( TNum & x, unsigned int exp) const
01236 {
01237         #ifdef SAFE
01238                 assert(exp>=0);
01239         #endif
01240 
01241         
01242         if (exp==1)
01243                 return ;
01244         if (exp==0)
01245                 x = TNum::One;
01246         
01247         TNum tmp = x;
01248         for (; exp >1; exp--)
01249         {
01250                 multiplyInPlaceRef( x, tmp ) ;                  
01251         }
01252         return;
01253 }
01254 
01255 
01256 //----------------------Index---------------------------------------------------
01257 
01258 template <class TNum,class kdefs>               
01259 inline  size_t  fast_Ring<TNum,kdefs>::getMaxSingleIndex() const
01260 { 
01261         return TNum::getMaxSingleIndex( getCharacteristic());
01262 }
01263 
01264 
01265 
01266 template <class TNum,class kdefs>               
01267 inline  size_t  fast_Ring<TNum,kdefs>::getMaxPairIndex() const
01268 { 
01269         return TNum::getMaxPairIndex( getCharacteristic() );
01270 }
01271 
01272 
01273 
01274 template <class TNum,class kdefs>               
01275 inline  size_t  fast_Ring<TNum,kdefs>::getSingleIndex(const TNum z1) const
01276 { 
01277         // 1. reicht das, wenn ich hier TNum::getPairIndex(z1,z2) einsetze,
01278         // oder muss ich ueberall TNum::getxxxIndex verwenden damit das Programm schnell laeuft?
01279         return TNum::getSingleIndex(z1, getCharacteristic());
01280 }
01281 
01282 template <class TNum,class kdefs>               
01283 inline  size_t  fast_Ring<TNum,kdefs>::getSingleIndexByRef(const TNum &z1) const
01284 { 
01285         return TNum::getSingleIndexByRef(z1, getCharacteristicRef());
01286 }
01287 
01288 template <class TNum,class kdefs>
01289 inline  size_t  fast_Ring<TNum,kdefs>::getPairIndex(const TNum z1, const TNum z2)  const
01290 { 
01291         return TNum::getPairIndex(z1, z2, getCharacteristic() );                        
01292 }
01293 
01294 
01295 template <class TNum,class kdefs>
01296 inline  size_t  fast_Ring<TNum,kdefs>::getPairIndexByRef(const TNum & z1, const TNum & z2) const
01297 { 
01298         return   TNum::getPairIndexByRef(z1, z2, getCharacteristicRef() ) ;
01299 }
01300 
01301 
01302 
Generated on Tue Nov 23 13:10:51 2010 for centerfocus by  doxygen 1.6.3