00001
00018 #include <assert.h>
00019
00020
00021 template <class TFrommerDefs, int variant>
00022 const typename TFrommerDefs::RingType * fast_Frommer< TFrommerDefs, variant>::getRing() const
00023 {
00024 return ring1;
00025 };
00026
00027 template <class TFrommerDefs, int variant>
00028 const typename TFrommerDefs::RingType & fast_Frommer< TFrommerDefs, variant>::getRingRef() const
00029 {
00030 return *ring1;
00031 };
00032
00034
00036 template <class TFrommerDefs, int variant>
00037 fast_Frommer< TFrommerDefs, variant>::
00038 fast_Frommer(short _maxFocalValuesToCompute, const TRing *_ring ) :
00039 name_m(""),
00040 ring1 ( _ring),
00041 field_ref_m(_ring->getFieldRef()),
00042 maxFocalValuesToCompute ( _maxFocalValuesToCompute ),
00043 maxDegree ( maxFocalValuesToCompute *2 + 3 ),
00044 pq ( NULL ),
00045 A ( new TMatrixXYType("A",maxDegree)),
00046 dA ( new TMatrixXYPairType ("dA",maxDegree) ),
00047 B ( new TMatrixXYType ("B",maxDegree) ),
00048 B0 ( new TMatrixXY_0Type ("B",maxDegree) ),
00049 a_table ( createLowATable(maxDegree, _ring) ),
00050 currFocalValuePos(0)
00051
00052 #ifdef FROMMERSTAGE_TIMER
00053 ,frommerTimer_m(_maxFocalValuesToCompute)
00054 #endif
00055 {
00056 #ifdef SAFE
00057 initialized=false;
00058 #endif
00059
00060 #ifdef FROMMERSTAGE_TIMER
00061 tim_m.clear();
00062 tim2_m.clear();
00063 #endif
00064
00065 minusp = NULL;
00066 q = NULL;
00067 lastDegree = maxDegree;
00068 computedFocalValues = new typename TRing::ElementType[ maxFocalValuesToCompute+1 ];
00069
00070 A->setCoeff (2,0, TRing::ElementType::One);
00071 A->setCoeff (1,1, TRing::ElementType::Zero);
00072 A->setCoeff (0,2, TRing::ElementType::One);
00073
00074 wellDefined();
00075 }
00076
00077 template <class TFrommerDefs, int variant>
00078 void fast_Frommer< TFrommerDefs, variant>::wellDefined()
00079 {
00080
00081 assert ( ring1->getLookupModuloTableSize()>14 );
00082
00084 TPolynomXY * testp = new TPolynomXY(3);
00085
00086 register typename TPolynomXY::CoefficientType * p_ElementAddr = testp->getCoeffAddr(0,2);
00087
00088
00089
00090
00091
00092 for (int degree = 0; degree<=3; degree++)
00093 {
00094 p_ElementAddr = testp->getCoeffAddr(degree,0);
00095 for (int yExp = 0; yExp<=degree; yExp++)
00096 {
00097 if ( testp->getCoeffAddr(degree-yExp, yExp) !=p_ElementAddr )
00098 {
00099 cerr << "degree" << degree << endl;
00100 cerr << "degree-yExp" << degree-yExp << endl;
00101 cerr << " yExp" << yExp << endl;
00102 cerr << "testp->getCoeffAddr(degree-yExp, yExp)" << testp->getCoeffAddr(degree-yExp, yExp) << endl;
00103 cerr << "p_ElementAddr" << p_ElementAddr << endl;
00104 }
00105 assert( testp->getCoeffAddr(degree-yExp, yExp) ==p_ElementAddr );
00106 p_ElementAddr++;
00107 }
00108 }
00109
00110
00112 for (int degree = 0; degree<=maxDegree; degree++)
00113 {
00114 register typename TRing::ElementType * p_A = A->getCoeffAddr(degree,0);
00115 for (int yExp = 0; yExp<=degree; yExp++)
00116 {
00117 assert( A->getCoeffAddr(degree-yExp, yExp) ==p_A );
00118 p_A++;
00119 }
00120 }
00121
00123 for (int degree = 0; degree<=maxDegree; degree++)
00124 {
00125 register typename TRing::ElementType * p_dA = dA->getCoeffAddr(degree,0);
00126 for (int yExp = 0; yExp<=degree; yExp++)
00127 {
00128 assert( dA->getCoeffAddr(degree-yExp, yExp) ==p_dA );
00129 p_dA++;
00130 p_dA++;
00131 }
00132 }
00133
00134 delete testp;
00135 }
00136
00137 template <class TFrommerDefs, int variant>
00138 fast_Frommer< TFrommerDefs, variant>::~fast_Frommer()
00139 {
00140 delete[] computedFocalValues;
00141 delete B;
00142 delete A;
00143 delete dA;
00144 delete[] a_table;
00145
00146 #ifdef FROMMERSTAGE_TIMER
00147 MtcpManager_g.disconnectTimer(tim_m);
00148 MtcpManager_g.disconnectTimer(tim2_m);
00149 #endif
00150
00151
00152 }
00153
00154
00155
00166 template <class TFrommerDefs, int variant>
00167 const typename TFrommerDefs::RingType::ScalarType * const fast_Frommer< TFrommerDefs, variant>::createLowATable(int maxDegree,const TRing *ring1 )
00168 {
00169 short i,j,h;
00170
00171 int tableSize=(maxDegree+1)*(maxDegree+1) ;
00172
00173 typename TRing::ScalarType * local_a_table = new typename TRing::ScalarType[ tableSize ];
00174
00175 for ( h=0; h<tableSize; h++)
00176 {
00177 local_a_table[h ] = TRing::ScalarType::Zero;
00178 }
00179
00180
00181 for ( h=0; h<=maxDegree; h++)
00182 {
00183
00184 local_a_table[h*(maxDegree+1)]= TRing::ScalarType::One;
00185
00186 for ( i=1; i<= h/2; i++)
00187 {
00188 typename TRing::ScalarType Produkt=TRing::ScalarType::One;
00189 for ( j=1; j<=i; j++)
00190 {
00191 ring1->getField()->multiplyInPlace(Produkt,
00192 ring1->getField()->multiply( h - (2*j-1),
00193 ring1->getField()->multInv(2*j-1)
00194 )
00195 );
00196 }
00197 local_a_table[ h*(maxDegree+1)+i ] = Produkt;
00198 }
00199
00200 }
00201 return local_a_table;
00202 }
00203
00204
00205
00212 template <class TFrommerDefs, int variant>
00213 inline void fast_Frommer< TFrommerDefs, variant>::init()
00214 {
00215
00216 #ifdef SAFE
00217 assert(A->getCoeff(2,0) == TRing::ElementType::One);
00218 assert(A->getCoeff(1,1) == TRing::ElementType::Zero);
00219 assert(A->getCoeff(0,2) == TRing::ElementType::One);
00220
00221 A->clear();
00222
00223 B->clear(lastDegree);
00224 B0->clear(lastDegree);
00225 dA->clear();
00226
00227 A->setCoeff (2,0, TRing::ElementType::One);
00228 A->setCoeff (1,1, TRing::ElementType::Zero);
00229 A->setCoeff (0,2, TRing::ElementType::One);
00230 #else
00231
00232
00233
00234 B->clear(lastDegree);
00235 B0->clear(lastDegree);
00236 #endif
00237
00238 }
00239
00240
00241
00242
00254 template <class TFrommerDefs, int variant>
00255 void fast_Frommer< TFrommerDefs, variant>::setPolynoms( const TPolynomXY * const minuspp,
00256 const TPolynomXY * const qq)
00257 {
00258
00259
00260 #ifdef SSAFE
00261
00262 assert( minuspp->getDegree() == qq->getDegree() );
00263
00264 if (minusp!=NULL)
00265 assert( minusp->getDegree() == qq->getDegree() );
00266 initialized=true;
00267 #endif
00268 #ifdef SAFE
00269 initialized=true;
00270 #endif
00271 q = qq;
00272 minusp = minuspp;
00273
00274
00275 };
00276
00277
00291 template <class TFrommerDefs, int variant>
00292 inline void fast_Frommer< TFrommerDefs, variant>::compute_dyA_and_dxA()
00293 {
00294 register short currentDegree_minus_2_minus_i=0;
00295
00296 register typename TRing::ElementType * p_dA = dA->getCoeffAddr(currentDegree-2, currentDegree_minus_2_minus_i);
00297
00298 register typename TRing::ElementType * pA = A->getCoeffAddr(currentDegree-1, currentDegree_minus_2_minus_i);
00299
00300
00301 for (register short i = currentDegree-2; i>=0; i--, currentDegree_minus_2_minus_i++ )
00302 {
00303
00304 *p_dA = ring1->scalarMultiply( i+1,*pA );
00305
00306 p_dA++;
00307 pA++;
00308
00309 *p_dA = ring1->scalarMultiply ( currentDegree_minus_2_minus_i+1 ,*pA );
00310 p_dA++;
00311 }
00312 }
00313
00314
00315
00337 template <class TFrommerDefs, int variant>
00338 inline void fast_Frommer< TFrommerDefs, variant>::perform_inner_C_Step( register typename TRing::ElementType * const b0,
00339 register const typename TRing::ElementType * const minusp0,
00340 register const typename TRing::ElementType * const q0,
00341 register const typename TRing::ElementType * const da0,
00342 short _n )
00343 {
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 #ifdef SAFE
00358 assert(_n<=currentDegree-2);
00359 assert(_n>0);
00360 #endif
00361 register short n = _n;
00362 register typename TRing::ElementType const * datmp = da0;
00363 register typename TRing::ElementType polCoeff = *minusp0;
00364 register typename TRing::ElementType * b1tmp = b0;
00365
00366
00367
00368
00369
00370
00371
00372
00373 do
00374 {
00375 datmp++;
00376
00377 ring1->accMultRef(*b1tmp,polCoeff, *datmp);
00378 datmp++;
00379 ++b1tmp;
00380 --n;
00381 }
00382 while (n>=0);
00383
00384
00385 n = _n;
00386 b1tmp = b0;
00387 polCoeff = *q0;
00388 datmp = da0;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 do
00399 {
00400
00401 ring1->accMultRef(*b1tmp,polCoeff, *datmp);
00402 datmp++;
00403 datmp++;
00404 ++b1tmp;
00405 --n;
00406 }
00407 while (n>=0);
00408
00409 }
00410
00412 template <class TFrommerDefs, int variant>
00413 inline void fast_Frommer< TFrommerDefs, variant>::perform_fast_inner_C_Step( register typename TMatrixXY_0Type::CoefficientType & b0,
00414 register const typename TRing::ElementType & minusp0,
00415 register const typename TRing::ElementType & q0,
00416 register const typename TRing::ElementType & da0,
00417 short _n )
00418 {
00419 #ifdef SAFE
00420 assert(_n<=currentDegree-2);
00421 assert(_n>0);
00422 #endif
00423
00424 register typename TRing::ElementType const * datmp = &da0;
00425 register typename TMatrixXY_0Type::CoefficientType * b1tmp = &b0;
00426
00427 for (register short i=_n; i>=0; i--)
00428 {
00429 *b1tmp += q0.getX()*datmp->getX() ;
00430 datmp++;
00431 *b1tmp += minusp0.getX()*datmp->getX() ;
00432 datmp++;
00433
00434 ++b1tmp;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 }
00466
00467
00477 template <class TFrommerDefs, int variant>
00478 inline void fast_Frommer< TFrommerDefs, variant>::perform_C_Step( )
00479 {
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 #ifdef SAFE
00490 assert(currentDegree-2>0);
00491 #endif
00492 switch ( q->getDegree() )
00493 {
00494
00495 case 3:
00496
00497
00498
00499 {
00500 register short n = currentDegree-2;
00501
00502
00503 register typename TRing::ElementType const* po = minusp->getCoeffConstAddr( 2,0 );
00504 register typename TRing::ElementType const* qo = q->getCoeffConstAddr( 2,0 );
00505 register typename TRing::ElementType * bo = B->getCoeffAddr( currentDegree,0 );
00506 register typename TRing::ElementType const * da0 = dA->getCoeffGroupAddr(n);
00507
00508
00509 perform_inner_C_Step(bo,po,qo,da0,n);
00510
00511
00512 po++;qo++;bo++;
00513 #ifdef SAFE
00514 assert( *po==minusp->getCoeff(1,1) );
00515 assert( *qo==q->getCoeff(1,1) );
00516 assert( *bo==B->getCoeff(currentDegree-1 , 1) );
00517 #endif
00518
00519 perform_inner_C_Step(bo,po,qo,da0,n);
00520
00521
00522
00523 po++;qo++;bo++;
00524 #ifdef SAFE
00525 assert(*po==minusp->getCoeff(0,2));
00526 assert(*qo==q->getCoeff(0,2));
00527 #endif
00528 perform_inner_C_Step(bo,po,qo,da0,n);
00529
00530 --n;
00531 if (n>0)
00532 {
00533
00534
00535 bo = B->getCoeffAddr( currentDegree,0 );
00536
00537 po=minusp->getCoeffConstAddr(3,0);
00538 qo=q->getCoeffConstAddr(3,0);
00539
00540
00541 da0 = dA->getCoeffGroupAddr(n);
00542
00543
00544 #ifdef SAFE
00545 assert(bo == B->getCoeffAddr( 3+n, 0 ));
00546 assert(bo == B->getCoeffAddr( currentDegree, 0 ));
00547
00548 assert(*po==minusp->getCoeff(3,0));
00549 assert(*qo==q->getCoeff(3,0));
00550 #endif
00551
00552 perform_inner_C_Step(bo,po,qo,da0,n);
00553
00554
00555
00556 po++;qo++;bo++;
00557 perform_inner_C_Step(bo,po,qo,da0,n);
00558
00559
00560 po++;qo++;bo++;
00561 #ifdef SAFE
00562 assert(*po==minusp->getCoeff(1,2));
00563 assert(*qo==q->getCoeff(1,2));
00564 #endif
00565
00566 perform_inner_C_Step(bo,po,qo,da0,n);
00567
00568
00569
00570 po++;qo++;bo++;
00571 #ifdef SAFE
00572 assert(*po==minusp->getCoeff(0,3));
00573 assert(*qo==q->getCoeff(0,3));
00574 #endif
00575
00576 perform_inner_C_Step(bo,po,qo,da0,n);
00577
00578 }
00579 }
00580
00581
00582
00583 break;
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 case 1:
00618
00619 break;
00620
00621
00622 default:
00623 perform_generic_C_Step();
00624 }
00625 }
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00640 template <class TFrommerDefs, int variant>
00641 void fast_Frommer< TFrommerDefs, variant>::perform_generic_C_Step()
00642 {
00643 short d = q->getDegree();
00644
00645 cerr << "q->getDegree() " << d << endl;
00646
00647
00648
00649
00650 for (register short monomDegree=2; monomDegree<=d; monomDegree++)
00651
00652 if ( (currentDegree - monomDegree)>0 )
00653 for (register short yExp=0; yExp<=monomDegree; yExp++)
00654 {
00655 short nn = currentDegree-monomDegree ;
00656 short xExp = monomDegree - yExp;
00657
00658
00659 assert( nn<=currentDegree-2 && nn>0 );
00660 if ( nn<=currentDegree-2 && nn>0 )
00661 {
00662 register typename TRing::ElementType const* po = minusp->getCoeffConstAddr(xExp,yExp);
00663 register typename TRing::ElementType const* qo = q->getCoeffConstAddr(xExp,yExp);
00664
00665 register typename TRing::ElementType * bo = B->getCoeffAddr(currentDegree - yExp, yExp);
00666 cerr << "currentDegree - yEx " << currentDegree - yExp << endl;
00667 cerr << "xExp " << xExp << endl;
00668 register typename TRing::ElementType const * da0 = dA->getCoeffGroupAddr(nn);
00669 #ifdef SAFE
00670
00671 assert( *po==minusp->getCoeff(xExp,yExp) );
00672 assert( *qo==q->getCoeff(xExp,yExp) );
00673 assert( *bo==B->getCoeff(currentDegree - yExp, yExp ) );
00674
00675 cerr << " *po" << *po << endl;
00676 cerr << " *qo" << *qo << endl;
00677 cerr << " *bo" << *bo << endl;
00678 #endif
00679 perform_inner_C_Step(bo,po,qo,da0,nn);
00680 #ifdef DEBUG2
00681 this->outputMatrix(B);
00682
00683 #endif
00684 }
00685 }
00686 }
00687
00688
00689 template <class TFrommerDefs, int variant>
00690 void fast_Frommer< TFrommerDefs, variant>::perform_first_C_Step()
00691 {
00692
00693 switch ( q->getDegree() )
00694 {
00695
00696 case 3:
00697 {
00698
00699
00700
00701 register typename TRing::ElementType const* coeff = q->getCoeffConstAddr( 2,0 );
00702
00703 register typename TMatrixXY_0Type::CoefficientType * bo = B0->getCoeffAddr( currentDegree,0 );
00704
00705 register typename TRing::ElementType const * da0 = dA->getCoeffGroupAddr(currentDegree-2);
00706
00707 register typename TMatrixXY_0Type::CoefficientType * tmpbo = bo;
00708
00709
00710 *tmpbo = coeff->getX()*da0->getX() ;
00711 tmpbo++;coeff++;
00712 *tmpbo = coeff->getX()*da0->getX() ;
00713 tmpbo++;coeff++;
00714 *tmpbo = coeff->getX()*da0->getX() ;
00715
00716
00717 da0++;
00718
00719 da0++;
00720
00721 da0++;
00722
00723 tmpbo = bo; tmpbo++;
00724 coeff = minusp->getCoeffConstAddr( 2,0 );
00725 *tmpbo += coeff->getX()*da0->getX() ;
00726 tmpbo++;coeff++;
00727 *tmpbo += coeff->getX()*da0->getX() ;
00728 tmpbo++;coeff++;
00729 *tmpbo = coeff->getX()*da0->getX() ;
00730
00731
00732
00733
00734 tmpbo = bo;
00735 register typename TRing::ElementType * boorig = B->getCoeffAddr(currentDegree,0);
00736 *boorig = field_ref_m.lookupModuloTable( *tmpbo ) ;
00737 tmpbo++;boorig++;
00738 *boorig = field_ref_m.lookupModuloTable( *tmpbo ) ;
00739 tmpbo++;boorig++;
00740 *boorig = field_ref_m.lookupModuloTable( *tmpbo ) ;
00741 tmpbo++;boorig++;
00742 *boorig = field_ref_m.lookupModuloTable( *tmpbo ) ;
00743 }
00744
00745 case 1:
00746
00747 break;
00748
00749
00750 default:
00751 perform_generic_C_Step();
00752 }
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00904 template <class TFrommerDefs, int variant>
00905 void fast_Frommer< TFrommerDefs, variant>::perform_fast_C_Step()
00906 {
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916 #ifdef SAFE
00917 assert( currentDegree-2>0);
00918 #endif
00919 switch ( q->getDegree() )
00920 {
00921
00922 case 3:
00923
00924
00925
00926 {
00927 register short n = currentDegree-2;
00928
00929
00930
00931
00932 register typename TRing::ElementType const* po = minusp->getCoeffConstAddr( 2,0 );
00933 register typename TRing::ElementType const* qo = q->getCoeffConstAddr( 2,0 );
00934 register typename TMatrixXY_0Type::CoefficientType * bo = B0->getCoeffAddr( currentDegree,0 );
00935 register typename TRing::ElementType const * da0 = dA->getCoeffGroupAddr(n);
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
00946
00947
00948 po++;qo++;bo++;
00949 #ifdef SAFE
00950 assert( *po==minusp->getCoeff(1,1) );
00951 assert( *qo==q->getCoeff(1,1) );
00952 assert( *bo==B0->getCoeff(currentDegree-1 , 1) );
00953 #endif
00954
00955 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
00956
00957
00958
00959 po++;qo++;bo++;
00960 #ifdef SAFE
00961 assert(*po==minusp->getCoeff(0,2));
00962 assert(*qo==q->getCoeff(0,2));
00963 #endif
00964 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
00965
00966 --n;
00967 if (n>0)
00968 {
00969
00970
00971 bo = B0->getCoeffAddr( currentDegree,0 );
00972
00973 po=minusp->getCoeffConstAddr(3,0);
00974 qo=q->getCoeffConstAddr(3,0);
00975
00976
00977 da0 = dA->getCoeffGroupAddr(n);
00978
00979 #ifdef SAFE
00980 assert(bo == B0->getCoeffAddr( 3+n, 0 ));
00981 assert(bo == B0->getCoeffAddr( currentDegree, 0 ));
00982
00983 assert(*po==minusp->getCoeff(3,0));
00984 assert(*qo==q->getCoeff(3,0));
00985 #endif
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 #ifdef SAFE
00997 assert(bo == B0->getCoeffAddr( 3+n, 0 ));
00998 assert(bo == B0->getCoeffAddr( currentDegree, 0 ));
00999
01000 assert(*po==minusp->getCoeff(3,0));
01001 assert(*qo==q->getCoeff(3,0));
01002 #endif
01003
01004 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
01005
01006
01007
01008 po++;qo++;bo++;
01009 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
01010
01011
01012 po++;qo++;bo++;
01013 #ifdef SAFE
01014 assert(*po==minusp->getCoeff(1,2));
01015 assert(*qo==q->getCoeff(1,2));
01016 #endif
01017
01018 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
01019
01020
01021
01022 po++;qo++;bo++;
01023 #ifdef SAFE
01024 assert(*po==minusp->getCoeff(0,3));
01025 assert(*qo==q->getCoeff(0,3));
01026 #endif
01027
01028 perform_fast_inner_C_Step(*bo,*po,*qo,*da0,n);
01029
01030 }
01031 register typename TRing::ElementType * boorig = B->getCoeffAddr(currentDegree,0);
01032 bo = B0->getCoeffAddr(currentDegree,0);
01033
01034 for (register short i=0;i<=currentDegree;i++ )
01035 {
01036 *boorig = field_ref_m.lookupModuloTable( *bo ) ;
01037 boorig++;
01038 bo++;
01039 }
01040
01041
01042
01043 }
01044
01045 break;
01046
01047
01048 case 1:
01049
01050 break;
01051
01052
01053 default:
01054 perform_generic_C_Step();
01055 }
01056 }
01057
01058
01067 template <class TFrommerDefs, int variant>
01068 inline void fast_Frommer< TFrommerDefs, variant>::perform_the_A_Step()
01069 {
01070 if (currentDegree % 2 == 1)
01071 {
01072 perform_the_odd_A_Step();
01073 }
01074 else
01075 {
01076 perform_the_even_A_Step();
01077 }
01078 }
01079
01080
01081
01082
01091
01092 template <class TFrommerDefs, int variant>
01093 inline void fast_Frommer< TFrommerDefs, variant>::perform_the_odd_A_Step()
01094 {
01095
01096
01097 typename TRing::ElementType * pA = A->getCoeffAddr(currentDegree-1, 1);
01098 typename TRing::ElementType const * pB = B->getCoeffConstAddr(currentDegree,0);
01099
01100 typename TRing::ElementType prevAVal=* pB;
01101 * pA= prevAVal;
01102
01103
01104
01105 short tmp=currentDegree-1;
01106
01107
01108 for(register short j=3;j<=currentDegree;j+=2,tmp-=2 )
01109 {
01110 pA+=2;
01111 pB+=2;
01112 #ifdef SAFE
01113 assert (pA == A->getCoeffAddr(currentDegree-j, j) );
01114 assert (pB == B->getCoeffAddr(currentDegree-j+1,j-1) );
01115 assert (prevAVal==A->getCoeffConstRef(currentDegree-j+2,j-2) );
01116 assert (tmp == currentDegree-j+2 );
01117 #endif
01118 prevAVal= ring1->scalarMultiply( field_ref_m.multInv((typename TRing::ScalarType)(j) ),
01119 ring1->add( ring1->scalarMultiply( tmp,
01120 prevAVal
01121 ),
01122 *pB
01123 )
01124 );
01125 *pA=prevAVal;
01126
01127 }
01128
01129
01130 pA-=1; pB+=1;
01131 #ifdef SAFE
01132 assert (pA == A->getCoeffAddr(1,currentDegree-1 ) );
01133 assert (pB == B->getCoeffAddr(0,currentDegree));
01134 #endif
01135
01136 prevAVal= ring1->addInv(*pB);
01137 *pA= prevAVal;
01138
01139
01140
01141 tmp=currentDegree-1;
01142
01143 for(register short j=3;j<=currentDegree; j+=2, tmp-=2 )
01144 {
01145
01146 pA-=2;
01147 pB-=2;
01148 #ifdef SAFE
01149 assert (pA == A->getCoeffAddr(j, currentDegree-j) );
01150 assert (pB == B->getCoeffAddr(j-1,currentDegree-j+1) );
01151 assert(prevAVal==A->getCoeffConstRef(j-2,currentDegree-j+2) );
01152 assert (tmp == currentDegree-j+2 );
01153 #endif
01154 prevAVal= ring1->scalarMultiply( field_ref_m.multInv( (typename TRing::ScalarType)(j) ),
01155 ring1->add( ring1->scalarMultiply( tmp,
01156 prevAVal
01157 ),
01158 ring1->addInv(*pB)
01159 )
01160 );
01161 *pA=prevAVal;
01162 }
01163 }
01164
01165
01174
01175
01176
01177 template <class TFrommerDefs, int variant>
01178 inline void fast_Frommer< TFrommerDefs, variant>::perform_the_even_A_Step()
01179 {
01180
01181 typename TRing::ScalarType const * p_a_table_loc = &( a_table[(maxDegree+1)*currentDegree] );
01182
01183 typename TRing::ElementType Summe = B->getCoeff(currentDegree,0);
01184
01185 typename TRing::ElementType const * pB = B->getCoeffConstAddr(currentDegree,0);
01186
01187 #ifdef SAFE
01188 assert(currentDegree%2==0);
01189 #endif
01190 for(register short j=1; j<=currentDegree/2; j++)
01191 {
01192 pB+=2;
01193
01194 #ifdef SAFE
01195 assert(pB==B->getCoeffAddr(currentDegree-j*2, j*2) );
01196 #endif
01197 ring1->addInPlace( Summe,
01198 ring1->addInv (ring1->scalarMultiply( field_ref_m.multInv( p_a_table_loc[j] ),
01199 * pB
01200
01201 )
01202 )
01203 );
01204 }
01205 ring1->scalarMultiplyInPlace( field_ref_m.multInv( (typename TRing::ScalarType )(2) ) ,
01206 Summe
01207 );
01208
01209
01210 typename TRing::ElementType * pA = A->getCoeffAddr(currentDegree-1,1);
01211
01212 *pA=Summe;
01213
01214
01215
01216 pB = B->getCoeffConstAddr(currentDegree,0);
01217
01218 for(register int j=3; j<=currentDegree-1; j+=2)
01219 {
01220 short mini = j-1;
01221
01222 pB+=2;
01223 #ifdef SAFE
01224 assert(pB==B->getCoeffAddr(currentDegree-mini,mini));
01225 #endif
01226 ring1->addInPlace( Summe,
01227 ring1->scalarMultiply( field_ref_m.multInv( p_a_table_loc[mini/2]),
01228 *pB
01229 )
01230 );
01231
01232 mini = min( j, currentDegree-j );
01233
01234 typename TRing::ElementType Summe2 = ring1->scalarMultiply( field_ref_m.multInv( mini), Summe );
01235
01236
01237 mini--; mini /= 2;
01238
01239 pA+=2;
01240 #ifdef SAFE
01241 assert(pA==A->getCoeffAddr(currentDegree-j,j));
01242 #endif
01243
01244 *pA= ring1->scalarMultiply( p_a_table_loc[mini], Summe2 ) ;
01245 }
01246
01247
01248
01249
01250 pA++;
01251 #ifdef SAFE
01252 assert(pA==A->getCoeffAddr(0,currentDegree));
01253 #endif
01254 *pA=TRing::ElementType::Zero;
01255
01256 typename TRing::ElementType prevAVal=* pA;
01257
01258 pB = B->getCoeffConstAddr(1,currentDegree-1);
01259
01260
01261
01262 for(register short j=2;j<=currentDegree;j+=2)
01263 {
01264 pA-=2;
01265 #ifdef SAFE
01266 short j_minus_zwei=j-2;
01267 assert(pA==A->getCoeffAddr(j, currentDegree-j));
01268 assert(pB==B->getCoeffAddr(j-1, currentDegree-j+1));
01269 assert(prevAVal==A->getCoeffConstRef(j_minus_zwei,currentDegree-j_minus_zwei));
01270 #endif
01271 prevAVal= ring1->scalarMultiply ( field_ref_m.multInv( (typename TRing::ScalarType)(j) ),
01272 ring1->add( ring1->scalarMultiply( currentDegree-j+2,
01273 prevAVal
01274 ),
01275 ring1->addInv(*pB )
01276 )
01277
01278 );
01279 *pA=prevAVal;
01280 pB-=2;
01281 }
01282 }
01283
01284
01286 template <class TFrommerDefs, int variant>
01287 template <class TemplateMatrix>
01288 inline void fast_Frommer< TFrommerDefs, variant>::outputMatrix(TemplateMatrix *mat) const
01289 {
01290 std::cerr << mat->getName() << std::endl;
01291 mat->outputMatrix();
01292 return;
01293 }
01294
01296 template <class TFrommerDefs, int variant>
01297 inline void fast_Frommer< TFrommerDefs, variant>::outputMatrices() const
01298 {
01299
01300 std::cout << "A: " << std::endl;
01301 A->outputMatrix();
01302
01303
01304 std::cout << "dA: " << std::endl;
01305 dA->outputMatrix();
01306
01307
01308 std::cout << "B: " << std::endl;
01309 B->outputMatrix();
01310
01311 return;
01312 }
01313
01314
01315 template <class TFrommerDefs, int variant>
01316 template<int tHowManyTimes>
01317 void fast_Frommer< TFrommerDefs, variant>::doitx(short howManyFocalValues)
01318 {
01319 #ifdef CF_TEST
01320
01321 doitxOld<tHowManyTimes>(howManyFocalValues);
01322 TMatrixXYType B=getB();
01323
01324
01325 doitxNew<tHowManyTimes>(howManyFocalValues);
01326 assert(B==getB());
01327
01328
01329 #else
01330 doitxNew<tHowManyTimes>(howManyFocalValues);
01331 #endif
01332 }
01333
01338
01339 template <class TFrommerDefs, int variant>
01340 template<int tHowManyTimes>
01341 void fast_Frommer< TFrommerDefs, variant>::doitxNew(short howManyFocalValues)
01342 {
01343 init();
01344 #ifdef SAFE
01345 assert(initialized);
01346 initialized=false;
01347 #endif
01348
01349 currFocalValuePos = 1;
01350
01351 currentDegree = 2;
01352
01353
01354 if (ring1->getEpsPrecision()==0)
01355 {
01356 #ifdef FROMMERSTAGE_TIMER
01357 tim_m.start();
01358 #endif
01359
01360 currentDegree++;
01361
01362
01363 compute_dyA_and_dxA();
01364
01365 #ifdef FROMMERSTAGE_TIMER
01366 tim2_m.start();
01367 #endif
01368
01369 perform_first_C_Step();
01370
01371
01372 #ifdef DEBUG2
01373 this->outputMatrix(B);
01374 #endif
01375 #ifdef FROMMERSTAGE_TIMER
01376 tim2_m.stop();
01377 frommerTimer_m.logCStepTime(tHowManyTimes,currentDegree-2 , tim2_m );
01378 tim2_m.clear();
01379 tim2_m.start();
01380 #endif
01381
01382
01383 perform_the_A_Step();
01384
01385 #ifdef FROMMERSTAGE_TIMER
01386 tim2_m.stop();
01387 tim_m.stop();
01388 frommerTimer_m.logAStepTime(tHowManyTimes,currentDegree-2, tim2_m );
01389 frommerTimer_m.logStepTime(tHowManyTimes, currentDegree-2, tim_m );
01390 tim2_m.clear();
01391 tim_m.clear();
01392 #endif
01393
01394 while(true)
01395 {
01396 #ifdef FROMMERSTAGE_TIMER
01397 tim_m.start();
01398 #endif
01399
01400 currentDegree++;
01401
01402 compute_dyA_and_dxA();
01403 #ifdef DEBUG2
01404 this->outputMatrices();
01405 #endif
01406 #ifdef FROMMERSTAGE_TIMER
01407 tim2_m.start();
01408 #endif
01409
01410 perform_fast_C_Step();
01411
01412
01413
01414 #ifdef DEBUG2
01415 this->outputMatrix(B);
01416 #endif
01417 #ifdef FROMMERSTAGE_TIMER
01418 tim2_m.stop();
01419 frommerTimer_m.logCStepTime(tHowManyTimes,currentDegree-2 , tim2_m );
01420 tim2_m.clear();
01421 tim2_m.start();
01422 #endif
01423 perform_the_A_Step();
01424 #ifdef DEBUG2
01425 this->outputMatrix(A);
01426 #endif
01427 #ifdef FROMMERSTAGE_TIMER
01428 tim2_m.stop();
01429 tim_m.stop();
01430 frommerTimer_m.logAStepTime(tHowManyTimes,currentDegree-2, tim2_m );
01431 frommerTimer_m.logStepTime(tHowManyTimes, currentDegree-2, tim_m );
01432 tim2_m.clear();
01433 tim_m.clear();
01434 #endif
01435 if ( (currentDegree %2 )==0)
01436 {
01437 computedFocalValues[currFocalValuePos] = ring1->add( A->getCoeffConstRef(1, currentDegree-1),
01438 B->getCoeffConstRef(0, currentDegree));
01439
01440 ++currFocalValuePos;
01441
01442 if ( currFocalValuePos > howManyFocalValues ) break;
01443 }
01444 }
01445 }
01446 else
01447 while(true)
01448 {
01449 #ifdef FROMMERSTAGE_TIMER
01450 tim_m.start();
01451 #endif
01452
01453 currentDegree++;
01454
01455 compute_dyA_and_dxA();
01456 #ifdef DEBUG2
01457 this->outputMatrices();
01458 #endif
01459 #ifdef FROMMERSTAGE_TIMER
01460 tim2_m.start();
01461 #endif
01462 perform_C_Step();
01463
01464
01465 #ifdef DEBUG2
01466 this->outputMatrix(B);
01467 #endif
01468 #ifdef FROMMERSTAGE_TIMER
01469 tim2_m.stop();
01470 frommerTimer_m.logCStepTime(tHowManyTimes,currentDegree-2 , tim2_m );
01471 tim2_m.clear();
01472 tim2_m.start();
01473 #endif
01474 perform_the_A_Step();
01475 #ifdef DEBUG2
01476 this->outputMatrix(A);
01477 #endif
01478 #ifdef FROMMERSTAGE_TIMER
01479 tim2_m.stop();
01480 tim_m.stop();
01481 frommerTimer_m.logAStepTime(tHowManyTimes,currentDegree-2, tim2_m );
01482 frommerTimer_m.logStepTime(tHowManyTimes, currentDegree-2, tim_m );
01483 tim2_m.clear();
01484 tim_m.clear();
01485 #endif
01486 if ( (currentDegree %2 )==0)
01487 {
01488 computedFocalValues[currFocalValuePos] = ring1->add( A->getCoeffConstRef(1, currentDegree-1),
01489 B->getCoeffConstRef(0, currentDegree));
01490
01491 ++currFocalValuePos;
01492
01493 if ( currFocalValuePos > howManyFocalValues ) break;
01494 }
01495 }
01496
01497
01498
01499 lastDegree = currentDegree;
01500 #ifdef SAFE
01501 assert( (currFocalValuePos-1) <= maxFocalValuesToCompute );
01502 #endif
01503 }
01504
01505
01506
01507 template <class TFrommerDefs, int variant>
01508 template<int tHowManyTimes>
01509 void fast_Frommer< TFrommerDefs, variant>::doitxOld(short howManyFocalValues)
01510 {
01511 init();
01512 #ifdef SAFE
01513 assert(initialized);
01514 initialized=false;
01515 #endif
01516
01517 currFocalValuePos = 1;
01518
01519 currentDegree = 2;
01520
01521
01522 while(true)
01523 {
01524 #ifdef FROMMERSTAGE_TIMER
01525 tim_m.start();
01526 #endif
01527
01528 currentDegree++;
01529
01530 compute_dyA_and_dxA();
01531 #ifdef DEBUG2
01532 this->outputMatrices();
01533 #endif
01534
01535 #ifdef FROMMERSTAGE_TIMER
01536 tim2_m.start();
01537 #endif
01538 perform_C_Step();
01539
01540
01541 #ifdef DEBUG2
01542 this->outputMatrix(B);
01543 #endif
01544
01545 #ifdef FROMMERSTAGE_TIMER
01546 tim2_m.stop();
01547 frommerTimer_m.logCStepTime(tHowManyTimes,currentDegree-2 , tim2_m );
01548 tim2_m.clear();
01549 tim2_m.start();
01550 #endif
01551
01552 perform_the_A_Step();
01553
01554 #ifdef DEBUG2
01555 this->outputMatrix(A);
01556 #endif
01557
01558 #ifdef FROMMERSTAGE_TIMER
01559 tim2_m.stop();
01560 tim_m.stop();
01561 frommerTimer_m.logAStepTime(tHowManyTimes,currentDegree-2, tim2_m );
01562 frommerTimer_m.logStepTime(tHowManyTimes, currentDegree-2, tim_m );
01563 tim2_m.clear();
01564 tim_m.clear();
01565 #endif
01566 if ( (currentDegree %2 )==0)
01567 {
01568 computedFocalValues[currFocalValuePos] = ring1->add( A->getCoeffConstRef(1, currentDegree-1),
01569 B->getCoeffConstRef(0, currentDegree));
01570
01571 ++currFocalValuePos;
01572
01573 if ( currFocalValuePos > howManyFocalValues ) break;
01574 }
01575
01576 }
01577
01578
01579 lastDegree = currentDegree;
01580 #ifdef SAFE
01581 assert( (currFocalValuePos-1) <= maxFocalValuesToCompute );
01582 #endif
01583 }
01584
01585
01586
01587
01588 template <class TFrommerDefs, int variant>
01589 void fast_Frommer< TFrommerDefs, variant>::doit(short bComputeAllFocalValues, int jacobian )
01590 {
01591 #ifdef CF_TEST
01592
01593 doitOld(bComputeAllFocalValues,jacobian);
01594 TMatrixXYType B=getB();
01595
01596
01597 #ifdef SAFE
01598 initialized=true;
01599 #endif
01600 doitNew(bComputeAllFocalValues,jacobian);
01601 assert(B==getB());
01602
01603
01604 #else
01605 doitNew(bComputeAllFocalValues, jacobian);
01606 #endif
01607 }
01608
01619 template <class TFrommerDefs, int variant>
01620 void fast_Frommer< TFrommerDefs, variant>::doitNew(short bComputeAllFocalValues, int jacobian )
01621 {
01622
01623
01624 #ifdef FROMMERSTAGE_TIMER
01625
01626 int hm=0;
01627 if (jacobian)
01628 hm=-2 ;
01629 else if (bComputeAllFocalValues)
01630 hm=maxFocalValuesToCompute ;
01631 else
01632 hm = 0 ;
01633 #endif
01634
01635
01636 #ifdef SAFE
01637 assert(initialized);
01638 initialized = false;
01639 #endif
01640 init();
01641 currFocalValuePos = 1;
01642
01643 currentDegree = 2;
01644
01645 typename TRing::ElementType res;
01646
01647 try
01648 {
01649
01650 #ifdef FROMMERSTAGE_TIMER
01651 tim_m.start();
01652 #endif
01653
01654 if (ring1->getEpsPrecision()==0)
01655 {
01656 currentDegree++;
01657 compute_dyA_and_dxA();
01658
01659 perform_first_C_Step();
01660
01661
01662 #ifdef FROMMERSTAGE_TIMER
01663 tim2_m.stop();
01664 frommerTimer_m.logCStepTime(hm, currentDegree-2, tim2_m );
01665 tim2_m.clear();
01666 tim2_m.start();
01667 #endif
01668
01669 #ifdef DEBUG2
01670 this->outputMatrix(B);
01671 #endif
01672
01673 perform_the_A_Step();
01674 #ifdef DEBUG2
01675 this->outputMatrix(A);
01676 #endif
01677
01678 #ifdef FROMMERSTAGE_TIMER
01679 tim2_m.stop();
01680 tim_m.stop();
01681 frommerTimer_m.logAStepTime(hm, currentDegree-2, tim2_m );
01682 frommerTimer_m.logStepTime( hm, currentDegree-2, tim_m );
01683 tim2_m.clear();
01684 tim_m.clear();
01685 #endif
01686
01687 }
01688 else
01689 {
01690
01691
01692 currentDegree++;
01693 compute_dyA_and_dxA();
01694
01695
01696
01697 perform_C_Step();
01698
01699
01700 #ifdef DEBUG2
01701 this->outputMatrix(B);
01702 #endif
01703
01704 #ifdef FROMMERSTAGE_TIMER
01705 tim2_m.stop();
01706 frommerTimer_m.logCStepTime(hm, currentDegree-2, tim2_m );
01707 tim2_m.clear();
01708 tim2_m.start();
01709 #endif
01710
01711
01712 perform_the_A_Step();
01713 #ifdef DEBUG2
01714 this->outputMatrix(A);
01715 #endif
01716
01717 #ifdef FROMMERSTAGE_TIMER
01718 tim2_m.stop();
01719 tim_m.stop();
01720 frommerTimer_m.logAStepTime(hm, currentDegree-2, tim2_m );
01721 frommerTimer_m.logStepTime( hm, currentDegree-2, tim_m );
01722 tim2_m.clear();
01723 tim_m.clear();
01724 #endif
01725
01726 }
01727
01728 while(true)
01729 {
01730 #ifdef FROMMERSTAGE_TIMER
01731 tim_m.start();
01732 #endif
01733
01734 currentDegree++;
01735
01736 compute_dyA_and_dxA();
01737
01738 #ifdef DEBUG2
01739 this->outputMatrices();
01740 #endif
01741 #ifdef FROMMERSTAGE_TIMER
01742 tim2_m.start();
01743 #endif
01744
01745 if (ring1->getEpsPrecision()!=0)
01746 {
01747
01748 perform_C_Step();
01749 }
01750 else
01751 {
01752
01753 perform_fast_C_Step();
01754
01755 }
01756
01757 #ifdef DEBUG2
01758 this->outputMatrix(B);
01759 #endif
01760
01761 #ifdef FROMMERSTAGE_TIMER
01762 tim2_m.stop();
01763 frommerTimer_m.logCStepTime(hm, currentDegree-2, tim2_m );
01764 tim2_m.clear();
01765 tim2_m.start();
01766 #endif
01767 perform_the_A_Step();
01768
01769 #ifdef DEBUG2
01770 this->outputMatrix(A);
01771 #endif
01772 #ifdef FROMMERSTAGE_TIMER
01773 tim2_m.stop();
01774 tim_m.stop();
01775 frommerTimer_m.logAStepTime(hm, currentDegree-2, tim2_m );
01776 frommerTimer_m.logStepTime( hm, currentDegree-2, tim_m );
01777 tim2_m.clear();
01778 tim_m.clear();
01779 #endif
01780
01781 if ((currentDegree %2) ==0)
01782 {
01783
01784
01785
01786 res = ring1->add( A->getCoeffConstRef(1, currentDegree-1),
01787 B->getCoeffConstRef(0, currentDegree));
01788
01789 computedFocalValues[currFocalValuePos] =res;
01790 #ifdef DEBUG
01791 std::cerr << currFocalValuePos << ". Strudelgroesse: ";
01792 std::cerr << (computedFocalValues[currFocalValuePos].getX()) << std::endl;
01793 #endif
01794
01795
01796 if (++currFocalValuePos > maxFocalValuesToCompute )
01797 {
01798 break;
01799 }
01800
01801
01802 if ( (bComputeAllFocalValues==0) && (res.getX() != 0) )
01803 {
01804 break;
01805 }
01806
01807 }
01808 }
01809
01810
01811 lastDegree = currentDegree;
01812
01813 }
01814 catch (const char* str)
01815 {
01816 #ifdef DEBUG
01817 std::cerr << typeid(this).name() << std::endl;
01818 #endif
01819 std::cerr <<"fast_Frommer< TFrommerDefs, variant> :: doit error during computation of " << currFocalValuePos << "-th focal value: " << std::endl << str << std::endl;
01820 exit(0);
01821 }
01822 }
01823
01824
01825
01826 template <class TFrommerDefs, int variant>
01827 void fast_Frommer< TFrommerDefs, variant>::doitOld(short bComputeAllFocalValues, int jacobian )
01828 {
01829
01830
01831 #ifdef FROMMERSTAGE_TIMER
01832
01833 int hm=0;
01834 if (jacobian)
01835 hm=-2 ;
01836 else if (bComputeAllFocalValues)
01837 hm=maxFocalValuesToCompute ;
01838 else
01839 hm = 0 ;
01840 #endif
01841
01842
01843 #ifdef SAFE
01844 assert(initialized);
01845 initialized = false;
01846 #endif
01847 init();
01848 currFocalValuePos = 1;
01849
01850 currentDegree = 2;
01851
01852 typename TRing::ElementType res;
01853
01854 try
01855 {
01856
01857 while(true)
01858 {
01859 #ifdef FROMMERSTAGE_TIMER
01860 tim_m.start();
01861 #endif
01862
01863 currentDegree++;
01864
01865 compute_dyA_and_dxA();
01866
01867 #ifdef DEBUG2
01868 this->outputMatrices();
01869 #endif
01870 #ifdef FROMMERSTAGE_TIMER
01871 tim2_m.start();
01872 #endif
01873
01874 perform_C_Step();
01875
01876 #ifdef DEBUG2
01877 this->outputMatrix(B);
01878 #endif
01879
01880 #ifdef FROMMERSTAGE_TIMER
01881 tim2_m.stop();
01882 frommerTimer_m.logCStepTime(hm, currentDegree-2, tim2_m );
01883 tim2_m.clear();
01884 tim2_m.start();
01885 #endif
01886
01887 perform_the_A_Step();
01888
01889 #ifdef DEBUG2
01890 this->outputMatrix(A);
01891 #endif
01892
01893 #ifdef FROMMERSTAGE_TIMER
01894 tim2_m.stop();
01895 tim_m.stop();
01896 frommerTimer_m.logAStepTime(hm, currentDegree-2, tim2_m );
01897 frommerTimer_m.logStepTime( hm, currentDegree-2, tim_m );
01898 tim2_m.clear();
01899 tim_m.clear();
01900 #endif
01901
01902 if ((currentDegree %2) ==0)
01903 {
01904
01905
01906
01907 res = ring1->add( A->getCoeffConstRef(1, currentDegree-1),
01908 B->getCoeffConstRef(0, currentDegree));
01909
01910 computedFocalValues[currFocalValuePos] =res;
01911 #ifdef DEBUG
01912 std::cerr << currFocalValuePos << ". Strudelgroesse: ";
01913 std::cerr << (computedFocalValues[currFocalValuePos].getX()) << std::endl;
01914 #endif
01915
01916
01917 if (++currFocalValuePos > maxFocalValuesToCompute )
01918 {
01919 break;
01920 }
01921
01922
01923 if ( (bComputeAllFocalValues==0) && (res.getX() != 0) )
01924 {
01925 break;
01926 }
01927
01928 }
01929 }
01930
01931
01932 lastDegree = currentDegree;
01933
01934 }
01935 catch (const char* str)
01936 {
01937 #ifdef DEBUG
01938 std::cerr << typeid(this).name() << std::endl;
01939 #endif
01940 std::cerr <<"fast_Frommer< TFrommerDefs, variant> :: doit error during computation of " << currFocalValuePos << "-th focal value: " << std::endl << str << std::endl;
01941 exit(0);
01942 }
01943 }
01944
01945
01955 template <class TFrommerDefs, int variant>
01956 inline typename TFrommerDefs::RingType::ElementType & fast_Frommer< TFrommerDefs, variant>::getFocalValue( int pos) const
01957 {
01958
01959 if (currFocalValuePos>pos && pos>0)
01960 return computedFocalValues[pos];
01961 else
01962 throw " requested focal value was not computed!" ;
01963
01964 }
01965
01966 template < class TFrommerDefs, int variant >
01967 void fast_Frommer< TFrommerDefs, variant>::getComputedFocalValues( vector<typename TFrommerDefs::RingType::ElementType> &computedFV ) const
01968 {
01969 computedFV.clear();
01970 computedFV.resize( currFocalValuePos-1 );
01971 for (int pos=1; pos<currFocalValuePos; pos++)
01972 {
01973 computedFV[ pos - 1 ] = computedFocalValues[ pos ] ;
01974 }
01975 }
01976
01977
01982 template <class TFrommerDefs, int variant>
01983 inline short fast_Frommer< TFrommerDefs, variant>::getSuccessiveVanishedFocalValuesCount() const
01984 {
01985 short i=0;
01986 while ( (i<maxFocalValuesToCompute) && (i+1<currFocalValuePos) && (computedFocalValues[i+1].getX()==0 ))
01987 {
01988
01989 i++;
01990 }
01991 assert(currFocalValuePos>=i);
01992 return i;
01993 }
01994
01995
01996 template < class TFrommerDefs, int variant >
01997 void fast_Frommer< TFrommerDefs, variant>::printStageTimings(std::ostream & os) const
01998 {
01999 #ifdef FROMMERSTAGE_TIMER
02000 os << "-- " << name_m << ": " << endl;
02001 frommerTimer_m.print(os);
02002 #endif
02003 }