test/test_romberg.cpp

Go to the documentation of this file.
00001 //
00002 // C++ Implementation: test_romberg
00003 //
00004 // Description: unit tests for romberg integration
00005 //
00006 //
00007 // Author: Roman Geus <geus@maxwell>, (C) 2004
00008 //
00009 // Copyright: See COPYING file that comes with this distribution
00010 //
00011 //
00012 
00013 #include <math.h>
00014 #include <tut.h>
00015 #include "romberg.h"
00016 
00017 static double zero(double x) {
00018     return 0.0;
00019 }
00020 
00021 static double one(double x) {
00022     return 1.0;
00023 }
00024 
00025 static double ramp(double x) {
00026     return x;
00027 }
00028 
00029 static double sawtooth(double x) {
00030     return x-floor(x);
00031 }
00032 
00033 static double recip(double x) {
00034     return 1.0/x;
00035 }
00036 
00037 namespace
00038 {
00039     // Example used in Gander Gautschi paper
00040     struct gg_example {
00041         gg_example() : num_eval(0)
00042         {
00043         }
00044         double operator()(double x) {
00045             num_eval ++;
00046             if (x < 1.0)
00047                 return x + 1.0;
00048             else if (x < 3.0)
00049                 return 3.0 - x;
00050             else
00051                 return 2.0;
00052         }
00053         int num_eval;
00054     };
00055 
00056     struct romberg_data
00057     {
00058         romberg_data()
00059             : pi(::acos(-1.0)),
00060               tol(1e-8)
00061         {
00062         }
00063         const double pi;
00064         const double tol;
00065     };
00066 
00067     typedef tut::test_group<romberg_data> testgroup;
00068     typedef testgroup::object testobject;
00069     testgroup romberg_group("romberg");
00070 
00071     template<>
00072     template<>
00073     void testobject::test<1>()
00074     {
00075         int info;
00076         double I = NR::qromb(zero, 0.0, 1.0, 1e-12, info);
00077         ensure(I == 0.0);
00078     }
00079 
00080     template<>
00081     template<>
00082     void testobject::test<2>()
00083     {
00084         int info;
00085         double I = NR::qromb(one, 0.0, 1.0, 1e-12, info);
00086         ensure(I == 1.0);
00087     }
00088 
00089     template<>
00090     template<>
00091     void testobject::test<3>()
00092     {
00093         int info;
00094         double I = NR::qromb(ramp, 0.0, 1.0, 1e-12, info);
00095         ensure(I == 0.5);
00096     }
00097 
00098     template<>
00099     template<>
00100     void testobject::test<4>()
00101     {
00102         int info;
00103         double I = NR::qromb(::sin, 0.0, pi, 1e-12, info);
00104         ensure(fabs(I - 2.0) <= tol);
00105     }
00106 
00107     template<>
00108     template<>
00109     void testobject::test<5>()
00110     {
00111         int info;
00112         double I = NR::qromb(::sin, 0.0, 2.0*pi, 1e-12, info);
00113         ensure(fabs(I) <= tol);
00114     }
00115 
00116     template<>
00117     template<>
00118     void testobject::test<6>()
00119     {
00120         // discontinous function
00121         int info;
00122         double I = NR::qromb(sawtooth, 0.0, 3.0, 1e-12, info);
00123         rDebug("I - 1.5 = %e", I - 1.5);
00124         ensure(fabs(I - 1.5) <= tol);
00125     }
00126 
00127     template<>
00128     template<>
00129     void testobject::test<7>()
00130     {
00131         // function with very big derivative
00132         int info;
00133         const double left = 1e-5;
00134         const double right = 1.0;
00135         double I = NR::qromb(recip, left, right, 1e-12, info);
00136         double expected = ::log(right) - ::log(left);
00137         rDebug("I - %e = %e", expected, I - expected);
00138         ensure(fabs(I - expected) <= tol);
00139     }
00140 
00141     template<>
00142     template<>
00143     void testobject::test<8>()
00144     {
00145         int info;
00146         gg_example f;
00147         double I = NR::qromb(f, 0.0, 5.0, 1e-12, info);
00148         double expected = 7.5;
00149         rDebug("I - %e = %e, num_eval=%d", expected, I - expected, f.num_eval);
00150         ensure(fabs((I - expected)/expected) <= 1e-5);
00151     }
00152 
00154     template<>
00155     template<>
00156     void testobject::test<9>()
00157     {
00158         int info;
00159         double I = NR::qromb(sin, pi, 0.0, 1e-12, info);
00160         ensure(fabs(I + 2.0) <= tol);
00161     }
00162 
00163 };

Generated on Fri Oct 26 13:35:13 2007 for FEMAXX (Finite Element Maxwell Eigensolver) by  doxygen 1.4.7