Silverfrost Forums

Welcome to our forums

Passing subroutine or array-valued function name as argument

22 Aug 2007 7:05 #2184

Esteemed FTN Gurus,

Both of My FTN 95 books are unclear on how to pass as arguments the names of (i) array-valued functions, and (ii) subroutines. Perhaps someone can help. :?:

A short sample program is appended at the end of this query to illustrate the problem. For a scalar-valued function, everything works. But with the array-valued function, passing its name as an argument bombs out ('floating point stack fault...') while running

  • although it does not generate any compile errors.

1.) Do I need the INTENT(IN) attribute in the REAL, EXTERNAL declaration of function FUNC_1D?

2.) What is the trick to getting the name of an array-valued function to work when passed as an argument?

3.) How do I pass the name of a subroutine as an argument?

With many thanks 😄, Ludwig

!############################################ module subroutine_library contains !------------------------------------------------- subroutine tabulate_function_1d (func) implicit none integer :: i real :: x real, external, intent(in) :: func do i = 1, 10 x = real(i) print 100, x, func(x) end do 100 format ('x = ', f12.7, 3x, 'f = ', f12.7) end subroutine tabulate_function_1d !------------------------------------------------- subroutine tabulate_function_2d (func) implicit none integer :: i, j real, dimension(2) :: x, f real, external, intent(in) :: func do i = 1, 3 do j = 1, 3 x = (/ real(i), real(j) /) f = func(x) print 100, x(1), x(2), f(1), f(2) end do end do 100 format ('x1 = ', f12.7, 1x, 'x2 = ', f12.7, 1x, / & 'f1 = ', f12.7, 1x, 'f2 = ', f12.7) end subroutine tabulate_function_2d !------------------------------------------------- end module subroutine_library !############################################ module function_library contains !------------------------------------------------- function func_1d (x) result (f) implicit none real, intent(in) :: x real :: f f = x**2 end function func_1d !------------------------------------------------- function func_2d (x) result (f) implicit none real, dimension(2), intent(in) :: x real, dimension(2) :: f f(1) = x(1) + x(2) f(2) = x(1)**2 + x(2)**2 end function func_2d !------------------------------------------------- end module function_library !############################################ program try use subroutine_library use function_library call tabulate_function_1d (func_1d) call tabulate_function_2d (func_2d) end program try !############################################

25 Aug 2007 4:50 #2197

Ludwig,

I must admit it is a long tome since I even had to pass a function as an argument. My preference is to pass an option variable which identifies the function and then provide all the functions in a select case structure. The receiving routine is then limited to the functions it has coded, but has always provided me with sufficient flexibility.

eg

subroutine tabulate_function (func_id) integer funct_id .. select case (func_id) case (1) ! function 1 is sin(x) case (2) ! function 2 is sqrt(x)

You can then also manage array functions much easier.

As for subroutines, I don't think it makes sence to transfer them as an external. Convert them to an integer function.

It's not somthing I would normally try. I suggest KISS

Good luck, John

26 Aug 2007 8:48 #2199

Greetings John,

Thanks for your comments - much appreciated.

Best regards, Ludwig

27 Aug 2007 8:48 #2201

Hi Ludwig and Paul

Your question piqued my interest. I actually thought you couldn't do array valued functions at all until I saw your question and looked it up, in the circumstances I would require them for I normally use subroutines with predefined arrays

in this sort of way :

!_____________________________! subroutine twiddle(arr) real arr(5) ! set array to 4.0

arr = 4.0

end subroutine

!____________________________!

program subcall

real arr(5)

arr = 0.0

write(,) arr

call twiddle(arr)

write(,) arr

end program !_________________________________!

the sub changes the array from 0.0 to 4.0

Anyway I started to play about with the compiler and I think I may have uncovered some compiler bugs in subroutine interfaces or alternatively in my interpretation of the ftn95 documentation and metcalf and reid

I think the following code should be OK according the the documentation on assumed shape arrays !______________________! subroutine twiddle(arr) implicit none

real arr(:) write(,) size(arr) arr = 4

end subroutine !_______________________! program subcall implicit none real arr(5)

arr = 0

write(,) arr

call twiddle(arr)

write(,) arr

end program !_______________________!

however the write statement in the subroutine suggests that the array has 13433 elements

I guess in a real example I would code round this somehow passing the size of the array dimensions explicitly or whatever, but I thouht the compiler should handle this without any messing about seting up an interfaces for the call in the program

which finally brings me to array valued functions

the only way I could get an array valued function of variable length to work was by using an interface in the calling program thus

!________________________________! real function arval ()

real arval(5)

arval = 5.0

end function

!_________________________________! program fnccall implicit none real arr(5)

interface real function arval() real arval(1) end function end interface

arr = 0

write(,) arr

arr = arval()

write(,) arr

end program !______________________________________!

now the thing is that the dimension in the return type requires a value but seems to be only there to get the code to compile I was kind of expecting to code

real arval(:)

in the interface

but this won't compile and the fixed value looks perverse in terms of readability if nothign else

Now I am not a full time fortran guy so apologies if these seem obvious or trivial.

I guess I am surprised I have to define an interface to get something to work since I have never seen one used in any of the code I have to maintain at work which is on the whole admittedly quite old.

apologies for over long post

Carl

Please login to reply.