00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Minuit2/MnLineSearch.h"
00011 #include "Minuit2/MnFcn.h"
00012 #include "Minuit2/MinimumParameters.h"
00013 #include "Minuit2/MnMachinePrecision.h"
00014 #include "Minuit2/MnParabola.h"
00015 #include "Minuit2/MnParabolaPoint.h"
00016 #include "Minuit2/MnParabolaFactory.h"
00017 #include "Minuit2/LaSum.h"
00018
00019 #include <iostream>
00020 #include "Minuit2/MnPrint.h"
00021
00022 #ifdef USE_OTHER_LS
00023
00024 #include "Math/SMatrix.h"
00025 #include "Math/SVector.h"
00026
00027 #include "Math/IFunction.h"
00028 #include "Math/Minimizer1D.h"
00029
00030 #endif
00031
00032
00033
00034 namespace ROOT {
00035
00036 namespace Minuit2 {
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 MnParabolaPoint MnLineSearch::operator()(const MnFcn& fcn, const MinimumParameters& st, const MnAlgebraicVector& step, double gdel, const MnMachinePrecision& prec, bool debug) const {
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifdef DEBUG
00060 debug = true;
00061 #endif
00062
00063 if (debug) {
00064 std::cout<<"gdel= "<<gdel<<std::endl;
00065 std::cout<<"step= "<<step<<std::endl;
00066 }
00067
00068 double overal = 1000.;
00069 double undral = -100.;
00070 double toler = 0.05;
00071 double slamin = 0.;
00072 double slambg = 5.;
00073 double alpha = 2.;
00074 int maxiter = 12;
00075
00076 int niter = 1;
00077
00078 for(unsigned int i = 0; i < step.size(); i++) {
00079 if(step(i) == 0 ) continue;
00080 double ratio = fabs(st.Vec()(i)/step(i));
00081 if( slamin == 0) slamin = ratio;
00082 if(ratio < slamin) slamin = ratio;
00083 }
00084 if(fabs(slamin) < prec.Eps()) slamin = prec.Eps();
00085 slamin *= prec.Eps2();
00086
00087 double f0 = st.Fval();
00088 double f1 = fcn(st.Vec()+step);
00089 niter++;
00090 double fvmin = st.Fval();
00091 double xvmin = 0.;
00092
00093 if(f1 < f0) {
00094 fvmin = f1;
00095 xvmin = 1.;
00096 }
00097 double toler8 = toler;
00098 double slamax = slambg;
00099 double flast = f1;
00100 double slam = 1.;
00101
00102 bool iterate = false;
00103 MnParabolaPoint p0(0., f0);
00104 MnParabolaPoint p1(slam, flast);
00105 double f2 = 0.;
00106
00107 do {
00108
00109 iterate = false;
00110
00111
00112 if (debug) {
00113
00114 std::cout<<"flast, f0= "<<flast<<", "<<f0<<std::endl;
00115 std::cout<<"flast-f0= "<<flast-f0<<std::endl;
00116 std::cout<<"slam= "<<slam<<std::endl;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125 double denom = 2.*(flast-f0-gdel*slam)/(slam*slam);
00126 if (debug) std::cout<<"denom= "<<denom<<std::endl;
00127 if(denom != 0) {
00128 slam = - gdel/denom;
00129 } else {
00130 denom = -0.1*gdel;
00131 slam = 1.;
00132 }
00133 if (debug) std::cout<<"new slam= "<<slam<<std::endl;
00134
00135
00136 #ifdef TRY_OPPOSIT_DIR
00137
00138 bool slamIsNeg = false;
00139 double slamNeg = 0;
00140 #endif
00141
00142 if(slam < 0.) {
00143 if (debug) std::cout<<"slam is negative- set to " << slamax << std::endl;
00144 #ifdef TRY_OPPOSITE_DIR
00145 slamNeg = 2*slam -1;
00146 slamIsNeg = true;
00147 if (debug) std::cout<<"slam is negative- compare values between "<< slamNeg << " and " << slamax << std::endl;
00148 #endif
00149 slam = slamax;
00150 }
00151
00152 if(slam > slamax) {
00153 slam = slamax;
00154 if (debug) std::cout << "slam larger than mac value - set to " << slamax << std::endl;
00155 }
00156
00157 if(slam < toler8) {
00158 if (debug) std::cout << "slam too small - set to " << toler8 << std::endl;
00159 slam = toler8;
00160 }
00161
00162 if(slam < slamin) {
00163 if (debug) std::cout << "slam smaller than " << slamin << " return " << std::endl;
00164
00165
00166
00167 return MnParabolaPoint(xvmin, fvmin);
00168 }
00169 if(fabs(slam - 1.) < toler8 && p1.Y() < p0.Y()) {
00170
00171
00172
00173 return MnParabolaPoint(xvmin, fvmin);
00174 }
00175 if(fabs(slam - 1.) < toler8) slam = 1. + toler8;
00176
00177
00178
00179
00180
00181
00182 f2 = fcn(st.Vec() + slam*step);
00183
00184 niter++;
00185
00186 #ifdef TRY_OPPOSITE_DIR
00187 if (slamIsNeg) {
00188
00189 double f2alt = fcn(st.Vec() + slamNeg*step);
00190 if (f2alt < f2) {
00191 slam = slamNeg;
00192 f2 = f2alt;
00193 undral += slam;
00194 }
00195 }
00196 #endif
00197 if(f2 < fvmin) {
00198 fvmin = f2;
00199 xvmin = slam;
00200 }
00201
00202 if (fabs( p0.Y() - fvmin) < fabs(fvmin)*prec.Eps() ) {
00203
00204 iterate = true;
00205 flast = f2;
00206 toler8 = toler*slam;
00207 overal = slam - toler8;
00208 slamax = overal;
00209 p1 = MnParabolaPoint(slam, flast);
00210
00211 }
00212 } while(iterate && niter < maxiter);
00213 if(niter >= maxiter) {
00214
00215 return MnParabolaPoint(xvmin, fvmin);
00216 }
00217
00218 if (debug){
00219 std::cout<<"after initial 2-point iter: "<<std::endl;
00220 std::cout<<"x0, x1, x2= "<<p0.X()<<", "<<p1.X()<<", "<<slam<<std::endl;
00221 std::cout<<"f0, f1, f2= "<<p0.Y()<<", "<<p1.Y()<<", "<<f2<<std::endl;
00222 }
00223
00224 MnParabolaPoint p2(slam, f2);
00225
00226
00227 do {
00228 slamax = std::max(slamax, alpha*fabs(xvmin));
00229 MnParabola pb = MnParabolaFactory()(p0, p1, p2);
00230 if (debug) {
00231 std::cout << "\nLS Iteration " << niter << std::endl;
00232 std::cout<<"x0, x1, x2= "<<p0.X()<<", "<<p1.X()<<", "<<p2.X() <<std::endl;
00233 std::cout<<"f0, f1, f2= "<<p0.Y()<<", "<<p1.Y()<<", "<<p2.Y() <<std::endl;
00234 std::cout << "slamax = " << slamax << std::endl;
00235 std::cout<<"p2-p0,p1: "<<p2.Y() - p0.Y()<<", "<<p2.Y() - p1.Y()<<std::endl;
00236 std::cout<<"a, b, c= "<<pb.A()<<" "<<pb.B()<<" "<<pb.C()<<std::endl;
00237 }
00238 if(pb.A() < prec.Eps2()) {
00239 double slopem = 2.*pb.A()*xvmin + pb.B();
00240 if(slopem < 0.) slam = xvmin + slamax;
00241 else slam = xvmin - slamax;
00242 if (debug) std::cout << "xvmin = " << xvmin << " slopem " << slopem << " slam " << slam << std::endl;
00243 } else {
00244 slam = pb.Min();
00245
00246 if(slam > xvmin + slamax) slam = xvmin + slamax;
00247 if(slam < xvmin - slamax) slam = xvmin - slamax;
00248 }
00249 if(slam > 0.) {
00250 if(slam > overal) slam = overal;
00251 } else {
00252 if(slam < undral) slam = undral;
00253 }
00254
00255 if (debug) {
00256 std::cout<<" slam= "<<slam<< " undral " << undral << " overal " << overal << std::endl;
00257 }
00258
00259 double f3 = 0.;
00260 do {
00261
00262 if (debug) std::cout << " iterate on f3- slam " << niter << " slam = " << slam << " xvmin " << xvmin << std::endl;
00263
00264 iterate = false;
00265 double toler9 = std::max(toler8, fabs(toler8*slam));
00266
00267 if(fabs(p0.X() - slam) < toler9 ||
00268 fabs(p1.X() - slam) < toler9 ||
00269 fabs(p2.X() - slam) < toler9) {
00270
00271
00272
00273 return MnParabolaPoint(xvmin, fvmin);
00274 }
00275
00276
00277
00278
00279 f3 = fcn(st.Vec() + slam*step);
00280 if (debug) {
00281 std::cout<<"f3= "<<f3<<std::endl;
00282 std::cout<<"f3-p(2-0).Y()= "<<f3-p2.Y()<<" "<<f3-p1.Y()<<" "<<f3-p0.Y()<<std::endl;
00283 }
00284
00285 if(f3 > p0.Y() && f3 > p1.Y() && f3 > p2.Y()) {
00286 if (debug) {
00287 std::cout<<"f3 worse than all three previous"<<std::endl;
00288 }
00289 if(slam > xvmin) overal = std::min(overal, slam-toler8);
00290 if(slam < xvmin) undral = std::max(undral, slam+toler8);
00291 slam = 0.5*(slam + xvmin);
00292 if (debug) {
00293 std::cout<<"new slam= "<<slam<<std::endl;
00294 }
00295 iterate = true;
00296 niter++;
00297 }
00298 } while(iterate && niter < maxiter);
00299 if(niter >= maxiter) {
00300
00301 return MnParabolaPoint(xvmin, fvmin);
00302 }
00303
00304
00305 MnParabolaPoint p3(slam, f3);
00306 if(p0.Y() > p1.Y() && p0.Y() > p2.Y()) p0 = p3;
00307 else if(p1.Y() > p0.Y() && p1.Y() > p2.Y()) p1 = p3;
00308 else p2 = p3;
00309 if (debug) std::cout << " f3 " << f3 << " fvmin " << fvmin << " xvmin " << xvmin << std::endl;
00310 if(f3 < fvmin) {
00311 fvmin = f3;
00312 xvmin = slam;
00313 } else {
00314 if(slam > xvmin) overal = std::min(overal, slam-toler8);
00315 if(slam < xvmin) undral = std::max(undral, slam+toler8);
00316 }
00317
00318 niter++;
00319 } while(niter < maxiter);
00320
00321 if (debug) {
00322 std::cout<<"f1, f2= "<<p0.Y()<<", "<<p1.Y()<<std::endl;
00323 std::cout<<"x1, x2= "<<p0.X()<<", "<<p1.X()<<std::endl;
00324 std::cout<<"x, f= "<<xvmin<<", "<<fvmin<<std::endl;
00325 }
00326 return MnParabolaPoint(xvmin, fvmin);
00327
00328 }
00329
00330 #ifdef USE_OTHER_LS
00331
00332
00333
00334
00335
00336 MnParabolaPoint MnLineSearch::CubicSearch(const MnFcn& fcn, const MinimumParameters& st, const MnAlgebraicVector& step, double gdel, double g2del, const MnMachinePrecision& prec, bool debug) const {
00337
00338
00339
00340 if (debug) {
00341 std::cout<<"gdel= "<<gdel<<std::endl;
00342 std::cout<<"g2del= "<<g2del<<std::endl;
00343 std::cout<<"step= "<<step<<std::endl;
00344 }
00345
00346
00347 double overal = 100.;
00348 double undral = -100.;
00349 double toler = 0.05;
00350 double slamin = 0.;
00351 double slambg = 5.;
00352 double alpha = 2.;
00353
00354 for(unsigned int i = 0; i < step.size(); i++) {
00355 if(step(i) == 0 ) continue;
00356 double ratio = fabs(st.Vec()(i)/step(i));
00357 if( slamin == 0) slamin = ratio;
00358 if(ratio < slamin) slamin = ratio;
00359 }
00360 if(fabs(slamin) < prec.Eps()) slamin = prec.Eps();
00361 slamin *= prec.Eps2();
00362
00363 double f0 = st.Fval();
00364 double f1 = fcn(st.Vec()+step);
00365 double fvmin = st.Fval();
00366 double xvmin = 0.;
00367 if (debug) std::cout << "f0 " << f0 << " f1 " << f1 << std::endl;
00368
00369 if(f1 < f0) {
00370 fvmin = f1;
00371 xvmin = 1.;
00372 }
00373 double toler8 = toler;
00374 double slamax = slambg;
00375 double flast = f1;
00376 double slam = 1.;
00377
00378
00379
00380
00381 ROOT::Math::SMatrix<double, 3> cubicMatrix;
00382 ROOT::Math::SVector<double, 3> cubicCoeff;
00383 ROOT::Math::SVector<double, 3> bVec;
00384 double x0 = 0;
00385
00386
00387
00388
00389 double x1 = slam;
00390 cubicMatrix(0,0) = (x0*x0*x0 - x1*x1*x1)/3.;
00391 cubicMatrix(0,1) = (x0*x0 - x1*x1)/2.;
00392 cubicMatrix(0,2) = (x0 - x1);
00393 cubicMatrix(1,0) = x0*x0;
00394 cubicMatrix(1,1) = x0;
00395 cubicMatrix(1,2) = 1;
00396 cubicMatrix(2,0) = 2.*x0;
00397 cubicMatrix(2,1) = 1;
00398 cubicMatrix(2,2) = 0;
00399
00400 bVec(0) = f0-f1;
00401 bVec(1) = gdel;
00402 bVec(2) = g2del;
00403
00404
00405 if (debug) std::cout << "Vec:\n " << bVec << std::endl;
00406
00407
00408 if (!cubicMatrix.Invert() ) {
00409 std::cout << "Inversion failed - return " << std::endl;
00410 return MnParabolaPoint(xvmin, fvmin);
00411 }
00412
00413 cubicCoeff = cubicMatrix * bVec;
00414 if (debug) std::cout << "Cubic:\n " << cubicCoeff << std::endl;
00415
00416
00417 double ddd = cubicCoeff(1)*cubicCoeff(1)-4*cubicCoeff(0)*cubicCoeff(2);
00418 double slam1, slam2 = 0;
00419
00420 if (cubicCoeff(0) > 0) {
00421 slam1 = (- cubicCoeff(1) - std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00422 slam2 = (- cubicCoeff(1) + std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00423 }
00424 else if (cubicCoeff(0) < 0) {
00425 slam1 = (- cubicCoeff(1) + std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00426 slam2 = (- cubicCoeff(1) - std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00427 }
00428 else {
00429 slam1 = - gdel/g2del;
00430 slam2 = slam1;
00431 }
00432
00433 std::cout << "slam1 & slam 2 " << slam1 << " " << slam2 << std::endl;
00434
00435
00436
00437 if (slam2 < undral) slam2 = undral;
00438 if (slam2 > overal) slam2 = overal;
00439
00440
00441
00442 if (std::fabs(slam2) < toler) slam2 = ( slam2 >=0 ) ? slamax : -slamax;
00443
00444
00445 std::cout << "try with slam 2 " << slam2 << std::endl;
00446
00447 double f2 = fcn(st.Vec()+slam2*step);
00448
00449 std::cout << "try with slam 2 " << slam2 << " f2 " << f2 << std::endl;
00450
00451 double fp;
00452
00453
00454 if (f2 < fvmin) {
00455 slam = slam2;
00456 xvmin = slam;
00457 fvmin = f2;
00458 fp = fvmin;
00459 } else {
00460
00461
00462 if (slam1 < undral) slam1 = undral;
00463 if (slam1 > overal) slam1 = overal;
00464
00465
00466 if (std::fabs(slam1) < toler) slam1 = ( slam1 >=0 ) ? -slamax : slamax;
00467
00468 double f3 = fcn(st.Vec()+slam1*step);
00469
00470 std::cout << "try with slam 1 " << slam1 << " f3 " << f3 << std::endl;
00471
00472 if (f3 < fvmin) {
00473 slam = slam1;
00474 fp = fvmin;
00475 xvmin = slam;
00476 fvmin = f3;
00477 } else {
00478
00479 if (f2 < f3) {
00480 slam = slam1;
00481 fp = f2;
00482 } else {
00483 slam = slam2;
00484 fp = f3;
00485 }
00486 }
00487 }
00488
00489 bool iterate2 = false;
00490 int niter = 0;
00491
00492 int maxiter = 10;
00493
00494 do {
00495 iterate2 = false;
00496
00497 std::cout << "\n iter" << niter << " test approx deriv ad second deriv at " << slam << " fp " << fp << std::endl;
00498
00499
00500 double h = 0.001*slam;
00501 double fh = fcn(st.Vec()+(slam+h)*step);
00502 double fl = fcn(st.Vec()+(slam-h)*step);
00503 double df = (fh-fl)/(2.*h);
00504 double df2 = (fh+fl-2.*fp )/(h*h);
00505
00506 std::cout << "deriv: " << df << " , " << df2 << std::endl;
00507
00508
00509 if ( std::fabs(df ) < prec.Eps() && std::fabs( df2 ) < prec.Eps() ) {
00510
00511 slam = ( slam >=0 ) ? -slamax : slamax;
00512 slamax *= 10;
00513 fp = fcn(st.Vec()+slam*step);
00514 }
00515 else if ( std::fabs(df2 ) <= 0) {
00516
00517
00518 return MnParabolaPoint(slam, fp);
00519
00520
00521
00522
00523
00524
00525
00526
00527 }
00528
00529 else
00530 return MnParabolaPoint(slam, fp);
00531
00532 niter++;
00533 } while (niter < maxiter);
00534
00535 return MnParabolaPoint(xvmin, fvmin);
00536
00537
00538 }
00539
00540
00541
00542 class ProjectedFcn : public ROOT::Math::IGenFunction {
00543
00544 public:
00545
00546 ProjectedFcn(const MnFcn & fcn, const MinimumParameters & pa, const MnAlgebraicVector & step) :
00547 fFcn(fcn),
00548 fPar(pa),
00549 fStep(step)
00550 {}
00551
00552
00553 ROOT::Math::IGenFunction * Clone() const { return new ProjectedFcn(*this); }
00554
00555 private:
00556
00557 double DoEval(double x) const {
00558 return fFcn(fPar.Vec() + x*fStep);
00559 }
00560
00561 const MnFcn & fFcn;
00562 const MinimumParameters & fPar;
00563 const MnAlgebraicVector & fStep;
00564 };
00565
00566
00567 MnParabolaPoint MnLineSearch::BrentSearch(const MnFcn& fcn, const MinimumParameters& st, const MnAlgebraicVector& step, double gdel, double g2del, const MnMachinePrecision& prec, bool debug) const {
00568
00569 if (debug) {
00570 std::cout<<"gdel= "<<gdel<<std::endl;
00571 std::cout<<"g2del= "<<g2del<<std::endl;
00572 for (unsigned int i = 0; i < step.size(); ++i) {
00573 if (step(i) != 0) {
00574 std::cout<<"step(i)= "<<step(i)<<std::endl;
00575 std::cout<<"par(i) " <<st.Vec()(i) <<std::endl;
00576 break;
00577 }
00578 }
00579 }
00580
00581 ProjectedFcn func(fcn, st, step);
00582
00583
00584
00585
00586 double f0 = st.Fval();
00587 double f1 = fcn(st.Vec()+step);
00588 f0 = func(0.0);
00589 f1 = func(1.);
00590 double fvmin = st.Fval();
00591 double xvmin = 0.;
00592 if (debug) std::cout << "f0 " << f0 << " f1 " << f1 << std::endl;
00593
00594 if(f1 < f0) {
00595 fvmin = f1;
00596 xvmin = 1.;
00597 }
00598
00599
00600
00601 double slam = 1.;
00602
00603 double undral = -1000;
00604 double overal = 1000;
00605
00606 double x0 = 0;
00607
00608
00609
00610 #ifdef USE_CUBIC
00611
00612 ROOT::Math::SMatrix<double, 3> cubicMatrix;
00613 ROOT::Math::SVector<double, 3> cubicCoeff;
00614 ROOT::Math::SVector<double, 3> bVec;
00615
00616
00617
00618
00619 double x1 = slam;
00620 cubicMatrix(0,0) = (x0*x0*x0 - x1*x1*x1)/3.;
00621 cubicMatrix(0,1) = (x0*x0 - x1*x1)/2.;
00622 cubicMatrix(0,2) = (x0 - x1);
00623 cubicMatrix(1,0) = x0*x0;
00624 cubicMatrix(1,1) = x0;
00625 cubicMatrix(1,2) = 1;
00626 cubicMatrix(2,0) = 2.*x0;
00627 cubicMatrix(2,1) = 1;
00628 cubicMatrix(2,2) = 0;
00629
00630 bVec(0) = f0-f1;
00631 bVec(1) = gdel;
00632 bVec(2) = g2del;
00633
00634
00635 if (debug) std::cout << "Vec:\n " << bVec << std::endl;
00636
00637
00638 if (!cubicMatrix.Invert() ) {
00639 std::cout << "Inversion failed - return " << std::endl;
00640 return MnParabolaPoint(xvmin, fvmin);
00641 }
00642
00643 cubicCoeff = cubicMatrix * bVec;
00644 if (debug) std::cout << "Cubic:\n " << cubicCoeff << std::endl;
00645
00646
00647 double ddd = cubicCoeff(1)*cubicCoeff(1)-4*cubicCoeff(0)*cubicCoeff(2);
00648 double slam1, slam2 = 0;
00649
00650 if (cubicCoeff(0) > 0) {
00651 slam1 = (- cubicCoeff(1) - std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00652 slam2 = (- cubicCoeff(1) + std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00653 }
00654 else if (cubicCoeff(0) < 0) {
00655 slam1 = (- cubicCoeff(1) + std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00656 slam2 = (- cubicCoeff(1) - std::sqrt(ddd) ) / ( 2. * cubicCoeff(0) );
00657 }
00658 else {
00659 slam1 = - gdel/g2del;
00660 slam2 = slam1;
00661 }
00662
00663 if (slam1 < undral) slam1 = undral;
00664 if (slam1 > overal) slam1 = overal;
00665
00666 if (slam2 < undral) slam2 = undral;
00667 if (slam2 > overal) slam2 = overal;
00668
00669
00670 double fs1 = func(slam1);
00671 double fs2 = func(slam2);
00672 std::cout << "slam1 & slam 2 " << slam1 << " " << slam2 << std::endl;
00673 std::cout << "f(slam1) & f(slam 2) " << fs1 << " " << fs2 << std::endl;
00674
00675 if (fs1 < fs2) {
00676 x0 = slam1;
00677 f0 = fs1;
00678 }
00679 else {
00680 x0 = slam2;
00681 f0 = fs2;
00682 }
00683
00684 #else
00685 x0 = xvmin;
00686 f0 = fvmin;
00687 #endif
00688
00689
00690 double astart = 100;
00691
00692
00693
00694 double a = x0 -astart;
00695 double b = x0 + astart;
00696
00697 int maxiter = 20;
00698 double absTol = 0.5;
00699 double relTol = 0.05;
00700
00701 ROOT::Math::Minim1D::Type minType = ROOT::Math::Minim1D::BRENT;
00702
00703 bool iterate = false;
00704 int iter = 0;
00705
00706 std::cout << "f(0)" << func(0.) << std::endl;
00707 std::cout << "f(1)" << func(1.0) << std::endl;
00708 std::cout << "f(3)" << func(3.0) << std::endl;
00709 std::cout << "f(5)" << func(5.0) << std::endl;
00710
00711 double fa = func(a);
00712 double fb = func(b);
00713
00714 double toler = 0.01;
00715 double delta0 = 5;
00716 double delta = delta0;
00717 bool enlarge = true;
00718 bool scanmin = false;
00719 double x2, f2 = 0;
00720 double dir = 1;
00721 int nreset = 0;
00722
00723 do {
00724
00725 std::cout << " iter " << iter << " a , b , x0 " << a << " " << b << " x0 " << x0 << std::endl;
00726 std::cout << " fa , fb , f0 " << fa << " " << fb << " f0 " << f0 << std::endl;
00727 if (fa <= f0 || fb <= f0) {
00728 scanmin = false;
00729 if (fa < fb) {
00730 if (fa < fvmin) {
00731 fvmin = fa;
00732 xvmin = a;
00733 }
00734
00735
00736 if (enlarge) {
00737 x2 = a - 1000;
00738 f2 = func(x2);
00739 }
00740 if ( std::fabs ( (fa -f2 )/(a-x2) ) > toler ) {
00741 x0 = a;
00742 f0 = fa;
00743 a = x2;
00744 fa = f2;
00745 enlarge = true;
00746 } else {
00747
00748
00749 if (nreset == 0) dir = -1;
00750 enlarge = false;
00751 x0 = x0 + dir * delta;
00752 f0 = func(x0);
00753
00754 if ( std::fabs (( f0 -fa )/(x0 -a) ) < toler ) {
00755 delta = 10 * delta0/(10.*(nreset+1));
00756 a = x0;
00757 fa = f0;
00758 x0 = delta;
00759 f0 = func(x0);
00760 dir *= -1;
00761 nreset++;
00762 std::cout << " A: Done a reset - scan in opposite direction ! " << std::endl;
00763 }
00764 delta *= 2;
00765 if (x0 < b && x0 > a )
00766 scanmin = true;
00767 else {
00768 x0 = 0;
00769 f0 = st.Fval();
00770 }
00771 }
00772 }
00773 else {
00774 if (fb < fvmin) {
00775 fvmin = fb;
00776 xvmin = b;
00777 }
00778 if (enlarge) {
00779 x2 = b + 1000;
00780 f2 = func(x2);
00781 }
00782 if ( std::fabs ( (fb -f2 )/(x2-b) ) > toler ) {
00783 f0 = fb;
00784 x0 = b;
00785 b = x2;
00786 fb = f2;
00787 enlarge = true;
00788 } else {
00789
00790
00791 if (nreset == 0) dir = 1;
00792 enlarge = false;
00793 x0 = x0 + dir * delta;
00794 f0 = func(x0);
00795
00796 if ( std::fabs ( ( f0 -fb )/(x0-b) ) < toler ) {
00797 delta = 10 * delta0/(10.*(nreset+1));
00798 b = x0;
00799 fb = f0;
00800 x0 = -delta;
00801 f0 = func(x0);
00802 dir *= -1;
00803 nreset++;
00804 std::cout << " B: Done a reset - scan in opposite direction ! " << std::endl;
00805 }
00806 delta *= 2;
00807 if (x0 > a && x0 < b)
00808 scanmin = true;
00809 else {
00810 x0 = 0;
00811 f0 = st.Fval();
00812 }
00813
00814 }
00815
00816 }
00817
00818 if ( f0 < fvmin) {
00819 x0 = xvmin;
00820 fvmin = f0;
00821 }
00822
00823 std::cout << " new x0 " << x0 << " " << f0 << std::endl;
00824
00825
00826 iterate = scanmin || enlarge;
00827
00828 } else {
00829 iterate = false;
00830 }
00831
00832 iter++;
00833 } while (iterate && iter < maxiter );
00834
00835 if ( f0 > fa || f0 > fb)
00836
00837
00838 return MnParabolaPoint(xvmin, fvmin);
00839
00840
00841
00842
00843 std::cout << "1D minimization using " << minType << std::endl;
00844
00845 ROOT::Math::Minimizer1D min(minType);
00846
00847 min.SetFunction(func,x0, a, b);
00848 int ret = min.Minimize(maxiter, absTol, relTol);
00849
00850 std::cout << "result of GSL 1D minimization: " << ret << " niter " << min.Iterations() << std::endl;
00851 std::cout << " xmin = " << min.XMinimum() << " fmin " << min.FValMinimum() << std::endl;
00852
00853 return MnParabolaPoint(min.XMinimum(), min.FValMinimum());
00854
00855 }
00856
00857 #endif
00858
00859
00860
00861 }
00862
00863 }