/home/coin/SVN-release/CoinAll-1.1.0/cppad/cppad/romberg_mul.hpp

Go to the documentation of this file.
00001 # ifndef CPPAD_ROMBERG_MUL_INCLUDED
00002 # define CPPAD_ROMBERG_MUL_INCLUDED
00003 
00004 /* --------------------------------------------------------------------------
00005 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-06 Bradley M. Bell
00006 
00007 CppAD is distributed under multiple licenses. This distribution is under
00008 the terms of the 
00009                     Common Public License Version 1.0.
00010 
00011 A copy of this license is included in the COPYING file of this distribution.
00012 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00013 -------------------------------------------------------------------------- */
00014 /*
00015 $begin RombergMul$$
00016 $spell
00017         cppad.hpp
00018         bool
00019         const
00020         Cpp
00021         RombergMulMul
00022 $$
00023 
00024 $section Multi-dimensional Romberg Integration$$
00025 
00026 $index integrate, multi-dimensional Romberg$$
00027 $index Romberg, multi-dimensional integrate$$
00028 $index multi, dimensional Romberg integration$$
00029 $index dimension, multi Romberg integration$$
00030 
00031 $head Syntax$$
00032 $code # include <cppad/romberg_mul.hpp>$$
00033 $pre
00034 $$
00035 $syntax%RombergMul<%Fun%, %SizeVector%, %FloatVector%, %m%> %R%$$
00036 $pre
00037 $$
00038 $syntax%%r% = %R%(%F%, %a%, %b%, %n%, %p%, %e%)%$$
00039 
00040 
00041 $head Description$$
00042 Returns the Romberg integration estimate
00043 $latex r$$ for the multi-dimensional integral
00044 $latex \[
00045 r = 
00046 \int_{a[0]}^{b[0]} \cdots \int_{a[m-1]}^{b[m-1]}
00047 \; F(x) \;
00048 {\bf d} x_0 \cdots {\bf d} x_{m-1} 
00049 \; + \; 
00050 \sum_{i=0}^{m-1} 
00051 O \left[ ( b[i] - a[i] ) / 2^{n[i]-1} \right]^{2(p[i]+1)}
00052 \] $$
00053 
00054 $head Include$$
00055 The file $code cppad/romberg_mul.hpp$$ is included by $code cppad/cppad.hpp$$
00056 but it can also be included separately with out the rest of 
00057 the $code CppAD$$ routines.
00058 
00059 $head m$$
00060 The template parameter $italic m$$ must be convertible to a $code size_t$$ 
00061 object with a value that can be determined at compile time; for example
00062 $code 2$$.
00063 It determines the dimension of the domain space for the integration.
00064 
00065 $head r$$
00066 The return value $italic r$$ has prototype
00067 $syntax%
00068         %Float% %r%
00069 %$$ 
00070 It is the estimate computed by $code RombergMul$$ for the integral above
00071 (see description of $xref/RombergMul/Float/Float/$$ below). 
00072 
00073 $head F$$
00074 The object $italic F$$ has the prototype
00075 $syntax%
00076         %Fun% &%F%
00077 %$$
00078 It must support the operation
00079 $syntax%
00080         %F%(%x%)
00081 %$$
00082 The argument $italic x$$ to $italic F$$ has prototype
00083 $syntax%
00084         const %Float% &%x%
00085 %$$
00086 The return value of $italic F$$ is a $italic Float$$ object
00087 
00088 $head a$$
00089 The argument $italic a$$ has prototype
00090 $syntax%
00091         const %FloatVector% &%a%
00092 %$$ 
00093 It specifies the lower limit for the integration
00094 (see description of $xref/RombergMul/FloatVector/FloatVector/$$ below). 
00095 
00096 $head b$$
00097 The argument $italic b$$ has prototype
00098 $syntax%
00099         const %FloatVector% &%b%
00100 %$$ 
00101 It specifies the upper limit for the integration.
00102 
00103 $head n$$
00104 The argument $italic n$$ has prototype
00105 $syntax%
00106         const %SizeVector% &%n%
00107 %$$ 
00108 A total number of $latex 2^{n[i]-1} + 1$$ 
00109 evaluations of $syntax%%F%(%x%)%$$ are used to estimate the integral
00110 with respect to $latex {\bf d} x_i$$.
00111 
00112 $head p$$
00113 The argument $italic p$$ has prototype
00114 $syntax%
00115         const %SizeVector% &%p%
00116 %$$ 
00117 For $latex i = 0 , \ldots , m-1$$,
00118 $latex n[i]$$ determines the accuracy order in the 
00119 approximation for the integral 
00120 that is returned by $code RombergMul$$.
00121 The values in $italic p$$ must be less than or equal $italic n$$; i.e.,
00122 $syntax%%p%[%i%] <= %n%[%i%]%$$.
00123 
00124 $head e$$
00125 The argument $italic e$$ has prototype
00126 $syntax%
00127         %Float% &%e%
00128 %$$ 
00129 The input value of $italic e$$ does not matter
00130 and its output value is an approximation for the absolute error in 
00131 the integral estimate.
00132 
00133 $head Float$$
00134 The type $italic Float$$ is defined as the type of the elements of
00135 $xref/RombergMul/FloatVector/FloatVector/$$.
00136 The type $italic Float$$ must satisfy the conditions
00137 for a $xref/NumericType/$$ type.
00138 The routine $xref/CheckNumericType/$$ will generate an error message
00139 if this is not the case.
00140 In addition, if $italic x$$ and $italic y$$ are $italic Float$$ objects,
00141 $syntax%
00142         %x% < %y%
00143 %$$     
00144 returns the $code bool$$ value true if $italic x$$ is less than 
00145 $italic y$$ and false otherwise.
00146 
00147 $head FloatVector$$
00148 The type $italic FloatVector$$ must be a $xref/SimpleVector/$$ class.
00149 The routine $xref/CheckSimpleVector/$$ will generate an error message
00150 if this is not the case.
00151 
00152 
00153 $children%
00154         example/romberg_mul.cpp
00155 %$$
00156 $head Example$$
00157 $comment%
00158         example/romberg_mul.cpp
00159 %$$
00160 The file
00161 $xref/RombergMul.cpp/$$
00162 contains an example and test a test of using this routine.
00163 It returns true if it succeeds and false otherwise.
00164 
00165 $head Source Code$$
00166 The source code for this routine is in the file
00167 $code cppad/romberg_mul.hpp$$.
00168 
00169 $end
00170 */
00171 
00172 # include <cppad/romberg_one.hpp>
00173 # include <cppad/check_numeric_type.hpp>
00174 # include <cppad/check_simple_vector.hpp>
00175 
00176 namespace CppAD { // BEGIN CppAD namespace
00177 
00178 template <class Fun, class FloatVector>
00179 class SliceLast {
00180         typedef typename FloatVector::value_type Float;
00181 private:
00182         Fun        *F;
00183         size_t      last;
00184         FloatVector x;
00185 public:
00186         SliceLast( Fun *F_, size_t last_, const FloatVector &x_ ) 
00187         : F(F_) , last(last_), x(last + 1)
00188         {       size_t i;
00189                 for(i = 0; i < last; i++)
00190                         x[i] = x_[i];
00191         }
00192         double operator()(const Float &xlast)
00193         {       x[last] = xlast;
00194                 return (*F)(x);
00195         }
00196 };
00197 
00198 template <class Fun, class SizeVector, class FloatVector, class Float>
00199 class IntegrateLast {
00200 private:
00201         Fun                 *F; 
00202         const size_t        last;
00203         const FloatVector   a; 
00204         const FloatVector   b; 
00205         const SizeVector    n; 
00206         const SizeVector    p; 
00207         Float               esum;
00208         size_t              ecount;
00209 
00210 public:
00211         IntegrateLast(
00212                 Fun                *F_    , 
00213                 size_t              last_ ,
00214                 const FloatVector  &a_    , 
00215                 const FloatVector  &b_    , 
00216                 const SizeVector   &n_    , 
00217                 const SizeVector   &p_    ) 
00218         : F(F_) , last(last_), a(a_) , b(b_) , n(n_) , p(p_) 
00219         { }             
00220         Float operator()(const FloatVector           &x)
00221         {       Float r, e;
00222                 SliceLast<Fun, FloatVector           > S(F, last, x);
00223                 r     = CppAD::RombergOne(
00224                         S, a[last], b[last], n[last], p[last], e
00225                 );
00226                 esum = esum + e;
00227                 ecount++;
00228                 return r;
00229         }
00230         void ClearEsum(void)
00231         {       esum   = 0.; }
00232         Float GetEsum(void)
00233         {       return esum; }
00234 
00235         void ClearEcount(void)
00236         {       ecount   = 0; }
00237         size_t GetEcount(void)
00238         {       return ecount; }
00239 };
00240 
00241 template <class Fun, class SizeVector, class FloatVector, size_t m>
00242 class RombergMul {
00243         typedef typename FloatVector::value_type Float;
00244 public:
00245         RombergMul(void)
00246         {       }
00247         Float operator() (
00248                 Fun                 &F  , 
00249                 const FloatVector   &a  ,
00250                 const FloatVector   &b  ,
00251                 const SizeVector    &n  ,
00252                 const SizeVector    &p  ,
00253                 Float               &e  )
00254         {       Float r;
00255 
00256                 typedef IntegrateLast<
00257                         Fun         , 
00258                         SizeVector  , 
00259                         FloatVector , 
00260                         Float       > IntegrateOne;
00261 
00262                 IntegrateOne Fm1(&F, m-1, a, b, n, p);
00263                 RombergMul<
00264                         IntegrateOne, 
00265                         SizeVector  ,
00266                         FloatVector ,
00267                         m-1         > RombergMulM1;
00268 
00269                 Fm1.ClearEsum();
00270                 Fm1.ClearEcount();
00271 
00272                 r  = RombergMulM1(Fm1, a, b, n, p, e);
00273 
00274                 size_t i, j;
00275                 Float prod = 1;
00276                 size_t pow2 = 1;
00277                 for(i = 0; i < m-1; i++)
00278                 {       prod *= (b[i] - a[i]);
00279                         for(j = 0; j < (n[i] - 1); j++)
00280                                 pow2 *= 2;
00281                 }
00282                 assert( Fm1.GetEcount() == (pow2+1) );
00283                 
00284                 e = e + Fm1.GetEsum() * prod / Fm1.GetEcount();
00285 
00286                 return r;
00287         }
00288 };
00289 
00290 template <class Fun, class SizeVector, class FloatVector>
00291 class RombergMul <Fun, SizeVector, FloatVector, 1> {
00292         typedef typename FloatVector::value_type Float;
00293 public:
00294         Float operator() (
00295                 Fun                 &F  , 
00296                 const FloatVector   &a  ,
00297                 const FloatVector   &b  ,
00298                 const SizeVector    &n  ,
00299                 const SizeVector    &p  ,
00300                 Float               &e  )
00301         {       Float r;
00302                 typedef IntegrateLast<
00303                         Fun         , 
00304                         SizeVector  , 
00305                         FloatVector , 
00306                         Float       > IntegrateOne;
00307 
00308                 // check simple vector class specifications
00309                 CheckSimpleVector<Float, FloatVector>();
00310 
00311                 // check numeric type specifications
00312                 CheckNumericType<Float>();
00313 
00314                 IntegrateOne F0(&F, 0, a, b, n, p);
00315 
00316                 F0.ClearEsum();
00317                 F0.ClearEcount();
00318 
00319                 r  = F0(a);
00320 
00321                 assert( F0.GetEcount() == 1 );
00322                 e = F0.GetEsum();
00323 
00324                 return r;
00325         }
00326 };
00327 
00328 } // END CppAD namespace
00329 
00330 # endif

Generated on Sun Nov 14 14:06:33 2010 for Coin-All by  doxygen 1.4.7