00001
00002
00003 #include "Math/Minimizer.h"
00004 #include "Math/Factory.h"
00005
00006 #include "TVirtualFitter.h"
00007
00008 #include "Math/IFunction.h"
00009 #include "Math/Util.h"
00010 #include <cmath>
00011 #include <cassert>
00012
00013 #include <string>
00014 #include <iostream>
00015
00016 #include "TStopwatch.h"
00017 #include "TMatrixD.h"
00018 #include "TVectorD.h"
00019 #include "TRandom3.h"
00020 #include "TMath.h"
00021
00022
00023
00024 int gNCall = 0;
00025 int gNCall2 = 0;
00026 int gNmin = 1000;
00027 int gVerbose = 0;
00028
00029
00030 bool minos = false;
00031
00032 double gAbsTolerance = 0.001;
00033
00034
00035
00036 typedef void (*FCN)(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00037
00038
00039
00040
00041
00042 void RosenBrock(Int_t &, Double_t *, Double_t &f, Double_t *par, Int_t )
00043 {
00044 gNCall++;
00045 const Double_t x = par[0];
00046 const Double_t y = par[1];
00047 const Double_t tmp1 = y-x*x;
00048 const Double_t tmp2 = 1-x;
00049 f = 100*tmp1*tmp1+tmp2*tmp2;
00050 }
00051
00052
00053
00054 class RosenBrockFunction : public ROOT::Math::IMultiGenFunction {
00055
00056 public :
00057
00058
00059 unsigned int NDim() const { return 2; }
00060
00061 ROOT::Math::IMultiGenFunction * Clone() const {
00062 return new RosenBrockFunction();
00063 }
00064
00065 const double * TrueMinimum() const {
00066 fTrueMin[0] = 1;
00067 fTrueMin[1] = 1;
00068 return fTrueMin;
00069 }
00070
00071 private:
00072
00073 inline double DoEval (const double * x) const {
00074 #ifdef USE_FREE_FUNC
00075 double f = 0;
00076 int ierr = 0;
00077 int i = 0;
00078 RosenBrock(i,0,f,const_cast<double *>(x),ierr);
00079 return f;
00080 #else
00081 gNCall++;
00082 const Double_t xx = x[0];
00083 const Double_t yy = x[1];
00084 const Double_t tmp1 = yy-xx*xx;
00085 const Double_t tmp2 = 1-xx;
00086 return 100*tmp1*tmp1+tmp2*tmp2;
00087 #endif
00088 }
00089
00090
00091 mutable double fTrueMin[2];
00092 };
00093
00094
00095
00096 class TrigoFletcherFunction : public ROOT::Math::IMultiGradFunction {
00097
00098 public :
00099
00100
00101 TrigoFletcherFunction(unsigned int dim) : fDim(dim) {
00102 double seed = 3;
00103 A.ResizeTo(dim,dim);
00104 B.ResizeTo(dim,dim);
00105 x0.ResizeTo(dim);
00106 sx0.ResizeTo(dim);
00107 cx0.ResizeTo(dim);
00108 sx.ResizeTo(dim);
00109 cx.ResizeTo(dim);
00110 v0.ResizeTo(dim);
00111 v.ResizeTo(dim);
00112 r.ResizeTo(dim);
00113 A.Randomize(-100.,100,seed);
00114 B.Randomize(-100.,100,seed);
00115 for (unsigned int i = 0; i < dim; i++) {
00116 for (unsigned int j = 0; j < dim; j++) {
00117 A(i,j) = int(A(i,j));
00118 B(i,j) = int(B(i,j));
00119 }
00120 }
00121 x0.Randomize(-TMath::Pi(),TMath::Pi(),seed);
00122
00123 for (unsigned int i = 0; i < fDim ; ++i) {
00124 cx0[i] = std::cos(x0[i]);
00125 sx0[i] = std::sin(x0[i]);
00126 }
00127 v0 = A*sx0+B*cx0;
00128 }
00129
00130
00131 unsigned int NDim() const { return fDim; }
00132
00133 ROOT::Math::IMultiGenFunction * Clone() const {
00134 TrigoFletcherFunction * f = new TrigoFletcherFunction(*this);
00135
00136
00137 return f;
00138 }
00139
00140
00141 void StartPoints(double * x, double * s) {
00142 TRandom3 rndm;
00143 const double stepSize = 0.01;
00144 const double deltaAmp = 0.1;
00145 const double pi = TMath::Pi();
00146 for (unsigned int i = 0; i < fDim; ++i) {
00147 double delta = rndm.Uniform(-deltaAmp*pi,deltaAmp*pi);
00148 x[i] = x0(i) + 0.1*delta;
00149 if (x[i] <= - pi) x[i] += 2.*pi;
00150 if (x[i] > pi) x[i] -= 2.*pi;
00151 s[i] = stepSize;
00152 }
00153 }
00154
00155
00156 const double * TrueMinimum() const {
00157 return x0.GetMatrixArray();
00158 }
00159
00160
00161 void Gradient (const double * x, double * g) const {
00162 gNCall2++;
00163
00164 for (unsigned int i = 0; i < fDim ; ++i) {
00165 cx [i] = std::cos(x[i]);
00166 sx [i] = std::sin(x[i]);
00167 }
00168
00169 v = A*sx +B*cx;
00170 r = v0-v;
00171
00172
00173
00174 for (unsigned int i = 0; i < fDim ; ++i) {
00175 g[i] = 0;
00176 for (unsigned int k = 0; k < fDim ; ++k) {
00177 g[i] += 2. * r(k) * ( - A(k,i) * cx(i) + B(k,i) * sx(i) );
00178 }
00179 }
00180
00181 }
00182
00183 #ifdef USE_FDF
00184 void FdF (const double * x, double & f, double * g) const {
00185 gNCall++;
00186
00187 for (unsigned int i = 0; i < fDim ; ++i) {
00188 cx [i] = std::cos(x[i]);
00189 sx [i] = std::sin(x[i]);
00190 }
00191
00192 v = A*sx +B*cx;
00193 r = v0-v;
00194
00195 f = r * r;
00196
00197
00198
00199 for (unsigned int i = 0; i < fDim ; ++i) {
00200 g[i] = 0;
00201 for (unsigned int k = 0; k < fDim ; ++k) {
00202 g[i] += 2. * r(k) * ( - A(k,i) * cx(i) + B(k,i) * sx(i) );
00203 }
00204 }
00205 }
00206 #endif
00207
00208 private:
00209
00210
00211
00212
00213 double DoEval (const double * x) const {
00214 gNCall++;
00215
00216
00217 for (unsigned int i = 0; i < fDim ; ++i) {
00218 cx [i] = std::cos(x[i]);
00219 sx [i] = std::sin(x[i]);
00220 }
00221
00222 v = A*sx +B*cx;
00223 r = v0-v;
00224
00225 return r * r;
00226 }
00227
00228
00229 double DoDerivative (const double * x, unsigned int i ) const {
00230 std::vector<double> g(fDim);
00231 Gradient(x,&g[0]);
00232 return g[i];
00233 }
00234
00235 private:
00236
00237 unsigned int fDim;
00238
00239 TMatrixD A;
00240 TMatrixD B;
00241 TVectorD x0;
00242 mutable TVectorD sx0;
00243 mutable TVectorD cx0;
00244 mutable TVectorD sx;
00245 mutable TVectorD cx;
00246 mutable TVectorD v0;
00247 mutable TVectorD v;
00248 mutable TVectorD r;
00249
00250
00251 };
00252
00253
00254
00255
00256 class ChebyQuadFunction : public ROOT::Math::IMultiGradFunction {
00257
00258 public :
00259
00260 ChebyQuadFunction(unsigned int n) :
00261 fDim(n),
00262 fvec(std::vector<double>(n) ),
00263 fTrueMin(std::vector<double>(n) )
00264 {
00265 }
00266
00267 unsigned int NDim() const { return fDim; }
00268
00269 ROOT::Math::IMultiGenFunction * Clone() const {
00270 return new ChebyQuadFunction(*this);
00271 }
00272
00273 const double * TrueMinimum() const {
00274 return &fTrueMin[0];
00275 }
00276
00277
00278 void StartPoints(double * x, double * s) {
00279 for (unsigned int i = 0; i < fDim; ++i) {
00280 s[i] = 0.01;
00281 x[i] = double(i)/(double(fDim)+1.0);
00282 }
00283 }
00284
00285
00286
00287 void Gradient(const double * x, double * g) const {
00288 gNCall2++;
00289 unsigned int n = fDim;
00290
00291 DoCalculatefi(x);
00292
00293 for (unsigned int j = 0; j < n; ++j) {
00294 g[j] = 0.0;
00295 double t1 = 1.0;
00296 double t2 = 2.0 * x[j] - 1.0;
00297 double t = 2.0 * t2;
00298 double s1 = 0.0;
00299 double s2 = 2.0;
00300 for (unsigned int i = 0; i < n; ++i) {
00301 g[j] += fvec[i] * s2;
00302 double th = 4.0 * t2 + t * s2 - s1;
00303 s1 = s2;
00304 s2 = th;
00305 th = t * t2 - t1;
00306 t1 = t2;
00307 t2 = th;
00308 }
00309 g[j] = 2. * g[j] / double(n);
00310 }
00311
00312
00313 }
00314
00315 private:
00316
00317 double DoEval (const double * x) const {
00318
00319 gNCall++;
00320 DoCalculatefi(x);
00321 double f = 0;
00322 for (unsigned int i = 0; i < fDim; ++i)
00323 f += fvec[i] * fvec[i];
00324
00325 return f;
00326
00327 }
00328
00329 double DoDerivative (const double * x, unsigned int i ) const {
00330 std::vector<double> g(fDim);
00331 Gradient(x,&g[0]);
00332 return g[i];
00333 }
00334
00335 void DoCalculatefi(const double * x) const {
00336
00337 unsigned int n = fDim;
00338 for (unsigned int i = 0; i < n; ++i)
00339 fvec[i] = 0;
00340
00341 for (unsigned int j = 0; j < n; ++j) {
00342 double t1 = 1.0;
00343 double t2 = 2.0 * x[j] - 1.0;
00344 double t = 2.0 * t2;
00345 for (unsigned int i = 0; i < n; ++i) {
00346 fvec[i] += t2;
00347 double th = t * t2 - t1;
00348 t1 = t2;
00349 t2 = th;
00350 }
00351 }
00352
00353
00354 for (unsigned int i = 1; i <= n; ++i) {
00355 int l = i-1;
00356 fvec[l] /= double ( n );
00357 if ( ( i % 2 ) == 0 ) {
00358 fvec[l] += 1.0 / ( double ( i*i ) - 1.0 );
00359 }
00360 }
00361 }
00362
00363 unsigned int fDim;
00364 mutable std::vector<double> fvec;
00365 mutable std::vector<double> fTrueMin;
00366 };
00367
00368
00369
00370 const double * TrueMinimum(const ROOT::Math::IMultiGenFunction & func) {
00371
00372 const RosenBrockFunction * fRB = dynamic_cast< const RosenBrockFunction *> (&func);
00373 if (fRB != 0) return fRB->TrueMinimum();
00374 const TrigoFletcherFunction * fTF = dynamic_cast< const TrigoFletcherFunction *> (&func);
00375 if (fTF != 0) return fTF->TrueMinimum();
00376
00377
00378 return 0;
00379 }
00380
00381 void printMinimum(const std::vector<double> & x) {
00382 std::cout << "Minimum X values\n";
00383 std::cout << "\t";
00384 int pr = std::cout.precision(12);
00385 unsigned int n = x.size();
00386 for (unsigned int i = 0; i < n; ++i) {
00387 std::cout << x[i];
00388 if ( i != n-1 ) std::cout << " , ";
00389 if ( i > 0 && i % 6 == 0 ) std::cout << "\n\t";
00390 }
00391 std::cout << std::endl;
00392 std::cout.precision(pr);
00393 }
00394
00395 int DoNewMinimization( const ROOT::Math::IMultiGenFunction & func, const double * x0, const double * s0, ROOT::Math::Minimizer * min, double &minval, double &edm, double * minx) {
00396
00397 int iret = 0;
00398
00399 if (func.NDim() >= 10) {
00400 min->SetMaxFunctionCalls(1000000);
00401 min->SetMaxIterations(100000);
00402 min->SetTolerance(0.001);
00403 if (func.NDim() >= 10) min->SetTolerance(0.01);
00404
00405 }
00406
00407 min->SetPrintLevel(gVerbose);
00408
00409 const ROOT::Math::IMultiGradFunction * gfunc = dynamic_cast<const ROOT::Math::IMultiGradFunction *>(&func);
00410 if (gfunc != 0)
00411 min->SetFunction(*gfunc);
00412 else
00413 min->SetFunction(func);
00414
00415 for (unsigned int i = 0; i < func.NDim(); ++i) {
00416 min->SetVariable(i,"x" + ROOT::Math::Util::ToString(i),x0[i], s0[i]);
00417 }
00418
00419 bool ret = min->Minimize();
00420 minval = min->MinValue();
00421 edm = min->Edm();
00422
00423 if (!ret) {
00424 delete min;
00425 return -1;
00426 }
00427
00428 const double * xmin = min->X();
00429
00430 bool ok = true;
00431 const double * trueMin = TrueMinimum(func);
00432 if (trueMin != 0) {
00433 for (unsigned int i = 0; i < func.NDim(); ++i)
00434 ok &= (std::fabs(xmin[i]-trueMin[i] ) < gAbsTolerance);
00435 }
00436
00437 if (!ok) iret = -2;
00438
00439
00440 if (minos) {
00441
00442 double el,eu;
00443 for (unsigned int i = 0; i < func.NDim(); ++i) {
00444 ret = min->GetMinosError(i,el,eu);
00445 if (ret) std::cout << "MINOS error for " << i << " = " << el << " " << eu << std::endl;
00446 else std::cout << "MINOS failed for " << i << std::endl;
00447 }
00448 }
00449
00450 #ifdef DEBUG
00451 std::cout << "ncalls = " << min->NCalls() << std::endl;
00452 #endif
00453
00454
00455 std::copy(xmin,xmin+func.NDim(),minx);
00456 min->Clear();
00457
00458 return iret;
00459 }
00460
00461 int DoOldMinimization( FCN func, TVirtualFitter * min, double &minval, double &edm) {
00462
00463 int iret = 0;
00464
00465 assert(min != 0);
00466 min->SetFCN( func );
00467
00468 Double_t arglist[100];
00469 arglist[0] = gVerbose-1;
00470 min->ExecuteCommand("SET PRINT",arglist,1);
00471
00472 min->SetParameter(0,"x",-1.2,0.01,0,0);
00473 min->SetParameter(1,"y", 1.0,0.01,0,0);
00474
00475 arglist[0] = 0;
00476 min->ExecuteCommand("SET NOW",arglist,0);
00477 arglist[0] = 1000;
00478 arglist[1] = 0.001;
00479
00480 min->ExecuteCommand("MIGRAD",arglist,2);
00481
00482 if (minos) min->ExecuteCommand("MINOS",arglist,0);
00483
00484 Double_t parx,pary;
00485 Double_t we,al,bl;
00486 Char_t parName[32];
00487 min->GetParameter(0,parName,parx,we,al,bl);
00488 min->GetParameter(1,parName,pary,we,al,bl);
00489
00490 bool ok = ( TMath::Abs(parx-1.) < gAbsTolerance &&
00491 TMath::Abs(pary-1.) < gAbsTolerance );
00492
00493
00494 double errdef = 0;
00495 int nvpar, nparx;
00496 min->GetStats(minval,edm,errdef,nvpar,nparx);
00497 if (!ok) iret = -2;
00498
00499 min->Clear();
00500 return iret;
00501
00502 }
00503
00504
00505 int testNewMinimizer( const ROOT::Math::IMultiGenFunction & func, const double * x0, const double * s0, const std::string & minimizer, const std::string & algoType) {
00506
00507 std::cout << "\n************************************************************\n";
00508 std::cout << "\tTest new ROOT::Math::Minimizer\n";
00509 std::cout << "\tMinimizer is " << minimizer << " " << algoType << std::endl;
00510
00511 int iret = 0;
00512 double minval,edm = 0;
00513 std::vector<double> xmin(func.NDim() );
00514
00515 TStopwatch w;
00516 w.Start();
00517
00518 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(minimizer, algoType);
00519 if (min == 0) {
00520 std::cout << "Error using minimizer " << minimizer << " " << algoType << std::endl;
00521 return -1;
00522 }
00523
00524
00525 for (int i = 0; i < gNmin; ++i) {
00526 gNCall = 0; gNCall2 = 0;
00527 iret |= DoNewMinimization(func, x0, s0, min,minval,edm,&xmin[0]);
00528 }
00529
00530 w.Stop();
00531 if (iret != 0) std::cout << "\n****** ERROR: Minimization FAILED ! \n";
00532 int pr = std::cout.precision(18);
00533 std::cout << "\nNCalls: \t" << gNCall << " , " << gNCall2
00534 << "\tMinValue: \t" << minval << "\tEdm: \t" << edm; std::cout.precision(pr);
00535 std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;
00536 printMinimum(xmin );
00537 std::cout << "\n************************************************************\n";
00538
00539 #ifdef CHECK_WITHMINUIT
00540
00541 if (minimizer == "GSL_BFGS") {
00542 std::cout << "DO Minuit2 from last point\n";
00543 gNCall = 0;
00544 iret |= DoNewMinimization(func, &xmin.front(), s0, "Minuit2","",minval,edm,&xmin[0]);
00545 int pr = std::cout.precision(18);
00546 std::cout << "\nNCalls: \t" << gNCall << "\tMinValue: \t" << minval << "\tEdm: \t" << edm; std::cout.precision(pr);
00547 std::cout << std::endl;
00548 }
00549 #endif
00550
00551 delete min;
00552
00553 return iret;
00554 }
00555
00556
00557 int testOldMinimizer( FCN func, const std::string & fitter, int n=25) {
00558
00559 std::cout << "\n************************************************************\n";
00560 std::cout << "\tTest using TVirtualFitter\n";
00561 std::cout << "\tFitter is " << fitter << std::endl;
00562
00563 int iret = 0;
00564 double minval,edm = 0;
00565
00566 TStopwatch w;
00567 w.Start();
00568
00569 TVirtualFitter::SetDefaultFitter(fitter.c_str());
00570
00571 TVirtualFitter *min = TVirtualFitter::Fitter(0,n);
00572
00573
00574
00575 for (int i = 0; i < gNmin; ++i) {
00576 gNCall = 0;
00577 iret |= DoOldMinimization(func, min,minval,edm);
00578 }
00579
00580 w.Stop();
00581 if (iret != 0) std::cout << "\n****** ERROR: Minimization FAILED ! \n";
00582 int pr = std::cout.precision(18);
00583 std::cout << "\nNCalls: \t" << gNCall << "\tMinValue: \t" << minval << "\tEdm: \t" << edm; std::cout.precision(pr);
00584 std::cout << "\nTime: \t" << w.RealTime() << " , " << w.CpuTime() << std::endl;
00585 std::cout << "\n************************************************************\n";
00586
00587 return iret;
00588 }
00589
00590 int testRosenBrock() {
00591
00592 int iret = 0;
00593
00594
00595 std::cout << "\n************************************************************\n";
00596 std::cout << "\tROSENBROCK function test\n\n";
00597
00598 double s0[2] = {0.01,0.01};
00599
00600
00601 #ifndef DEBUG
00602 gNmin = 10000;
00603 #endif
00604 iret |= testOldMinimizer(RosenBrock,"Minuit",2);
00605 iret |= testOldMinimizer(RosenBrock,"Minuit2",2);
00606
00607 RosenBrockFunction fRB;
00608 double xRB[2] = { -1.,1.2};
00609 iret |= testNewMinimizer(fRB,xRB,s0,"Minuit","");
00610 iret |= testNewMinimizer(fRB,xRB,s0,"Minuit2","");
00611 iret |= testNewMinimizer(fRB,xRB,s0,"GSLMultiMin","ConjugateFR");
00612 iret |= testNewMinimizer(fRB,xRB,s0,"GSLMultiMin","ConjugatePR");
00613 iret |= testNewMinimizer(fRB,xRB,s0,"GSLMultiMin","BFGS");
00614 iret |= testNewMinimizer(fRB,xRB,s0,"GSLMultiMin","BFGS2");
00615
00616
00617
00618 return iret;
00619 }
00620
00621
00622 int testTrigoFletcher() {
00623
00624 int iret = 0;
00625
00626
00627
00628 #ifndef DEBUG
00629 gNmin = 1;
00630 #endif
00631
00632 const int nT = 50;
00633 TrigoFletcherFunction fTrigo(nT);
00634 double sTrigo[nT];
00635 double xTrigo[nT];
00636 fTrigo.StartPoints(xTrigo,sTrigo);
00637
00638 std::cout << "\n************************************************************\n";
00639 std::cout << "\tTRIGONOMETRIC Fletcher function test , n = " << nT << "\n\n";
00640
00641
00642 iret |= testNewMinimizer(fTrigo,xTrigo,sTrigo,"Minuit2","");
00643 iret |= testNewMinimizer(fTrigo,xTrigo,sTrigo,"Minuit","");
00644 iret |= testNewMinimizer(fTrigo,xTrigo,sTrigo,"GSLMultiMin","ConjugateFR");
00645 iret |= testNewMinimizer(fTrigo,xTrigo,sTrigo,"GSLMultiMin","ConjugatePR");
00646 iret |= testNewMinimizer(fTrigo,xTrigo,sTrigo,"GSLMultiMin","BFGS");
00647
00648
00649 return iret;
00650 }
00651
00652 int testChebyQuad() {
00653
00654 int iret = 0;
00655
00656
00657
00658 const int n = 8;
00659 ChebyQuadFunction func(n);
00660
00661 #ifndef DEBUG
00662 gNmin = std::max(1, int(1000/n/n) );
00663 #endif
00664
00665
00666 double s0[n];
00667 double x0[n];
00668 func.StartPoints(x0,s0);
00669
00670 std::cout << "\n************************************************************\n";
00671 std::cout << "\tCHEBYQUAD function test , n = " << n << "\n\n";
00672
00673
00674
00675
00676
00677
00678 double x1[100] = { 0.00712780070646 , 0.0123441993113 , 0.0195428378255 , 0.0283679084192 , 0.0385291131289 , 0.0492202424892 , 0.0591277976178 ,
00679 0.0689433195252 , 0.0791293590525 , 0.088794974369 , 0.0988949579193 , 0.108607151294 , 0.118571075831 ,
00680 0.128605446238 , 0.137918291068 , 0.149177761352 , 0.156665324587 , 0.170851061982 , 0.174688134016 ,
00681 0.192838903364 , 0.193078270803 , 0.209255377225 , 0.217740096779 , 0.225888518345 , 0.241031047421 ,
00682 0.244253844041 , 0.257830449676 , 0.269467652526 , 0.274286498012 , 0.288877029988 , 0.297549406597 ,
00683 0.304950954529 , 0.319230811642 , 0.326387092206 , 0.335229058731 , 0.349178359226 , 0.355905988048 ,
00684 0.365197862755 , 0.379068092603 , 0.385826036925 , 0.394978252826 , 0.408974425717 , 0.415968185065 ,
00685 0.424621041584 , 0.438837361714 , 0.446214149031 , 0.454242324351 , 0.468614308013 , 0.476506553416 ,
00686 0.483916944941 , 0.498229247409 , 0.506794629616 , 0.513736742474 , 0.527712475478 , 0.537073277673 ,
00687 0.543731917673 , 0.557187513963 , 0.567346279639 , 0.57379846397 , 0.586691058785 , 0.597561941009 ,
00688 0.60382873461 , 0.616316037506 , 0.627719652101 , 0.633760038662 , 0.646175283836 , 0.657809344891 ,
00689 0.663569004722 , 0.676314563639 , 0.687674566849 , 0.69332205923 , 0.706839545953 , 0.716907408637 ,
00690 0.723407327715 , 0.738019389561 , 0.744806584048 , 0.754657613362 , 0.769181875619 , 0.772250323489 ,
00691 0.787104833193 , 0.795856360905 , 0.804099304478 , 0.82142178741 , 0.819589601284 , 0.839024540481 ,
00692 0.842457233039 , 0.857393475964 , 0.86408033345 , 0.876329840525 , 0.884867318008 , 0.895744532071 ,
00693 0.905113958163 , 0.915445338697 , 0.925148068352 , 0.935344457785 , 0.945127838313 , 0.955272197168 ,
00694 0.965687518559 , 0.975129521484 , 0.982662007764 };
00695
00696 std::cout << "FUNC " << func(x1) << std::endl;
00697
00698
00699 iret |= testNewMinimizer(func,x0,s0, "Minuit2","");
00700 iret |= testNewMinimizer(func,x0,s0, "Minuit","");
00701 iret |= testNewMinimizer(func,x0,s0, "GSLMultiMin","ConjugateFR");
00702 iret |= testNewMinimizer(func,x0,s0, "GSLMultiMin","ConjugatePR");
00703 iret |= testNewMinimizer(func,x0,s0, "GSLMultiMin","BFGS");
00704
00705 return iret;
00706 }
00707
00708 int main() {
00709
00710 int iret = 0;
00711
00712 #ifdef DEBUG
00713 gVerbose = 3;
00714 gNmin = 1;
00715 #endif
00716
00717 iret |= testRosenBrock();
00718
00719
00720
00721
00722
00723 if (iret != 0)
00724 std::cerr << "testMinim :\t FAILED " << std::endl;
00725 else
00726 std::cerr << "testMinim :\t OK " << std::endl;
00727 return iret;
00728
00729 }