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_ROOT_BRACKET_H_
00037 #define _NUMERICS4CPP_ROOT_BRACKET_H_
00038
00039 #include <algorithm>
00040 #include <cmath>
00041 #include "../exception/exception.h"
00042
00043 NUM_NAMESPACE_BEGIN
00044
00049 template<class Function>
00050 class bracket {
00051
00052 public:
00058 bracket(Function& f, unsigned int iterations = 100) : _function(f) {
00059 maximum_iterations(iterations);
00060 }
00061
00066 int maximum_iterations() const {
00067 return _maximum_iterations;
00068 }
00069
00074 void maximum_iterations(unsigned int iterations) {
00075 if (iterations == 0) {
00076 throw invalid_argument_exception("Maximum iterations must be positive.");
00077 }
00078 _maximum_iterations = iterations;
00079 }
00080
00095 void bracket_out(double lower, double initial, double upper) {
00096 if (lower > initial) {
00097 throw invalid_argument_exception("Lower bound must be less than initial value.");
00098 }
00099
00100 if (initial > upper) {
00101 throw invalid_argument_exception("Upper bound must be greater than initial value.");
00102 }
00103
00104 if (is_nan(lower) || is_nan(initial) || is_nan(upper)) {
00105 _lower_bound = _upper_bound = std::numeric_limits<double>::quiet_NaN();
00106 } else {
00107 double a = initial;
00108 double b = a;
00109 double fa;
00110 double fb;
00111 int n = 0;
00112 double factor = std::fabs(a * .10);
00113 double change = 0.0;
00114
00115 _lower_bound = lower;
00116 _upper_bound = upper;
00117
00118 do {
00119 n += 1;
00120 change += factor;
00121 a = std::max(a - change, lower);
00122 b = std::min(b + change, upper);
00123 fa = _function(a);
00124 fb = _function(b);
00125 } while ((fa * fb > 0.0) && (n < maximum_iterations()));
00126
00127 if (n >= maximum_iterations()) {
00128 throw convergence_exception("Continued fraction failed to converge.");
00129 }
00130
00131 _lower_bound = a;
00132 _upper_bound = b;
00133 }
00134 }
00135
00141 double upper_bound() const {
00142 return _upper_bound;
00143 }
00144
00150 double lower_bound() const {
00151 return _lower_bound;
00152 }
00153
00154 private:
00156 Function& _function;
00157
00159 unsigned int _maximum_iterations;
00160
00162 double _lower_bound;
00163
00165 double _upper_bound;
00166 };
00167
00168 NUM_NAMESPACE_END
00169
00170 #endif