00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_MULTI_MIN_FIX_H 00024 #define O2SCL_MULTI_MIN_FIX_H 00025 00026 #include <o2scl/multi_min.h> 00027 #include <o2scl/gsl_mmin_simp.h> 00028 00029 #ifndef DOXYGENP 00030 namespace o2scl { 00031 #endif 00032 00033 /** \brief Multidimensional minimizer fixing some variables and 00034 varying others 00035 00036 See an example for the usage of this class 00037 in \ref ex_mmin_fix_sect . 00038 00039 \todo Generalize to all vector types 00040 \todo Generalize to minimizers which require derivatives 00041 00042 */ 00043 #ifdef DOXYGENP 00044 template<class param_t, class bool_vec_t> 00045 class multi_min_fix : public multi_min 00046 #else 00047 template<class param_t, class bool_vec_t> 00048 class multi_min_fix : public multi_min<param_t,multi_funct<param_t> > 00049 #endif 00050 { 00051 00052 public: 00053 00054 /** \brief Specify the member function pointer 00055 */ 00056 multi_min_fix() { 00057 mmp=&def_mmin; 00058 } 00059 00060 virtual ~multi_min_fix() {} 00061 00062 /** \brief Calculate the minimum \c min of \c func w.r.t. the 00063 array \c x of size \c nvar. 00064 */ 00065 virtual int mmin(size_t nvar, ovector_base &x, double &fmin, 00066 param_t &pa, multi_funct<param_t> &func) { 00067 00068 // Copy arguments for later use 00069 xp=&x; 00070 funcp=&func; 00071 unv=nvar; 00072 nv_new=nvar; 00073 ovector xnew(nv_new); 00074 00075 // Copy initial guess to new format 00076 for(size_t i=0;i<nvar;i++) { 00077 xnew[i]=x[i]; 00078 } 00079 00080 // Perform minimization 00081 multi_funct_mfptr<multi_min_fix,param_t> 00082 mfm(this,&multi_min_fix::min_func); 00083 int ret=mmp->mmin(nv_new,xnew,fmin,pa,mfm); 00084 if (ret!=0) { 00085 O2SCL_ERR("Minimizer failed in multi_min_fix::mmin().",ret); 00086 } 00087 00088 // Copy final result back to original format 00089 for(size_t i=0;i<nvar;i++) { 00090 x[i]=xnew[i]; 00091 } 00092 00093 this->last_ntrial=mmp->last_ntrial; 00094 00095 return ret; 00096 } 00097 00098 /** \brief Calculate the minimum of \c func while fixing 00099 some parameters as specified in \c fix. 00100 00101 If all of entries <tt>fix[0], fix[1], ... fix[nvar-1]</tt> 00102 are true, then this function assumes all of the parameters 00103 are fixed and that there is no minimization to be performed. 00104 In this case, it will return 0 for success without calling 00105 the error handler. 00106 */ 00107 virtual int mmin_fix(size_t nvar, ovector_base &x, double &fmin, 00108 bool_vec_t &fix, param_t &pa, 00109 multi_funct<param_t> &func) { 00110 00111 // Copy arguments for later use 00112 xp=&x; 00113 funcp=&func; 00114 unv=nvar; 00115 fixp=&fix; 00116 nv_new=0; 00117 for(size_t i=0;i<nvar;i++) { 00118 if (fix[i]==false) nv_new++; 00119 } 00120 if (nv_new==0) return 0; 00121 00122 // Copy initial guess to new format 00123 size_t j=0; 00124 ovector xnew(nv_new); 00125 for(size_t i=0;i<nvar;i++) { 00126 if (fix[i]==false) { 00127 xnew[j]=x[i]; 00128 j++; 00129 } 00130 } 00131 00132 // Perform minimization 00133 multi_funct_mfptr<multi_min_fix,param_t> 00134 mfm(this,&multi_min_fix::min_func); 00135 int ret=mmp->mmin(nv_new,xnew,fmin,pa,mfm); 00136 if (ret!=0) { 00137 O2SCL_ERR("Minimizer failed in multi_min_fix::mmin_fix().",ret); 00138 } 00139 00140 // Copy final result back to original format 00141 j=0; 00142 for(size_t i=0;i<nvar;i++) { 00143 if (fix[i]==false) { 00144 x[i]=xnew[j]; 00145 j++; 00146 } 00147 } 00148 00149 this->last_ntrial=mmp->last_ntrial; 00150 00151 return ret; 00152 } 00153 00154 /// Change the base minimizer 00155 int set_mmin(multi_min<param_t,multi_funct_mfptr 00156 <multi_min_fix,param_t> > &min) { 00157 mmp=&min; 00158 return 0; 00159 } 00160 00161 /// The default base minimizer 00162 gsl_mmin_simp<param_t,multi_funct_mfptr<multi_min_fix,param_t> > def_mmin; 00163 00164 #ifndef DOXYGEN_INTERNAL 00165 00166 protected: 00167 00168 /** \brief The new function to send to the minimizer 00169 */ 00170 virtual int min_func(size_t nv, const ovector_base &x, double &y, 00171 param_t &pa) { 00172 ovector tmp(unv); 00173 size_t j=0; 00174 for(size_t i=0;i<unv;i++) { 00175 if (nv_new<unv && (*fixp)[i]==true) { 00176 tmp[i]=(*xp)[i]; 00177 } else { 00178 tmp[i]=x[j]; 00179 j++; 00180 } 00181 } 00182 int ret=(*funcp)(unv,tmp,y,pa); 00183 return ret; 00184 } 00185 00186 /// The minimizer 00187 multi_min<param_t,multi_funct_mfptr<multi_min_fix,param_t> > *mmp; 00188 00189 /// The user-specified function 00190 multi_funct<param_t> *funcp; 00191 00192 /// The user-specified number of variables 00193 size_t unv; 00194 00195 /// The new number of variables 00196 size_t nv_new; 00197 00198 /// Specify which parameters to fix 00199 bool_vec_t *fixp; 00200 00201 /// The user-specified initial vector 00202 ovector_base *xp; 00203 00204 #ifndef DOXYGENP 00205 #endif 00206 00207 private: 00208 00209 multi_min_fix(const multi_min_fix &); 00210 multi_min_fix& operator=(const multi_min_fix&); 00211 00212 #endif 00213 00214 }; 00215 00216 00217 #ifndef DOXYGENP 00218 } 00219 #endif 00220 00221 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page