MnUserParameterState.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: MnUserParameterState.cxx 34256 2010-06-30 21:07:32Z moneta $
00002 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005  
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
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 // construct from user parameters (befor minimization)
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    // construct from user parameters (befor minimization)
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 // construct from user parameters + errors (befor minimization)
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    // construct from user parameters + errors (before minimization) using std::vector for parameter error and    // an std::vector of size n*(n+1)/2 for the covariance matrix  and n (rank of cov matrix) 
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    //construct from user parameters + errors (befor minimization) using std::vector (params) and MnUserCovariance class
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    //construct from user parameters + errors (befor minimization) using 
00074    // MnUserParameters and MnUserCovariance objects
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    // need to Fix that in case of limited parameters
00087    //   fIntCovariance = MnUserCovariance();
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    // construct from internal parameters (after minimization)
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 // facade: forward interface of MnUserParameters and MnUserTransformation
00143 // via MnUserParameterState
00144 
00145 
00146 const std::vector<MinuitParameter>& MnUserParameterState::MinuitParameters() const {
00147    //access to parameters (row-wise)
00148    return fParameters.Parameters();
00149 }
00150  
00151 std::vector<double> MnUserParameterState::Params() const {
00152    //access to parameters in column-wise representation
00153    return fParameters.Params();
00154 }
00155 std::vector<double> MnUserParameterState::Errors() const {
00156    //access to errors in column-wise representation
00157    return fParameters.Errors();
00158 }
00159 
00160 const MinuitParameter& MnUserParameterState::Parameter(unsigned int i) const {
00161    //access to single Parameter i
00162    return fParameters.Parameter(i);
00163 }
00164 
00165 void MnUserParameterState::Add(const std::string & name, double val, double err) {
00166    //add free Parameter
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       // redefine an existing parameter
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       // release if it was fixed 
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    //add limited Parameter
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 { // Parameter already exist - just set values
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       // release if it was fixed 
00208       if (Parameter(i).IsFixed() ) Release(i);  
00209    }
00210    
00211    
00212 }
00213 
00214 void MnUserParameterState::Add(const std::string & name, double val) {
00215    //add const Parameter
00216    if ( fParameters.Add(name, val) ) 
00217       fValid = true;
00218    else 
00219       SetValue(name,val);
00220 }
00221 
00222 //interaction via external number of Parameter
00223 
00224 void MnUserParameterState::Fix(unsigned int e) {
00225    // fix parameter e (external index)
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    // release parameter e (external index)
00240    // no-op if parameter is const
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    // set value for parameter e ( external index )
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    // set error for  parameter e (external index)
00266    fParameters.SetError(e, val);
00267 }
00268 
00269 void MnUserParameterState::SetLimits(unsigned int e, double low, double up) {
00270    // set limits for parameter e (external index)
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    // set upper limit for parameter e (external index)
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    // set lower limit for parameter e (external index)
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    // remove limit for parameter e (external index)
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    // get value for parameter e (external index)
00322    return fParameters.Value(i);
00323 }
00324 double MnUserParameterState::Error(unsigned int i) const {
00325    // get error for parameter e (external index)
00326    return fParameters.Error(i);
00327 }
00328 
00329 //interaction via name of Parameter
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    //convert name into external number of Parameter
00354    return fParameters.Index(name);
00355 }
00356 
00357 const char* MnUserParameterState::Name(unsigned int i) const {
00358    //convert external number into name of Parameter (API returing a const char *)
00359    return fParameters.Name(i);
00360 }
00361 const std::string & MnUserParameterState::GetName(unsigned int i) const {
00362    //convert external number into name of Parameter (new interface returning a string) 
00363    return fParameters.GetName(i);
00364 }
00365 
00366 // transformation internal <-> external (forward to transformation class)
00367 
00368 double MnUserParameterState::Int2ext(unsigned int i, double val) const {
00369    // internal to external value
00370    return fParameters.Trafo().Int2ext(i, val);
00371 }
00372 double MnUserParameterState::Ext2int(unsigned int e, double val) const {
00373     // external  to internal value 
00374    return fParameters.Trafo().Ext2int(e, val);
00375 }
00376 unsigned int MnUserParameterState::IntOfExt(unsigned int ext) const {
00377    // return internal index for external index ext 
00378    return fParameters.Trafo().IntOfExt(ext);
00379 }
00380 unsigned int MnUserParameterState::ExtOfInt(unsigned int internal) const { 
00381     // return external index for internal index internal
00382    return fParameters.Trafo().ExtOfInt(internal);
00383 }
00384 unsigned int MnUserParameterState::VariableParameters() const {
00385    // return number of variable parameters
00386    return fParameters.Trafo().VariableParameters();
00387 }
00388 const MnMachinePrecision& MnUserParameterState::Precision() const {
00389    // return global parameter precision
00390    return fParameters.Precision();
00391 }
00392 
00393 void MnUserParameterState::SetPrecision(double eps) {
00394    // set global parameter precision
00395    fParameters.SetPrecision(eps);
00396 }
00397 
00398    }  // namespace Minuit2
00399 
00400 }  // namespace ROOT

Generated on Tue Jul 5 14:37:11 2011 for ROOT_528-00b_version by  doxygen 1.5.1