00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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 the index 00045 specified in the function set_oned_inte(). For 00046 <tt>n-</tt>dimensional integration, <tt>n</tt> one-dimensional 00047 integration objects should be specified, with indexes <tt>0</tt> 00048 through <tt>n-1</tt>. The integration routines are called in 00049 order of their index, so that the outermost integration is done 00050 by the routine specified with index 0. The integral 00051 performed is: 00052 \f[ 00053 \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)} 00054 f(x_0, x_1) ... 00055 \int_{x_{\mathrm{n}-1}=a_{\mathrm{n}-1}(x_0,x_1,..,x_{\mathrm{n}-2})}^ 00056 {x_{\mathrm{n}-1}=b_{\mathrm{n}-1}(x_0,x_1,..,x_{\mathrm{n}-2})} 00057 f(x_0,x_1,...,x_{\mathrm{n-1}})~d x_{\mathrm{n}-1}~...~d x_1~d x_0 00058 \f] 00059 00060 This class is particularly useful if \f$ f_0 \f$ is time-consuming 00061 to evaluate, and separable from \f$ f_{n-1} \f$ . 00062 00063 See the discussion about the functions \c func, \c lower and \c 00064 upper in the documentation for the class gen_inte. 00065 00066 No error estimate is performed. Error estimation for multiple 00067 dimension integrals is provided by the Monte Carlo integration 00068 classes (see \ref mcarlo_inte). 00069 00070 \future Provide an example of usage for this class. 00071 */ 00072 template<class param_t, class func_t, class lfunc_t=func_t, 00073 class ufunc_t=func_t, class vec_t=ovector_base, 00074 class alloc_vec_t=ovector, class alloc_t=ovector_alloc> 00075 class comp_gen_inte : 00076 public gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t> { 00077 00078 #ifndef DOXYGEN_INTERNAL 00079 00080 protected: 00081 00082 /// The independent variable vector 00083 alloc_vec_t *cx; 00084 /// The function specifying the lower limits 00085 lfunc_t *lowerp; 00086 /// The function specifying the upper limits 00087 ufunc_t *upperp; 00088 /// The function to be integrated 00089 func_t *mf; 00090 /// The number of dimensions 00091 size_t ndim; 00092 /// The user-specified parameter 00093 param_t *vp; 00094 00095 #endif 00096 00097 public: 00098 00099 comp_gen_inte() { 00100 00101 fmn=new funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t, 00102 ufunc_t,vec_t,alloc_vec_t,alloc_t>,size_t> 00103 (this,&comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t,vec_t, 00104 alloc_vec_t,alloc_t>::odfunc); 00105 nint=0; 00106 max_dim=100; 00107 } 00108 00109 virtual ~comp_gen_inte() { 00110 delete fmn; 00111 } 00112 00113 /** \brief Set the one-dimensional integration object with 00114 index \c i. 00115 */ 00116 int set_oned_inte(inte<size_t> &it, size_t i) { 00117 00118 if (i>=max_dim) { 00119 O2SCL_ERR_RET("Index >= max_dim in composite_inte::set_oned_inte().", 00120 gsl_einval); 00121 } 00122 00123 if (nint==0) { 00124 00125 // Create new space 00126 nint=i+1; 00127 iptrs=new inte<size_t> *[nint]; 00128 tptrs=new bool[nint]; 00129 00130 } else if (i>nint-1) { 00131 00132 // Create new space and copy old info over 00133 size_t nint_new=i+1; 00134 00135 inte<size_t> **iptrs_new= 00136 new inte<size_t> *[nint_new]; 00137 bool *tptrs_new=new bool[nint_new]; 00138 00139 for(size_t j=0;j<nint;j++) { 00140 iptrs_new[j]=iptrs[j]; 00141 tptrs_new[j]=tptrs[j]; 00142 } 00143 00144 delete[] iptrs; 00145 delete[] tptrs; 00146 00147 iptrs=iptrs_new; 00148 tptrs=tptrs_new; 00149 nint=nint_new; 00150 00151 } 00152 00153 iptrs[i]=⁢ 00154 tptrs[i]=true; 00155 00156 return gsl_success; 00157 } 00158 00159 /** \brief Integrate function \c func from 00160 \f$ {\ell}_i=f_i(x_i) \f$ to \f$ u_i=g_i(x_i) \f$ for 00161 \f$ 0<i<\mathrm{n}-1 \f$. 00162 */ 00163 virtual double ginteg(func_t &func, size_t n, func_t &lower, 00164 func_t &upper, param_t &pa) { 00165 00166 // Test to make sure the 1-d integrators were set 00167 bool enough_oned=true; 00168 if (n>nint) enough_oned=false; 00169 for(size_t i=0;i<n;i++) { 00170 if (tptrs[i]==false) enough_oned=false; 00171 } 00172 00173 if (enough_oned==false) { 00174 O2SCL_ERR("Too few objects specified with set_ptrs() in minteg().", 00175 gsl_einval); 00176 return 0.0; 00177 } 00178 00179 // Perform integration 00180 alloc_vec_t c; 00181 ao.allocate(c,n); 00182 00183 cx=&c; 00184 lowerp=&lower; 00185 upperp=&upper; 00186 mf=&func; 00187 vp=&pa; 00188 ndim=n; 00189 size_t ix=0; 00190 00191 double res=iptrs[0]->integ(*fmn,lower(0,c,pa),upper(0,c,pa),ix); 00192 00193 ao.free(c); 00194 00195 return res; 00196 } 00197 00198 /// Return string denoting type ("comp_gen_inte") 00199 virtual const char *type() { return "comp_gen_inte"; } 00200 00201 /// The maxiumum number of integration dimensions (default 100) 00202 size_t max_dim; 00203 00204 #ifndef DOXYGEN_INTERNAL 00205 00206 protected: 00207 00208 /// Memory allocator for objects of type \c alloc_vec_t 00209 alloc_t ao; 00210 00211 /// The function to send to the integrators 00212 funct_mfptr_noerr<comp_gen_inte<param_t,func_t,lfunc_t,ufunc_t, 00213 vec_t,alloc_vec_t,alloc_t>,size_t> *fmn; 00214 00215 /// The one-dimensional integration function 00216 double odfunc(double x, size_t &ix) { 00217 00218 double res; 00219 00220 (*cx)[ix]=x; 00221 if (ix==ndim-1) { 00222 (*mf)(ndim,(*cx),res,*vp); 00223 } else { 00224 size_t ix_next=ix+1; 00225 (*mf)(ix_next,*cx,res,*vp); 00226 res*=iptrs[ix]->integ(*fmn,(*lowerp)(ix_next,*cx,*vp), 00227 (*upperp)(ix_next,*cx,*vp),ix_next); 00228 } 00229 return res; 00230 } 00231 00232 /// The size of the integration object arrays 00233 size_t nint; 00234 00235 /// Pointers to the integration objects 00236 inte<size_t,funct<size_t> > **iptrs; 00237 00238 /// Flag indicating if integration object has been set 00239 bool *tptrs; 00240 00241 #endif 00242 00243 00244 }; 00245 00246 #ifndef DOXYGENP 00247 } 00248 #endif 00249 00250 #endif 00251
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