The REALVEC module

The REALVEC module is concerned with vectors of double precision numbers. This programs illustrates the minimisation of vector functions using various methods. It is very easy.

As in the case of the REAL module, the actual functions to be minimised are provided in a separate module TEST. Note that the routines are all made [selfless] which means, unlike every other routine in TONTO, there is no self variable automatically declared as the first variable.

Code

program run_realvec

   use TYPES
   use SYSTEM
   use REALVEC
   use TEXTFILE
   use TEST

#  include "macros"

   implicit none

   REALVEC(2) :: p
   REALMAT(2,2) :: directions
   REAL :: fret,tol,ftol
   STR :: algorithm

   tonto.initialize

   stdout.create_stdout
   stdout.open

   stdout.flush
   stdout.text("Minimise the function (x-1)^2 + (y-1)^2 + 1 using the")
   stdout.text("Powell method")
   stdout.flush
   stdout.text("This function is defined in the TEST module")
   stdout.flush
  
   tol = TOL(7)
   ftol = TOL(7)
   p = [ 0.1, 0.1 ]
   directions(1,1) = 1
   directions(2,1) = 1
   directions(1,2) = 1
   directions(2,2) =-1

   stdout.flush
   stdout.show("Start point   =",p)
   stdout.flush
   stdout.text("Initial directions (as columns):")
   stdout.put(directions)

   stdout.flush
   stdout.text("Minimise the function ...")

   funk.minimise_powell(p,directions,fret,tol,ftol)

   stdout.flush
   stdout.text("Answer:")
   stdout.show("Minimum point =",p)
   stdout.show("Minimum value =",fret)

   stdout.flush
   stdout.text("Now minimise the same functions using the FR")
   stdout.text("(Fletcher-Reeves) method. This requires the ")
   stdout.text("the derivative of the function as well.")
   stdout.flush

   p = [ 0.1, 0.1 ]
   algorithm = "Fletcher-Reeves"
   funk.minimise_FRPR(dfunk,p,fret,tol,ftol,algorithm)

   stdout.flush
   stdout.text("Answer:")
   stdout.show("Minimum point =",p)
   stdout.show("Minimum value =",fret)

   stdout.flush
   stdout.text("Now minimise the same functions using the BFGS")
   stdout.text("(Broyden-Fletcher-Goldfarb-Shanno) method. This also")
   stdout.text("requires the derivative of the function")
   stdout.flush


   p = [ 0.1, 0.1 ]
   funk.minimise_BFGS(dfunk,p,fret,tol,ftol)

   stdout.flush
   stdout.text("Answer:")
   stdout.show("Minimum point =",p)
   stdout.show("Minimum value =",fret)

end

And here is the relevant part of the TEST module:

module TEST

   use TYPES
   use SYSTEM
   use REALVEC
   use REALMAT

   implicit none

#  include "macros"

   public funk
   public dfunk

contains

   funk(p) result (res) [selfless]
   ! A test function for minimising
      REALVEC(2) :: p
      REAL :: res
      REAL :: x,y
      x = p(1); y = p(2)
      res = (x-1)*(x-1) + (y-1)*(y-1) + 1
   end

   dfunk(p) result (res) [selfless]
   ! A test function for minimising
      REALVEC(2) :: p,res
      REAL :: x,y
      x = p(1); y = p(2)
      res(1) = 2*(x-1)
      res(2) = 2*(y-1)
   end

end

Results

Minimise the function (x-1)^2 + (y-1)^2 + 1 using the
Powell method

This function is defined in the TEST module


Start point   =         0.100000001         0.100000001

Initial directions (as columns):
                            1                   2

        1         1.000000000         1.000000000
        2         1.000000000        -1.000000000

Minimise the function ...

Answer:
Minimum point =         0.999999995         0.999999995
Minimum value =         1.000000000

Now minimise the same functions using the FR
(Fletcher-Reeves) method. This requires the
the derivative of the function as well.


Answer:
Minimum point =         1.000000000         1.000000000
Minimum value =         1.000000000

Now minimise the same functions using the BFGS
(Broyden-Fletcher-Goldfarb-Shanno) method. This also
requires the derivative of the function


Answer:
Minimum point =         1.000000000         1.000000000
Minimum value =         1.000000000