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_SERIES_POWERSERIES_H_
00037 #define _NUMERICS4CPP_SERIES_POWERSERIES_H_
00038
00039 #include <cmath>
00040 #include "../iterativemethod.h"
00041 #include "../exception/exception.h"
00042
00043 NUM_NAMESPACE_BEGIN
00044
00092 template<class Term>
00093 class power_series : public iterative_method {
00094
00095 public:
00103 power_series(Term& t, unsigned int first = 0, unsigned int iterations = 100,
00104 double relative_error = 1.0e-13)
00105 : iterative_method(iterations, relative_error),
00106 _first_index(first), _term(t)
00107 {
00108 }
00109
00113 ~power_series() {
00114 }
00115
00121 double evaluate(double x) {
00122 unsigned int n = _first_index;
00123 double z = std::pow(x, (double)n);
00124 double t = _term(n) * z;
00125 double s = t;
00126 double sn = s;
00127 double error = std::numeric_limits<double>::infinity();
00128
00129 do {
00130 ++n;
00131 z *= x;
00132 sn = s + (_term(n) * z);
00133 error = std::fabs(sn / s - 1.0);
00134 s = sn;
00135 } while (n <= maximum_iterations() && error > maximum_relative_error());
00136
00137 if (n > maximum_iterations()) {
00138 throw convergence_exception("Power series failed to converge.");
00139 }
00140
00141 return s;
00142 }
00143
00144 private:
00146 unsigned int _first_index;
00147
00149 Term& _term;
00150 };
00151
00155 typedef double power_series_term(unsigned int);
00156
00157 NUM_NAMESPACE_END
00158
00159 #endif