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

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.