Object-oriented Scientific Computing Library: Version 0.910
composite_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_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 #include <o2scl/multi_funct.h>
00031 
00032 #ifndef DOXYGENP
00033 namespace o2scl {
00034 #endif
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 1-dimensional integration routines are specified in the function
00044       set_oned_inte().
00045 
00046       The integration routines are called in order of the index
00047       specified in the function set_oned_inte(). For
00048       <tt>n-</tt>dimensional integration, <tt>n</tt> one-dimensional
00049       integration objects should be specified, with indexes <tt>0</tt>
00050       through <tt>n-1</tt>. The integration routines are called in
00051       order of their index, so that the outermost integration is done
00052       by the routine specified with index 0.
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       \future Create a function to set an entire array of
00065       one-dimensional integration objects at once
00066   */
00067   template<class func_t=multi_funct<>, 
00068     class vec_t=ovector_base, class alloc_vec_t=ovector, 
00069     class alloc_t=ovector_alloc> class composite_inte : 
00070   public multi_inte<func_t,vec_t> {
00071     
00072 #ifndef DOXYGEN_INTERNAL
00073 
00074   protected:
00075     
00076   /// The user-specified upper limits
00077   const vec_t *ax;
00078   /// The user-specified lower limits
00079   const vec_t *bx;
00080   /// The independent variable vector
00081   alloc_vec_t *cx;
00082   /// The user-specified function
00083   func_t *mf;
00084   /// The user-specified number of dimensions
00085   size_t ndim;
00086   
00087 #endif
00088 
00089   public:
00090 
00091   composite_inte() {
00092     nint=0;
00093     max_dim=100;
00094   }
00095     
00096   virtual ~composite_inte() {
00097     if (nint>0) {
00098       delete[] iptrs;
00099       delete[] tptrs;
00100     }
00101   }
00102 
00103   /** \brief Set the one-dimensional integration object with 
00104       index \c i.
00105   */
00106   int set_oned_inte(inte<funct> &it, size_t i) {
00107 
00108     if (i>=max_dim) {
00109       O2SCL_ERR_RET("Index >= max_dim in composite_inte::set_oned_inte().",
00110                   gsl_einval);
00111     }
00112 
00113     if (nint==0) {
00114 
00115       // Create new space
00116       nint=i+1;
00117       iptrs=new inte<funct> *[nint];
00118       tptrs=new bool[nint];
00119 
00120     } else if (i>nint-1) {
00121         
00122       // Create new space and copy old info over
00123       size_t nint_new=i+1;
00124 
00125       inte<funct> **iptrs_new=new inte<funct> *[nint_new];
00126       bool *tptrs_new=new bool[nint_new];
00127 
00128       for(size_t j=0;j<nint;j++) {
00129         iptrs_new[j]=iptrs[j];
00130         tptrs_new[j]=tptrs[j];
00131       }
00132 
00133       delete[] iptrs;
00134       delete[] tptrs;
00135 
00136       iptrs=iptrs_new;
00137       tptrs=tptrs_new;
00138       nint=nint_new;
00139 
00140     }
00141 
00142     iptrs[i]=&it;
00143     tptrs[i]=true;
00144 
00145     return gsl_success;
00146   }
00147 
00148   /** \brief Integrate function \c func over the hypercube from 
00149       \f$ x_i=a_i \f$ to \f$ x_i=b_i \f$ for 
00150       \f$ 0<i< \f$ ndim-1  
00151       
00152       The function set_oned_inte() must be used first to set the 
00153       one-dimensional routines to use.
00154   */
00155   virtual int minteg_err(func_t &func, size_t n, const vec_t &a, 
00156                          const vec_t &b, double &res, double &err) {
00157     err=0.0;
00158 
00159     // Test to make sure the 1-d integrators were set
00160     bool enough_oned=true;
00161     if (n>nint) enough_oned=false;
00162     for(size_t i=0;i<n;i++) {
00163       if (tptrs[i]==false) enough_oned=false;
00164     }
00165       
00166     if (enough_oned==false) {
00167       O2SCL_ERR_RET("Too few objects specified with set_ptrs() in minteg().",
00168                     gsl_einval);
00169     }
00170 
00171     // Perform integration
00172     alloc_vec_t c;
00173     ao.allocate(c,n);
00174 
00175     ax=&a;
00176     bx=&b;
00177     cx=&c;
00178     mf=&func;
00179     ndim=n;
00180     size_t ix=0;
00181         
00182     funct_mfptr_param<composite_inte<func_t,vec_t,
00183     alloc_vec_t,alloc_t>,size_t> 
00184     fmn(this,&composite_inte<func_t,vec_t,alloc_vec_t,alloc_t>::odfunc,
00185         ix);
00186     
00187     res=iptrs[0]->integ(fmn,a[0],b[0]);
00188     
00189     ao.free(c);
00190     
00191     return gsl_success;
00192     
00193   }
00194     
00195   /// Return string denoting type ("composite_inte")
00196   virtual const char *type() { return "composite_inte"; }
00197 
00198   /// The maxiumum number of integration dimensions (default 100)
00199   size_t max_dim;
00200 
00201   protected:
00202 
00203 #ifndef DOXYGEN_INTERNAL
00204 
00205   /// Memory allocator for objects of type \c alloc_vec_t
00206   alloc_t ao;
00207 
00208   /// The one-dimensional integration function
00209   double odfunc(double x, size_t &ix) {
00210 
00211     double res;
00212         
00213     (*cx)[ix]=x;
00214     if (ix==ndim-1) {
00215       res=(*mf)(ndim,(*cx));
00216     } else {
00217       size_t ix_next=ix+1;
00218 
00219       /// This function to send to the integrators
00220       funct_mfptr_param<composite_inte<func_t,vec_t,
00221         alloc_vec_t,alloc_t>,size_t> 
00222         fmn(this,&composite_inte<func_t,vec_t,alloc_vec_t,alloc_t>::odfunc,
00223             ix_next);
00224 
00225       res=iptrs[ix]->integ(fmn,(*ax)[ix+1],(*bx)[ix+1]);
00226     }
00227     return res;
00228   }
00229     
00230   /// The size of the integration object arrays
00231   size_t nint;
00232 
00233   /// Pointers to the integration objects
00234   inte<funct> **iptrs;
00235 
00236   /// Flag indicating if integration object has been set
00237   bool *tptrs;
00238 
00239 #endif
00240 
00241   };
00242 
00243 #ifndef DOXYGENP
00244 }
00245 #endif
00246 
00247 #endif
00248 
 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.