00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Minuit2/MnUserParameterState.h"
00011 #include "Minuit2/MnCovarianceSqueeze.h"
00012 #include "Minuit2/MinimumState.h"
00013
00014 #include "Minuit2/MnPrint.h"
00015
00016
00017 namespace ROOT {
00018
00019 namespace Minuit2 {
00020
00021
00022
00023
00024
00025 MnUserParameterState::MnUserParameterState(const std::vector<double>& par, const std::vector<double>& err) :
00026 fValid(true), fCovarianceValid(false), fGCCValid(false), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(MnUserParameters(par, err)), fCovariance(MnUserCovariance()), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(par), fIntCovariance(MnUserCovariance())
00027 {}
00028
00029 MnUserParameterState::MnUserParameterState(const MnUserParameters& par) :
00030 fValid(true), fCovarianceValid(false), fGCCValid(false), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(par), fCovariance(MnUserCovariance()), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(std::vector<double>()), fIntCovariance(MnUserCovariance()) {
00031
00032
00033 for(std::vector<MinuitParameter>::const_iterator ipar = MinuitParameters().begin(); ipar != MinuitParameters().end(); ipar++) {
00034 if((*ipar).IsConst() || (*ipar).IsFixed()) continue;
00035 if((*ipar).HasLimits())
00036 fIntParameters.push_back(Ext2int((*ipar).Number(), (*ipar).Value()));
00037 else
00038 fIntParameters.push_back((*ipar).Value());
00039 }
00040 }
00041
00042
00043
00044
00045 MnUserParameterState::MnUserParameterState(const std::vector<double>& par, const std::vector<double>& cov, unsigned int nrow) : fValid(true), fCovarianceValid(true), fGCCValid(false), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(MnUserParameters()), fCovariance(MnUserCovariance(cov, nrow)), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(par), fIntCovariance(MnUserCovariance(cov, nrow)) {
00046
00047
00048 std::vector<double> err; err.reserve(par.size());
00049 for(unsigned int i = 0; i < par.size(); i++) {
00050 assert(fCovariance(i,i) > 0.);
00051 err.push_back(sqrt(fCovariance(i,i)));
00052 }
00053 fParameters = MnUserParameters(par, err);
00054 assert(fCovariance.Nrow() == VariableParameters());
00055 }
00056
00057 MnUserParameterState::MnUserParameterState(const std::vector<double>& par, const MnUserCovariance& cov) :
00058 fValid(true), fCovarianceValid(true), fGCCValid(false), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(MnUserParameters()), fCovariance(cov), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(par), fIntCovariance(cov) {
00059
00060
00061 std::vector<double> err; err.reserve(par.size());
00062 for(unsigned int i = 0; i < par.size(); i++) {
00063 assert(fCovariance(i,i) > 0.);
00064 err.push_back(sqrt(fCovariance(i,i)));
00065 }
00066 fParameters = MnUserParameters(par, err);
00067 assert(fCovariance.Nrow() == VariableParameters());
00068 }
00069
00070
00071 MnUserParameterState::MnUserParameterState(const MnUserParameters& par, const MnUserCovariance& cov) :
00072 fValid(true), fCovarianceValid(true), fGCCValid(false), fFVal(0.), fEDM(0.), fNFcn(0), fParameters(par), fCovariance(cov), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(std::vector<double>()), fIntCovariance(cov) {
00073
00074
00075
00076 fIntCovariance.Scale(0.5);
00077 for(std::vector<MinuitParameter>::const_iterator ipar = MinuitParameters().begin(); ipar != MinuitParameters().end(); ipar++) {
00078 if((*ipar).IsConst() || (*ipar).IsFixed()) continue;
00079 if((*ipar).HasLimits())
00080 fIntParameters.push_back(Ext2int((*ipar).Number(), (*ipar).Value()));
00081 else
00082 fIntParameters.push_back((*ipar).Value());
00083 }
00084 assert(fCovariance.Nrow() == VariableParameters());
00085
00086
00087
00088
00089 }
00090
00091
00092
00093 MnUserParameterState::MnUserParameterState(const MinimumState& st, double up, const MnUserTransformation& trafo) :
00094 fValid(st.IsValid()), fCovarianceValid(false), fGCCValid(false), fFVal(st.Fval()), fEDM(st.Edm()), fNFcn(st.NFcn()), fParameters(MnUserParameters()), fCovariance(MnUserCovariance()), fGlobalCC(MnGlobalCorrelationCoeff()), fIntParameters(std::vector<double>()), fIntCovariance(MnUserCovariance()) {
00095
00096
00097
00098 for(std::vector<MinuitParameter>::const_iterator ipar = trafo.Parameters().begin(); ipar != trafo.Parameters().end(); ipar++) {
00099 if((*ipar).IsConst()) {
00100 Add((*ipar).GetName(), (*ipar).Value());
00101 } else if((*ipar).IsFixed()) {
00102 Add((*ipar).GetName(), (*ipar).Value(), (*ipar).Error());
00103 if((*ipar).HasLimits()) {
00104 if((*ipar).HasLowerLimit() && (*ipar).HasUpperLimit())
00105 SetLimits((*ipar).GetName(), (*ipar).LowerLimit(),(*ipar).UpperLimit());
00106 else if((*ipar).HasLowerLimit() && !(*ipar).HasUpperLimit())
00107 SetLowerLimit((*ipar).GetName(), (*ipar).LowerLimit());
00108 else
00109 SetUpperLimit((*ipar).GetName(), (*ipar).UpperLimit());
00110 }
00111 Fix((*ipar).GetName());
00112 } else if((*ipar).HasLimits()) {
00113 unsigned int i = trafo.IntOfExt((*ipar).Number());
00114 double err = st.HasCovariance() ? sqrt(2.*up*st.Error().InvHessian()(i,i)) : st.Parameters().Dirin()(i);
00115 Add((*ipar).GetName(), trafo.Int2ext(i, st.Vec()(i)), trafo.Int2extError(i, st.Vec()(i), err));
00116 if((*ipar).HasLowerLimit() && (*ipar).HasUpperLimit())
00117 SetLimits((*ipar).GetName(), (*ipar).LowerLimit(), (*ipar).UpperLimit());
00118 else if((*ipar).HasLowerLimit() && !(*ipar).HasUpperLimit())
00119 SetLowerLimit((*ipar).GetName(), (*ipar).LowerLimit());
00120 else
00121 SetUpperLimit((*ipar).GetName(), (*ipar).UpperLimit());
00122 } else {
00123 unsigned int i = trafo.IntOfExt((*ipar).Number());
00124 double err = st.HasCovariance() ? sqrt(2.*up*st.Error().InvHessian()(i,i)) : st.Parameters().Dirin()(i);
00125 Add((*ipar).GetName(), st.Vec()(i), err);
00126 }
00127 }
00128
00129 fCovarianceValid = st.Error().IsValid();
00130
00131 if(fCovarianceValid) {
00132 fCovariance = trafo.Int2extCovariance(st.Vec(), st.Error().InvHessian());
00133 fIntCovariance = MnUserCovariance(std::vector<double>(st.Error().InvHessian().Data(), st.Error().InvHessian().Data()+st.Error().InvHessian().size()), st.Error().InvHessian().Nrow());
00134 fCovariance.Scale(2.*up);
00135 fGlobalCC = MnGlobalCorrelationCoeff(st.Error().InvHessian());
00136 fGCCValid = fGlobalCC.IsValid();
00137
00138 assert(fCovariance.Nrow() == VariableParameters());
00139 }
00140 }
00141
00142
00143
00144
00145
00146 const std::vector<MinuitParameter>& MnUserParameterState::MinuitParameters() const {
00147
00148 return fParameters.Parameters();
00149 }
00150
00151 std::vector<double> MnUserParameterState::Params() const {
00152
00153 return fParameters.Params();
00154 }
00155 std::vector<double> MnUserParameterState::Errors() const {
00156
00157 return fParameters.Errors();
00158 }
00159
00160 const MinuitParameter& MnUserParameterState::Parameter(unsigned int i) const {
00161
00162 return fParameters.Parameter(i);
00163 }
00164
00165 void MnUserParameterState::Add(const std::string & name, double val, double err) {
00166
00167 if ( fParameters.Add(name, val, err) ) {
00168 fIntParameters.push_back(val);
00169 fCovarianceValid = false;
00170 fGCCValid = false;
00171 fValid = true;
00172 }
00173 else {
00174
00175 int i = Index(name);
00176 SetValue(i,val);
00177 if (Parameter(i).IsConst() ) {
00178 std::string msg = "Cannot modify status of constant parameter " + name;
00179 MN_INFO_MSG2("MnUserParameterState::Add",msg.c_str());
00180 return;
00181 }
00182 SetError(i,err);
00183
00184 if (Parameter(i).IsFixed() ) Release(i);
00185 }
00186
00187 }
00188
00189 void MnUserParameterState::Add(const std::string & name, double val, double err, double low, double up) {
00190
00191 if ( fParameters.Add(name, val, err, low, up) ) {
00192 fCovarianceValid = false;
00193 fIntParameters.push_back(Ext2int(Index(name), val));
00194 fGCCValid = false;
00195 fValid = true;
00196 }
00197 else {
00198 int i = Index(name);
00199 SetValue(i,val);
00200 if (Parameter(i).IsConst() ) {
00201 std::string msg = "Cannot modify status of constant parameter " + name;
00202 MN_INFO_MSG2("MnUserParameterState::Add",msg.c_str());
00203 return;
00204 }
00205 SetError(i,err);
00206 SetLimits(i,low,up);
00207
00208 if (Parameter(i).IsFixed() ) Release(i);
00209 }
00210
00211
00212 }
00213
00214 void MnUserParameterState::Add(const std::string & name, double val) {
00215
00216 if ( fParameters.Add(name, val) )
00217 fValid = true;
00218 else
00219 SetValue(name,val);
00220 }
00221
00222
00223
00224 void MnUserParameterState::Fix(unsigned int e) {
00225
00226 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
00227 unsigned int i = IntOfExt(e);
00228 if(fCovarianceValid) {
00229 fCovariance = MnCovarianceSqueeze()(fCovariance, i);
00230 fIntCovariance = MnCovarianceSqueeze()(fIntCovariance, i);
00231 }
00232 fIntParameters.erase(fIntParameters.begin()+i, fIntParameters.begin()+i+1);
00233 }
00234 fParameters.Fix(e);
00235 fGCCValid = false;
00236 }
00237
00238 void MnUserParameterState::Release(unsigned int e) {
00239
00240
00241 if (Parameter(e).IsConst() ) return;
00242 fParameters.Release(e);
00243 fCovarianceValid = false;
00244 fGCCValid = false;
00245 unsigned int i = IntOfExt(e);
00246 if(Parameter(e).HasLimits())
00247 fIntParameters.insert(fIntParameters.begin()+i, Ext2int(e, Parameter(e).Value()));
00248 else
00249 fIntParameters.insert(fIntParameters.begin()+i, Parameter(e).Value());
00250 }
00251
00252 void MnUserParameterState::SetValue(unsigned int e, double val) {
00253
00254 fParameters.SetValue(e, val);
00255 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
00256 unsigned int i = IntOfExt(e);
00257 if(Parameter(e).HasLimits())
00258 fIntParameters[i] = Ext2int(e, val);
00259 else
00260 fIntParameters[i] = val;
00261 }
00262 }
00263
00264 void MnUserParameterState::SetError(unsigned int e, double val) {
00265
00266 fParameters.SetError(e, val);
00267 }
00268
00269 void MnUserParameterState::SetLimits(unsigned int e, double low, double up) {
00270
00271 fParameters.SetLimits(e, low, up);
00272 fCovarianceValid = false;
00273 fGCCValid = false;
00274 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
00275 unsigned int i = IntOfExt(e);
00276 if(low < fIntParameters[i] && fIntParameters[i] < up)
00277 fIntParameters[i] = Ext2int(e, fIntParameters[i]);
00278 else
00279 fIntParameters[i] = Ext2int(e, 0.5*(low+up));
00280 }
00281 }
00282
00283 void MnUserParameterState::SetUpperLimit(unsigned int e, double up) {
00284
00285 fParameters.SetUpperLimit(e, up);
00286 fCovarianceValid = false;
00287 fGCCValid = false;
00288 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
00289 unsigned int i = IntOfExt(e);
00290 if(fIntParameters[i] < up)
00291 fIntParameters[i] = Ext2int(e, fIntParameters[i]);
00292 else
00293 fIntParameters[i] = Ext2int(e, up - 0.5*fabs(up + 1.));
00294 }
00295 }
00296
00297 void MnUserParameterState::SetLowerLimit(unsigned int e, double low) {
00298
00299 fParameters.SetLowerLimit(e, low);
00300 fCovarianceValid = false;
00301 fGCCValid = false;
00302 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst()) {
00303 unsigned int i = IntOfExt(e);
00304 if(low < fIntParameters[i])
00305 fIntParameters[i] = Ext2int(e, fIntParameters[i]);
00306 else
00307 fIntParameters[i] = Ext2int(e, low + 0.5*fabs(low + 1.));
00308 }
00309 }
00310
00311 void MnUserParameterState::RemoveLimits(unsigned int e) {
00312
00313 fParameters.RemoveLimits(e);
00314 fCovarianceValid = false;
00315 fGCCValid = false;
00316 if(!Parameter(e).IsFixed() && !Parameter(e).IsConst())
00317 fIntParameters[IntOfExt(e)] = Value(e);
00318 }
00319
00320 double MnUserParameterState::Value(unsigned int i) const {
00321
00322 return fParameters.Value(i);
00323 }
00324 double MnUserParameterState::Error(unsigned int i) const {
00325
00326 return fParameters.Error(i);
00327 }
00328
00329
00330
00331 void MnUserParameterState::Fix(const std::string & name) { Fix(Index(name));}
00332
00333 void MnUserParameterState::Release(const std::string & name) {Release(Index(name));}
00334
00335 void MnUserParameterState::SetValue(const std::string & name, double val) {SetValue(Index(name), val);}
00336
00337 void MnUserParameterState::SetError(const std::string & name, double val) { SetError(Index(name), val);}
00338
00339 void MnUserParameterState::SetLimits(const std::string & name, double low, double up) {SetLimits(Index(name), low, up);}
00340
00341 void MnUserParameterState::SetUpperLimit(const std::string & name, double up) { SetUpperLimit(Index(name), up);}
00342
00343 void MnUserParameterState::SetLowerLimit(const std::string & name, double low) {SetLowerLimit(Index(name), low);}
00344
00345 void MnUserParameterState::RemoveLimits(const std::string & name) {RemoveLimits(Index(name));}
00346
00347 double MnUserParameterState::Value(const std::string & name) const {return Value(Index(name));}
00348
00349 double MnUserParameterState::Error(const std::string & name) const {return Error(Index(name));}
00350
00351
00352 unsigned int MnUserParameterState::Index(const std::string & name) const {
00353
00354 return fParameters.Index(name);
00355 }
00356
00357 const char* MnUserParameterState::Name(unsigned int i) const {
00358
00359 return fParameters.Name(i);
00360 }
00361 const std::string & MnUserParameterState::GetName(unsigned int i) const {
00362
00363 return fParameters.GetName(i);
00364 }
00365
00366
00367
00368 double MnUserParameterState::Int2ext(unsigned int i, double val) const {
00369
00370 return fParameters.Trafo().Int2ext(i, val);
00371 }
00372 double MnUserParameterState::Ext2int(unsigned int e, double val) const {
00373
00374 return fParameters.Trafo().Ext2int(e, val);
00375 }
00376 unsigned int MnUserParameterState::IntOfExt(unsigned int ext) const {
00377
00378 return fParameters.Trafo().IntOfExt(ext);
00379 }
00380 unsigned int MnUserParameterState::ExtOfInt(unsigned int internal) const {
00381
00382 return fParameters.Trafo().ExtOfInt(internal);
00383 }
00384 unsigned int MnUserParameterState::VariableParameters() const {
00385
00386 return fParameters.Trafo().VariableParameters();
00387 }
00388 const MnMachinePrecision& MnUserParameterState::Precision() const {
00389
00390 return fParameters.Precision();
00391 }
00392
00393 void MnUserParameterState::SetPrecision(double eps) {
00394
00395 fParameters.SetPrecision(eps);
00396 }
00397
00398 }
00399
00400 }