25 namespace BrentMethods {
27 double MinimStep(
const IGenFunction*
function,
int type,
double &xmin,
double &xmax,
double fy,
int npx,
bool logStep)
37 xmin = std::log(xmin);
38 xmax = std::log(xmax);
42 if (npx < 2)
return 0.5*(xmax-xmin);
43 double dx = (xmax-xmin)/(npx-1);
44 double xxmin = (logStep) ? std::exp(xmin) : xmin;
49 bool foundInterval = (type != 4);
51 yymin = (*function)(xxmin);
53 yymin = -(*function)(xxmin);
55 yymin = (*function)(xxmin)-fy;
64 for (
int i=1; i<=npx-1; i++) {
65 double x = xmin + i*dx;
66 if (logStep) x = std::exp(x);
73 y = (*function)(x)-fy;
75 if ( type < 4 && y < yymin) {
90 if (std::copysign(1.,y)*std::copysign(1.,yymin) < 0 ) {
93 xmiddle = 0.5*(xmax+xmin);
105 xmin = std::exp(xmin);
106 xmax = std::exp(xmax);
108 xmin = std::max(xmin,xxmin-dx);
109 xmax = std::min(xmax,xxmin+dx);
110 xmiddle = std::min(xxmin,xmax);
114 if (!foundInterval) {
115 MATH_INFO_MSG(
"BrentMethods::MinimStep",
"Grid search failed to find a root in the interval ");
116 std::cout <<
"xmin = " << xmin <<
" xmax = " << xmax <<
" npts = " << npx << std::endl;
125 double MinimBrent(
const IGenFunction*
function,
int type,
double &xmin,
double &xmax,
double xmiddle,
double fy,
bool &ok,
int &niter,
double epsabs,
double epsrel,
int itermax)
141 const double c = 3.81966011250105097e-01;
142 double u, v, w, x, fv, fu, fw, fx, e, p, q, r, t2, d=0, m, tol;
149 fv = fw = fx = (*function)(x);
151 fv = fw = fx = -(*function)(x);
153 fv = fw = fx = std::fabs((*
function)(x)-fy);
155 for (
int i=0; i<itermax; i++){
157 tol = epsrel*(std::fabs(x))+epsabs;
160 if (std::fabs(x-m) <= (t2-0.5*(b-a))) {
172 if (std::fabs(e)>tol){
176 p = (x-v)*q - (x-w)*r;
186 if (std::fabs(p) >= std::fabs(0.5*q*r) || p <= q*(a-x) || p >= q*(b-x)) {
188 e=(x>=m ? a-x : b-x);
194 if (u-a < t2 || b-u < t2)
196 d=(m-x >= 0) ? std::fabs(tol) : -std::fabs(tol);
199 e=(x>=m ? a-x : b-x);
202 u = (std::fabs(d)>=tol ? x+d : x+ ((d >= 0) ? std::fabs(tol) : -std::fabs(tol)) );
206 fu = -(*function)(u);
208 fu = std::fabs((*
function)(u)-fy);
213 v=w; fv=fw; w=x; fw=fx; x=u; fx=fu;
218 v=w; fv=fw; w=u; fw=fu;
220 else if (fu<=fv || v==x || v==w){