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_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 template<class param_t, class func_t, class vec_t, 00065 class alloc_vec_t, class alloc_t> class composite_inte : 00066 public multi_inte<param_t,func_t,vec_t> { 00067 00068 public: 00069 00070 /** 00071 \brief Parameters to send to the 1-d integration functions 00072 00073 This structure is not intended to be frequently used 00074 directly by the class-user, but must be public so 00075 that the 1-d integration objects can be specified. 00076 */ 00077 typedef struct { 00078 /// The user-specified upper limits 00079 const vec_t *ax; 00080 /// The user-specified lower limits 00081 const vec_t *bx; 00082 /// The independent variable vector 00083 alloc_vec_t *cx; 00084 /// The user-specified function 00085 func_t *mf; 00086 /// The user-specified number of dimensions 00087 int ndim; 00088 /// The present recursion level 00089 int idim; 00090 /// The user-specified parameter 00091 param_t *vp; 00092 } od_parms; 00093 00094 composite_inte() { 00095 ptrs_set=false; 00096 ndim=0; 00097 fmn=new funct_mfptr_noerr<composite_inte<param_t,func_t, 00098 vec_t,alloc_vec_t,alloc_t>,od_parms> 00099 (this,&composite_inte<param_t,func_t,vec_t, 00100 alloc_vec_t,alloc_t>::odfunc); 00101 } 00102 00103 virtual ~composite_inte() { 00104 delete fmn; 00105 } 00106 00107 /** 00108 \brief Designate the pointers to the integration routines 00109 00110 This function allows duplicate objects in this list in order 00111 to allow the user to use only one object for more than one of 00112 the integrations. 00113 00114 If more 1-d integration routines than necessary are given, 00115 the extras will be unused. 00116 */ 00117 int set_ptrs(inte<od_parms,funct<od_parms> > **ip, int n) { 00118 if (n<1) { 00119 set_err_ret("Number of dimensions less than 1 in set_ptrs().", 00120 gsl_einval); 00121 } 00122 iptrs=ip; 00123 ndim=n; 00124 ptrs_set=true; 00125 return 0; 00126 } 00127 00128 /* \brief Integrate function \c func over the hypercube from 00129 \f$ x_i=a_i \f$ to \f$ x_i=b_i \f$ for 00130 \f$ 0<i< \f$ ndim-1 00131 00132 The function set_ptrs() must be used first to set the 00133 one-dimensional routines to use. 00134 */ 00135 virtual double minteg(func_t &func, size_t n, const vec_t &a, 00136 const vec_t &b, param_t &pa) 00137 { 00138 if (ptrs_set==false || n>ndim) { 00139 set_err("Too few objects specified with set_ptrs() in minteg().", 00140 gsl_einval); 00141 return 0.0; 00142 } 00143 00144 alloc_vec_t cx; 00145 ao.allocate(cx,n); 00146 00147 od_parms op={&a,&b,&cx,&func,n,0,&pa}; 00148 00149 double res=iptrs[0]->integ(*fmn,a[0],b[0],op); 00150 00151 ao.free(cx); 00152 00153 return res; 00154 00155 } 00156 00157 /// Return string denoting type ("composite_inte") 00158 virtual const char *type() { return "composite_inte"; } 00159 00160 protected: 00161 00162 #ifndef DOXYGEN_INTERNAL 00163 00164 /// Memory allocator for objects of type \c alloc_vec_t 00165 alloc_t ao; 00166 00167 /// The one-dimensional integration function 00168 double odfunc(double x, od_parms &od) { 00169 00170 double res; 00171 00172 (*od.cx)[od.idim]=x; 00173 if (od.idim==od.ndim-1) { 00174 (*od.mf)(od.ndim,(*od.cx),res,*od.vp); 00175 } else { 00176 od_parms op2={od.ax,od.bx,od.cx,od.mf,od.ndim,od.idim+1,od.vp}; 00177 res=iptrs[od.idim]->integ(*fmn,(*od.ax)[od.idim+1], 00178 (*od.bx)[od.idim+1],op2); 00179 } 00180 return res; 00181 } 00182 00183 /// This function to send to the integrators 00184 funct_mfptr_noerr<composite_inte<param_t,func_t,vec_t, 00185 alloc_vec_t,alloc_t>,od_parms> *fmn; 00186 00187 /// The number of dimensions 00188 size_t ndim; 00189 00190 /// Pointers to the integration objects 00191 inte<od_parms,funct<od_parms> > **iptrs; 00192 00193 /// True if the integration objects have been specified 00194 bool ptrs_set; 00195 00196 #endif 00197 00198 }; 00199 00200 #ifndef DOXYGENP 00201 } 00202 #endif 00203 00204 #endif 00205
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