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_CONTINUEDFRACTION_CONTINUEDFRACTION_H_
00037 #define _NUMERICS4CPP_CONTINUEDFRACTION_CONTINUEDFRACTION_H_
00038
00039 #include "../iterativemethod.h"
00040 #include "../exception/exception.h"
00041
00042 NUM_NAMESPACE_BEGIN
00043
00101 template<class A, class B>
00102 class continued_fraction : public iterative_method {
00103
00104 public:
00112 continued_fraction(A& coefA, B& coefB, unsigned int iterations = 100, double relative_error = 1.0e-15) : iterative_method(iterations, relative_error), _a(coefA), _b(coefB) {
00113 }
00114
00118 ~continued_fraction() {
00119 }
00120
00127 double evaluate(double x) {
00128 double f = zero_to_tiny(_a(0, x));
00129 double c = f;
00130 double delta;
00131 double d = 0.0;
00132 unsigned int n = 0;
00133
00134 do {
00135 ++n;
00136 double a = _a(n, x);
00137 double b = _b(n, x);
00138 d = zero_to_tiny(a + b * d);
00139 c = zero_to_tiny(a + b / c);
00140 d = 1.0 / d;
00141 delta = c * d;
00142 f = f * delta;
00143 } while (n < maximum_iterations() &&
00144 std::fabs(delta - 1.0) >= maximum_relative_error());
00145
00146 if (n >= maximum_iterations()) {
00147 throw convergence_exception("Continued fraction failed to converge.");
00148 }
00149
00150 return f;
00151 }
00152
00153 private:
00160 double zero_to_tiny(double x) {
00161 return (x == 0.0 ? 1.0e-100 : x);
00162 }
00163
00164 private:
00166 A& _a;
00167
00169 B& _b;
00170 };
00171
00175 typedef double continued_fraction_coefficient(unsigned int, double);
00176
00177 NUM_NAMESPACE_END
00178
00179 #endif