composite_inte.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_COMPOSITE_INTE_H
00024 #define O2SCL_COMPOSITE_INTE_H
00025 
00026 #include <iostream>
00027 #include <o2scl/multi_inte.h>
00028 #include <o2scl/inte.h>
00029 #include <o2scl/funct.h>
00030 
00031 #ifndef DOXYGENP
00032 namespace o2scl {
00033 #endif
00034 
00035   /** 
00036       \brief Naive multi-dimensional integration over a hypercube
00037 
00038       Naively combine several one-dimensional integration objects from
00039       class inte in order to perform a multi-dimensional integration
00040       over a region defined by constant limits. For more general regions
00041       of integration, use children of the class \ref gen_inte.
00042 
00043       The integration routines are specified in the function
00044       set_ptrs().
00045 
00046       The integration routines are called in order of their
00047       specification in the list <tt>inte **ip</tt>. For the example of
00048       a two-dimensional integration <tt>ip[0]</tt> is called first
00049       with limits <tt>a[0]</tt> and <tt>b[0]</tt> and performs the
00050       integral of the integral given by <tt>ip[1]</tt> of the function
00051       from <tt>a[1]</tt> to <tt>b[1]</tt>. In other words, the
00052       integral performed is:
00053       \f[ 
00054       \int_{x_0=a_0}^{x_0=b_0} \int_{x_1=a_1}^{x_1=b_1} ...
00055       \int_{x_{\mathrm{n}-1}=a_{\mathrm{n}-1}}^
00056       {x_{\mathrm{n}-1}=b_{\mathrm{n}-1}} 
00057       f(x_0,x_1,...,x_{\mathrm{n}})
00058       \f]
00059       
00060       No error estimate is performed. Error estimation for multiple
00061       dimension integrals is provided by the Monte Carlo integration
00062       classes (see \ref mcarlo_inte).
00063 
00064       \todo Convert to using std::vector<inte> for the 1-d integration 
00065       pointers
00066   */
00067   template<class param_t, class func_t, class vec_t,
00068     class alloc_vec_t, class alloc_t> class composite_inte : 
00069   public multi_inte<param_t,func_t,vec_t> {
00070     
00071   public:
00072     
00073     /** 
00074         \brief Parameters to send to the 1-d integration functions
00075 
00076         This structure is not intended to be frequently used 
00077         directly by the class-user, but must be public so 
00078         that the 1-d integration objects can be specified.
00079      */
00080     typedef struct {
00081       /// The user-specified upper limits
00082       const vec_t *ax;
00083       /// The user-specified lower limits
00084       const vec_t *bx;
00085       /// The independent variable vector
00086       alloc_vec_t *cx;
00087       /// The user-specified function
00088       func_t *mf;
00089       /// The user-specified number of dimensions
00090       int ndim;
00091       /// The present recursion level
00092       int idim;
00093       /// The user-specified parameter
00094       param_t *vp;
00095     } od_parms;
00096       
00097     composite_inte() {
00098       ptrs_set=false;
00099       ndim=0;
00100       fmn=new funct_mfptr_noerr<composite_inte<param_t,func_t,
00101         vec_t,alloc_vec_t,alloc_t>,od_parms>
00102         (this,&composite_inte<param_t,func_t,vec_t,
00103          alloc_vec_t,alloc_t>::odfunc);
00104     }
00105     
00106     virtual ~composite_inte() {
00107       delete fmn;
00108     }
00109     
00110     /** 
00111         \brief Designate the pointers to the integration routines
00112         
00113         This function allows duplicate objects in this list in order
00114         to allow the user to use only one object for more than one of
00115         the integrations.
00116         
00117         If more 1-d integration routines than necessary are given,
00118         the extras will be unused.
00119     */
00120     int set_ptrs(inte<od_parms,funct<od_parms> > **ip, int n) {
00121       if (n<1) {
00122         set_err_ret("Number of dimensions less than 1 in set_ptrs().",
00123                     gsl_einval);
00124       }
00125       iptrs=ip;
00126       ndim=n;
00127       ptrs_set=true;
00128       return 0;
00129     }
00130       
00131     /* \brief Integrate function \c func over the hypercube from 
00132         \f$ x_i=a_i \f$ to \f$ x_i=b_i \f$ for 
00133         \f$ 0<i< \f$ ndim-1  
00134 
00135         The function set_ptrs() must be used first to set the 
00136         one-dimensional routines to use.
00137     */
00138     virtual double minteg(func_t &func, size_t n, const vec_t &a, 
00139                           const vec_t &b, param_t &pa) 
00140     {
00141       if (ptrs_set==false || n>ndim) {
00142         set_err("Too few objects specified with set_ptrs() in minteg().",
00143                 gsl_einval);
00144         return 0.0;
00145       }
00146 
00147       alloc_vec_t cx;
00148       ao.allocate(cx,n);
00149 
00150       od_parms op={&a,&b,&cx,&func,n,0,&pa};
00151         
00152       double res=iptrs[0]->integ(*fmn,a[0],b[0],op);
00153         
00154       ao.free(cx);
00155 
00156       return res;
00157 
00158     }
00159     
00160     /// Return string denoting type ("composite_inte")
00161     virtual const char *type() { return "composite_inte"; }
00162 
00163   protected:
00164 
00165 #ifndef DOXYGEN_INTERNAL
00166 
00167     /// Memory allocator for objects of type \c alloc_vec_t
00168     alloc_t ao;
00169 
00170     /// The one-dimensional integration function
00171     double odfunc(double x, od_parms &od) {
00172 
00173       double res;
00174         
00175       (*od.cx)[od.idim]=x;
00176       if (od.idim==od.ndim-1) {
00177         (*od.mf)(od.ndim,(*od.cx),res,*od.vp);
00178       } else {
00179         od_parms op2={od.ax,od.bx,od.cx,od.mf,od.ndim,od.idim+1,od.vp};
00180         res=iptrs[od.idim]->integ(*fmn,(*od.ax)[od.idim+1],
00181                                   (*od.bx)[od.idim+1],op2);
00182       }
00183       return res;
00184     }
00185     
00186     /// This function to send to the integrators
00187     funct_mfptr_noerr<composite_inte<param_t,func_t,vec_t,
00188       alloc_vec_t,alloc_t>,od_parms> *fmn;
00189 
00190     /// The number of dimensions
00191     size_t ndim;
00192 
00193     /// Pointers to the integration objects
00194     inte<od_parms,funct<od_parms> > **iptrs;
00195 
00196     /// True if the integration objects have been specified
00197     bool ptrs_set;
00198 
00199 #endif
00200 
00201   };
00202 
00203 #ifndef DOXYGENP
00204 }
00205 #endif
00206 
00207 #endif
00208 

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