IT++ Logo Newcom Logo

integration.cpp

Go to the documentation of this file.
00001 
00033 #include <itpp/base/integration.h>
00034 #include <itpp/base/vec.h>
00035 #include <itpp/base/specmat.h>
00036 #include <itpp/base/matfunc.h>
00037 #include <itpp/base/help_functions.h>
00038 
00039 
00040 namespace itpp {
00041 
00042   double quadstep(double (*f)(double), const double a, const double b, const double fa, const double fm, const double fb, const double is)
00043   {
00044     double Q, m, h, fml, fmr, i1, i2;
00045     vec x(2), y(2);
00046 
00047     m = (a+b)/2; h = (b-a)/4;
00048     x = vec_2(a+h, b-h);
00049     y = vec_function(f, x);
00050     fml = y(0); fmr = y(1);
00051 
00052     i1 = h/1.5 * (fa + 4*fm + fb);
00053     i2 = h/3 * (fa + 4*(fml + fmr) + 2*fm + fb);
00054     i1 = (16*i2 - i1)/15;
00055 
00056     if( (is + (i1-i2) == is) || (m<=a) || (b<=m) ) {
00057       if( (m <= a) || (b<=m) ) {
00058         it_warning("Interval contains no more machine number. Required tolerance may not be met");
00059       }
00060       Q = i1;
00061       return Q;
00062     } else {
00063       Q = quadstep(f, a, m, fa, fml, fm, is) + quadstep(f, m, b, fm, fmr, fb, is);
00064     }
00065     return Q;
00066   }
00067 
00068 
00069   double quad(double (*f)(double), const double a, const double b, const double tol)
00070   {
00071     vec x(3), y(3), yy(5);
00072     double Q, fa, fm, fb, is;
00073 
00074     x = vec_3(a, (a+b)/2, b);
00075     y = vec_function(f, x);
00076     fa = y(0); fm = y(1); fb = y(2);
00077     yy = vec_function(f, a + vec(".9501 .2311 .6068 .4860 .8913")*(b-a));
00078     is = (b-a)/8*(sum(y)+sum(yy));
00079 
00080     if (is == 0.0)
00081       is = b-a;
00082 
00083     is = is*tol/std::numeric_limits<double>::epsilon();
00084     Q = quadstep(f, a, b, fa, fm, fb, is);
00085 
00086     return Q;
00087   }
00088 
00089 
00090   //--------------------- quadl() ----------------------------------------
00091 
00092   double quadlstep(double (*f)(double), const double a, const double b, const double fa, const double fb, const double is)
00093   {
00094     double Q, h, m, alpha, beta, mll, ml, mr, mrr, fmll, fml, fm, fmr, fmrr, i1, i2;
00095     vec x(5), y(5);
00096 
00097     h=(b-a)/2; m=(a+b)/2;
00098     alpha=sqrt(2.0/3); beta=1.0/sqrt(5.0);
00099     mll=m-alpha*h; ml=m-beta*h; mr=m+beta*h; mrr=m+alpha*h;
00100     x(0)=mll; x(1) = ml; x(2) = m; x(3) = mr; x(4) = mrr;
00101 
00102     y=vec_function(f, x);
00103     
00104     fmll=y(0); fml=y(1); fm=y(2); fmr=y(3); fmrr=y(4);
00105     
00106     i2 = (h/6)*(fa+fb+5*(fml+fmr));
00107     i1 = (h/1470)*(77*(fa+fb)+432*(fmll+fmrr)+625*(fml+fmr)+672*fm);
00108 
00109     if( (is + (i1-i2) == is) || (mll<=a) || (b<=mrr) ) {
00110       if( (m <= a) || (b<=m) ) {
00111         it_warning("Interval contains no more machine number. Required tolerance may not be met");
00112       }
00113       Q = i1;
00114       return Q;
00115     } else {
00116       Q=quadlstep(f, a, mll, fa, fmll, is) + quadlstep(f, mll, ml, fmll, fml, is) + quadlstep(f, ml, m, fml, fm, is) +
00117       quadlstep(f, m, mr, fm, fmr, is) + quadlstep(f, mr, mrr, fmr, fmrr, is) + quadlstep(f, mrr, b, fmrr, fb, is);
00118     }
00119     return Q;
00120   }
00121 
00122   double quadl(double (*f)(double), const double a, const double b, const double tol)
00123   {
00124     double Q, m, h, alpha, beta, x1, x2, x3, fa, fb, i1, i2, is, s, erri1, erri2, R;
00125     vec x(13), y(13);
00126     double tol2 = tol;
00127 
00128     m=(a+b)/2; h=(b-a)/2;
00129     
00130     alpha=std::sqrt(2.0/3); beta=1/sqrt(5.0);
00131 
00132     x1=.942882415695480; x2=.641853342345781; x3=.236383199662150;
00133     x(0)=a; x(1)=m-x1*h; x(2)=m-alpha*h; x(3)=m-x2*h;
00134     x(4)=m-beta*h; x(5)=m-x3*h; x(6)=m; x(7)=m+x3*h; 
00135     x(8)=m+beta*h; x(9)=m+x2*h; x(10)=m+alpha*h; 
00136     x(11)=m+x1*h; x(12)=b;
00137 
00138     y=vec_function(f, x);
00139 
00140     fa=y(0); fb=y(12);
00141     i2=(h/6)*(y(0)+y(12)+5*(y(4)+y(8)));
00142     i1=(h/1470)*(77*(y(0)+y(12))+432*(y(2)+y(10))+ 625*(y(4)+y(8))+672*y(6));
00143 
00144     is=h*(.0158271919734802*(y(0)+y(12))+.0942738402188500*(y(1)+y(11))+.155071987336585*(y(2)+y(10))+ 
00145           .188821573960182*(y(3)+y(9))+.199773405226859 *(y(4)+y(8))+.224926465333340*(y(5)+y(7))+.242611071901408*y(6));
00146 
00147     s=sign(is);
00148     if (s == 0.0)
00149       s = 1;
00150     
00151     erri1 = std::abs(i1-is);
00152     erri2 = std::abs(i2-is);
00153 
00154     R=1;
00155     if (erri2 != 0.0)
00156       R = erri1/erri2;
00157 
00158     if (R>0 && R<1)
00159       tol2=tol2/R;
00160 
00161     is = s*std::abs(is)*tol2/std::numeric_limits<double>::epsilon();
00162     if (is == 0.0)
00163       is=b-a;
00164 
00165     Q = quadlstep(f, a, b, fa, fb, is);
00166 
00167     return Q;
00168   }
00169 
00170 
00171 } // namespace itpp
SourceForge Logo

Generated on Fri Jun 8 02:08:51 2007 for IT++ by Doxygen 1.5.2