comp_gen_inte.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 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_COMP_GEN_INTE_H
00024 #define O2SCL_COMP_GEN_INTE_H
00025 
00026 #include <iostream>
00027 #include <o2scl/collection.h>
00028 #include <o2scl/funct.h>
00029 #include <o2scl/inte.h>
00030 #include <o2scl/gen_inte.h>
00031 
00032 #ifndef DOXYGENP
00033 namespace o2scl {
00034 #endif
00035 
00036   /** 
00037       \brief Naive generalized multi-dimensional integration 
00038 
00039       Naively combine several one-dimensional integration objects from
00040       class inte in order to perform a multi-dimensional integration.
00041       The integration routines are specified in the function
00042       set_ptrs().
00043 
00044       The integration routines are called in order of their
00045       specification in the list <tt>inte **ip</tt>. For the example of
00046       a two-dimensional integration <tt>ip[0]</tt> is called first
00047       with limits <tt>a[0]</tt> and <tt>b[0]</tt> and performs the
00048       integral of the integral given by <tt>ip[1]</tt> of the function
00049       from <tt>a[1]</tt> to <tt>b[1]</tt>, both of which may depend
00050       explicitly on <tt>x[0]</tt>. The integral performed is:
00051       \f[ 
00052       \int_{x_0=a_0}^{x_0=b_0} f(x_0) \int_{x_1=a_1(x_0)}^{x_1=b_1(x_0)} 
00053       f(x_0, x_1) ...
00054       \int_{x_{\mathrm{n}-1}=a_{\mathrm{n}-1}(x_0,x_1,..,x_{\mathrm{n}-2})}^
00055       {x_{\mathrm{n}-1}=b_{\mathrm{n}-1}(x_0,x_1,..,x_{\mathrm{n}-2})} 
00056       f(x_0,x_1,...,x_{\mathrm{n-1}})~d x_{\mathrm{n}-1}~...~d x_1~d x_0
00057       \f]
00058 
00059       See the discussion about the functions \c func, \c lower and \c
00060       upper in the documentation for the class gen_inte.
00061 
00062       No error estimate is performed. Error estimation for multiple
00063       dimension integrals is provided by the Monte Carlo integration
00064       classes (see \ref mcarlo_inte).
00065   */
00066   template<class param_t, class func_t, class lfunc_t=func_t, 
00067     class ufunc_t=func_t, class vec_t=ovector_view, 
00068     class alloc_vec_t=ovector, class alloc_t=ovector_alloc> 
00069     class comp_gen_inte : 
00070   public gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t> {
00071 
00072     public:
00073 
00074     comp_gen_inte() {
00075       
00076       ptrs_set=false;
00077       
00078       fmn=new funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t,
00079       ufunc_t,vec_t,alloc_vec_t,alloc_t>,od_parms>
00080       (this,&comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t,
00081        alloc_vec_t,alloc_t>::odfunc);
00082 
00083       ndim=0;
00084     }
00085     
00086     virtual ~comp_gen_inte() {
00087       delete fmn;
00088     }
00089     
00090     /** 
00091         \brief Parameters to send to the 1-d integration functions
00092         
00093         For basic usage, the class-user needs this type 
00094         to specify the parameter type for 1-d integration objects.
00095     */
00096     typedef struct {
00097       /// The independent variable vector
00098       alloc_vec_t *cx;
00099       /// The function specifying the lower limits
00100       lfunc_t *lower;
00101       /// The function specifying the upper limits
00102       ufunc_t *upper;
00103       /// The function to be integrated
00104       func_t *func;
00105       /// The number of dimensions
00106       int ndim;
00107       /// The present recursion level
00108       int idim;
00109       /// The user-specified parameter
00110       param_t *vp;
00111     } od_parms;
00112   
00113     /** 
00114         \brief Designate the pointers to the integration routines
00115         
00116         The user can, in principle, specify the one instance of an
00117         \ref inte object for several of the pointers, but this is
00118         discouraged as most inte objects cannot be used this way.
00119         This function will not warn you if some of the pointers
00120         specified in \c ip refer to the same object.
00121 
00122         If more 1-d integration routines than necessary are given,
00123         the extras will be unused.
00124     */
00125     int set_ptrs(inte<od_parms,funct<od_parms> > **ip, int n) {
00126       if (n<1) {
00127         set_err_ret
00128           ("Number of dimensions less than 1 in set_ptrs().",gsl_einval);
00129       }
00130       ptrs=ip;
00131       ndim=n;
00132       ptrs_set=true;
00133       return 0;
00134     }
00135 
00136     /** \brief Integrate function \c func from 
00137         \f$ {\ell}_i=f_i(x_i) \f$ to \f$ u_i=g_i(x_i) \f$ for 
00138         \f$ 0<i<\mathrm{n}-1 \f$.
00139     */
00140     virtual double ginteg(func_t &func, size_t n, func_t &lower, 
00141                           func_t &upper, param_t &pa) {
00142       
00143       if (ptrs_set==false || n>ndim || n==0) {
00144         set_err("Pointers not set with proper dimension in ginteg().",
00145                 gsl_einval);
00146         return 0.0;
00147       }
00148       
00149       alloc_vec_t cx;
00150       ao.allocate(cx,n);
00151       
00152       od_parms op={&cx,&lower,&upper,&func,n,0,&pa};
00153       
00154       double res=ptrs[0]->integ(*fmn,lower(0,cx,pa),upper(0,cx,pa),op);
00155       
00156       ao.free(cx);
00157       
00158       return res;
00159     }
00160   
00161     /// Return string denoting type ("comp_gen_inte")
00162     virtual const char *type() { return "comp_gen_inte"; }
00163 
00164 #ifndef DOXYGEN_INTERNAL
00165     
00166     protected:
00167     
00168     /// Memory allocator for objects of type \c alloc_vec_t 
00169     alloc_t ao;
00170     
00171     /// The function to send to the integrators
00172     funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t,
00173     vec_t,alloc_vec_t,alloc_t>,od_parms> *fmn;
00174     
00175     /// The one-dimensional integration function
00176     double odfunc(double x, od_parms &od) {
00177 
00178       double res;
00179 
00180       (*od.cx)[od.idim]=x;
00181       if (od.idim==od.ndim-1) {
00182         (*od.func)(od.ndim,(*od.cx),res,*od.vp);
00183       } else {
00184         od_parms od2={od.cx,od.lower,od.upper,od.func,
00185                       od.ndim,od.idim+1,od.vp};
00186         (*od.func)(od.idim+1,*od.cx,res,*od.vp);
00187         res*=ptrs[od.idim]->integ
00188           (*fmn,(*od.lower)(od.idim+1,*od.cx,*od.vp),
00189            (*od.upper)(od.idim+1,*od.cx,*od.vp),od2);
00190       }
00191       return res;
00192     }
00193   
00194     /// The number of dimensions
00195     size_t ndim;
00196     
00197     /// Pointers to the integration objects
00198     inte<od_parms,funct<od_parms> > **ptrs;
00199 
00200     /// True if the integration objects have been specified
00201     bool ptrs_set;
00202 
00203 #endif
00204 
00205 
00206   };
00207 
00208 #ifndef DOXYGENP
00209 }
00210 #endif
00211 
00212 #endif
00213 

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