Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

calling several functions

rodolfob
Beginner
511 Views
Hey there, I use Visual Fortran 5.0 to do some numerical simulations and today I need to evaluate several functions. Here is how it works (in a simplified way)...

- I have the main program that needs to know the integral of several already defined numerical functions.
- To evaluate the integral I have a general procedure that only requires the integration limits since it already contains the function to be integrated as a subroutine within the procedure.
- The question is can I use this procedure several times indicating which function it has to evaluate on each call?, and how do I indicate that??

If you can suggest any reading on this topic that will be great!!!!...

Thanks in advance!
0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
511 Views
I guess you're looking for something like:
program p
implicit none
!Without external, p doesn't "know" that it's a 
!function defined somewhere else:
real, external:: sin3, x5exp, Integral
real::           x
write(*,*) Integral(sin3, 0., 1.)
write(*,*) Integral(x5exp, 0., 1.)
write(*,*) Integral(sinh, 0., 1.)
end program p
!-----------------
real function Integral(FuncToEval, down, up)
!dumb square integration
implicit none
real, external::  FuncToEval
real::            down, up
real::            x, dx
!
dx = 1.e-6
x = down
Integral = 0. 
do while(x < up)
   Integral = Integral + dx*FuncToEval(x)
   x = x+dx
end do
!
end function FuncToEval
!-----------------
real function sin3(x)
implicit none
real:: x
sin3 = sin(x**3)
end function sin3
!-----------------
real function x5exp(x)
implicit none
real:: x5exp
x5exp = 5*exp(x)
end function x5exp
I hope it's self-explaining. As you can see, you can pass procedure names around as arguments, as long as you ensure that every procedure involved "knows" it's a function name, not a variable name. In the sample, I used "F77-style" EXTERNAL keyword for this purpose. In F90, you could use use-association (modules) to ensure visibility, and INTERFACE block to FuncToEval within Integral to ensure typechecking.

A limitation is that every function involved must have same prototype (real function with 1 real argument in the sample). Note that, since e.g. intrinsic SINH satisifes the prototype, it can be used as well.

Paradoxically, similar technique is used a lot in GUI programming, where called user-writen routines are referred to as callbacks or handlers -- for example, one writes a routine that will be automatically called by the system when a mouse button is pressed.

CVF QSORT routine is another sample to take a look at.

Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
511 Views
P.S. If I recall correctly, DVF 5 has a bug so it won't accept "real, external::" form. Instead, you need either an interface block:
interface
   real function sin3(x)
   real:: x 
   end function
end interface
or "F77-style" declaration:
real sin3
external sin3


0 Kudos
Reply