00001 00012 #ifdef _MSC_VER 00013 #include "msdevstudio/MSconfig.h" 00014 #endif 00015 00016 #include "StatedFCN.h" 00017 00018 #include "functions/FunctionBase.h" 00019 00020 #include <stdexcept> 00021 00022 using std::string; 00023 using std::vector; 00024 00025 using namespace hippodraw; 00026 00027 StatedFCN:: 00028 StatedFCN ( ) 00029 : m_function ( 0 ), 00030 m_needs_derivs ( false ) 00031 { 00032 } 00033 00034 StatedFCN:: 00035 StatedFCN ( const StatedFCN & fcn ) 00036 : FCNBase (), 00037 m_fixed_flags ( fcn.m_fixed_flags ), 00038 m_function ( fcn.m_function ), 00039 m_needs_derivs ( fcn.m_needs_derivs ) 00040 { 00041 } 00042 00043 void 00044 StatedFCN:: 00045 copyFrom ( const StatedFCN * other ) 00046 { 00047 m_fixed_flags = other -> m_fixed_flags; 00048 m_function = other -> m_function; 00049 00050 } 00051 00052 bool 00053 StatedFCN:: 00054 hasFunction () const 00055 { 00056 return m_function != 0; 00057 } 00058 00062 void 00063 StatedFCN:: 00064 setFunction ( FunctionBase * function ) 00065 { 00066 bool yes = isCompatible ( function ); 00067 if ( yes == false ) { 00068 string what ( "StatedFCN: The function `" ); 00069 what += function -> name (); 00070 what += "' can not provide partial\n"; 00071 what += "derivatives needed by this fitter."; 00072 throw std::runtime_error ( what ); 00073 } 00074 00075 m_function = function; 00076 unsigned int size = m_function -> size(); 00077 m_fixed_flags.resize ( size ); 00078 00079 for ( unsigned int i = 0; i < size; i++ ) { 00080 m_fixed_flags [i] = 0; 00081 } 00082 } 00083 00084 const vector < string > & 00085 StatedFCN:: 00086 getParmNames () const 00087 { 00088 return m_function -> parmNames (); 00089 } 00090 00091 const vector < double > & 00092 StatedFCN:: 00093 getParameters ( ) const 00094 { 00095 return m_function -> getParameters ( ); 00096 } 00097 00098 void 00099 StatedFCN:: 00100 setParameters ( const std::vector < double > & parms ) 00101 { 00102 m_function -> setParameters ( parms ); 00103 } 00104 00105 void 00106 StatedFCN:: 00107 fillFreeParameters ( std::vector < double > & free_parms ) const 00108 { 00109 free_parms.clear(); 00110 const vector < double > & parms = m_function -> getParameters (); 00111 unsigned int size = parms.size (); 00112 for ( unsigned int i = 0; i < size; i++ ) { 00113 if ( m_fixed_flags[ i ] == 0 ) { 00114 free_parms.push_back ( parms[ i ] ); 00115 } 00116 } 00117 } 00118 00119 unsigned int 00120 StatedFCN:: 00121 getNumberFreeParms () const 00122 { 00123 unsigned int number = 0; 00124 unsigned int size = m_fixed_flags.size (); 00125 for ( unsigned int i = 0; i < size; i++ ) { 00126 if ( m_fixed_flags[i] == 0 ) number++; 00127 } 00128 00129 return number; 00130 } 00131 00132 const vector < int > & 00133 StatedFCN:: 00134 getFixedFlags () const 00135 { 00136 return m_fixed_flags; 00137 } 00138 00139 void 00140 StatedFCN:: 00141 setFixedFlags ( const std::vector < int > & flags ) 00142 { 00143 m_fixed_flags = flags; 00144 } 00145 00146 void 00147 StatedFCN:: 00148 setFreeParameters ( const std::vector < double > & free_parms ) 00149 { 00150 vector < double > parms = m_function -> getParameters (); 00151 unsigned int size = parms.size (); 00152 unsigned int j = 0; 00153 00154 for ( unsigned int i = 0; i < size; i++ ) { 00155 if ( m_fixed_flags [i] == 0 ) { 00156 parms[i] = free_parms[j]; 00157 j++; 00158 } 00159 } 00160 00161 m_function -> setParameters ( parms ); 00162 } 00163 00164 void 00165 StatedFCN:: 00166 fillFreeDerivatives ( std::vector < double > & derives, double x ) 00167 { 00168 derives.clear(); 00169 const vector < double > & parms = m_function -> getParameters (); 00170 unsigned int size = parms.size(); 00171 00172 for ( unsigned int i = 0; i < size; i++ ) { 00173 if ( m_fixed_flags [i] == 0 ) { 00174 double value = m_function -> derivByParm ( i, x ); 00175 derives.push_back ( value ); 00176 } 00177 } 00178 } 00179 00180 double 00181 StatedFCN:: 00182 operator () ( const std::vector < double > & parms ) const 00183 { 00184 m_function -> setParameters ( parms ); 00185 00186 return objectiveValue (); 00187 } 00188 00189 void 00190 StatedFCN:: 00191 setNeedsDerivatives ( bool yes ) 00192 { 00193 m_needs_derivs = yes; 00194 } 00195 00196 bool 00197 StatedFCN:: 00198 isCompatible ( const FunctionBase * function ) const 00199 { 00200 bool yes = true; 00201 if ( m_needs_derivs && 00202 ( function -> hasDerivatives () == false ) ) { 00203 yes = false; 00204 } 00205 00206 return yes; 00207 }