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 inte **ip. For the example of a
00046       two-dimensional integration ip[0] is called first with limits a[0]
00047       and b[0] and performs the integral of the integral given by ip[1]
00048       of the function from a[1] to b[1], both of which may depend
00049       explicitly on x[0]. The integral performed is:
00050 
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   */
00063   template<class param_t, class func_t, class lfunc_t=func_t, 
00064     class ufunc_t=func_t, class vec_t=ovector_view, 
00065     class alloc_vec_t=ovector, class alloc_t=ovector_alloc> 
00066     class comp_gen_inte : 
00067   public gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t> {
00068 
00069     public:
00070 
00071     comp_gen_inte() {
00072       
00073       ptrs_set=false;
00074       
00075       fmn=new funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t,
00076       ufunc_t,vec_t,alloc_vec_t,alloc_t>,od_parms>
00077       (this,&comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t,
00078        alloc_vec_t,alloc_t>::odfunc);
00079     }
00080     
00081     virtual ~comp_gen_inte() {
00082       delete fmn;
00083     }
00084     
00085     /** 
00086         \brief Parameters to send to the 1-d integration functions
00087         
00088         For basic usage, the class-user needs this type 
00089         to specify the parameter type for 1-d integration objects.
00090     */
00091     typedef struct {
00092       /// The independent variable vector
00093       alloc_vec_t *cx;
00094       /// The function specifying the lower limits
00095       lfunc_t *lower;
00096       /// The function specifying the upper limits
00097       ufunc_t *upper;
00098       /// The function to be integrated
00099       func_t *func;
00100       /// The number of dimensions
00101       int ndim;
00102       /// The present recursion level
00103       int idim;
00104       /// The user-specified parameter
00105       param_t *vp;
00106     } od_parms;
00107   
00108     /** 
00109         \brief Designate the pointers to the integration routines
00110         
00111         The user can, in principle, specify the one instance of an
00112         \ref inte object for several of the pointers, but this is
00113         discouraged as most inte objects cannot be used this way.
00114         This function will not warn you if some of the pointers
00115         specified in \c ip refer to the same object.
00116 
00117         If more 1-d integration routines than necessary are given,
00118         the extras will be unused.
00119 
00120         \comment
00121         \endcomment
00122     */
00123     int set_ptrs(inte<od_parms,funct<od_parms> > **ip, int n) {
00124       if (n<1) {
00125         set_err_ret
00126           ("Number of dimensions less than 1 in set_ptrs().",gsl_einval);
00127       }
00128       ptrs=ip;
00129       ndim=n;
00130       ptrs_set=true;
00131       return 0;
00132     }
00133 
00134     /** \brief Integrate function \c func from 
00135         \f$ {\ell}_i=f_i(x_i) \f$ to \f$ u_i=g_i(x_i) \f$ for 
00136         \f$ 0<i<\mathrm{n}-1 \f$.
00137     */
00138     virtual double ginteg(func_t &func, size_t n, func_t &lower, 
00139                           func_t &upper, param_t &pa) {
00140       
00141       if (ptrs_set==false || n>ndim || n==0) {
00142         set_err("Pointers not set with proper dimension in ginteg().",
00143                 gsl_einval);
00144         return 0.0;
00145       }
00146       
00147       alloc_vec_t cx;
00148       ao.allocate(cx,n);
00149       
00150       od_parms op={&cx,&lower,&upper,&func,n,0,&pa};
00151       
00152       double res=ptrs[0]->integ(*fmn,lower(0,cx,pa),upper(0,cx,pa),op);
00153       
00154       ao.free(cx);
00155       
00156       return res;
00157     }
00158   
00159     /// Return string denoting type ("comp_gen_inte")
00160     virtual const char *type() { return "comp_gen_inte"; }
00161 
00162 #ifndef DOXYGEN_INTERNAL
00163     
00164     protected:
00165     
00166     /// Memory allocator for objects of type \c alloc_vec_t 
00167     alloc_t ao;
00168     
00169     /// The function to send to the integrators
00170     funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t,
00171     vec_t,alloc_vec_t,alloc_t>,od_parms> *fmn;
00172     
00173     /// The one-dimensional integration function
00174     double odfunc(double x, od_parms &od) {
00175 
00176       double res;
00177 
00178       (*od.cx)[od.idim]=x;
00179       if (od.idim==od.ndim-1) {
00180         (*od.func)(od.ndim,(*od.cx),res,*od.vp);
00181       } else {
00182         od_parms od2={od.cx,od.lower,od.upper,od.func,
00183                       od.ndim,od.idim+1,od.vp};
00184         (*od.func)(od.idim+1,*od.cx,res,*od.vp);
00185         res*=ptrs[od.idim]->integ
00186           (*fmn,(*od.lower)(od.idim+1,*od.cx,*od.vp),
00187            (*od.upper)(od.idim+1,*od.cx,*od.vp),od2);
00188       }
00189       return res;
00190     }
00191   
00192     /// The number of dimensions
00193     size_t ndim;
00194     
00195     /// Pointers to the integration objects
00196     inte<od_parms,funct<od_parms> > **ptrs;
00197 
00198     /// True if the integration objects have been specified
00199     bool ptrs_set;
00200 
00201 #endif
00202 
00203 
00204   };
00205 
00206 #ifndef DOXYGENP
00207 }
00208 #endif
00209 
00210 #endif
00211 

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