#include <limits>
#include <cmath>
Go to the source code of this file.
Functions | |
template<class T, class FUNC> | |
T | Fmin (T a, T b, FUNC &f, T tol) |
This function performs a uni-dimensional minimization by Brent's method. |
A translation of Fmin.java by Steve Verrill to C++ Version 0.000318 (March 18, 2000) by Brad Hanson (http://www.b-a-h.com/index.html)
This software is available at http://www.smallwaters.com/software/cpp/uncmin.html
Fmin.java can be obtained from http://www1.fpl.fs.fed.us/optimization.html Information about Fmin.java is given below.
Fmin.java copyright claim: This software is based on the public domain fmin routine. The FORTRAN version can be found at www.netlib.org This software was translated from the FORTRAN version to Java by a US government employee on official time. Thus this software is also in the public domain. The translator's mail address is: Steve Verrill USDA Forest Products Laboratory 1 Gifford Pinchot Drive Madison, Wisconsin 53705 The translator's e-mail address is: steve@ws13.fpl.fs.fed.us
(c) 2008, Werner Wothke, Fmin documentation.
DISCLAIMER OF WARRANTIES: THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE TRANSLATOR DOES NOT WARRANT, GUARANTEE OR MAKE ANY REPRESENTATIONS REGARDING THE SOFTWARE OR DOCUMENTATION IN TERMS OF THEIR CORRECTNESS, RELIABILITY, CURRENTNESS, OR OTHERWISE. THE ENTIRE RISK AS TO THE RESULTS AND PERFORMANCE OF THE SOFTWARE IS ASSUMED BY YOU. IN NO CASE WILL ANY PARTY INVOLVED WITH THE CREATION OR DISTRIBUTION OF THE SOFTWARE BE LIABLE FOR ANY DAMAGE THAT MAY RESULT FROM THE USE OF THIS SOFTWARE. Sorry about that.
History: Date Translator Changes 3/09/08 Werner Wothke Doxygen-compatible documentation.
3/24/98 Steve Verrill Translated
Definition in file Fmin.h.
T Fmin | ( | T | a, | |
T | b, | |||
FUNC & | f, | |||
T | tol | |||
) | [inline] |
This function performs a uni-dimensional minimization by Brent's method.
This class was translated by a statistician from the FORTRAN version of fmin. It is NOT an official translation. When public domain Java optimization routines become available from professional numerical analysts, then THE CODE PRODUCED BY THE NUMERICAL ANALYSTS SHOULD BE USED.
Meanwhile, if you have suggestions for improving this code, please contact Steve Verrill at steve@ws13.fpl.fs.fed.us.
Convergence is never much slower than that for a Fibonacci search. If f has a continuous second derivative which is positive at the minimum (which is not at ax or bx), then convergence is superlinear, and usually of the order of about 1.324.
The function f is never evaluated at two points closer together than eps*abs(fmin)+(tol/3), where eps is approximately the square root of the relative machine precision. If f is a unimodal function and the computed values of f are always unimodal when separated by at least eps*abs(x)+(tol/3), then fmin approximates the abcissa of the global minimum of f on the interval (ax,bx) with an error less than 3*eps*abs(fmin)+tol. If f is not unimodal, then fmin may approximate a local, but perhaps non-global, minimum to the same accuracy.
This function subprogram is a slightly modified version of the Algol 60 procedure localmin given in Richard Brent, Algorithms For Minimization Without Derivatives, Prentice-Hall, Inc. (1973).
This method is a translation from FORTRAN to Java of the Netlib function fmin. In the Netlib listing no author is given.
Translated by Steve Verrill, March 24, 1998.
Translated from Java to C++ by Brad Hanson (bradh@pobox.com)
T | Floating point type (e.g., double, float) | |
FUNC | Function object type giving function to minimize. |
[in] | a | Left endpoint of initial interval |
[in] | b | Right endpoint of initial interval |
[in] | f | A class that overloads the function call operator [operator()()] to implement the function f(x) for any x in the interval (a,b) |
[in] | tol | Desired length of the interval in which the minimum will be determined to lie (This should be greater than, roughly, 3.0e-8.) |
Definition at line 122 of file Fmin.h.
00123 { 00124 T c,d,e,eps,xm,p,q,r,tol1,t2, 00125 u,v,w,fu,fv,fw,fx,x,tol3; 00126 c = .5*(3.0 - std::sqrt(5.0)); 00127 d = 0.0; 00128 // 1.1102e-16 is machine precision 00129 eps = std::numeric_limits<T>::epsilon(); 00130 tol1 = eps + 1.0; 00131 eps = std::sqrt(eps); 00132 v = a + c*(b-a); 00133 w = v; 00134 x = v; 00135 e = 0.0; 00136 fx = f(x); 00137 fv = fx; 00138 fw = fx; 00139 tol3 = tol/3.0; 00140 xm = .5*(a + b); 00141 tol1 = eps*std::fabs(x) + tol3; 00142 t2 = 2.0*tol1; 00143 // main loop 00144 while (std::fabs(x-xm) > (t2 - .5*(b-a))) { 00145 p = q = r = 0.0; 00146 if (std::fabs(e) > tol1) { 00147 // fit the parabola 00148 r = (x-w)*(fx-fv); 00149 q = (x-v)*(fx-fw); 00150 p = (x-v)*q - (x-w)*r; 00151 q = 2.0*(q-r); 00152 if (q > 0.0) { 00153 p = -p; 00154 } else { 00155 q = -q; 00156 } 00157 r = e; 00158 e = d; 00159 // brace below corresponds to statement 50 00160 } 00161 if ((std::fabs(p) < std::fabs(.5*q*r)) && 00162 (p > q*(a-x)) && 00163 (p < q*(b-x))) { 00164 // a parabolic interpolation step 00165 d = p/q; 00166 u = x+d; 00167 // f must not be evaluated too close to a or b 00168 if (((u-a) < t2) || ((b-u) < t2)) { 00169 d = tol1; 00170 if (x >= xm) d = -d; 00171 } 00172 // brace below corresponds to statement 60 00173 } else { 00174 // a golden-section step 00175 if (x < xm) { 00176 e = b-x; 00177 } else { 00178 e = a-x; 00179 } 00180 d = c*e; 00181 } 00182 // f must not be evaluated too close to x 00183 if (std::fabs(d) >= tol1) { 00184 u = x+d; 00185 } else { 00186 if (d > 0.0) { 00187 u = x + tol1; 00188 } else { 00189 u = x - tol1; 00190 } 00191 } 00192 fu = f(u); 00193 // Update a, b, v, w, and x 00194 if (fx <= fu) { 00195 if (u < x) { 00196 a = u; 00197 } else { 00198 b = u; 00199 } 00200 // brace below corresponds to statement 140 00201 } 00202 if (fu <= fx) { 00203 if (u < x) { 00204 b = x; 00205 } else { 00206 a = x; 00207 } 00208 v = w; 00209 fv = fw; 00210 w = x; 00211 fw = fx; 00212 x = u; 00213 fx = fu; 00214 xm = .5*(a + b); 00215 tol1 = eps*std::fabs(x) + tol3; 00216 t2 = 2.0*tol1; 00217 // brace below corresponds to statement 170 00218 } else { 00219 if ((fu <= fw) || (w == x)) { 00220 v = w; 00221 fv = fw; 00222 w = u; 00223 fw = fu; 00224 xm = .5*(a + b); 00225 tol1 = eps*std::fabs(x) + tol3; 00226 t2 = 2.0*tol1; 00227 } else if ((fu > fv) && (v != x) && (v != w)) { 00228 xm = .5*(a + b); 00229 tol1 = eps*std::fabs(x) + tol3; 00230 t2 = 2.0*tol1; 00231 } else { 00232 v = u; 00233 fv = fu; 00234 xm = .5*(a + b); 00235 tol1 = eps*std::fabs(x) + tol3; 00236 t2 = 2.0*tol1; 00237 } 00238 } 00239 // brace below corresponds to statement 190 00240 } 00241 return x; 00242 }