- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi everyone,
I'm trying to learn how to use IMSL. I have a very simple program that finds a minimum and I would like to make a modification to it.
Right now the function I'm minimizing is
F = 1.0E2*(X(2)-X(1)*X(1))**2 + (1.0E0-X(1))**2
I would like to have a and b instead of1.0E2 and1.0E0 and pass a and b to the minimizer.
Is this posible?
Thanks!!!
Link Copied
16 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One way, older F77 style: define A and B in a common block, set A and B to the desired values in the main program (or subprogram that calls BCONF), and use those values in the subroutine that defines the objective function.
More modern way: define A and B in a module, initialize A and B in that module; USE the module in the subroutine.
[fortran]module pars
IMPLICIT NONE
real :: A = 1.0E2, B = 1.0E0
end module pars
program topt
USE BCONF_INT
USE UMACH_INT
IMPLICIT NONE
INTEGER N
PARAMETER (N=2)
!
INTEGER IPARAM(7), ITP, L, NOUT
REAL F, FSCALE, RPARAM(7), X(N), XGUESS(N), &
XLB(N), XSCALE(N), XUB(N)
EXTERNAL ROSBRK
!
DATA XGUESS/-1.2E0, 1.0E0/
DATA XLB/-2.0E0, -1.0E0/, XUB/0.5E0, 2.0E0/
! All the bounds are provided
ITP = 0
! Default parameters are used
IPARAM(1) = 0
! Minimize Rosenbrock function using
! initial guesses of -1.2 and 1.0
CALL BCONF (ROSBRK, ITP, XLB, XUB, X, XGUESS=XGUESS, &
iparam=iparam, FVALUE=F)
! Print results
CALL UMACH (2, NOUT)
WRITE (NOUT,99999) X, F, (IPARAM(L),L=3,5)
!
99999 FORMAT (' The solution is ', 6X, 2F8.3, //, ' The function ', &
'value is ', F8.3, //, ' The number of iterations is ', &
10X, I3, /, ' The number of function evaluations is ', &
I3, /, ' The number of gradient evaluations is ', I3)
!
END
!
SUBROUTINE ROSBRK (N, X, F)
USE PARS
IMPLICIT NONE
INTEGER N
REAL X(N), F
!
F = A*(X(2)-X(1)*X(1))**2 + (B-X(1))**2
!
RETURN
END
[/fortran]
More modern way: define A and B in a module, initialize A and B in that module; USE the module in the subroutine.
[fortran]module pars
IMPLICIT NONE
real :: A = 1.0E2, B = 1.0E0
end module pars
program topt
USE BCONF_INT
USE UMACH_INT
IMPLICIT NONE
INTEGER N
PARAMETER (N=2)
!
INTEGER IPARAM(7), ITP, L, NOUT
REAL F, FSCALE, RPARAM(7), X(N), XGUESS(N), &
XLB(N), XSCALE(N), XUB(N)
EXTERNAL ROSBRK
!
DATA XGUESS/-1.2E0, 1.0E0/
DATA XLB/-2.0E0, -1.0E0/, XUB/0.5E0, 2.0E0/
! All the bounds are provided
ITP = 0
! Default parameters are used
IPARAM(1) = 0
! Minimize Rosenbrock function using
! initial guesses of -1.2 and 1.0
CALL BCONF (ROSBRK, ITP, XLB, XUB, X, XGUESS=XGUESS, &
iparam=iparam, FVALUE=F)
! Print results
CALL UMACH (2, NOUT)
WRITE (NOUT,99999) X, F, (IPARAM(L),L=3,5)
!
99999 FORMAT (' The solution is ', 6X, 2F8.3, //, ' The function ', &
'value is ', F8.3, //, ' The number of iterations is ', &
10X, I3, /, ' The number of function evaluations is ', &
I3, /, ' The number of gradient evaluations is ', I3)
!
END
!
SUBROUTINE ROSBRK (N, X, F)
USE PARS
IMPLICIT NONE
INTEGER N
REAL X(N), F
!
F = A*(X(2)-X(1)*X(1))**2 + (B-X(1))**2
!
RETURN
END
[/fortran]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot for the help :-) !
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is there a way to have a and b to be pass as arguments of a subrutine.
I want to be able to do
CALL MINIMIZE1(a, b, X, F)
where x is the vector that minimize the function and F is the value of the function.
Thanks a lot for the help!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you have the source code for MINIMIZE1, you can modify it as you wish. If you are writing your own software, you can put into it whatever you wish.
When calling an optimization routine in a library such as IMSL, however, you cannot do so. There is a specified interface for the user-defined subroutine, and you have to follow that interface. Adding subroutine arguments arbitrarily, as you did, will lead to program failure.
When calling an optimization routine in a library such as IMSL, however, you cannot do so. There is a specified interface for the user-defined subroutine, and you have to follow that interface. Adding subroutine arguments arbitrarily, as you did, will lead to program failure.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I understand that. What I'm trying to figure out whether is possible to write my own subroutine (minimize1) that uses IMSL and takes a and b as arguments.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Certainly. You write a "wrapper" subroutine that can, optionally, do a small amount of processing in addition to organizing the argument list to the IMSL subroutine, allocate work-space, if desired, call the IMSL routine, and do a little bit of post-processing to transform the results as necessary.
I fact, you can convert your first program to a subroutine and call that subroutine from a new main program.
I fact, you can convert your first program to a subroutine and call that subroutine from a new main program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will try that.
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm having troubles thinking how to implement this wraper idea.
I now have 2 files, my main program min.f90 and a module test2.f90
In the main program i set the values a and b and call a subrutine that is in the module passing a and b as arguments.
In the module I have the subroutine that calls imsl and a subrutine with the function that imsl uses.
My problem is that i don't undersand how to pass a and b to the function that imsl uses (in this exampleROSBRK)
Thanks for all the help :-)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here are modified versions of your code:
[fortran]module test2 USE BCONF_INT USE UMACH_INT implicit none REAL :: a, b !CHGS contains SUBROUTINE minimizer (aval, bval, x, F) INTEGER N PARAMETER (N=2) ! INTEGER IPARAM(7), ITP, L, NOUT REAL F, FSCALE, RPARAM(7), X(N), XGUESS(N), & XLB(N), XSCALE(N), XUB(N) real, intent(in) :: aval, bval ! EXTERNAL ROSBRK !CHGS do not declare internal subroutines external! ! DATA XGUESS/-1.2E0, 1.0E0/ DATA XLB/-2.0E0, -1.0E0/, XUB/0.5E0, 2.0E0/ ! All the bounds are provided ITP = 0 ! Default parameters are used IPARAM(1) = 0 ! Minimize Rosenbrock function using ! initial guesses of -1.2 and 1.0 a = aval b = bval CALL BCONF (ROSBRK, ITP, XLB, XUB, X, XGUESS=XGUESS, & iparam=iparam, FVALUE=F) ! Print results CALL UMACH (2, NOUT) WRITE (NOUT,99999) X, F, (IPARAM(L),L=3,5) ! 99999 FORMAT (' The solution is ', 6X, 2F8.3, //, ' The function ', & 'value is ', F8.3, //, ' The number of iterations is ', & 10X, I3, /, ' The number of function evaluations is ', & I3, /, ' The number of gradient evaluations is ', I3) END subroutine minimizer SUBROUTINE ROSBRK (N, X, F) INTEGER N REAL X(N), F ! F = a*(X(2)-X(1)*X(1))**2 + (b-X(1))**2 ! RETURN END SUBROUTINE ROSBRK end module test2 [/fortran]
[fortran]PROGRAM minimum USE test2 REAL :: aval, bval, X(2) aval = 1.0E2 bval = 1.0E0 CALL minimizer (aval, bval, x, F) print *, x end program minimum [/fortran] Program Output:
[bash]s:imsl>ifort %f90flags% test2.f90 min.f90 %link_fnl_shared% s:imsl>test2 The solution is 0.500 0.250 The function value is 0.250 The number of iterations is 25 The number of function evaluations is 35 The number of gradient evaluations is 27 0.5000000 0.2499999 [/bash]
[fortran]module test2 USE BCONF_INT USE UMACH_INT implicit none REAL :: a, b !CHGS contains SUBROUTINE minimizer (aval, bval, x, F) INTEGER N PARAMETER (N=2) ! INTEGER IPARAM(7), ITP, L, NOUT REAL F, FSCALE, RPARAM(7), X(N), XGUESS(N), & XLB(N), XSCALE(N), XUB(N) real, intent(in) :: aval, bval ! EXTERNAL ROSBRK !CHGS do not declare internal subroutines external! ! DATA XGUESS/-1.2E0, 1.0E0/ DATA XLB/-2.0E0, -1.0E0/, XUB/0.5E0, 2.0E0/ ! All the bounds are provided ITP = 0 ! Default parameters are used IPARAM(1) = 0 ! Minimize Rosenbrock function using ! initial guesses of -1.2 and 1.0 a = aval b = bval CALL BCONF (ROSBRK, ITP, XLB, XUB, X, XGUESS=XGUESS, & iparam=iparam, FVALUE=F) ! Print results CALL UMACH (2, NOUT) WRITE (NOUT,99999) X, F, (IPARAM(L),L=3,5) ! 99999 FORMAT (' The solution is ', 6X, 2F8.3, //, ' The function ', & 'value is ', F8.3, //, ' The number of iterations is ', & 10X, I3, /, ' The number of function evaluations is ', & I3, /, ' The number of gradient evaluations is ', I3) END subroutine minimizer SUBROUTINE ROSBRK (N, X, F) INTEGER N REAL X(N), F ! F = a*(X(2)-X(1)*X(1))**2 + (b-X(1))**2 ! RETURN END SUBROUTINE ROSBRK end module test2 [/fortran]
[fortran]PROGRAM minimum USE test2 REAL :: aval, bval, X(2) aval = 1.0E2 bval = 1.0E0 CALL minimizer (aval, bval, x, F) print *, x end program minimum [/fortran] Program Output:
[bash]s:imsl>ifort %f90flags% test2.f90 min.f90 %link_fnl_shared% s:imsl>test2 The solution is 0.500 0.250 The function value is 0.250 The number of iterations is 25 The number of function evaluations is 35 The number of gradient evaluations is 27 0.5000000 0.2499999 [/bash]
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
exactly was i was trying to do :-)
Thanks a lot!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I guess i don't really understand the use of external.
I'm following http://www.roguewave.com/Portals/0/products/imsl-numerical-libraries/fortran-library/docs/6.0/math/uvmif.htmand trying to do the same thing, write a wraper so I can pass a as and argument.
When I try to compile I get:
test2.f90(25): error #6637: This actual argument must be the name of an external user function or the name of an intrinsic function.
CALL UVMIF (F, XGUESS, BOUND, X, STEP=STEP, XACC=XACC, MAXFN=MAXFN)
------------------^
compilation aborted for test2.f90 (code 1)
What am I doing wrong?
Thanks!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You should probably take a little time off and read Fortran books and the compiler documentation.
Variables and entry points (subroutine and function names, whether user-supplied or in libraries) have similar names, but need to be processed differently by the compiler. When a name follows a CALL keyword or is used with an argument list within parenthesis, and the name is not declared as an array, the compiler assumes that the name is that of an entry point rather than a variable name. It outputs information in the .OBJ (.o in Linux/Unix) file to tell the linker to resolve the external symbol at link time.
When a subroutine argument is, itself, an entry point, such as F in the call to UMINF, the entry point name is not followed by an argument list, and the compiler cannot tell whether F is an undeclared variable, in which case the compiler allocates memory based on implicit or explicit typing, as applicable, or if F is an external symbol, in which case the compiler has to provide information for the linker to substitute the address of the entry point at link time.
In other words, if an argument in a call to a subroutine or function is intended to be an external symbol, i.e., a subroutine or function declared and defined elsewhere, that argument has to be declared EXTERNAL.
Variables and entry points (subroutine and function names, whether user-supplied or in libraries) have similar names, but need to be processed differently by the compiler. When a name follows a CALL keyword or is used with an argument list within parenthesis, and the name is not declared as an array, the compiler assumes that the name is that of an entry point rather than a variable name. It outputs information in the .OBJ (.o in Linux/Unix) file to tell the linker to resolve the external symbol at link time.
When a subroutine argument is, itself, an entry point, such as F in the call to UMINF, the entry point name is not followed by an argument list, and the compiler cannot tell whether F is an undeclared variable, in which case the compiler allocates memory based on implicit or explicit typing, as applicable, or if F is an external symbol, in which case the compiler has to provide information for the linker to substitute the address of the entry point at link time.
In other words, if an argument in a call to a subroutine or function is intended to be an external symbol, i.e., a subroutine or function declared and defined elsewhere, that argument has to be declared EXTERNAL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you recomend me a book?
When I declare F as external i can compile either
min3.f90(3): error #6401: The attributes of this name conflict with those made accessible by a USE statement.
Could you please help me solve this one so I can make some progress with my work (I promise to get a book asap and read it)
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, I cannot recommend a book since I do not know your background. I learned Fortran decades ago and the books that I used are either out of print or obsolete.
You have multiple declarations of F: some imply that F is a variable, and others that F is an entry point.
In test3.f90, use
real, external :: F
as the only declaration of F.
In min3.f90, you should not have any declaration for F, since the declaration made available by "USE test3" is already sufficient.
OUTPUT:
s:\imsl>test3
The minimum is at 1.609
The function value is -3.047
1.609407
You have multiple declarations of F: some imply that F is a variable, and others that F is an entry point.
In test3.f90, use
real, external :: F
as the only declaration of F.
In min3.f90, you should not have any declaration for F, since the declaration made available by "USE test3" is already sufficient.
OUTPUT:
s:\imsl>test3
The minimum is at 1.609
The function value is -3.047
1.609407
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot!!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now everyting is working like a charm :-)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page