Object-oriented Scientific Computing Library: Version 0.910
mroot.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_MROOT_H
00024 #define O2SCL_MROOT_H
00025 
00026 #include <o2scl/ovector_tlate.h>
00027 #include <o2scl/mm_funct.h>
00028 #include <o2scl/jacobian.h>
00029 
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033 
00034   /** \brief Multidimensional root-finding [abstract base]
00035       
00036       <b>The template parameters:</b>
00037       The template parameter \c func_t specifies the functions to 
00038       solve and should be a class containing a definition 
00039       \code
00040       func_t::operator()(size_t nv, const vec_t &x, vec_t &y);
00041       \endcode
00042       where \c y is the value of the functions at \c x with parameter \c pa
00043       and \c x and \c y are a array-like classes defining \c operator[] 
00044       of size \c nv. If the Jacobian matrix is to be specified by the
00045       user, then the parameter \c jfunc_t specifies the jacobian
00046       and should contain the definition
00047       \code
00048       jfunc_t::operator(size_t nv, vec_t &x, vec_t &y, mat_t &j);
00049       \endcode
00050       where \c x is the independent variables, \c y is the array of 
00051       function values, and \c j is the Jacobian matrix. This template
00052       parameter can be ignored if only the function msolve() will be used.
00053 
00054       \warning Many of the routines assume that the scale of the
00055       functions and their variables is of order unity. The solution
00056       routines may lose precision if this is not the case.
00057 
00058       There is an example for the usage of the multidimensional solver
00059       classes given in <tt>examples/ex_mroot.cpp</tt>, see \ref
00060       ex_mroot_sect .
00061 
00062       \future Change ntrial to size_t?
00063   */
00064   template<class func_t, class vec_t=ovector_base,
00065     class jfunc_t=jac_funct<vec_t,omatrix_base> > class mroot {
00066     
00067     public:
00068 
00069     mroot() {
00070       ntrial=100;
00071       tol_rel=1.0e-8;
00072       verbose=0;
00073       tol_abs=1.0e-12;
00074       last_ntrial=0;
00075       err_nonconv=true;
00076     }
00077 
00078     virtual ~mroot() {}
00079   
00080     /// The maximum value of the functions for success (default 1.0e-8)
00081     double tol_rel;
00082     
00083     /// The minimum allowable stepsize (default 1.0e-12)
00084     double tol_abs;
00085     
00086     /// Output control (default 0)
00087     int verbose;
00088     
00089     /// Maximum number of iterations (default 100)
00090     int ntrial;
00091 
00092     /// The number of iterations for in the most recent minimization
00093     int last_ntrial;
00094     
00095     /** \brief If true, call the error handler if msolve() or
00096         msolve_de() does not converge (default true)
00097     */
00098     bool err_nonconv;
00099     
00100     /** \brief Zero if last call to msolve() or msolve_de() converged. 
00101         
00102         This is particularly useful if err_nonconv is false to test
00103         if the last call to msolve() or msolve_de() converged.
00104     */
00105     int last_conv;
00106     
00107     /// Return the type, \c "mroot".
00108     virtual const char *type() { return "mroot"; }
00109       
00110     /// Solve \c func using \c x as an initial guess, returning \c x.
00111     virtual int msolve(size_t n, vec_t &x, func_t &func)=0;
00112     
00113     /** \brief Solve \c func with derivatives \c dfunc using \c x as 
00114         an initial guess, returning \c x.
00115         
00116         By default, this function just calls msolve() and ignores the 
00117         last argument.
00118     */
00119     virtual int msolve_de(size_t n, vec_t &x, func_t &func,
00120                           jfunc_t &dfunc) {
00121       return msolve(n,x,func);
00122     }
00123 
00124     /** \brief Print out iteration information.
00125           
00126         Depending on the value of the variable verbose, this prints out
00127         the iteration information. If verbose=0, then no information is
00128         printed, while if verbose>1, then after each iteration, the
00129         present values of x and y are output to std::cout along with the
00130         iteration number. If verbose>=2 then each iteration waits for a
00131         character.  
00132 
00133         This is implemented as a template class using a new vector type
00134         because sometimes the internal vector class is distinct from
00135         the user-specified vector class (e.g. in \ref gsl_mroot_hybrids).
00136     */
00137     template<class vec2_t, class vec3_t>
00138     int print_iter(size_t n, const vec2_t &x, const vec3_t &y, 
00139                    int iter, double value=0.0, double limit=0.0,
00140                    std::string comment="") 
00141     {
00142       if (verbose<=0) return o2scl::gsl_success;
00143       
00144       char ch;
00145         
00146       std::cout << comment << " Iteration: " << iter << std::endl;
00147       for(size_t i=0;i<n;i++) {
00148         std::cout.width(3);
00149         std::cout << i;
00150         if (x[i]>=0.0) {
00151           std::cout << "  " << x[i];
00152         } else {
00153           std::cout << " " << x[i];
00154         }
00155         if (y[i]>=0.0) {
00156           std::cout << "  " << y[i] << std::endl;
00157         } else {
00158           std::cout << " " << y[i] << std::endl;
00159         }
00160       }
00161       std::cout << "Val: " << value << " Lim: " << limit << std::endl;
00162       if (verbose>1) {
00163         std::cout << "Press a key and type enter to continue. ";
00164         std::cin >> ch;
00165       }
00166   
00167       return o2scl::gsl_success;
00168         
00169     }
00170       
00171   };
00172   
00173 #ifndef DOXYGENP
00174 }
00175 #endif
00176 
00177 #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.