00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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 };