00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "FunctionR1toR1.h"
00014 #include <math.h>
00015
00016 using namespace std;
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 double FunctionR1toR1::Brent_fmin(double ax, double bx,
00082 double tol)
00083 {
00084
00085 const double c = (3. - sqrt(5.)) * .5;
00086
00087
00088 double a, b, d, e, p, q, r, u, v, w, x;
00089 double t2, fu, fv, fw, fx, xm, eps, tol1, tol3;
00090 int maxIters = 100000;
00091
00092
00093 eps = 1e-50;
00094 tol1 = eps + 1.;
00095 eps = sqrt(eps);
00096
00097 a = ax;
00098 b = bx;
00099 v = a + c * (b - a);
00100 w = v;
00101 x = v;
00102
00103 d = 0.;
00104 e = 0.;
00105 fx = function(x);
00106 fv = fx;
00107 fw = fx;
00108 tol3 = tol / 3.;
00109
00110
00111 int iter = 0;
00112 for(;;) {
00113 iter++;
00114 xm = (a + b) * .5;
00115 tol1 = eps * fabs(x) + tol3;
00116 t2 = tol1 * 2.;
00117
00118
00119
00120 if (fabs(x - xm) <= t2 - (b - a) * .5 || iter > maxIters) break;
00121 p = 0.;
00122 q = 0.;
00123 r = 0.;
00124 if (fabs(e) > tol1) {
00125
00126 r = (x - w) * (fx - fv);
00127 q = (x - v) * (fx - fw);
00128 p = (x - v) * q - (x - w) * r;
00129 q = (q - r) * 2.;
00130 if (q > 0.) p = -p; else q = -q;
00131 r = e;
00132 e = d;
00133 }
00134
00135 if (fabs(p) >= fabs(q * .5 * r) ||
00136 p <= q * (a - x) || p >= q * (b - x)) {
00137
00138 if (x < xm) e = b - x; else e = a - x;
00139 d = c * e;
00140 }
00141 else {
00142
00143 d = p / q;
00144 u = x + d;
00145
00146
00147
00148 if (u - a < t2 || b - u < t2) {
00149 d = tol1;
00150 if (x >= xm) d = -d;
00151 }
00152 }
00153
00154
00155
00156 if (fabs(d) >= tol1)
00157 u = x + d;
00158 else if (d > 0.)
00159 u = x + tol1;
00160 else
00161 u = x - tol1;
00162
00163 fu = function(u);
00164
00165
00166
00167
00168
00169 if (x <= fu) {
00170 if (u < x)
00171 a = u;
00172 else
00173 b = u;
00174 }
00175 if (fu <= fx) {
00176 if (u < x)
00177 b = x;
00178 else
00179 a = x;
00180 v = w; w = x; x = u;
00181 fv = fw; fw = fx; fx = fu;
00182 }
00183 else {
00184 if (fu <= fw || w == x) {
00185 v = w; fv = fw;
00186 w = u; fw = fu;
00187 }
00188 else if (fu <= fv || v == x || v == w) {
00189 v = u; fv = fu;
00190 }
00191 }
00192 }
00193
00194
00195
00196 if(iter > maxIters)
00197 {
00198 clog << "Warning: maximum iterations reached in Brent minimzation" << endl;
00199 clog << " iter = " << iter << endl;
00200 clog << " tol = " << tol << endl;
00201 clog << " fabs(x - xm) = " << fabs(x - xm) << endl;
00202 clog << " is supposed to be <= " << endl;
00203 clog << " t2 - (b - a) * .5 = " << t2 - (b - a) * .5 << endl;
00204 }
00205
00206 return x;
00207 }
00208
00209 double FunctionR1toR1::function(double x)
00210 {
00211 evaluate(x);
00212 return getFunctionValue();
00213 }
00214
00215 double FunctionR1toR1::minimum(double left, double right)
00216 {
00217 cout << "left = " << left << " right = " << right << endl;
00218
00219 return Brent_fmin(left, right, 1e-50);
00220 }