testIntegrator.cc
Go to the documentation of this file.
1 
11 #include <cmath>
12 #include <iostream>
13 #include <utl/Integrator.h>
14 
15 #include <tst/Verify.h>
16 #include <cppunit/extensions/HelperMacros.h>
17 
18 using namespace std;
19 using namespace utl;
20 using namespace tst;
21 
22 
26 class SinFunctor {
27 public:
28  SinFunctor(const double frequency, const double amplitude)
29  : fFrequency(frequency), fAmplitude(amplitude) { }
30 
31  double operator()(const double x) const
32  { return fAmplitude * sin(fFrequency * x); }
33 
34 private:
35  const double fFrequency;
36  const double fAmplitude;
37 };
38 
39 
43 class CountedLog {
44 public:
45  CountedLog() : fCounter(0) { }
46 
47  double operator()(const double x)
48  { ++fCounter; return log(x); }
49 
50  int GetCounter() const { return fCounter; }
51 
52  void Reset() { fCounter = 0; }
53 
54 private:
55  int fCounter;
56 };
57 
58 
62 double
63 MyLog(const double x)
64 {
65  return log(x);
66 }
67 
68 
72 class IntegratorTest : public CppUnit::TestFixture {
73 
74  CPPUNIT_TEST_SUITE(IntegratorTest);
75  CPPUNIT_TEST(testFactory);
76  CPPUNIT_TEST(testRomberg);
77  CPPUNIT_TEST(testTrapezoidal);
78  CPPUNIT_TEST(testSimpson);
79  CPPUNIT_TEST(testCancellation);
80  CPPUNIT_TEST(testZero);
81  CPPUNIT_TEST(testFunction);
82  CPPUNIT_TEST(testSpeed);
83  CPPUNIT_TEST_SUITE_END();
84 
85 public:
86  void setUp() { }
87 
88  void tearDown() { }
89 
90  void
92  {
93  SinFunctor sinf(M_PI, 2);
94  const double res =
95  MakeIntegrator(sinf).GetIntegral(0, 1);
96  CPPUNIT_ASSERT(Verify<CloseTo>(res, 4/M_PI));
97  }
98 
99  void
101  {
102  SinFunctor sinf(M_PI, 2);
103  const double res1 =
104  Integrator<SinFunctor>(sinf, 1e-5).GetRombergIntegral(0, 1);
105  CPPUNIT_ASSERT(Verify<CloseTo>(res1, 4/M_PI, 1e-11));
106  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res1, 4/M_PI, 1e-12));
107  const double res2 =
108  Integrator<SinFunctor>(sinf, 1e-6).GetRombergIntegral(0, 1);
109  CPPUNIT_ASSERT(Verify<CloseTo>(res2, 4/M_PI, 1e-11));
110  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res2, 4/M_PI, 1e-12));
111  const double res3 =
112  Integrator<SinFunctor>(sinf, 1e-5).GetRombergIntegral(1, 2);
113  CPPUNIT_ASSERT(Verify<CloseTo>(res3, -4/M_PI, 1e-11));
114  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res3, -4/M_PI, 1e-12));
115  }
116 
117  void
119  {
120  SinFunctor sinf(M_PI, 2);
121  const double res1 =
122  Integrator<SinFunctor>(sinf, 1e-5).GetTrapezoidalIntegral(0, 1);
123  CPPUNIT_ASSERT(Verify<CloseTo>(res1, 4/M_PI, 1e-5));
124  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res1, 4/M_PI, 1e-6));
125  const double res2 =
126  Integrator<SinFunctor>(sinf, 1e-6).GetTrapezoidalIntegral(0, 1);
127  CPPUNIT_ASSERT(Verify<CloseTo>(res2, 4/M_PI, 1e-6));
128  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res2, 4/M_PI, 1e-7));
129  const double res3 =
130  Integrator<SinFunctor>(sinf, 1e-5).GetTrapezoidalIntegral(1, 2);
131  CPPUNIT_ASSERT(Verify<CloseTo>(res3, -4/M_PI, 1e-5));
132  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res3, -4/M_PI, 1e-6));
133  }
134 
135  void
137  {
138  SinFunctor sinf(M_PI, 2);
139  const double res1 =
140  Integrator<SinFunctor>(sinf, 1e-5).GetSimpsonIntegral(0, 1);
141  CPPUNIT_ASSERT(Verify<CloseTo>(res1, 4/M_PI, 1e-5));
142  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res1, 4/M_PI, 1e-7));
143  const double res2 =
144  Integrator<SinFunctor>(sinf, 1e-6).GetSimpsonIntegral(0, 1);
145  CPPUNIT_ASSERT(Verify<CloseTo>(res2, 4/M_PI, 1e-6));
146  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res2, 4/M_PI, 1e-8));
147  const double res3 =
148  Integrator<SinFunctor>(sinf, 1e-5).GetSimpsonIntegral(1, 2);
149  CPPUNIT_ASSERT(Verify<CloseTo>(res3, -4/M_PI, 1e-5));
150  CPPUNIT_ASSERT(Verify<Not<CloseTo> >(res1, -4/M_PI, 1e-7));
151  }
152 
153  void
155  {
156  SinFunctor sinf(M_PI, 10);
157  const double res1 =
158  MakeIntegrator(sinf).GetIntegral(0, 3);
159  CPPUNIT_ASSERT(Verify<CloseTo>(res1, 20/M_PI));
160  const double res2 =
161  MakeIntegrator(sinf).GetIntegral(1, 4);
162  CPPUNIT_ASSERT(Verify<CloseTo>(res2, -20/M_PI));
163  }
164 
165  void
167  {
168  SinFunctor sinf(M_PI, 1);
169  const double res1 =
170  MakeIntegrator(sinf).GetRombergIntegral(0, 2);
171  CPPUNIT_ASSERT(Verify<CloseTo>(res1, 0.));
172  const double res2 =
173  MakeIntegrator(sinf).GetTrapezoidalIntegral(0, 2);
174  CPPUNIT_ASSERT(Verify<CloseTo>(res2, 0.));
175  const double res3 =
176  MakeIntegrator(sinf).GetSimpsonIntegral(0, 2);
177  CPPUNIT_ASSERT(Verify<CloseTo>(res3, 0.));
178 
179  const double resa =
180  MakeIntegrator(sinf).GetRombergIntegral(1, 3);
181  CPPUNIT_ASSERT(Verify<CloseTo>(resa, 0.));
182  const double resb =
183  MakeIntegrator(sinf).GetTrapezoidalIntegral(1, 3);
184  CPPUNIT_ASSERT(Verify<CloseTo>(resb, 0.));
185  const double resc =
186  MakeIntegrator(sinf).GetSimpsonIntegral(1, 3);
187  CPPUNIT_ASSERT(Verify<CloseTo>(resc, 0.));
188  }
189 
190  void
192  {
193  const double res = MakeIntegrator(MyLog).GetIntegral(1, M_E);
194  CPPUNIT_ASSERT(Verify<CloseTo>(res, 1.));
195  }
196 
197  void
199  {
200  const double eps = 1e-9;
201  CountedLog clog;
202  Integrator<CountedLog> clogint(clog, eps);
203  const double ress = clogint.GetSimpsonIntegral(1, M_E);
204  CPPUNIT_ASSERT(Verify<CloseTo>(ress, 1.));
205  const int ns = clog.GetCounter();
206  clog.Reset();
207  const double rest = clogint.GetTrapezoidalIntegral(1, M_E);
208  CPPUNIT_ASSERT(Verify<CloseTo>(rest, 1.));
209  const int nt = clog.GetCounter();
210  clog.Reset();
211  const double resr = clogint.GetRombergIntegral(1, M_E);
212  CPPUNIT_ASSERT(Verify<CloseTo>(resr, 1.));
213  const int nr = clog.GetCounter();
214  cerr << "\nNumber of function calls:\n"
215  " Romberg " << nr << "\n"
216  " Simpson " << ns << "\n"
217  "Trapezoidal " << nt
218  << endl;
219  }
220 
221 };
222 
223 
225 
226 
227 // Configure (x)emacs for this file ...
228 // Local Variables:
229 // mode: c++
230 // End:
double MyLog(const double x)
int GetCounter() const
Class for integration of functions with one independent parameter.
Definition: Integrator.h:72
double operator()(const double x)
double GetTrapezoidalIntegral(const double a, const double b, const int minLevel=4, const int maxLevel=20) const
basic trapezoidal integration
Definition: Integrator.h:155
CPPUNIT_TEST_SUITE_REGISTRATION(testAiresShowerFile)
double GetSimpsonIntegral(const double a, const double b, const int minLevel=4, const int maxLevel=20) const
Simpson improvement build on top of the trapezoidal integration.
Definition: Integrator.h:124
Definition: Test.h:180
double operator()(const double x) const
const double ns
bool Verify(const Predicate &pred, const T &lhs, const T &rhs)
Test condition by evaluating a predicate and print on failure.
Definition: Verify.h:38
double eps
SinFunctor(const double frequency, const double amplitude)
const double fFrequency
Integrator< Functor > MakeIntegrator(Functor &f)
convenience factory
Definition: Integrator.h:236
double GetRombergIntegral(const double a, const double b, const int order=5, const int maxIterations=20) const
Romberg integration Setting order to 2 is equivalent to the Simpson&#39;s method.
Definition: Integrator.h:89
const double fAmplitude

, generated on Tue Sep 26 2023.