The REAL module

The REAL module is concerned with double precision numbers. In this program we illustrate how functions which take and return a double precision number may be minimised.

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

Code

program run_real

   use TYPES
   use SYSTEM
   use REAL
   use TEXTFILE
   use TEST

#  include "macros"

   implicit none
  
   REAL :: val,x,y
   REAL :: a,b,c,fa,fb,fc,fx
   INT :: i

   tonto.initialize
   stdout.create_stdout
   stdout.open

   stdout.text("10 random numbers:")
   stdout.flush
   do i=1,10
     a.to_random_normal
     stdout.put(a,flush=1)
   end


   stdout.flush
   stdout.text("Find an initial bracket for the function (x-1)^2 + 1")
   stdout.text("which contains its minimum value")
   stdout.flush

   a = 1.8
   b = 1.5
   c = 1.3
   stdout.text("Initially")
   stdout.show("a  =",a)
   stdout.show("b  =",b)
   stdout.show("c  =",c)
   stdout.show("fa =",func(a))
   stdout.show("fb =",func(b))
   stdout.show("fc =",func(c))

   func.find_initial_bracket(a,b,c,fa,fb,fc)

   stdout.flush
   stdout.text("Finally")
   stdout.show("a  =",a)
   stdout.show("b  =",b)
   stdout.show("c  =",c)
   stdout.show("fa =",fa)
   stdout.show("fb =",fb)
   stdout.show("fc =",fc)

   stdout.flush
   stdout.text("Now minimise the function ...")
   stdout.flush

   func.minimise_brent(a,b,c,x,fx,0.00001d0)

   stdout.show("x_min  =",x)
   stdout.show("f_min  =",fx)

   stdout.flush
   stdout.text("Now integrate it from 1->2:")
   stdout.flush

   val = func.integrate_adaptive_trapezoid(1.0d0,2.0d0,TOL(8))
   stdout.show("Answer =",val)

   stdout.flush
   stdout.text("Integrate arcsin using adaptive trapezoid method")
   stdout.text("from 0->1/2")
   stdout.flush

   val = arcsin.integrate_adaptive_trapezoid(0.0d0,0.5d0,TOL(8))
   stdout.show("Answer =",val)

   stdout.flush
   stdout.text("Integrate arcsin using adaptive simpson method")
   stdout.text("from 0->1/2")
   stdout.flush

   val = arcsin.integrate_adaptive_simpson(0.0d0,0.5d0,TOL(8))
   stdout.show("Answer =",val)

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 func
   public arcsin

contains

   func(x) result (res) [selfless]
   !  A test function for minimising
      REAL :: x,res
      res = (x-1)*(x-1) + 1
   end

   arcsin(x) result (res) [selfless]
   ! Return the arcsin for x. Corrects bug for numbers close to 1.
      REAL :: x,res
      if (abs(abs(x)-ONE)<TOL(5)) then
         if (x<0) then; res = -PI/TWO
         else;             res = +PI/TWO
         end
      else
         res = asin(x)
      end
   end

end

Results

10 random numbers:

         0.905442547
        -0.350476891
        -0.945527330
        -1.354792694
         0.992321475
        -0.643725104
         0.177373302
        -1.877569698
         0.126510113
         0.281241703

Find an initial bracket for the function (x-1)^2 + 1
which contains its minimum value

Initially
a  =         1.800000000
b  =         1.500000000
c  =         1.300000000
fa =         1.640000000
fb =         1.250000000
fc =         1.090000000

Finally
a  =         0.229179586
b  =         1.014589798
c  =         1.500000000
fa =         1.594164111
fb =         1.000212862
fc =         1.250000000

Now minimise the function ...

x_min  =         1.000000000
f_min  =         1.000000000

Now integrate it from 1->2:

Answer =         1.333333333

Integrate arcsin using adaptive trapezoid method
from 0->1/2

Answer =         0.127824792

Integrate arcsin using adaptive simpson method
from 0->1/2

Answer =         0.127824792