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