00001 #include "TROOT.h"
00002 #include "TFitterMinuit.h"
00003 #include "TF1.h"
00004 #include "TH1.h"
00005 #include "TGraph.h"
00006
00007 #include "TChi2FCN.h"
00008 #include "TChi2ExtendedFCN.h"
00009 #include "TBinLikelihoodFCN.h"
00010 #include "TInterpreter.h"
00011 #include "TError.h"
00012
00013
00014 #include "Minuit2/MnMigrad.h"
00015 #include "Minuit2/MnMinos.h"
00016 #include "Minuit2/MnHesse.h"
00017 #include "Minuit2/MinuitParameter.h"
00018 #include "Minuit2/MnPrint.h"
00019 #include "Minuit2/FunctionMinimum.h"
00020 #include "Minuit2/VariableMetricMinimizer.h"
00021 #include "Minuit2/SimplexMinimizer.h"
00022 #include "Minuit2/CombinedMinimizer.h"
00023 #include "Minuit2/ScanMinimizer.h"
00024
00025 #include <iomanip>
00026
00027 using namespace ROOT::Minuit2;
00028
00029 #ifndef ROOT_TMethodCall
00030 #include "TMethodCall.h"
00031 #endif
00032
00033
00034
00035
00036 #ifdef OLDFCN_INTERFACE
00037 extern void H1FitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00038 extern void H1FitLikelihood(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00039 extern void Graph2DFitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00040 extern void MultiGraphFitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00041 #endif
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 ClassImp(TFitterMinuit);
00069
00070 TFitterMinuit* gMinuit2 = 0;
00071
00072 TFitterMinuit::TFitterMinuit() : fErrorDef(1.) , fEDMVal(0.), fGradient(false),
00073 fState(MnUserParameterState()), fMinosErrors(std::vector<MinosError>()), fMinimizer(0), fMinuitFCN(0), fDebug(1), fStrategy(1), fMinTolerance(0) {
00074
00075 Initialize();
00076 }
00077
00078
00079 TFitterMinuit::TFitterMinuit(Int_t ) : fErrorDef(1.) , fEDMVal(0.), fGradient(false), fState(MnUserParameterState()), fMinosErrors(std::vector<MinosError>()), fMinimizer(0), fMinuitFCN(0), fDebug(1), fStrategy(1), fMinTolerance(0) {
00080
00081 Initialize();
00082 }
00083
00084 void TFitterMinuit::Initialize() {
00085
00086 SetName("Minuit2");
00087 gMinuit2 = this;
00088 gROOT->GetListOfSpecials()->Add(gMinuit2);
00089
00090 }
00091
00092
00093 void TFitterMinuit::CreateMinimizer(EMinimizerType type) {
00094
00095 #ifdef DEBUG
00096 std::cout<<"TFitterMinuit:create minimizer of type "<< type << std::endl;
00097 #endif
00098 if (fMinimizer) delete fMinimizer;
00099
00100 switch (type) {
00101 case kMigrad:
00102 SetMinimizer( new VariableMetricMinimizer() );
00103 return;
00104 case kSimplex:
00105 SetMinimizer( new SimplexMinimizer() );
00106 return;
00107 case kCombined:
00108 SetMinimizer( new CombinedMinimizer() );
00109 return;
00110 case kScan:
00111 SetMinimizer( new ScanMinimizer() );
00112 return;
00113 case kFumili:
00114 std::cout << "TFitterMinuit::Error - Fumili Minimizer must be created from TFitterFumili " << std::endl;
00115 SetMinimizer(0);
00116 return;
00117 default:
00118
00119 SetMinimizer( new VariableMetricMinimizer() );
00120 }
00121 }
00122
00123
00124
00125 TFitterMinuit::~TFitterMinuit() {
00126
00127
00128
00129 #ifdef DEBUG
00130 std::cout << "delete minimizer and FCN" << std::endl;
00131 #endif
00132 if (fMinuitFCN) delete fMinuitFCN;
00133 if (fMinimizer) delete fMinimizer;
00134
00135 gROOT->GetListOfSpecials()->Remove(this);
00136 if (gMinuit2 == this) gMinuit2 = 0;
00137
00138 }
00139
00140 Double_t TFitterMinuit::Chisquare(Int_t npar, Double_t *params) const {
00141
00142 const TBinLikelihoodFCN * fcn = dynamic_cast<const TBinLikelihoodFCN *> (GetMinuitFCN() );
00143 if (fcn == 0) return 0;
00144 std::vector<double> p(npar);
00145 for (int i = 0; i < npar; ++i)
00146 p[i] = params[i];
00147 return fcn->Chi2(p);
00148 }
00149
00150 void TFitterMinuit::Clear(Option_t*) {
00151
00152
00153
00154
00155 fErrorDef = 1.;
00156 fEDMVal = 0;
00157 fGradient = false;
00158 State() = MnUserParameterState();
00159 fMinosErrors.clear();
00160
00161 fStrategy = 1;
00162 fMinTolerance = 0;
00163 fCovar.clear();
00164
00165
00166
00167
00168
00169 if (fMinimizer) {
00170 delete fMinimizer;
00171 fMinimizer = 0;
00172 }
00173
00174 }
00175
00176
00177
00178 FunctionMinimum TFitterMinuit::DoMinimization( int nfcn, double edmval) {
00179
00180
00181
00182 assert(GetMinuitFCN() != 0 );
00183 assert(GetMinimizer() != 0 );
00184
00185 fMinuitFCN->SetErrorDef(fErrorDef);
00186
00187 if (fDebug >=1) {
00188 std::cout << "TFitterMinuit - Minimize with max iterations = " << nfcn << " edmval = " << edmval << " errorDef = " << fMinuitFCN->Up() << std::endl;
00189 }
00190
00191
00192 return GetMinimizer()->Minimize(*GetMinuitFCN(), State(), MnStrategy(fStrategy), nfcn, edmval);
00193 }
00194
00195
00196
00197 int TFitterMinuit::Minimize( int nfcn, double edmval) {
00198
00199
00200
00201 edmval = std::max(fMinTolerance, edmval);
00202
00203
00204 int prevLevel = gErrorIgnoreLevel;
00205 if (fDebug < 0)
00206 gErrorIgnoreLevel = 1001;
00207
00208 FunctionMinimum min = DoMinimization(nfcn,edmval);
00209
00210 if (fDebug < 0) gErrorIgnoreLevel = prevLevel;
00211
00212 fState = min.UserState();
00213 return ExamineMinimum(min);
00214 }
00215
00216 Int_t TFitterMinuit::ExecuteCommand(const char *command, Double_t *args, Int_t nargs){
00217
00218
00219 #ifdef DEBUG
00220 std::cout<<"Execute command= "<<command<<std::endl;
00221 #endif
00222
00223
00224
00225 if (strncmp(command,"MIG",3) == 0 || strncmp(command,"mig",3) == 0) {
00226 int nfcn = 0;
00227 double edmval = 0.1;
00228
00229
00230 if (nargs > 0) nfcn = int ( args[0] );
00231 if (nargs > 1) edmval = args[1];
00232
00233
00234 CreateMinimizer(kMigrad);
00235 return Minimize(nfcn, edmval);
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 }
00249
00250 if (strncmp(command,"MINI",4) == 0 || strncmp(command,"mini",4) == 0) {
00251
00252 int nfcn = 0;
00253 double edmval = 0.1;
00254 if (nargs > 0) nfcn = int ( args[0] );
00255 if (nargs > 1) edmval = args[1];
00256
00257 CreateMinimizer(kCombined);
00258 return Minimize(nfcn, edmval);
00259 }
00260
00261 if (strncmp(command,"SIM",3) == 0 || strncmp(command,"sim",3) == 0) {
00262
00263 int nfcn = 0;
00264 double edmval = 0.1;
00265 if (nargs > 0) nfcn = int ( args[0] );
00266 if (nargs > 1) edmval = args[1];
00267
00268 CreateMinimizer(kSimplex);
00269 return Minimize(nfcn, edmval);
00270 }
00271
00272 if (strncmp(command,"SCA",3) == 0 || strncmp(command,"sca",3) == 0) {
00273
00274 int nfcn = 0;
00275 double edmval = 0.1;
00276 if (nargs > 0) nfcn = int ( args[0] );
00277 if (nargs > 1) edmval = args[1];
00278
00279 CreateMinimizer(kScan);
00280 return Minimize(nfcn, edmval);
00281 }
00282
00283 else if (strncmp(command,"MINO",4) == 0 || strncmp(command,"mino",4) == 0) {
00284
00285
00286 int prevLevel = gErrorIgnoreLevel;
00287 if (fDebug < 0)
00288 gErrorIgnoreLevel = 1001;
00289
00290
00291
00292
00293 FunctionMinimum min = DoMinimization();
00294 if (!min.IsValid() ) {
00295 std::cout << "TFitterMinuit::MINOS failed due to invalid function minimum" << std::endl;
00296 if (fDebug < 0) gErrorIgnoreLevel = prevLevel;
00297 return -10;
00298 }
00299 MnMinos minos( *fMinuitFCN, min);
00300 fMinosErrors.clear();
00301 for(unsigned int i = 0; i < State().VariableParameters(); i++) {
00302 if (fDebug>=3) std::cout << "Running Minos for parameter (ext#) " << State().ExtOfInt(i) << std::endl;
00303 MinosError me = minos.Minos(State().ExtOfInt(i));
00304
00305 if (fDebug >= 0) {
00306 if ( !me.IsValid() )
00307 std::cout << "Error running Minos for parameter " << State().ExtOfInt(i) << std::endl;
00308 }
00309 if (fDebug >= 1) {
00310 if (!me.LowerValid() )
00311 std::cout << "Minos: Invalid lower error for parameter " << State().ExtOfInt(i) << std::endl;
00312 if(me.AtLowerLimit())
00313 std::cout << "Minos: Parameter is at Lower limit."<<std::endl;
00314 if(me.AtLowerMaxFcn())
00315 std::cout << "Minos: Maximum number of function calls exceeded when running for lower error" <<std::endl;
00316 if(me.LowerNewMin() )
00317 std::cout << "Minos: New Minimum found while running Minos for lower error" <<std::endl;
00318
00319 if (!me.UpperValid() )
00320 std::cout << "Minos: Invalid upper error for parameter " << State().ExtOfInt(i) << std::endl;
00321 if(me.AtUpperLimit())
00322 std::cout << "Minos: Parameter is at Upper limit."<<std::endl;
00323 if(me.AtUpperMaxFcn())
00324 std::cout << "Minos: Maximum number of function calls exceeded when running for upper error" <<std::endl;
00325 if(me.UpperNewMin() )
00326 std::cout << "Minos: New Minimum found while running Minos for upper error" <<std::endl;
00327
00328 }
00329
00330
00331 fMinosErrors.push_back(me);
00332 }
00333 if (fDebug >= 3) {
00334 for(std::vector<MinosError>::const_iterator ime = fMinosErrors.begin();
00335 ime != fMinosErrors.end(); ime++)
00336 std::cout<<*ime<<std::endl;
00337 }
00338
00339 if (fDebug < 0) gErrorIgnoreLevel = prevLevel;
00340
00341 return 0;
00342 }
00343
00344 else if (strncmp(command,"HES",3) == 0 || strncmp(command,"hes",3) == 0) {
00345
00346
00347 int prevLevel = gErrorIgnoreLevel;
00348 if (fDebug < 0)
00349 gErrorIgnoreLevel = 1001;
00350
00351 MnHesse hesse( GetStrategy() );
00352
00353 const FCNBase * fcn = GetMinuitFCN();
00354 assert(fcn != 0);
00355 fState = hesse(*fcn, State(),100000 );
00356
00357 if (fDebug < 0) gErrorIgnoreLevel = prevLevel;
00358
00359 if (!fState.IsValid() ) {
00360 std::cout << "TFitterMinuit::Hesse calculation failed " << std::endl;
00361 return -10;
00362 }
00363 return 0;
00364 }
00365
00366
00367 else if (strncmp(command,"FIX",3) == 0 || strncmp(command,"fix",3) == 0) {
00368 for(int i = 0; i < nargs; i++) {
00369 FixParameter(int(args[i])-1);
00370 }
00371 return 0;
00372 }
00373
00374 else if (strncmp(command,"SET LIM",7) == 0 || strncmp(command,"set lim",7) == 0) {
00375 assert(nargs >= 3);
00376 int ipar = int(args[0]);
00377 double low = args[1];
00378 double up = args[2];
00379 State().SetLimits(ipar, low, up);
00380 return 0;
00381 }
00382
00383 else if (strncmp(command,"SET PRINT",9) == 0 || strncmp(command,"set print",9) == 0) {
00384 fDebug = int(args[0]);
00385
00386 #ifdef DEBUG
00387 fDebug = 3;
00388 #endif
00389 return 0;
00390 }
00391
00392 else if (strncmp(command,"SET Err",7) == 0 || strncmp(command,"set err",7) == 0) {
00393 fErrorDef = args[0];
00394 return 0;
00395 }
00396
00397 else if (strncmp(command,"SET STR",7) == 0 || strncmp(command,"set str",7) == 0) {
00398 fStrategy = int(args[0]);
00399 return 0;
00400 }
00401
00402 else if (strncmp(command,"SET GRA",7) == 0 || strncmp(command,"set gra",7) == 0) {
00403
00404
00405 return -1;
00406 }
00407
00408 else if (strncmp(command,"CALL FCN",8) == 0 || strncmp(command,"call fcn",8) == 0) {
00409
00410 if (nargs < 1 || fFCN == 0) return -1;
00411 const std::vector<double> & params = State().Params();
00412 std::cout << State() << std::endl;
00413 int npar = params.size();
00414 double fval = 0;
00415 (*fFCN)(npar, 0, fval, const_cast<double *>(¶ms.front()),int(args[0]) ) ;
00416 return 0;
00417 }
00418 else {
00419
00420 return 0;
00421 }
00422
00423
00424 }
00425
00426
00427
00428 int TFitterMinuit::ExamineMinimum(const FunctionMinimum & min) {
00429
00430
00431
00432 if (fDebug >= 3) {
00433 #ifdef LATER
00434 const std::vector<MinimumState>& iterationStates = min.States();
00435 std::cout << "Number of iterations " << iterationStates.size() << std::endl;
00436 for (unsigned int i = 0; i < iterationStates.size(); ++i) {
00437
00438 const MinimumState & st = iterationStates[i];
00439 std::cout << "----------> Iteration " << i << std::endl;
00440 int pr = std::cout.precision(18);
00441 std::cout << " FVAL = " << st.Fval() << " Edm = " << st.Edm() << " Nfcn = " << st.NFcn() << std::endl;
00442 std::cout.precision(pr);
00443 std::cout << " Error matrix change = " << st.Error().Dcovar() << std::endl;
00444 std::cout << " Internal parameters : ";
00445 for (int j = 0; j < st.size() ; ++j) std::cout << " p" << j << " = " << st.Vec()(j);
00446 std::cout << std::endl;
00447 }
00448 #endif
00449 }
00450
00451 if (min.IsValid() ) {
00452 if (fDebug >=1 ) {
00453 std::cout << "Minimum Found" << std::endl;
00454 int pr = std::cout.precision(18);
00455 std::cout << "FVAL = " << State().Fval() << std::endl;
00456 std::cout << "Edm = " << State().Edm() << std::endl;
00457 std::cout.precision(pr);
00458 std::cout << "Nfcn = " << State().NFcn() << std::endl;
00459 std::vector<double> par = State().Params();
00460 std::vector<double> err = State().Errors();
00461 for (unsigned int i = 0; i < State().Params().size(); ++i)
00462 std::cout << State().Parameter(i).Name() << "\t = " << par[i] << "\t +/- " << err[i] << std::endl;
00463 }
00464 return 0;
00465 }
00466 else {
00467 if (fDebug >= 1) {
00468 std::cout << "TFitterMinuit::Minimization DID not converge !" << std::endl;
00469 std::cout << "FVAL = " << State().Fval() << std::endl;
00470 std::cout << "Edm = " << State().Edm() << std::endl;
00471 std::cout << "Nfcn = " << State().NFcn() << std::endl;
00472 }
00473 if (min.HasMadePosDefCovar() ) {
00474 if (fDebug >= 1) std::cout << " Covar was made pos def" << std::endl;
00475 return -11;
00476 }
00477 if (min.HesseFailed() ) {
00478 if (fDebug >= 1) std::cout << " Hesse is not valid" << std::endl;
00479 return -12;
00480 }
00481 if (min.IsAboveMaxEdm() ) {
00482 if (fDebug >= 1) std::cout << " Edm is above max" << std::endl;
00483 return -13;
00484 }
00485 if (min.HasReachedCallLimit() ) {
00486 if (fDebug >= 1) std::cout << " Reached call limit" << std::endl;
00487 return -14;
00488 }
00489 return -10;
00490 }
00491 return 0;
00492 }
00493
00494 void TFitterMinuit::FixParameter(Int_t ipar) {
00495
00496
00497 State().Fix(ipar);
00498 }
00499
00500 Double_t* TFitterMinuit::GetCovarianceMatrix() const {
00501
00502
00503
00504 unsigned int npar = State().Covariance().Nrow();
00505 if ( int(npar) != GetNumberFreeParameters() ) {
00506
00507 std::cout << "TFitterMinuit::GetCovarianceMatrix Error - return null pointer" << std::endl;
00508 return 0;
00509 }
00510 if (fCovar.size() != npar )
00511 fCovar.resize(npar*npar);
00512
00513 for (unsigned int i = 0; i < npar; ++i) {
00514 for (unsigned int j = 0; j < npar; ++j) {
00515 fCovar[j + npar*i] = State().Covariance()(i,j);
00516 }
00517 }
00518 return &(fCovar.front());
00519 }
00520
00521 Double_t TFitterMinuit::GetCovarianceMatrixElement(Int_t i, Int_t j) const {
00522
00523 return State().Covariance()(i,j);
00524 }
00525
00526
00527 Int_t TFitterMinuit::GetErrors(Int_t ipar,Double_t &eplus, Double_t &eminus, Double_t &eparab, Double_t &globcc) const {
00528
00529
00530 eplus = 0.;
00531 eminus = 0.;
00532
00533 MinuitParameter mpar = State().Parameters().Parameter(ipar);
00534 if (mpar.IsFixed() || mpar.IsConst() ) return 0;
00535 if(fMinosErrors.empty()) return 0;
00536
00537
00538 unsigned int nintern = State().IntOfExt(ipar);
00539 eplus = fMinosErrors[nintern].Upper();
00540 eminus = fMinosErrors[nintern].Lower();
00541
00542 eparab = State().Error(ipar);
00543 globcc = State().GlobalCC().GlobalCC()[ipar];
00544 return 0;
00545 }
00546
00547
00548
00549
00550 Int_t TFitterMinuit::GetNumberTotalParameters() const {
00551
00552 return State().Parameters().Parameters().size();
00553 }
00554 Int_t TFitterMinuit::GetNumberFreeParameters() const {
00555
00556 return State().Parameters().VariableParameters();
00557 }
00558
00559
00560 Double_t TFitterMinuit::GetParError(Int_t ipar) const {
00561
00562
00563 return State().Error(ipar);
00564 }
00565
00566 Double_t TFitterMinuit::GetParameter(Int_t ipar) const {
00567
00568
00569 return State().Value(ipar);
00570 }
00571
00572 Int_t TFitterMinuit::GetParameter(Int_t ipar,char *name,Double_t &value,Double_t &verr,Double_t &vlow, Double_t &vhigh) const {
00573
00574
00575 const MinuitParameter& mp = State().Parameter(ipar);
00576
00577 std::string mpName = mp.Name();
00578 std::copy(mpName.c_str(), mpName.c_str() + mpName.size(), name);
00579 value = mp.Value();
00580 verr = mp.Error();
00581 vlow = mp.LowerLimit();
00582 vhigh = mp.UpperLimit();
00583 return 0;
00584 }
00585
00586 const char *TFitterMinuit::GetParName(Int_t ipar) const {
00587
00588 const MinuitParameter& mp = State().Parameter(ipar);
00589 return mp.Name();
00590 }
00591
00592 Int_t TFitterMinuit::GetStats(Double_t &amin, Double_t &edm, Double_t &errdef, Int_t &nvpar, Int_t &nparx) const {
00593
00594
00595 amin = State().Fval();
00596 edm = State().Edm();
00597 errdef = fErrorDef;
00598 nvpar = State().VariableParameters();
00599 nparx = State().Parameters().Parameters().size();
00600 return 0;
00601 }
00602
00603 Double_t TFitterMinuit::GetSumLog(Int_t) {
00604
00605 return 0.;
00606 }
00607
00608
00609 Bool_t TFitterMinuit::IsFixed(Int_t ipar) const {
00610
00611 return State().Parameter(ipar).IsFixed();
00612 }
00613
00614
00615 void TFitterMinuit::PrintResults(Int_t level, Double_t) const {
00616
00617
00618
00619
00620 if (fDebug >= 0 || level > 3) {
00621 std::cout<<State()<<std::endl;
00622 }
00623 else {
00624
00625 if(!State().IsValid()) {
00626 std::cout << std::endl;
00627 std::cout << "WARNING: Minimum is not valid."<<std::endl;
00628 std::cout << std::endl;
00629 }
00630
00631 std::cout << "# of function calls: "<<State().NFcn()<<std::endl;
00632 std::cout << "function Value: "<< std::setprecision(12) << State().Fval()<<std::endl;
00633 std::cout << "expected distance to the Minimum (edm): "<< std::setprecision(8) << State().Edm()<<std::endl;
00634 std::cout << "fitted parameters: "<<State().Parameters()<<std::endl;
00635 }
00636
00637
00638 if (level > 3) {
00639 for(std::vector<MinosError>::const_iterator ime = fMinosErrors.begin();
00640 ime != fMinosErrors.end(); ime++) {
00641 std::cout<<*ime<<std::endl;
00642 }
00643 }
00644 }
00645
00646 void TFitterMinuit::ReleaseParameter(Int_t ipar) {
00647
00648
00649
00650 State().Release(ipar);
00651 }
00652
00653
00654
00655 void TFitterMinuit::SetFitMethod(const char *name) {
00656
00657
00658
00659 #ifdef DEBUG
00660 std::cout<<"SetFitMethod to "<< name << std::endl;
00661 #endif
00662 if (!strcmp(name,"H1FitChisquare")) {
00663
00664 #ifdef OLDFCN_INTERFACE
00665 SetFCN(H1FitChisquare);
00666 #else
00667
00668 CreateChi2FCN();
00669 #endif
00670 return;
00671 }
00672 if (!strcmp(name,"GraphFitChisquare")) {
00673 #ifdef OLDFCN_INTERFACE
00674 SetFCN(GraphFitChisquare);
00675 #else
00676
00677 if (!GetFitOption().W1)
00678 CreateChi2ExtendedFCN( );
00679 else
00680 CreateChi2FCN( );
00681 #endif
00682 return;
00683 }
00684 if (!strcmp(name, "Graph2DFitChisquare")) {
00685 #ifdef OLDFCN_INTERFACE
00686 SetFCN(Graph2DFitChisquare);
00687 #else
00688
00689
00690
00691
00692 CreateChi2FCN( );
00693 #endif
00694 return;
00695 }
00696 if (!strcmp(name, "MultiGraphFitChisquare")) {
00697 fErrorDef = 1.;
00698 #ifdef OLDFCN_INTERFACE
00699 SetFCN(MultiGraphFitChisquare);
00700 #else
00701 CreateChi2FCN();
00702 #endif
00703 return;
00704 }
00705 if (!strcmp(name, "H1FitLikelihood")) {
00706
00707 #ifdef OLDFCN_INTERFACE
00708 SetFCN(H1FitLikelihood);
00709 #else
00710 CreateBinLikelihoodFCN();
00711 #endif
00712 return;
00713 }
00714
00715 std::cout << "TFitterMinuit::fit method " << name << " is not supported !" << std::endl;
00716
00717 assert(fMinuitFCN != 0);
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 }
00729
00730 Int_t TFitterMinuit::SetParameter(Int_t,const char *parname,Double_t value,Double_t verr,Double_t vlow, Double_t vhigh) {
00731
00732
00733
00734
00735 #ifdef DEBUG
00736 std::cout<<"SetParameter";
00737 std::cout << parname<<" value = " << value << " verr= "<<verr<<std::endl;
00738 #endif
00739 if(vlow < vhigh) {
00740 State().Add(parname, value, verr, vlow, vhigh);
00741 }
00742 else
00743 State().Add(parname, value, verr);
00744
00745
00746 if (verr == 0) State().Fix(parname);
00747 return 0;
00748 }
00749
00750
00751 void TFitterMinuit::SetFCN(void (*fcn)(Int_t &, Double_t *, Double_t &f, Double_t *, Int_t))
00752 {
00753
00754
00755
00756
00757 fFCN = fcn;
00758 if (fMinuitFCN) delete fMinuitFCN;
00759 fMinuitFCN = new TFcnAdapter(fFCN);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769 void Minuit2InteractiveFCN(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
00770 {
00771
00772
00773
00774 TMethodCall *m = gMinuit2->GetMethodCall();
00775 if (!m) return;
00776
00777 Long_t args[5];
00778 args[0] = (Long_t)∦
00779 args[1] = (Long_t)gin;
00780 args[2] = (Long_t)&f;
00781 args[3] = (Long_t)u;
00782 args[4] = (Long_t)flag;
00783 m->SetParamPtrs(args);
00784 Double_t result;
00785 m->Execute(result);
00786 }
00787
00788
00789
00790 void TFitterMinuit::SetFCN(void *fcn)
00791 {
00792
00793
00794
00795
00796
00797 if (!fcn) return;
00798
00799 const char *funcname = gCint->Getp2f2funcname(fcn);
00800 if (funcname) {
00801 fMethodCall = new TMethodCall();
00802 fMethodCall->InitWithPrototype(funcname,"Int_t&,Double_t*,Double_t&,Double_t*,Int_t");
00803 }
00804 fFCN = Minuit2InteractiveFCN;
00805 gMinuit2 = this;
00806
00807 if (fMinuitFCN) delete fMinuitFCN;
00808 fMinuitFCN = new TFcnAdapter(fFCN);
00809 }
00810
00811 void TFitterMinuit::SetMinuitFCN( FCNBase * f) {
00812
00813
00814 if (fMinuitFCN) delete fMinuitFCN;
00815 fMinuitFCN = f;
00816 }
00817
00818 void TFitterMinuit::CreateChi2FCN() {
00819
00820 SetMinuitFCN(new TChi2FCN( *this ) );
00821 }
00822
00823
00824 void TFitterMinuit::CreateChi2ExtendedFCN() {
00825
00826
00827 SetMinuitFCN(new TChi2ExtendedFCN( *this ) );
00828 }
00829
00830 void TFitterMinuit::CreateBinLikelihoodFCN() {
00831
00832 SetMinuitFCN(new TBinLikelihoodFCN( *this ) );
00833 }