Object-oriented Scientific Computing Library: Version 0.910
multi_min_fix.h
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
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.