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
,
O2scl Sourceforge Project Page