# [IMSL]

## [IMSL]

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!!! test.f90

17 posts / 0 new
For more complete information about compiler optimizations, see our Optimization Notice.

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.

```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
```

Thanks a lot for the help :-) !

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!!!

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.

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.

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 will try that. Thanks!

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 :-) min.f90test2.f90

Here are modified versions of your code:

```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

```

```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

```
Program Output:

```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

```

exactly was i was trying to do :-) Thanks a lot!!!

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. [F] 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!!! min.f90test2.f90

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.

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. [F] 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! min3.f90test3.f90

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

Thanks a lot!!!

Now everyting is working like a charm :-)