![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, 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_simp2.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 \todo At the moment, the user has to change def_mmin::ntrial 00042 instead of multi_min_fix::ntrial, which is a bit confusing. 00043 Fix this. 00044 */ 00045 #ifdef DOXYGENP 00046 template<class bool_vec_t> class multi_min_fix : public multi_min 00047 #else 00048 template<class bool_vec_t> class multi_min_fix : 00049 public multi_min<multi_funct<> > 00050 #endif 00051 { 00052 00053 public: 00054 00055 /** \brief Specify the member function pointer 00056 */ 00057 multi_min_fix() { 00058 mmp=&def_mmin; 00059 } 00060 00061 virtual ~multi_min_fix() {} 00062 00063 /** \brief Calculate the minimum \c min of \c func w.r.t. the 00064 array \c x of size \c nvar. 00065 */ 00066 virtual int mmin(size_t nvar, ovector_base &x, double &fmin, 00067 multi_funct<> &func) { 00068 00069 // Copy arguments for later use 00070 xp=&x; 00071 funcp=&func; 00072 unv=nvar; 00073 nv_new=nvar; 00074 ovector xnew(nv_new); 00075 00076 // Copy initial guess to new format 00077 for(size_t i=0;i<nvar;i++) { 00078 xnew[i]=x[i]; 00079 } 00080 00081 // Perform minimization 00082 multi_funct_mfptr<multi_min_fix> mfm(this,&multi_min_fix::min_func); 00083 int ret=mmp->mmin(nv_new,xnew,fmin,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, multi_funct<> &func) { 00109 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> mfm(this,&multi_min_fix::min_func); 00134 int ret=mmp->mmin(nv_new,xnew,fmin,mfm); 00135 if (ret!=0) { 00136 O2SCL_ERR("Minimizer failed in multi_min_fix::mmin_fix().",ret); 00137 } 00138 00139 // Copy final result back to original format 00140 j=0; 00141 for(size_t i=0;i<nvar;i++) { 00142 if (fix[i]==false) { 00143 x[i]=xnew[j]; 00144 j++; 00145 } 00146 } 00147 00148 this->last_ntrial=mmp->last_ntrial; 00149 00150 return ret; 00151 } 00152 00153 /// Change the base minimizer 00154 int set_mmin(multi_min<multi_funct_mfptr<multi_min_fix> > &min) { 00155 00156 mmp=&min; 00157 return 0; 00158 } 00159 00160 /// The default base minimizer 00161 gsl_mmin_simp2<multi_funct_mfptr<multi_min_fix> > def_mmin; 00162 00163 #ifndef DOXYGEN_INTERNAL 00164 00165 protected: 00166 00167 /** \brief The new function to send to the minimizer 00168 */ 00169 virtual double min_func(size_t nv, const ovector_base &x) { 00170 00171 ovector tmp(unv); 00172 size_t j=0; 00173 for(size_t i=0;i<unv;i++) { 00174 if (nv_new<unv && (*fixp)[i]==true) { 00175 tmp[i]=(*xp)[i]; 00176 } else { 00177 tmp[i]=x[j]; 00178 j++; 00179 } 00180 } 00181 return (*funcp)(unv,tmp); 00182 } 00183 00184 /// The minimizer 00185 multi_min<multi_funct_mfptr<multi_min_fix> > *mmp; 00186 00187 /// The user-specified function 00188 multi_funct<> *funcp; 00189 00190 /// The user-specified number of variables 00191 size_t unv; 00192 00193 /// The new number of variables 00194 size_t nv_new; 00195 00196 /// Specify which parameters to fix 00197 bool_vec_t *fixp; 00198 00199 /// The user-specified initial vector 00200 ovector_base *xp; 00201 00202 #ifndef DOXYGENP 00203 #endif 00204 00205 private: 00206 00207 multi_min_fix(const multi_min_fix &); 00208 multi_min_fix& operator=(const multi_min_fix&); 00209 00210 #endif 00211 00212 }; 00213 00214 00215 #ifndef DOXYGENP 00216 } 00217 #endif 00218 00219 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).