00001
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
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
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
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
00176
00177 B->clear(lastDegree);
00178
00179
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
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;
00237 register short currentDegree_minus_2_minus_i = currentDegree_minus_2;
00238
00239 for (register short i=0; i<=currentDegree_minus_2; ++i,--currentDegree_minus_2_minus_i)
00240 {
00241
00242
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
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
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
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
00302 ring->accMultRef(b, ppp, dyA->getCoeffConstRef(0, n));
00303
00304
00305 const typename TRing::ElementType & qqq = q->getCoeffConstRef(j, l);
00306
00307 ring->accMultRef(b, qqq, dxA->getCoeffConstRef(0, n));
00308
00309
00310 --n;
00311
00312
00313 int tmpn = n;
00314 assert( n>=0);
00315
00316 for (register unsigned short m=1; n>=0; ++m,--n)
00317 {
00318
00319
00320
00321 ring->accMultRef(B->getCoeffRef(j+m, l+n), qqq, dxA->getCoeffConstRef(m, n));
00322
00323
00324
00325
00326
00327
00328
00329 }
00330 n=tmpn;
00331 for (register unsigned short m=1; n>=0; ++m,--n)
00332
00333 {
00334
00335
00336
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
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
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
00373 ring->accMultRef(b, ppp, dyA->getCoeffConstRef(0, n));
00374
00375
00376 const typename TRing::ElementType & qqq = q->getCoeffConstRef(j, l);
00377
00378 ring->accMultRef(b, qqq, dxA->getCoeffConstRef(0, n));
00379
00380
00381 --n;
00382
00383
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
00393
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
00399
00400
00401
00402
00403
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;
00414
00415 switch ( q->getDegree() )
00416 {
00417
00418 case 3:
00419
00420 #ifdef SAFE
00421 assert(n>0);
00422 #endif
00423
00424 {
00425
00426 perform_inner_C_Step_differ_stages<depth, stage>(0,2,n);
00427
00428 perform_inner_C_Step_differ_stages<depth,stage>(1,1,n);
00429
00430
00431 perform_inner_C_Step_differ_stages<depth,stage>(2,0,n);
00432 --n;
00433
00434 if (n>0)
00435 {
00436
00437 perform_inner_C_Step_differ_stages<depth,stage>(0,3,n);
00438
00439
00440 perform_inner_C_Step_differ_stages<depth,stage>(1,2,n);
00441
00442
00443 perform_inner_C_Step_differ_stages<depth,stage>(2,1,n);
00444
00445
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)
00454 {
00455
00456
00457 perform_inner_C_Step_differ_stages<depth,stage>(0,2,n);
00458 #ifdef DEBUG2
00459 this->outputMatrix(B);
00460 #endif
00461
00462
00463 perform_inner_C_Step_differ_stages<depth,stage>(1,1,n);
00464 #ifdef DEBUG2
00465 this->outputMatrix(B);
00466 #endif
00467
00468
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();
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;
00532
00533 switch ( q->getDegree() )
00534 {
00535
00536 case 3:
00537
00538 #ifdef SAFE
00539 assert(n>0);
00540 #endif
00541
00542 {
00543
00544 perform_inner_C_Step(0,2,n);
00545
00546 perform_inner_C_Step(1,1,n);
00547
00548
00549 perform_inner_C_Step(2,0,n);
00550 --n;
00551
00552 if (n>0)
00553 {
00554
00555 perform_inner_C_Step(0,3,n);
00556
00557
00558 perform_inner_C_Step(1,2,n);
00559
00560
00561 perform_inner_C_Step(2,1,n);
00562
00563
00564 perform_inner_C_Step(3,0,n);
00565 }
00566 }
00567
00568 break;
00569
00570 case 2:
00571 if (n>0)
00572 {
00573
00574
00575 perform_inner_C_Step(0,2,n);
00576 #ifdef DEBUG2
00577 this->outputMatrix(B);
00578 #endif
00579
00580
00581 perform_inner_C_Step(1,1,n);
00582 #ifdef DEBUG2
00583 this->outputMatrix(B);
00584 #endif
00585
00586
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
00618 if (currentDegree % 2 == 1)
00619 {
00620 perform_the_odd_A_Step();
00621 }
00622 else
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
00642 A->setCoeff(currentDegree-1, 1, B->getCoeffRef(currentDegree,0));
00643
00644
00645
00646
00647
00648
00649
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
00665 A->setCoeff ( 1, currentDegree-1,
00666 ring->addInvRef( B->getCoeffConstRef( 0,currentDegree) )
00667 );
00668
00669
00670
00671
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
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
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
00718 ring->scalarMultiplyInPlace( field_ref_m.multInv(typename TRing::ScalarType(2) ), Summe );
00719
00720 A->setCoeff(currentDegree-1, 1, Summe );
00721
00722
00723
00724
00725
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
00750
00751
00752
00753 A->setCoeff( 0, currentDegree, TRing::ElementType::Zero );
00754
00755
00756 for(register short j=2;j<=currentDegree;j+=2)
00757 {
00758 register short j_minus_zwei = j-2;
00759
00760
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
00795
00796 std::cerr << "dxA: " << std::endl;
00797 dxA->outputMatrix();
00798
00799
00800 std::cerr << "dyA: " << std::endl;
00801 dyA->outputMatrix();
00802
00803
00804 std::cerr << "B: " << std::endl;
00805 B->outputMatrix();
00806
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();
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
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
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)
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
00988 {
00989
00990
00991 init();
00992
00993
00994
00995 currFocalValuePos=1;
00996
00997 currentDegree = 2;
00998
00999 try
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
01024
01025
01026
01027
01028
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
01055 #endif
01056
01057
01058
01059
01060
01061
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
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
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
01102 lastDegree = currentDegree;
01103 #ifdef DEBUG2
01104 std::cerr << "doit::getChar" << std::endl;
01105
01106 #endif
01107
01108
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