Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Minimization of Internal Function

Status
Not open for further replies.

HughPhilly

Programmer
Jul 25, 2010
3
US
Hi guys,
I am a newby to Fortran programming, so this problem might be very simple to many of you.

Goal: Minimize internal function using Nelder-Mead subroutine. Internal function uses global variables..

Situation: Function is defined within program under 'contains'. So it is internal and it is defined by some global variables.. (My work environment is Linux Ubuntu 10.04, Gfortran, Fortran 90.)

Problem: When I compile the main and minimization subroutine (gfortran Internal_Function_Minimization.f90 Simples_routine.f90), I get a message 'undefined reference to internal function'.


I am attaching my code. It has two files. One is the main program file contains objective function to be minimized. The other file is Nelder-Mead Minimization subroutine.

The global variable is 'i' which is an iterator and it is used to define the internal function..


How can I hold the global variable and just minimize the internal function in terms of the local variables?


I really appreciate your help in advance.
 
The code you posted is lousy. I corected
Code:
    write ynewlo ! this should be always zero.
to
Code:
    write (*,*)  ynewlo ! this should be always zero.
but then I got an error
Code:
In file Internal_function.f90:11

    write (*,*)  ynewlo ! this should be always zero.
                 1
Error: Symbol 'ynewlo' at (1) has no IMPLICIT type
What should be ynewlo ?
And what is this ?
Code:
    call Test01
I couldn't find any subroutine Test01 in the source you posted...

 
Thanks mikrom. Sorry for the previous code -- I had to upload the newer version. Here is the new version but I still get the same message "undefined reference to internal_function".

ynewlo is the 'intent(out)' variable from 'nelmin' subroutine. It is the minimized value of the objective function, Internal_Function.

Thanks
Hugh
 
 http://www.mediafire.com/file/zgei68idddxa6oe/Internal_Function.f90
I changed a little bit your program, so the function now uses assumed-size array:
Code:
Program Internal_Function_Minimization
Implicit None
integer ( kind = 4 ) n
Integer*4 :: i
Real*8 :: ynewlo
real    ( kind = 8 ) vec(2)

vec = (/1.0D+00,1.0D+00/)
Do i=1,4
    write(*,*) Internal_Function(vec)
End Do

Do i=1,4
    call minimization
    write(*,*) ynewlo ! This is a minized value. This should be always zero.
End Do


Contains

subroutine minimization


  implicit none

  integer ( kind = 4 ), parameter :: n = 2

  integer ( kind = 4 ) i
  integer ( kind = 4 ) icount
  integer ( kind = 4 ) ifault
  integer ( kind = 4 ) kcount
  integer ( kind = 4 ) konvge
  integer ( kind = 4 ) numres
  real    ( kind = 8 ) reqmin
  real    ( kind = 8 ) start(n)
  real    ( kind = 8 ) step(n)
  real    ( kind = 8 ) xmin(n)
  real    ( kind = 8 ) ynewlo

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) 'TEST01'
  write ( *, '(a)' ) '  Apply NELMIN to Internal function.'

  start(1) = -1.2D+00
  start(2) =  1.0D+00

  reqmin = 1.0D-08

  step(1) = 1.0D+00
  step(2) = 1.0D+00

  konvge = 10
  kcount = 500

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Starting point X:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) start(i)
  end do

  ynewlo = Internal_Function (start)

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X) = ', ynewlo

  call nelmin ( Internal_Function, n, start, xmin, ynewlo, reqmin, step, &
    konvge, kcount, icount, numres, ifault )

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Return code IFAULT = ', ifault
  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Estimate of minimizing value X*:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) xmin(i)
  end do

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X*) = ', ynewlo

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Number of iterations = ', icount
  write ( *, '(a,i8)' ) '  Number of restarts =   ', numres

  return
end subroutine minimization

Real*8 Function Internal_Function (vec)
Implicit None
Real*8 :: vec(*)

Internal_Function = vec(1)**2 + vec(2)**2
End Function Internal_Function

End Program Internal_Function_Minimization
It compiles now with g95 and runs
Code:
$ g95 internal_function.f90 simplex_routine.f90 -o min
But it doesn't compile with gfortran.
To compile it with gfortran you must not declare the function in the contains section together with the subroutine, but after the program:
Code:
Program Internal_Function_Minimization
Implicit None
integer ( kind = 4 ) n
Integer*4 :: i
Real*8 :: ynewlo
real    ( kind = 8 ) vec(2)
real    ( kind = 8 ) :: internal_function

vec = (/1.0D+00,1.0D+00/)
Do i=1,4
    write(*,*) Internal_Function(vec)
End Do

Do i=1,4
    call minimization
    write(*,*) ynewlo ! This is a minized value. This should be always zero.
End Do

Contains

subroutine minimization
  implicit none

  integer ( kind = 4 ), parameter :: n = 2

  integer ( kind = 4 ) i
  integer ( kind = 4 ) icount
  integer ( kind = 4 ) ifault
  integer ( kind = 4 ) kcount
  integer ( kind = 4 ) konvge
  integer ( kind = 4 ) numres
  real    ( kind = 8 ) reqmin
  real    ( kind = 8 ) start(n)
  real    ( kind = 8 ) step(n)
  real    ( kind = 8 ) xmin(n)
  real    ( kind = 8 ) ynewlo
  real    ( kind = 8 ) :: internal_function

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) 'TEST01'
  write ( *, '(a)' ) '  Apply NELMIN to Internal function.'

  start(1) = -1.2D+00
  start(2) =  1.0D+00

  reqmin = 1.0D-08

  step(1) = 1.0D+00
  step(2) = 1.0D+00

  konvge = 10
  kcount = 500

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Starting point X:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) start(i)
  end do

  ynewlo = Internal_Function (start)

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X) = ', ynewlo

  call nelmin ( Internal_Function, n, start, xmin, ynewlo, reqmin, step, &
    konvge, kcount, icount, numres, ifault )

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Return code IFAULT = ', ifault
  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Estimate of minimizing value X*:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) xmin(i)
  end do

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X*) = ', ynewlo

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Number of iterations = ', icount
  write ( *, '(a,i8)' ) '  Number of restarts =   ', numres

  return
end subroutine minimization

End Program Internal_Function_Minimization

Real*8 Function Internal_Function (vec)
Implicit None
Real*8 :: vec(*)

Internal_Function = vec(1)**2 + vec(2)**2
End Function Internal_Function
it compiles and runs
Code:
$ gfortran internal_function.f90 simplex_routine.f90 -o min
Other solution is not to use contains section of the program and declare the function and the subroutine after the main program:
Code:
Program Internal_Function_Minimization
Implicit None
integer ( kind = 4 ) n
Integer*4 :: i
Real*8 :: ynewlo
real    ( kind = 8 ) vec(2)
real    ( kind = 8 ) :: internal_function

vec = (/1.0D+00,1.0D+00/)
Do i=1,4
    write(*,*) Internal_Function(vec)
End Do

Do i=1,4
    call minimization
    write(*,*) ynewlo ! This is a minized value. This should be always zero.
End Do
End Program Internal_Function_Minimization

subroutine minimization
  implicit none

  integer ( kind = 4 ), parameter :: n = 2

  integer ( kind = 4 ) i
  integer ( kind = 4 ) icount
  integer ( kind = 4 ) ifault
  integer ( kind = 4 ) kcount
  integer ( kind = 4 ) konvge
  integer ( kind = 4 ) numres
  real    ( kind = 8 ) reqmin
  real    ( kind = 8 ) start(n)
  real    ( kind = 8 ) step(n)
  real    ( kind = 8 ) xmin(n)
  real    ( kind = 8 ) ynewlo
  real    ( kind = 8 ) :: internal_function

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) 'TEST01'
  write ( *, '(a)' ) '  Apply NELMIN to Internal function.'

  start(1) = -1.2D+00
  start(2) =  1.0D+00

  reqmin = 1.0D-08

  step(1) = 1.0D+00
  step(2) = 1.0D+00

  konvge = 10
  kcount = 500

  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Starting point X:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) start(i)
  end do

  ynewlo = Internal_Function (start)

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X) = ', ynewlo

  call nelmin ( Internal_Function, n, start, xmin, ynewlo, reqmin, step, &
    konvge, kcount, icount, numres, ifault )

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Return code IFAULT = ', ifault
  write ( *, '(a)' ) ' '
  write ( *, '(a)' ) '  Estimate of minimizing value X*:'
  write ( *, '(a)' ) ' '
  do i = 1, n
    write ( *, '(2x,g14.6)' ) xmin(i)
  end do

  write ( *, '(a)' ) ' '
  write ( *, '(a,g14.6)' ) '  F(X*) = ', ynewlo

  write ( *, '(a)' ) ' '
  write ( *, '(a,i8)' ) '  Number of iterations = ', icount
  write ( *, '(a,i8)' ) '  Number of restarts =   ', numres

  return
end subroutine minimization

Real*8 Function Internal_Function (vec)
Implicit None
Real*8 :: vec(*)

Internal_Function = vec(1)**2 + vec(2)**2
End Function Internal_Function
It compiles and runs - however I don't know if the result is correct or not :)
Code:
$ gfortran internal_function.f90 simplex_routine.f90 -o min

$ min
   2.0000000000000000     
   2.0000000000000000     
   2.0000000000000000     
   2.0000000000000000     
 
TEST01
  Apply NELMIN to Internal function.
 
  Starting point X:
 
    -1.20000    
     1.00000    
 
  F(X) =    2.44000    
 
  Return code IFAULT =        0
 
  Estimate of minimizing value X*:
 
   -0.641388E-04
   -0.178307E-04
 
  F(X*) =   0.443172E-08
 
  Number of iterations =       67
  Number of restarts =          1
   0.0000000000000000     
 
TEST01
  Apply NELMIN to Internal function.
 
  Starting point X:
 
    -1.20000    
     1.00000    
 
  F(X) =    2.44000    
 
  Return code IFAULT =        0
 
  Estimate of minimizing value X*:
 
   -0.641388E-04
   -0.178307E-04
 
  F(X*) =   0.443172E-08
 
  Number of iterations =       67
  Number of restarts =          1
   0.0000000000000000     
 
TEST01
  Apply NELMIN to Internal function.
 
  Starting point X:
 
    -1.20000    
     1.00000    
 
  F(X) =    2.44000    
 
  Return code IFAULT =        0
 
  Estimate of minimizing value X*:
 
   -0.641388E-04
   -0.178307E-04
 
  F(X*) =   0.443172E-08
 
  Number of iterations =       67
  Number of restarts =          1
   0.0000000000000000     
 
TEST01
  Apply NELMIN to Internal function.
 
  Starting point X:
 
    -1.20000    
     1.00000    
 
  F(X) =    2.44000    
 
  Return code IFAULT =        0
 
  Estimate of minimizing value X*:
 
   -0.641388E-04
   -0.178307E-04
 
  F(X*) =   0.443172E-08
 
  Number of iterations =       67
  Number of restarts =          1
   0.0000000000000000
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top