00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Fit/FitConfig.h"
00014
00015 #include "Math/IParamFunction.h"
00016 #include "Math/Util.h"
00017
00018 #include "Math/Minimizer.h"
00019 #include "Math/Factory.h"
00020
00021 #include <cmath>
00022
00023 #include <string>
00024 #include <sstream>
00025
00026 #include "Math/Error.h"
00027
00028
00029 #ifdef DEBUG
00030 #endif
00031 #include <iostream>
00032
00033 namespace ROOT {
00034
00035 namespace Fit {
00036
00037
00038
00039 FitConfig::FitConfig(unsigned int npar) :
00040 fNormErrors(false),
00041 fParabErrors(false),
00042 fMinosErrors(false),
00043 fSettings(std::vector<ParameterSettings>(npar) )
00044 {
00045
00046 }
00047
00048
00049 FitConfig::~FitConfig()
00050 {
00051
00052 }
00053
00054 FitConfig::FitConfig(const FitConfig &rhs) {
00055
00056 (*this) = rhs;
00057 }
00058
00059 FitConfig & FitConfig::operator = (const FitConfig &rhs) {
00060
00061 if (this == &rhs) return *this;
00062
00063 fNormErrors = rhs.fNormErrors;
00064 fParabErrors = rhs.fParabErrors;
00065 fMinosErrors = rhs.fMinosErrors;
00066
00067 fSettings = rhs.fSettings;
00068 fMinosParams = rhs.fMinosParams;
00069
00070 fMinimizerOpts = rhs.fMinimizerOpts;
00071
00072 return *this;
00073 }
00074
00075 void FitConfig::SetParamsSettings(unsigned int npar, const double *params, const double * vstep ) {
00076
00077
00078 if (params == 0) {
00079 fSettings = std::vector<ParameterSettings>(npar);
00080 return;
00081 }
00082
00083 bool createNew = false;
00084 if (npar != fSettings.size() ) {
00085 fSettings.clear();
00086 fSettings.reserve(npar);
00087 createNew = true;
00088 }
00089 unsigned int i = 0;
00090 const double * end = params+npar;
00091 for (const double * ipar = params; ipar != end; ++ipar) {
00092 double val = *ipar;
00093 double step = 0;
00094 if (vstep == 0) {
00095 step = 0.3*std::fabs(val);
00096
00097 if (val == 0) step = 0.3;
00098 }
00099 else
00100 step = vstep[i];
00101
00102 if (createNew)
00103 fSettings.push_back( ParameterSettings("Par_" + ROOT::Math::Util::ToString(i), val, step ) );
00104 else {
00105 fSettings[i].SetValue(val);
00106 fSettings[i].SetStepSize(step);
00107 }
00108
00109 i++;
00110 }
00111 }
00112
00113 void FitConfig::CreateParamsSettings(const ROOT::Math::IParamMultiFunction & func) {
00114
00115
00116 unsigned int npar = func.NPar();
00117 const double * begin = func.Parameters();
00118 if (begin == 0) {
00119 fSettings = std::vector<ParameterSettings>(npar);
00120 return;
00121 }
00122
00123 fSettings.clear();
00124 fSettings.reserve(npar);
00125 const double * end = begin+npar;
00126 unsigned int i = 0;
00127 for (const double * ipar = begin; ipar != end; ++ipar) {
00128 double val = *ipar;
00129 double step = 0.3*std::fabs(val);
00130
00131 if (val == 0) step = 0.3;
00132
00133 fSettings.push_back( ParameterSettings(func.ParameterName(i), val, step ) );
00134 #ifdef DEBUG
00135 std::cout << "FitConfig: add parameter " << func.ParameterName(i) << " val = " << val << std::endl;
00136 #endif
00137 i++;
00138 }
00139
00140 }
00141
00142 ROOT::Math::Minimizer * FitConfig::CreateMinimizer() {
00143
00144
00145
00146 const std::string & minimType = fMinimizerOpts.MinimizerType();
00147 const std::string & algoType = fMinimizerOpts.MinimizerAlgorithm();
00148
00149 std::string defaultMinim = ROOT::Math::MinimizerOptions::DefaultMinimizerType();
00150 ROOT::Math::Minimizer * min = ROOT::Math::Factory::CreateMinimizer(minimType, algoType);
00151
00152 const std::string & minim_newDefault = ROOT::Math::MinimizerOptions::DefaultMinimizerType();
00153 if (defaultMinim != minim_newDefault ) fMinimizerOpts.SetMinimizerType(minim_newDefault.c_str());
00154
00155 if (min == 0) {
00156
00157 std::string minim2 = "Minuit";
00158 if (minimType == "Minuit") minim2 = "Minuit2";
00159 if (minimType != minim2 ) {
00160 std::string msg = "Could not create the " + minimType + " minimizer. Try using the minimizer " + minim2;
00161 MATH_WARN_MSG("FitConfig::CreateMinimizer",msg.c_str());
00162 min = ROOT::Math::Factory::CreateMinimizer(minim2,"Migrad");
00163 if (min == 0) {
00164 MATH_ERROR_MSG("FitConfig::CreateMinimizer","Could not create the Minuit2 minimizer");
00165 return 0;
00166 }
00167 SetMinimizer( minim2.c_str(),"Migrad");
00168 }
00169 else {
00170 std::string msg = "Could not create the Minimizer " + minimType;
00171 MATH_ERROR_MSG("FitConfig::CreateMinimizer",msg.c_str());
00172 return 0;
00173 }
00174 }
00175
00176
00177
00178 if (fMinimizerOpts.MaxFunctionCalls() == 0) {
00179 unsigned int npar = fSettings.size();
00180 int maxfcn = 1000 + 100*npar + 5*npar*npar;
00181 fMinimizerOpts.SetMaxFunctionCalls(maxfcn);
00182 }
00183
00184
00185
00186 min->SetPrintLevel( fMinimizerOpts.PrintLevel() );
00187 min->SetMaxFunctionCalls( fMinimizerOpts.MaxFunctionCalls() );
00188 min->SetMaxIterations( fMinimizerOpts.MaxIterations() );
00189 min->SetTolerance( fMinimizerOpts.Tolerance() );
00190 min->SetPrecision( fMinimizerOpts.Precision() );
00191 min->SetValidError( fParabErrors );
00192 min->SetStrategy( fMinimizerOpts.Strategy() );
00193 min->SetErrorDef( fMinimizerOpts.ErrorDef() );
00194
00195
00196 return min;
00197 }
00198
00199 void FitConfig::SetDefaultMinimizer(const char * type, const char *algo ) {
00200
00201 ROOT::Math::MinimizerOptions::SetDefaultMinimizer(type, algo);
00202 }
00203
00204 void FitConfig::SetMinimizerOptions(const ROOT::Math::MinimizerOptions & minopt) {
00205
00206 fMinimizerOpts = minopt;
00207 }
00208
00209
00210 }
00211
00212 }
00213