-------------- Original message ----------------------
From: Colin Millar <[log in to unmask]>
>
>
>
> Hi,
>
> This is a short question....
>
> Is there a better way of coding the following:
>
> function p_at_M (M, M_trip)
>
> double precision, dimension(:,:,:,:,:,:), intent(in ) :: M
>
> double precision, dimension(:,:,:,:,:), intent(in ) :: M_trip
>
> double precision,
> dimension(size(M,1),size(M,2),size(M,3),size(M,4),size(M,5),size(M,6))
> :: p_at_M
>
> p_at_M = -1.d0*(M - spread(M_trip,6,size(M,6)))**2
>
> end function p_at_M
>
>
>
> Also - is it possible to have functions with variable dimensionality?
> My issue is with the dimension attribute - ideally I would like to do
> something like
>
> dimension(shape(M)) :: p_at_M
>
> Or
>
> dimension(repeat(3,4)) :: p_at_M
>
> any suggestions would be appreciated,
>
> Many thanks,
>
> Colin.
>
As Aleks said, Fortran doesn't have much support for fooling around
with rank. Fortran 2008 has a MACRO capability that can do what you
want, but it will be a while before there are 2008 compilers ;).
you can make functions with variable dimensions by creating a family
of generic functions and let the compiler resolve them by rank. The
drawback is that you have to create each instance by hand--there's
not much compiler magic to help. About the best you can do is use
INCLUDE files to bring in the rankless code. something like
>
> function p_at_M_6 (M, M_trip) RESULT (p_at_M)
INCLUDE "declarations_that_dont_vary_with_rank"
>
> double precision, dimension(:,:,:,:,:,:), intent(in ) :: M
>
> double precision, dimension(:,:,:,:,:), intent(in ) :: M_trip
>
> double precision,
> dimension(size(M,1),size(M,2),size(M,3),size(M,4),size(M,5),size(M,6))
> :: p_at_M
INTEGER, parameter :: D = 6
INCLUDE "the_executable_guts_of_routine"
>
>
> end function p_at_M_6
And fix up "the guts" to look like
> p_at_M = -1.d0*(M - spread(M_trip,D,size(M,D)))**2
And the including isn't worth the effort unless there are a bunch of lines
in the routine.
Dick Hendrickson
|