00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef _NUMERICS4CPP_INTEGRATION_SIMPSONS_H_
00037 #define _NUMERICS4CPP_INTEGRATION_SIMPSONS_H_
00038
00039 #include "trapezoid.h"
00040
00041 NUM_NAMESPACE_BEGIN
00042
00088 template<class Function>
00089 class simpsons_integrator : public iterative_method {
00090
00091 public:
00098 simpsons_integrator(Function& f, unsigned int iterations = 100,
00099 double relative_error = 1.0e-13)
00100 : iterative_method(iterations, relative_error), _function(f)
00101 {
00102 }
00103
00107 ~simpsons_integrator() {
00108 }
00109
00116 double integrate(double a, double b) {
00117 trapezoidal_integrator_state<Function> state(_function, a, b);
00118
00119 double sumTrapezoidal = state.result();
00120 double sumTrapezoidalNext = sumTrapezoidal;
00121 double error = std::numeric_limits<double>::max();
00122 double sumSimpons = sumTrapezoidal;
00123 do {
00124 state.iterate();
00125 sumTrapezoidalNext = state.result();
00126 double sumSimponsNext = (4.0 * sumTrapezoidalNext / 3.0) -
00127 (sumTrapezoidal / 3.0);
00128 error = std::fabs(sumSimponsNext / sumSimpons - 1.0);
00129 sumTrapezoidal = sumTrapezoidalNext;
00130 sumSimpons = sumSimponsNext;
00131 } while (state.iterations() < maximum_iterations() &&
00132 error > maximum_relative_error());
00133
00134 if (state.iterations() >= maximum_iterations()) {
00135 throw convergence_exception(
00136 "Simpson's integration failed to converge.");
00137 }
00138
00139 return sumSimpons;
00140 }
00141
00142 private:
00144 Function& _function;
00145 };
00146
00147 NUM_NAMESPACE_END
00148
00149 #endif