multi_min_fix.h

00001 /*
00002   -------------------------------------------------------------------
00003 
00004   Copyright (C) 2006, 2007, 2008, 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       \todo Generalize to all vector types
00037   */
00038   template<class param_t, class bool_vec_t>
00039     class multi_min_fix : public multi_min<param_t,multi_funct<param_t> > {
00040     
00041   public:
00042     
00043     /** \brief Specify the member function pointer
00044      */
00045     multi_min_fix() {
00046       mmp=&def_mmin;
00047     }
00048     
00049     virtual ~multi_min_fix() {}
00050     
00051     /** \brief Calculate the minimum \c min of \c func w.r.t. the
00052         array \c x of size \c nvar.
00053     */
00054     virtual int mmin(size_t nvar, ovector_view &x, double &fmin, 
00055                      param_t &pa, multi_funct<param_t> &func) {
00056 
00057       // Copy arguments for later use
00058       xp=&x;
00059       funcp=&func;
00060       unv=nvar;
00061       nv_new=nvar;
00062       ovector xnew(nv_new);
00063 
00064       // Copy initial guess to new format
00065       for(size_t i=0;i<nvar;i++) {
00066         xnew[i]=x[i];
00067       }
00068 
00069       // Perform minimization
00070       multi_funct_mfptr<multi_min_fix,param_t> 
00071         mfm(this,&multi_min_fix::min_func);
00072       int ret=mmp->mmin(nv_new,xnew,fmin,pa,mfm);
00073       if (ret!=0) {
00074         add_err("Minimizer failed in multi_min_fix::mmin().",
00075                 gsl_efailed);
00076         ret=gsl_efailed;
00077       }
00078 
00079       // Copy final result back to original format
00080       for(size_t i=0;i<nvar;i++) {
00081         x[i]=xnew[i];
00082       }
00083 
00084       return ret;
00085     }
00086 
00087     /** \brief Calculate the minimum of \c func while fixing 
00088         some parameters as specified in \c fix.
00089 
00090         If all of entries <tt>fix[0], fix[1], ... fix[nvar-1]</tt>
00091         are true, then this function assumes all of the parameters
00092         are fixed and that there is no minimization to be performed.
00093         In this case, it will return 0 for success without calling
00094         the error handler. 
00095     */
00096     virtual int mmin_fix(size_t nvar, ovector_view &x, double &fmin, 
00097                          bool_vec_t &fix, param_t &pa, 
00098                          multi_funct<param_t> &func) {
00099 
00100       // Copy arguments for later use
00101       xp=&x;
00102       funcp=&func;
00103       unv=nvar;
00104       fixp=&fix;
00105       nv_new=0;
00106       for(size_t i=0;i<nvar;i++) {
00107         if (fix[i]==false) nv_new++;
00108       }
00109       if (nv_new==0) return 0;
00110 
00111       // Copy initial guess to new format
00112       size_t j=0;
00113       ovector xnew(nv_new);
00114       for(size_t i=0;i<nvar;i++) {
00115         if (fix[i]==false) {
00116           xnew[j]=x[i];
00117           j++;
00118         }
00119       }
00120 
00121       // Perform minimization
00122       multi_funct_mfptr<multi_min_fix,param_t> 
00123         mfm(this,&multi_min_fix::min_func);
00124       int ret=mmp->mmin(nv_new,xnew,fmin,pa,mfm);
00125       if (ret!=0) {
00126         add_err("Minimizer failed in multi_min_fix::mmin_fix().",
00127                 gsl_efailed);
00128         ret=gsl_efailed;
00129       }
00130 
00131       // Copy final result back to original format
00132       j=0;
00133       for(size_t i=0;i<nvar;i++) {
00134         if (fix[i]==false) {
00135           x[i]=xnew[j];
00136           j++;
00137         }
00138       }
00139 
00140       return ret;
00141     }
00142 
00143     /// Change the base minimizer
00144     int set_mmin(multi_min<param_t,multi_funct_mfptr
00145                  <multi_min_fix,param_t> > &min) {
00146       mmp=&min;
00147       return 0;
00148     }
00149 
00150     /// The default base minimizer
00151     gsl_mmin_simp<param_t,multi_funct_mfptr<multi_min_fix,param_t> > def_mmin;
00152     
00153 #ifndef DOXYGEN_INTERNAL
00154     
00155   protected:
00156     
00157     /** \brief The new function to send to the minimizer
00158      */
00159     virtual int min_func(size_t nv, const ovector_view &x, double &y, 
00160                          param_t &pa) {
00161       ovector tmp(unv);
00162       size_t j=0;
00163       for(size_t i=0;i<unv;i++) {
00164         if (nv_new<unv && (*fixp)[i]==true) {
00165           tmp[i]=(*xp)[i];
00166         } else {
00167           tmp[i]=x[j];
00168           j++;
00169         }
00170       }
00171       int ret=(*funcp)(unv,tmp,y,pa);
00172       return ret;
00173     }
00174     
00175     /// The minimizer
00176     multi_min<param_t,multi_funct_mfptr<multi_min_fix,param_t> > *mmp;
00177 
00178     /// The user-specified function
00179     multi_funct<param_t> *funcp;
00180 
00181     /// The user-specified number of variables
00182     size_t unv;
00183 
00184     /// The new number of variables
00185     size_t nv_new;
00186     
00187     /// Specify which parameters to fix
00188     bool_vec_t *fixp;
00189     
00190     /// The user-specified initial vector
00191     ovector_view *xp;
00192 
00193 #ifndef DOXYGENP
00194 #endif
00195 
00196   private:
00197  
00198     multi_min_fix(const multi_min_fix &);
00199     multi_min_fix& operator=(const multi_min_fix&);
00200 
00201 #endif
00202 
00203   };
00204 
00205 
00206 #ifndef DOXYGENP
00207 }
00208 #endif
00209 
00210 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page