frommer.cpp

Go to the documentation of this file.
00001 // Frommer.cpp: Implementierung der Klasse Frommer.
00002 //
00003 
00004  
00005 using namespace nCenterFocus;
00006 
00007 template < class TFrommerDefs, int variant>
00008 const typename TFrommerDefs::RingType* Frommer< TFrommerDefs, variant >::getRing() const
00009 {
00010         return ring;
00011 };
00012 
00013 template < class TFrommerDefs, int variant>
00014 const typename TFrommerDefs::RingType& Frommer< TFrommerDefs, variant >::getRingRef() const
00015 {
00016         return *ring;
00017 };
00019 // Konstruktion/Destruktion
00022 template < class TFrommerDefs, int variant >
00023 Frommer< TFrommerDefs, variant >::Frommer(short m,const TRing *_ring):  
00024                                                         name_m(""),
00025                                                         ring(_ring), 
00026                                                         field_ref_m( _ring->getFieldRef() ),
00027                                                         maxFocalValuesToCompute(m),
00028                                                         maxDegree( m *2 + 3),
00029                                                         A  ( new TMatrixXYType ("A"  ,maxDegree)),
00030                                                         B  ( new TMatrixXYType ("B"  ,maxDegree)),
00031 
00032                                                         dxA( new TMatrixXYType ("dxA",maxDegree)),
00033 
00034                                                         dyA( new TMatrixXYType ("dyA",maxDegree)),
00035                                                         a_table(createLowATable() ),
00036 
00037                                                         currFocalValuePos(0)
00038                                                         #ifdef FROMMERSTAGE_TIMER
00039                                                                 , frommerTimer_m(m)
00040                                                         #endif
00041 
00042 {
00043         #ifdef FROMMERSTAGE_TIMER
00044                 tim_m.clear();
00045                 tim2_m.clear();
00046         #endif
00047 
00048         
00049         #ifdef SAFE
00050                 initialized=false;
00051         #endif
00052 
00053         minusp = NULL;
00054         q      = NULL;
00055         lastDegree = maxDegree;
00056 
00057         assert(minusp == NULL);
00058 
00059         //computedFocalValues = new typename TRing::ElementType[ maxFocalValuesToCompute+1 ];
00060         computedFocalValues = new typename TRing::ElementType[ maxFocalValuesToCompute+1 ];
00061         
00062 
00063         assert(minusp == NULL);
00064 
00065         A->setCoeff (2,0,  TRing::ElementType::One);
00066         A->setCoeff (1,1,  TRing::ElementType::Zero);
00067         A->setCoeff (0,2,  TRing::ElementType::One);
00068 
00069 
00070 }
00071 
00072 
00073 template < class TFrommerDefs, int variant>
00074 Frommer< TFrommerDefs, variant >::~Frommer()
00075 {
00076         delete[] computedFocalValues;
00077         delete   B;
00078         delete   A;
00079         delete   dxA;
00080         delete   dyA;
00081         delete[] a_table;
00082         #ifdef FROMMERSTAGE_TIMER
00083                 MtcpManager_g.disconnectTimer(tim_m);
00084                 MtcpManager_g.disconnectTimer(tim2_m);
00085         #endif
00086 }
00087 
00088 
00089 template < class TFrommerDefs, int variant>
00090 void Frommer< TFrommerDefs, variant >::printLowATable(typename TFrommerDefs::RingType::ScalarType* aTable)
00091 {
00092 
00093         for (int row=0;row<maxDegree+1;row++)
00094         {
00095                 for (int col=0;col<maxDegree+1;col++)
00096                 {
00097                         cerr << aTable[(maxDegree+1)*row+col] << " " ;
00098                 }
00099                 cerr << "\n" << endl;
00100         }
00101 }
00102 
00112 template < class TFrommerDefs, int variant>
00113 typename TFrommerDefs::RingType::ScalarType* Frommer< TFrommerDefs, variant >::createLowATable()
00114 {
00115 
00116         int tableSize= (maxDegree+1)*(maxDegree+1);
00117 
00118         typename TRing::ScalarType* t_a_table = new typename TRing::ScalarType[ tableSize ];
00119 
00120         short   i,j, h;
00121 
00122         for ( h=0; h<tableSize; h++)
00123         {
00124                 t_a_table[h ] = TRing::ScalarType::Zero;
00125         }
00126 
00127         for ( h=0; h<maxDegree+1; h++)
00128         {
00129                 t_a_table[ h*(maxDegree+1) ] =  TRing::ScalarType::One;
00130                         
00131                 for ( i=1; i<= h/2; i++)
00132                 {
00133                         typename TRing::ScalarType  Produkt =  TRing::ScalarType::One;
00134                         for ( j=1; j<=i; j++)
00135                         {
00136                                 field_ref_m.multiplyInPlace(    Produkt,
00137                                                                                 field_ref_m.multiply(   h - (2*j-1), 
00138                                                                                                                         field_ref_m.multInv(2*j-1)
00139                                                                                                 ) 
00140                                                                 );
00141                         }
00142                         t_a_table[ h*(maxDegree+1)+i ]= Produkt;
00143                 }
00144         }
00145         //printLowATable(t_a_table); getchar();
00146         return t_a_table;
00147 }
00148 
00149 
00156 template < class TFrommerDefs,int variant>
00157 inline void Frommer< TFrommerDefs, variant >::init()
00158 {
00159 
00160         #ifdef SAFE
00161                 assert(A->getCoeff(2,0) == TRing::ElementType::One);
00162                 assert(A->getCoeff(1,1) == TRing::ElementType::Zero);
00163                 assert(A->getCoeff(0,2) == TRing::ElementType::One);
00164         
00165                 A->clear();
00166                 B->clear();
00167                 dxA->clear();
00168                 dyA->clear();
00169 
00170                 A->setCoeff (2,0,  TRing::ElementType::One);
00171                 A->setCoeff (1,1,  TRing::ElementType::Zero);
00172                 A->setCoeff (0,2,  TRing::ElementType::One);
00173                 
00174         #else
00175                 // A->clear(); // nicht mehr notwendig !
00176                 // dyA->clear(lastDegree);//  nicht mehr notwendig!
00177                 B->clear(lastDegree); //notwendig bei Wiederverwendung!
00178                 // dxA->clear(lastDegree); // nicht mehr notwendig, zumindest nicht für Grad 3, weil
00179                 //  vor dem C-Schritt dxa und dya vom aktuellenGrad-2(zeile+spalte) initialisiert  werden 
00180         #endif
00181 }
00182 
00183 
00184 
00198 template < class TFrommerDefs, int variant>
00199 inline void Frommer< TFrommerDefs, variant >::setPolynoms(const TPolynomXY * const minuspp, const TPolynomXY *const qq) 
00200 {
00201 
00202         // setze  berechneten focal Values = nix ! (computedFocalValus = currFocalValuePos-1 )
00203         currFocalValuePos=1;
00204         #ifdef SAFE
00205                 initialized=true;
00206         #endif
00207         #ifdef SSAFE
00208                 assert( minuspp->getDegree() == qq->getDegree() );
00209                 if (minusp!=NULL)
00210                         assert( minusp->getDegree() == qq->getDegree() );
00211                 initialized=true;
00212         #endif
00213 
00214         q       =       qq;
00215         minusp  =       minuspp;
00216 
00217         
00218 
00219 };
00220 
00221 
00233 template < class TFrommerDefs, int variant >
00234 inline  void Frommer< TFrommerDefs, variant >::compute_dyA_and_dxA()
00235 {
00236         register const short    currentDegree_minus_2           = currentDegree -2; //fest
00237         register short          currentDegree_minus_2_minus_i   = currentDegree_minus_2; //Laufvariable
00238 
00239         for (register short i=0; i<=currentDegree_minus_2; ++i,--currentDegree_minus_2_minus_i)
00240         {
00241 
00242                 //dyA[i, currentDegree-2-i]:=(currentDegree-1-i)*A[i, currentDegree-1-i];
00243                 dyA->setCoeff(  i, currentDegree_minus_2_minus_i, 
00244                                         ring->scalarMultiply (  currentDegree_minus_2_minus_i + 1 ,
00245                                                                         A->getCoeffConstRef( i   , currentDegree_minus_2_minus_i + 1)
00246                                                         
00247                                                                 )
00248                                 );
00249 
00250                 //dxA[i, aktueller_grad-2-i]:=(i+1)*A[i+1, aktueller_grad-2-i];
00251                 dxA->setCoeff(  i, currentDegree_minus_2_minus_i, 
00252                                         ring->scalarMultiply (  i+1 ,
00253                                                                         A->getCoeffConstRef( i+1 , currentDegree_minus_2_minus_i  )
00254                                                         
00255                                                                 )
00256                                 );
00257         }
00258 }
00259 
00260 
00274 template < class TFrommerDefs, int variant >
00275 inline void Frommer< TFrommerDefs, variant >::perform_inner_C_Step(register const short j, 
00276                                                                                          register const short l,
00277                                                                                          register  short n       )
00278 {
00279         // m läuft, j,l hier fest, n =(currentDegree-m-j-l) folgt aus Bedingung (m+n+j+l==currentDegree).
00280         // Berechnungen finden nur statt,
00281         //  wenn (m>=0), (n>=0) und  (m+n)>0 und 
00282         //(m+n)<=currentDegree-2  (letztere Bedingung ist nach Opel 
00283         //zumindest für  Polynome dritten Grades berechtigt, siehe :
00284         // implizite Annahmen: bei Funktionseintritt ist n>0; (n<=currentDegree-2), (j+l)>1
00285         // im ersten Schritt sind alle Bedingungen erfüllt, erst ab dem zweiten (m>=1) muss 
00286         //lediglich geprüft werden, ob (n>=0) ist.
00287         
00288         //-------------------
00289         // Starte also bei m=0:
00290         #ifdef SAFE
00291                 assert(n<=currentDegree-2);
00292                 assert(n>0);
00293         #endif 
00294 
00295         const   typename TRing::ElementType &   ppp = minusp->getCoeffConstRef(j, l); 
00296 
00297         
00298 
00299         register        typename TRing::ElementType & b   = B->getCoeffRef(j, l+n);     
00300 
00301         //ACCUMULATE MULTIPLICATION: b = b + p(j,l) * dya(m,n)
00302         ring->accMultRef(b, ppp, dyA->getCoeffConstRef(0, n));
00303         
00304 
00305         const   typename TRing::ElementType &  qqq = q->getCoeffConstRef(j, l); 
00306         //ACCUMULATE MULTIPLICATION:  b = b + q(j,l) * dxa(m,n)
00307         ring->accMultRef(b, qqq, dxA->getCoeffConstRef(0, n));
00308 
00309         //----------m>0
00310         --n; // das dazugehoerige m++ steht in der Scheifeninitialisierung (m=1)
00311 
00312         // bei erfullten Vorbedingungen reicht es zu prüfen ob n>=0 .
00313         int tmpn = n;
00314         assert( n>=0);
00315         
00316         for (register unsigned short m=1; n>=0; ++m,--n)
00317         {
00318                 
00319                 //register typename TRing::ElementType & b2 = ; 
00320                 //ACCUMULATE mULTIPLICATION:   b2 = b2 + q(j, l) * dxa(m,n)
00321                 ring->accMultRef(B->getCoeffRef(j+m, l+n), qqq, dxA->getCoeffConstRef(m, n));
00322         
00323                 // Formel moeglicherweiwe so implementieren,
00324                 // dass erst am Schluss eines C-schritts, also beim Plusgleich 
00325                 //das Ergebnis in das des vorgegebenen Koerpers umgerechnet wird.
00326                 // dazu ist 
00327                 //1 .eine Analyse notwendig, welche Operation wie lange dauert.
00328                 //2. Ein entsprechend geraeumiger Datentyp fuer ein B-Eintrag, welcher nicht gleich ueberlaeuft.
00329         }
00330         n=tmpn;
00331         for (register unsigned short m=1; n>=0; ++m,--n)
00332         
00333         {
00334         //      register typename TRing::ElementType & b2 = B->getCoeffRef(j+m, l+n);   
00335 
00336                 //ACCUMULATE mULTIPLICATION:   b2 = b2 + p(j, l) * dya(m,n)
00337                 ring->accMultRef(B->getCoeffRef(j+m, l+n), ppp, dyA->getCoeffConstRef(m, n));
00338         }
00339 }
00340 
00341 
00342 
00343 
00344 template < class TFrommerDefs, int variant >
00345 template <int depth,int stage>
00346 inline void Frommer< TFrommerDefs, variant >::perform_inner_C_Step_differ_stages(register const short j, 
00347                                                                                          register const short l,
00348                                                                                          register  short n       )
00349 {
00350         // m läuft, j,l hier fest, n =(currentDegree-m-j-l) folgt aus Bedingung (m+n+j+l==currentDegree).
00351         // Berechnungen finden nur statt,
00352         //  wenn (m>=0), (n>=0) und  (m+n)>0 und 
00353         //(m+n)<=currentDegree-2  (letztere Bedingung ist nach Opel 
00354         //zumindest für  Polynome dritten Grades berechtigt, siehe :
00355         // implizite Annahmen: bei Funktionseintritt ist n>0; (n<=currentDegree-2), (j+l)>1
00356         // im ersten Schritt sind alle Bedingungen erfüllt, erst ab dem zweiten (m>=1) muss 
00357         //lediglich geprüft werden, ob (n>=0) ist.
00358         
00359         //-------------------
00360         // Starte also bei m=0:
00361         #ifdef SAFE
00362                 assert(n<=currentDegree-2);
00363                 assert(n>0);
00364         #endif 
00365 
00366         const   typename TRing::ElementType &   ppp = minusp->getCoeffConstRef(j, l); 
00367 
00368         
00369 
00370         register        typename TRing::ElementType & b   = B->getCoeffRef(j, l+n);     
00371 
00372         //ACCUMULATE MULTIPLICATION: b = b + p(j,l) * dya(m,n)
00373         ring->accMultRef(b, ppp, dyA->getCoeffConstRef(0, n));
00374         
00375 
00376         const   typename TRing::ElementType &  qqq = q->getCoeffConstRef(j, l); 
00377         //ACCUMULATE MULTIPLICATION:  b = b + q(j,l) * dxa(m,n)
00378         ring->accMultRef(b, qqq, dxA->getCoeffConstRef(0, n));
00379 
00380         //----------m>0
00381         --n; // das dazugehoerige m++ steht in der Scheifeninitialisierung (m=1)
00382 
00383         // bei erfullten Vorbedingungen reicht es zu prüfen ob n>=0 .
00384 
00385         cerr << "ppp" << ppp << endl;
00386         cerr << " qqq" << qqq << endl;
00387         cerr << " bo" << B->getCoeffRef(j, l+n) << endl;
00388 
00389         for (register unsigned short m=1; n>=0; ++m,--n)
00390         {
00391                 
00392                 //register typename TRing::ElementType & b2 = ; 
00393                 //ACCUMULATE mULTIPLICATION:   b2 = b2 + q(j, l) * dxa(m,n)
00394                 ring->accMultRef(B->getCoeffRef(j+m, l+n), qqq, dxA->getCoeffConstRef(m, n));
00395         
00396                 ring->accMultRef(B->getCoeffRef(j+m, l+n), ppp, dyA->getCoeffConstRef(m, n));
00397 
00398                 // Formel moeglicherweiwe so implementieren,
00399                 // dass erst am Schluss eines C-schritts, also beim Plusgleich 
00400                 //das Ergebnis in das des vorgegebenen Koerpers umgerechnet wird.
00401                 // dazu ist 
00402                 //1 .eine Analyse notwendig, welche Operation wie lange dauert.
00403                 //2. Ein entsprechend geraeumiger Datentyp fuer ein B-Eintrag, welcher nicht gleich ueberlaeuft.
00404         }
00405 }
00406 
00407 
00408 template < class TFrommerDefs, int variant >
00409 template <int depth, int stage>
00410 inline void Frommer< TFrommerDefs, variant >::perform_C_Step_differ_stages()
00411 {
00412 
00413         register short n = currentDegree-2; // n muss n=currentDegree-l-j erfüllen ! una, ach vergesst es.
00414 
00415         switch ( q->getDegree() )
00416         {
00417                                 
00418         case 3: 
00419         
00420                 #ifdef SAFE
00421                         assert(n>0);//gilt normalerweise immer, da currentDegree bei 3 startet!
00422                 #endif
00423                 //if ( n>0) gilt immer!
00424                 {       
00425                         //(0,2)
00426                                  perform_inner_C_Step_differ_stages<depth, stage>(0,2,n);
00427                         //(1,1)
00428                                  perform_inner_C_Step_differ_stages<depth,stage>(1,1,n);
00429                 
00430                         //(2,0)
00431                                  perform_inner_C_Step_differ_stages<depth,stage>(2,0,n);
00432                         --n;
00433                         //if (n>0) gilt immer fuer currentDegree >=4
00434                         if (n>0)
00435                         {
00436                                 //(0,3)
00437                                          perform_inner_C_Step_differ_stages<depth,stage>(0,3,n);
00438                                 
00439                                 //(1,2)
00440                                          perform_inner_C_Step_differ_stages<depth,stage>(1,2,n);
00441                                         
00442                                 //(2,1)
00443                                          perform_inner_C_Step_differ_stages<depth,stage>(2,1,n);
00444                                 
00445                                 //(3,0)
00446                                          perform_inner_C_Step_differ_stages<depth,stage>(3,0,n);
00447                         }
00448                 }
00449         
00450                 break;
00451         
00452         case 2:
00453                 if (n>0) // gilt immer !
00454                 {
00455                 
00456                         //(0,2)
00457                                  perform_inner_C_Step_differ_stages<depth,stage>(0,2,n);
00458         #ifdef DEBUG2
00459                                                 this->outputMatrix(B);
00460                                         #endif
00461                         
00462                         //(1,1)
00463                                  perform_inner_C_Step_differ_stages<depth,stage>(1,1,n);
00464         #ifdef DEBUG2
00465                                                 this->outputMatrix(B);
00466                                         #endif
00467                         
00468                         //(2,0)
00469                                  perform_inner_C_Step_differ_stages<depth,stage>(2,0,n);        
00470         #ifdef DEBUG2
00471                                                 this->outputMatrix(B);
00472                                         #endif
00473                 }
00474                 
00475                 break;
00476         
00477         case 1:
00478         
00479                 break;
00480         
00481         
00482         default:
00483                 perform_generic_C_Step();
00484         }
00485 }
00486 
00487 
00488 
00491 template <class TFrommerDefs, int variant>
00492 inline void Frommer< TFrommerDefs, variant >::perform_generic_C_Step()
00493 {
00494          
00495         short d = q->getDegree(); // p->getgrad kann nicht genommen werden!! sonst maxDegree evtl falsch!!
00496         
00497                 if (currentDegree<d)
00498                         d=currentDegree;
00499         
00500                 for (register short  j=0; j<=d; j++)
00501                         for (register short l=0; l<=d-j; l++)
00502                         {
00503                                 short nn=currentDegree-j-l;
00504 
00505                         
00506 
00507                                 if (nn<=currentDegree-2 && nn>0)
00508                                 {
00509                                          perform_inner_C_Step(j, l, nn);
00510 
00511                                         #ifdef DEBUG2
00512                                                 this->outputMatrix(B);
00513                                         #endif
00514 
00515                                 }
00516                         }
00517 }
00518 
00519 
00527 template < class TFrommerDefs, int variant >
00528 inline void Frommer< TFrommerDefs, variant >::perform_C_Step()
00529 {
00530 
00531         register short n = currentDegree-2; // n muss n=currentDegree-l-j erfüllen ! una, ach vergesst es.
00532 
00533         switch ( q->getDegree() )
00534         {
00535                                 
00536         case 3: 
00537         
00538                 #ifdef SAFE
00539                         assert(n>0);//gilt normalerweise immer, da currentDegree bei 3 startet!
00540                 #endif
00541                 //if ( n>0) gilt immer!
00542                 {       
00543                         //(0,2)
00544                                 perform_inner_C_Step(0,2,n);
00545                         //(1,1)
00546                                 perform_inner_C_Step(1,1,n);
00547                 
00548                         //(2,0)
00549                                 perform_inner_C_Step(2,0,n);
00550                         --n;
00551                         //if (n>0)
00552                         if (n>0)
00553                         {
00554                                 //(0,3)
00555                                         perform_inner_C_Step(0,3,n);
00556                                 
00557                                 //(1,2)
00558                                         perform_inner_C_Step(1,2,n);
00559                                         
00560                                 //(2,1)
00561                                         perform_inner_C_Step(2,1,n);
00562                                 
00563                                 //(3,0)
00564                                         perform_inner_C_Step(3,0,n);
00565                         }
00566                 }
00567         
00568                 break;
00569         
00570         case 2:
00571                 if (n>0)
00572                 {
00573                 
00574                         //(0,2)
00575                                 perform_inner_C_Step(0,2,n);
00576                                 #ifdef DEBUG2
00577                                                 this->outputMatrix(B);
00578                                 #endif
00579                         
00580                         //(1,1)
00581                                 perform_inner_C_Step(1,1,n);
00582                                         #ifdef DEBUG2
00583                                                 this->outputMatrix(B);
00584                                         #endif
00585                         
00586                         //(2,0)
00587                                 perform_inner_C_Step(2,0,n);    
00588                                 #ifdef DEBUG2
00589                                                 this->outputMatrix(B);
00590                                 #endif
00591                 }
00592                 
00593                 break;
00594         
00595         case 1:
00596         
00597                 break;
00598         
00599         
00600         default:
00601                 perform_generic_C_Step();
00602         }
00603 }
00604 
00605 
00614 template < class TFrommerDefs, int variant >
00615 inline  void Frommer< TFrommerDefs, variant >::perform_the_A_Step()
00616 {
00617         //ungerader A-Schritt, siehe http://www.uni-bayreuth.de/departments/math/org/mathe6/publ/da/hoehn/node13.html
00618         if (currentDegree % 2 == 1)  
00619         {
00620                 perform_the_odd_A_Step();
00621         }
00622         else //Gerader A-Schritt, siehe z.B. http://www.uni-bayreuth.de/departments/math/org/mathe6/publ/da/hoehn/node14.html
00623         {
00624                 perform_the_even_A_Step();
00625                 
00626         }
00627 
00628 }
00638 template < class TFrommerDefs, int variant >
00639 inline  void Frommer< TFrommerDefs, variant >::perform_the_odd_A_Step()
00640 {
00641         //A(n-1,1) = B(n,0)
00642                 A->setCoeff(currentDegree-1, 1, B->getCoeffRef(currentDegree,0));
00643         //      typename TRing::ScalarType* test = new typename TRing::ScalarType(5);
00644 
00645         //      assert (typename TRing::ScalarType(5) == *test );
00646         //      typename TRing::ScalarType* test2 =&(typename TRing::ScalarType(5));
00647         //      assert (*test2 == *test);
00648                 //j=3,5,7,..,n:
00649                 //A(n-j,j) = ((n-j+2)A(n-j+2,j-2)+B(n-j+1,j-1))/j
00650                 for(register short j=3;j<=currentDegree;j+=2)
00651                 {
00652                         short j_minus_zwei=j-2;
00653                         A->setCoeff(    currentDegree-j,j,
00654                                         ring->scalarMultiplyRef(        field_ref_m.multInv( typename TRing::ScalarType(j) ),
00655                                                                         ring->addRef(   ring->scalarMultiplyRef(        currentDegree-j_minus_zwei, 
00656                                                                                                                         A->getCoeffConstRef(currentDegree-j_minus_zwei,j_minus_zwei)
00657                                                                                                                 ),
00658                                                                                         B->getCoeffConstRef(currentDegree-j+1,j-1)
00659                                                                                 )
00660                                                                 )
00661                                 );
00662                 }
00663 
00664                 //A(1,n-1) = -B(0,n)
00665                 A->setCoeff     (       1, currentDegree-1, 
00666                                         ring->addInvRef( B->getCoeffConstRef( 0,currentDegree) ) 
00667                                 );
00668                 
00669                 //j=3,5,7,...n:
00670 
00671                 //A(j,n-j) = ((n-j+2)A(j-2,n-j+2)-B(j-1,n-j+1))/j
00672                 for(register short j=3;j<=currentDegree;j+=2)
00673                 { 
00674                         short j_minus_zwei=j-2;
00675                         A->setCoeff(j,currentDegree-j,
00676                                         ring->scalarMultiplyRef(        field_ref_m.multInv(typename TRing::ScalarType(j)),
00677                                                                         ring->addRef(   ring->scalarMultiplyRef( currentDegree - j_minus_zwei,
00678                                                                                                                                 A->getCoeffConstRef( j_minus_zwei, currentDegree-j_minus_zwei )
00679                                                                                                                 ),
00680                                                                                         ring->addInvRef( B->getCoeffConstRef(j-1,currentDegree-j+1) )
00681                                                                                 )
00682                                                                 )
00683                                         );
00684                 }
00685 }
00686 
00687 
00688 
00697 template < class TFrommerDefs, int variant >
00698 inline  void Frommer< TFrommerDefs, variant >::perform_the_even_A_Step()
00699 {
00700                 // 1. compute A[n-l,l];  l=1, see Paper
00701                 register typename TRing::ScalarType const * p_a_table_loc       =& (a_table[(maxDegree+1)*currentDegree]);
00702 
00703                 typename TRing::ElementType             Summe           = B->getCoeff(currentDegree,0);
00704 
00705                 // jetzt in der Schleife alle uebrigen negativen  (was?) aufaddieren:
00706                 for( register short j=2; j<=currentDegree; j+=2 )
00707                 {       
00708                         
00709                         ring->addInPlace( Summe, 
00710                                           ring->addInv  (  ring->scalarMultiplyRef( field_ref_m.multInv(p_a_table_loc[j/2]) ,
00711                                                                                         B->getCoeffConstRef(currentDegree-j, j)
00712                                                                                         
00713                                                                                 )   
00714                                                                 )
00715                                         );
00716                 }
00717                 // Summe = summe *2. - kommentar stimmt nicht. in Wirklichkeit wird berechet: Summe=Summe/2.
00718                 ring->scalarMultiplyInPlace( field_ref_m.multInv(typename TRing::ScalarType(2) ), Summe  );
00719 
00720                 A->setCoeff(currentDegree-1, 1, Summe );
00721                 
00722                 // so. jetzt is A[currentDegree-1,1] berechnet.
00723 
00724                 //beim naechsten A muss ich ein positives B zweimal dazuaddieren und das Ergebnis mit p_a_table[ ...?
00725                 // vielleicht Tabelle  C[x..,..]/a[i] anlegen
00726                 for(register int j=3; j<=currentDegree-1; j+=2)
00727                 {
00728                         register short mini=j-1;
00729                         
00730 
00731                         ring->addInPlace( Summe, 
00732                                           ring->scalarMultiplyRef(       field_ref_m.multInv(p_a_table_loc[ mini/2 ]),
00733                                                                  B->getCoeffConstRef(currentDegree-mini, mini)
00734                                                         
00735                                                       )
00736                                         );
00737 
00738                         mini = min( j, currentDegree-j );
00739 
00740                         typename TRing::ElementType     Summe2 = ring->scalarMultiplyRef(field_ref_m.multInv(mini), Summe  );
00741                         
00742                         mini--; mini/=2;
00743 
00744                         A->setCoeff(    currentDegree-j, j, 
00745                                         ring->scalarMultiplyRef( p_a_table_loc[mini], Summe2    ) 
00746                                    );
00747 
00748                 }
00749                 //puhhh, geschafft.
00750 
00751                 //------------
00752                 //A(0,n) = 0;
00753                 A->setCoeff( 0, currentDegree,  TRing::ElementType::Zero );
00754 
00755                 //j=2,4,6,...n:
00756                 for(register short j=2;j<=currentDegree;j+=2)
00757                 { 
00758                         register short j_minus_zwei = j-2;
00759 
00760                         //A(j,n-j) = ((n-j+2)A(j-2,n-j+2)-B(j-1,n-j+1))/j
00761                         A->setCoeff(j,currentDegree-j, 
00762                                         ring->scalarMultiplyRef(   field_ref_m.multInv(typename TRing::ScalarType(j) ) ,
00763                                                                         ring->addRef(   ring->scalarMultiplyRef( currentDegree-j_minus_zwei,
00764                                                                                                                          A->getCoeffConstRef(j_minus_zwei, currentDegree-j_minus_zwei) 
00765                                                                                                         ),
00766                                                                                         ring->addInvRef( B->getCoeffConstRef(j-1,currentDegree-j+1) ) 
00767                                                                                 ) 
00768                                                                 )
00769                                   );
00770                 }
00771 }
00772 
00773 
00774 
00775 
00776 
00777 
00779 template < class TFrommerDefs, int variant >
00780 template <class TemplateMatrix>
00781 inline void Frommer< TFrommerDefs, variant >::outputMatrix(TemplateMatrix *mat) const
00782 {
00783         std::cerr << mat->getName() << std::endl;
00784         mat->outputMatrix();
00785         return;
00786 }
00787 
00789 template < class TFrommerDefs, int variant >
00790 inline void Frommer< TFrommerDefs, variant >::outputMatrices() const
00791 {
00792         std::cerr << "A: " << std::endl;
00793         A->outputMatrix();
00794                 //getchar();
00795         
00796         std::cerr << "dxA: " << std::endl;
00797                 dxA->outputMatrix();
00798                 //getchar();
00799         
00800         std::cerr << "dyA: " << std::endl;
00801                 dyA->outputMatrix();
00802                 //getchar();
00803         
00804         std::cerr << "B: " << std::endl;
00805                 B->outputMatrix();
00806                 //getchar();
00807 }
00808 
00809 
00810 
00811 
00812  
00818 template < class TFrommerDefs, int variant >
00819 template < int hm >
00820   void Frommer< TFrommerDefs, variant >::doitx(short howMany)
00821 {
00822         init(); //- clears b and initializes some Coefficients of A
00823 
00824         #ifdef SAFE
00825                 assert(initialized);
00826                 initialized=false;
00827                 assert(howMany<=maxFocalValuesToCompute && howMany>0);
00828         #endif
00829 
00830 
00831         currFocalValuePos=1;
00832         
00833         // Idee: merke mir aktuellen Grad und beim Neustart Daten nur bis currentDegree loeschen!
00834         currentDegree = 2; 
00835 
00836         while(true)
00837         {
00838                 #ifdef FROMMERSTAGE_TIMER
00839                         tim_m.start();
00840                 #endif
00841 
00842                 currentDegree++; 
00843                         
00844                 compute_dyA_and_dxA();
00845 
00846                 #ifdef FROMMERSTAGE_TIMER
00847                         tim2_m.start();
00848                 #endif
00849 
00850                 //perform_C_Step_wrapper< hm >(currentDegree);
00851                 perform_C_Step();
00852                 #ifdef FROMMERSTAGE_TIMER
00853                         tim2_m.stop();
00854                         frommerTimer_m.logCStepTime(hm,currentDegree-2,tim2_m  );
00855                         tim2_m.clear();
00856                         tim2_m.start();
00857                 #endif
00858                 
00859                 
00860 
00861                 perform_the_A_Step();
00862 
00863                 #ifdef FROMMERSTAGE_TIMER
00864                         tim2_m.stop();
00865                         tim_m.stop();   
00866                         frommerTimer_m.logAStepTime(hm,currentDegree-2, tim2_m );
00867                         frommerTimer_m.logStepTime(hm, currentDegree-2, tim_m  );
00868                         tim2_m.clear();
00869                         tim_m.clear();
00870                 #endif
00871 
00872                 
00873                 if ( (currentDegree %2 )==0)//gerade --> Strudelgroesse berechnen
00874                 {
00875                         computedFocalValues[currFocalValuePos] = ring->add(     A->getCoeffConstRef( 1, currentDegree-1 ), 
00876                                                                                                 B->getCoeffConstRef( 0, currentDegree   )
00877                                                                                         );
00878 
00879                         ++currFocalValuePos;
00880 
00881                         if (  currFocalValuePos > hm )  break;
00882                 }
00883         }
00884         lastDegree=currentDegree;
00885 }
00886 
00890 
00891 template < class TFrommerDefs, int variant >
00892 template <int depth>
00893 inline void 
00894 Frommer< TFrommerDefs, variant >::perform_C_Step_wrapper(const int stage)
00895 {
00896         switch (stage)
00897         {
00898                 case 3:
00899                          perform_C_Step_differ_stages<depth, 4>();
00900                         break;  
00901                 case 4:
00902                          perform_C_Step_differ_stages<depth,4>();
00903                         break;  
00904                 case 5:
00905                          perform_C_Step_differ_stages<depth,6>();
00906                         break;  
00907                 case 6:
00908                          perform_C_Step_differ_stages<depth,6>();
00909                         break;  
00910                 case 7:
00911                          perform_C_Step_differ_stages<depth,8>();
00912                         break;  
00913                 case 8:
00914                          perform_C_Step_differ_stages<depth,8>();
00915                         break;  
00916                 case 9:
00917                          perform_C_Step_differ_stages<depth,10>();
00918                         break;  
00919                 case 10:
00920                          perform_C_Step_differ_stages<depth,10>();
00921                         break;  
00922                 case 11:
00923                          perform_C_Step_differ_stages<depth,12>();
00924                         break;  
00925                 case 12:
00926                          perform_C_Step_differ_stages<depth,12>();
00927                         break;  
00928                 case 13:
00929                          perform_C_Step_differ_stages<depth,14>();
00930                         break;  
00931                 case 14:
00932                          perform_C_Step_differ_stages<depth,14>();
00933                         break;  
00934                 case 15:
00935                          perform_C_Step_differ_stages<depth,16>();
00936                         break;  
00937                 case 16:
00938                          perform_C_Step_differ_stages<depth,16>();
00939                         break;  
00940                 case 17:
00941                          perform_C_Step_differ_stages<depth,18>();
00942                         break;  
00943                 case 18:
00944                          perform_C_Step_differ_stages<depth,18>();
00945                         break;  
00946                 case 19:
00947                          perform_C_Step_differ_stages<depth,20>();
00948                         break;  
00949                 case 20:
00950                          perform_C_Step_differ_stages<depth,20>();
00951                         break;  
00952                 case 21:
00953                          perform_C_Step_differ_stages<depth,22>();
00954                         break;  
00955                 case 22:
00956                          perform_C_Step_differ_stages<depth,22>();
00957                         break;
00958                 case 23:
00959                          perform_C_Step_differ_stages<depth,24>();
00960                         break;  
00961                 case 24:
00962                          perform_C_Step_differ_stages<depth,24>();
00963                         break;  
00964                 case 25:
00965                          perform_C_Step_differ_stages<depth,26>();
00966                         break;          
00967                 case 26:
00968                          perform_C_Step_differ_stages<depth,26>();
00969                         break;
00970                 default:
00971                         perform_C_Step();
00972         }
00973 }
00974 
00984 template < class TFrommerDefs, int variant >
00985  
00986 inline void Frommer< TFrommerDefs, variant >::doit(int bComputeAllFocalValues, int jacobi)
00987 //inline void Frommer< TFrommerDefs, variant >::doit(int currNumValuesToCompute, bool bComputeAllFocalValues)
00988 {
00989 
00990         
00991         init();//- clears b and initializes some Coefficients of A
00992 
00993         
00994 
00995         currFocalValuePos=1;
00996         
00997         currentDegree = 2; 
00998         
00999         try     // evtl ist try-catch teuer!
01000         {
01001                 while(true)
01002                 {
01003                         #ifdef FROMMERSTAGE_TIMER
01004                                 tim_m.start();
01005                         #endif
01006 
01007                         currentDegree++; 
01008                 
01009 
01010         
01011                         compute_dyA_and_dxA();
01012 
01013                                 #ifdef DEBUG2
01014                                         this->outputMatrices();
01015                                 #endif
01016                 
01017                         #ifdef FROMMERSTAGE_TIMER
01018                                 tim2_m.start();
01019                         #endif
01020 
01021                                 perform_C_Step();
01022                         
01023                                 /*if (jacobi)
01024                                         perform_C_Step_wrapper<-2>(currentDegree);
01025                                 else if (bComputeAllFocalValues)
01026                                         perform_C_Step_wrapper<-1>(currentDegree);
01027                                 else
01028                                         perform_C_Step_wrapper<0>(currentDegree);
01029                                 */
01030 
01031                                 #ifdef DEBUG2
01032                                         outputMatrix(B);
01033                                 #endif
01034 
01035                         #ifdef FROMMERSTAGE_TIMER
01036                                 tim2_m.stop();
01037                                 int hm=-1000;
01038                                 if (jacobi)
01039                                         hm=-2 ;
01040                                 else if (bComputeAllFocalValues)
01041                                         hm=maxFocalValuesToCompute ;
01042                                 else
01043                                         hm = 0 ;
01044                                 frommerTimer_m.logCStepTime(hm,currentDegree-2, tim2_m  );
01045 
01046                                 tim2_m.clear();
01047                                 tim2_m.start();
01048                         #endif
01049 
01050                         perform_the_A_Step();
01051 
01052                                 #ifdef DEBUG2
01053                                         outputMatrix(A);
01054                                         //getchar();
01055                                 #endif
01056                 
01057                         // Problem: um A(1, currentDegree-1) zu berechnen braucht man alle B-Werte...
01058                         // Man kann lediglich die letzte for-Schleife der A-Stufe weglassen...
01059                         // Aber: man kann die Fälle focalValues=2 ,=3 Spezialisieren 
01060 
01061                         //A(1,n-1) = -B(0,n)
01062                         #ifdef FROMMERSTAGE_TIMER
01063                                 tim2_m.stop();
01064                                 tim_m.stop();   
01065                                 frommerTimer_m.logAStepTime(hm,currentDegree-2 , tim2_m  );
01066                                 frommerTimer_m.logStepTime( hm, currentDegree-2, tim_m   );
01067                                 tim2_m.clear();
01068                                 tim_m.clear();
01069                         #endif
01070                  
01071 
01072 
01073                         if (currentDegree % 2 == 0)
01074                         {
01075                                 //gerade --> Strudelgroesse berechnen
01076 
01077                                 typename TRing::ElementType res = ring->add(    A->getCoeffConstRef(1, currentDegree-1), 
01078                                                                                                 B->getCoeffConstRef(0, currentDegree)
01079                                                                                 );
01080 
01081                                 computedFocalValues[currFocalValuePos] = res;
01082 
01083                                 if (++currFocalValuePos > maxFocalValuesToCompute  )
01084                                 {                                                               
01085                                         break;
01086                                 }
01087                                 //++currFocalValuePos gehoert ganz ans ende der if-Abfrage !, 
01088                                 if (      (     ( bComputeAllFocalValues==0 )   &&      
01089                                                 ( res.getX() != typename TRing::ElementType(0).getX() ) )
01090                                 )
01091                                 {                                                               
01092                                         break;
01093                                         
01094                                         #ifdef DEBUG
01095                                                 std::cerr << "finished" << std::endl;
01096                                         #endif
01097                                 }
01098                                 
01099                         }
01100                 }
01101                 //  merke mir aktuellen Grad um bei einem Neustart möglichst wenig neu zu initialisieren
01102                 lastDegree = currentDegree;
01103                 #ifdef DEBUG2
01104                         std::cerr << "doit::getChar" << std::endl;
01105                         //getchar();
01106                 #endif
01107                 /*
01108                 if 
01109                 */
01110         
01111         }
01112         catch (const char* str)
01113         {
01114                 std::cerr << " error during computation of " << currFocalValuePos << "-th focal value: ";
01115                 std::cerr << std::endl << str << std::endl;
01116                 exit(0);
01117         }
01118         
01119 }
01120 
01127 
01128 template < class TFrommerDefs, int variant >
01129 typename TFrommerDefs::RingType::ElementType
01130 Frommer< TFrommerDefs, variant >::getFocalValue( int pos) const
01131 {
01132         assert(pos<=maxFocalValuesToCompute );
01133 
01134         if (currFocalValuePos>pos && pos>0)
01135                 return computedFocalValues[pos];
01136         else 
01137         {
01138                 std::cerr << "currFocalValuePos" << currFocalValuePos << std::endl;
01139                 throw " requested focal value was not computed!" ;
01140         }
01141 }
01142 
01143 
01144 template < class TFrommerDefs, int variant >
01145 void            Frommer< TFrommerDefs, variant >::getComputedFocalValues( vector<typename TRing::ElementType> &computedFV ) const
01146 {
01147         computedFV.clear();
01148         computedFV.resize( currFocalValuePos-1 );
01149         for (int pos=1; pos<currFocalValuePos; pos++)
01150         {
01151                 computedFV[ pos - 1 ] = computedFocalValues[ pos ] ;
01152         }
01153 }
01154 
01155 
01156 
01161 template < class TFrommerDefs, int variant >
01162 short Frommer< TFrommerDefs, variant >::getSuccessiveVanishedFocalValuesCount() const
01163 {
01164         short i=0;
01165         while (         (i<maxFocalValuesToCompute)
01166                         &&      (i+1<currFocalValuePos)
01167                         &&      ((int) computedFocalValues[i+1].getX()==0)
01168                   )
01169         {
01170                 i++;
01171         }
01172 
01173         return i;
01174 }
01175 
01179 template < class TFrommerDefs, int variant >
01180 void Frommer< TFrommerDefs, variant >::printStageTimings(std::ostream & os) const
01181 {
01182         #ifdef FROMMERSTAGE_TIMER
01183                 os  << "--" << name_m << ": " << endl;
01184                 frommerTimer_m.print(os);
01185         #endif
01186 }
01187 
Generated on Tue Nov 23 13:10:52 2010 for centerfocus by  doxygen 1.6.3