00001
00012 #include "MinuitMigrad.h"
00013
00014 #include "StatedFCN.h"
00015
00016 #include "FitterException.h"
00017
00018 #include <Minuit/FunctionMinimum.h>
00019 #include <Minuit/MinuitParameter.h>
00020 #include <Minuit/MnMigrad.h>
00021 #include <Minuit/MnUserParameters.h>
00022
00023 using std::string;
00024 using std::vector;
00025
00026 MinuitMigrad::
00027 MinuitMigrad ( const char * name )
00028 : Fitter ( name ),
00029 m_minimizer ( 0 )
00030 {
00031 }
00032
00033 MinuitMigrad::
00034 MinuitMigrad ( const MinuitMigrad & mm )
00035 : Fitter ( mm ),
00036 m_minimizer ( 0 )
00037 {
00038 if ( mm.m_minimizer != 0 ) {
00039 m_minimizer = new MnMigrad ( * mm.m_minimizer );
00040 }
00041 }
00042
00043 Fitter *
00044 MinuitMigrad::
00045 clone ( ) const
00046 {
00047 return new MinuitMigrad ( *this );
00048 }
00049
00050 bool
00051 MinuitMigrad::
00052 needsDerivatives () const
00053 {
00054 return false;
00055 }
00056
00057 void
00058 MinuitMigrad::
00059 initialize ()
00060 {
00061 m_minimizer = 0;
00062 bool yes = m_fcn -> hasFunction ();
00063 if ( yes ) {
00064 const vector < string > & names = m_fcn -> getParmNames ();
00065 unsigned int size = names.size ();
00066 const vector < double > & parms = m_fcn -> getParameters ();
00067 MnUserParameters mn_parms;
00068
00069 for ( unsigned int i = 0; i < size; i++ ) {
00070 const string name = names [ i ];
00071 double value = parms [ i ];
00072 mn_parms.add ( name.c_str(), value, 0.1 );
00073 }
00074 m_minimizer = new MnMigrad ( *m_fcn, mn_parms );
00075 }
00076 }
00077
00078 void
00079 MinuitMigrad::
00080 checkIndex ( unsigned int i )
00081 {
00082 if ( m_minimizer == 0 ) initialize ();
00083
00084 if ( m_minimizer == 0 ) {
00085 string what ( m_name );
00086 what += ": model function no yet set";
00087 throw FitterException ( what );
00088 }
00089 const vector < double > & parms = m_fcn -> getParameters ();
00090 unsigned int size = parms.size();
00091 if ( i < size == false ) {
00092 string what ( m_name );
00093 what += ": index to parameter out of range";
00094 throw FitterException ( what );
00095 }
00096 }
00097
00098 void
00099 MinuitMigrad::
00100 setLimits ( unsigned int i, double lower, double upper )
00101 {
00102 checkIndex ( i );
00103 m_minimizer -> setLimits ( i, lower, upper );
00104 }
00105
00106 void
00107 MinuitMigrad::
00108 setStepSize ( unsigned int i, double size )
00109 {
00110 checkIndex ( i );
00111 m_minimizer -> setError ( i, size );
00112 }
00113
00114 bool
00115 MinuitMigrad::
00116 calcBestFit ()
00117 {
00118 if ( m_minimizer == 0 ) initialize ();
00119
00120 const vector < double > & init_parms = m_fcn -> getParameters ();
00121 const vector < int > & fixes = m_fcn -> getFixedFlags ();
00122 const vector < MinuitParameter> & mparms
00123 = m_minimizer -> minuitParameters ();
00124 unsigned int size = fixes.size();
00125
00126 for ( unsigned int i = 0; i < size; i++ ) {
00127 m_minimizer -> setValue ( i, init_parms[i] );
00128 bool yes = fixes [i] != 0;
00129 const MinuitParameter & mparm = mparms [i];
00130 if ( yes && mparm.isFixed() == false ) {
00131 m_minimizer -> fix ( i );
00132 }
00133 else if ( mparm.isFixed() == true ) {
00134 m_minimizer -> release ( i );
00135 }
00136 }
00137
00138 FunctionMinimum fun_min = m_minimizer -> operator () ();
00139
00140
00141
00142 std::vector < double > cur_parms = m_minimizer -> params();
00143 m_fcn -> setParameters ( cur_parms );
00144
00145 return fun_min.isValid ();
00146 }
00147
00148 int
00149 MinuitMigrad::
00150 calcCovariance ( std::vector < std::vector < double > >& covar )
00151 {
00152
00153 if ( m_minimizer == 0 ) initialize ();
00154
00155 const MnUserCovariance & covar_m = m_minimizer ->covariance ();
00156
00157 unsigned int size = covar_m.nrow ();
00158 covar.resize ( size );
00159 for ( unsigned int i = 0; i < size; i++ ) {
00160 covar[i].resize ( size, 0.0 );
00161 }
00162
00163 for ( unsigned int i = 0; i < size; i++ ) {
00164 for ( unsigned int j = 0; j < size; j++ ) {
00165 covar[i][j] = covar_m ( i, j );
00166 }
00167 }
00168
00169 return EXIT_SUCCESS;
00170 }