Skip to content

Commit

Permalink
Start with Fortran source downloaded from Netlib
Browse files Browse the repository at this point in the history
  • Loading branch information
kagalenko-m-b committed Jan 24, 2024
1 parent 9a8908e commit c08d198
Showing 1 changed file with 159 additions and 0 deletions.
159 changes: 159 additions & 0 deletions src/fmin.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
double precision function fmin(ax,bx,f,tol)
double precision ax,bx,f,tol
c
c an approximation x to the point where f attains a minimum on
c the interval (ax,bx) is determined.
c
c
c input..
c
c ax left endpoint of initial interval
c bx right endpoint of initial interval
c f function subprogram which evaluates f(x) for any x
c in the interval (ax,bx)
c tol desired length of the interval of uncertainty of the final
c result ( .ge. 0.0d0)
c
c
c output..
c
c fmin abcissa approximating the point where f attains a minimum
c
c
c the method used is a combination of golden section search and
c successive parabolic interpolation. convergence is never much slower
c than that for a fibonacci search. if f has a continuous second
c derivative which is positive at the minimum (which is not at ax or
c bx), then convergence is superlinear, and usually of the order of
c about 1.324....
c the function f is never evaluated at two points closer together
c than eps*abs(fmin) + (tol/3), where eps is approximately the square
c root of the relative machine precision. if f is a unimodal
c function and the computed values of f are always unimodal when
c separated by at least eps*abs(x) + (tol/3), then fmin approximates
c the abcissa of the global minimum of f on the interval ax,bx with
c an error less than 3*eps*abs(fmin) + tol. if f is not unimodal,
c then fmin may approximate a local, but perhaps non-global, minimum to
c the same accuracy.
c this function subprogram is a slightly modified version of the
c algol 60 procedure localmin given in richard brent, algorithms for
c minimization without derivatives, prentice - hall, inc. (1973).
c
c
double precision a,b,c,d,e,eps,xm,p,q,r,tol1,tol2,u,v,w
double precision fu,fv,fw,fx,x
double precision dabs,dsqrt,dsign
c
c c is the squared inverse of the golden ratio
c
c = 0.5d0*(3. - dsqrt(5.0d0))
c
c eps is approximately the square root of the relative machine
c precision.
c
eps = 1.0d00
10 eps = eps/2.0d00
tol1 = 1.0d0 + eps
if (tol1 .gt. 1.0d00) go to 10
eps = dsqrt(eps)
c
c initialization
c
a = ax
b = bx
v = a + c*(b - a)
w = v
x = v
e = 0.0d0
fx = f(x)
fv = fx
fw = fx
c
c main loop starts here
c
20 xm = 0.5d0*(a + b)
tol1 = eps*dabs(x) + tol/3.0d0
tol2 = 2.0d0*tol1
c
c check stopping criterion
c
if (dabs(x - xm) .le. (tol2 - 0.5d0*(b - a))) go to 90
c
c is golden-section necessary
c
if (dabs(e) .le. tol1) go to 40
c
c fit parabola
c
r = (x - w)*(fx - fv)
q = (x - v)*(fx - fw)
p = (x - v)*q - (x - w)*r
q = 2.0d00*(q - r)
if (q .gt. 0.0d0) p = -p
q = dabs(q)
r = e
e = d
c
c is parabola acceptable
c
30 if (dabs(p) .ge. dabs(0.5d0*q*r)) go to 40
if (p .le. q*(a - x)) go to 40
if (p .ge. q*(b - x)) go to 40
c
c a parabolic interpolation step
c
d = p/q
u = x + d
c
c f must not be evaluated too close to ax or bx
c
if ((u - a) .lt. tol2) d = dsign(tol1, xm - x)
if ((b - u) .lt. tol2) d = dsign(tol1, xm - x)
go to 50
c
c a golden-section step
c
40 if (x .ge. xm) e = a - x
if (x .lt. xm) e = b - x
d = c*e
c
c f must not be evaluated too close to x
c
50 if (dabs(d) .ge. tol1) u = x + d
if (dabs(d) .lt. tol1) u = x + dsign(tol1, d)
fu = f(u)
c
c update a, b, v, w, and x
c
if (fu .gt. fx) go to 60
if (u .ge. x) a = x
if (u .lt. x) b = x
v = w
fv = fw
w = x
fw = fx
x = u
fx = fu
go to 20
60 if (u .lt. x) a = u
if (u .ge. x) b = u
if (fu .le. fw) go to 70
if (w .eq. x) go to 70
if (fu .le. fv) go to 80
if (v .eq. x) go to 80
if (v .eq. w) go to 80
go to 20
70 v = w
fv = fw
w = u
fw = fu
go to 20
80 v = u
fv = fu
go to 20
c
c end of main loop
c
90 fmin = x
return
end

0 comments on commit c08d198

Please sign in to comment.