I have the following problem:
I have a module containing some fortran function, which takes 2 (mathematical) functions as its input. The way I do this at the moment is by defining an interface for the input functions. My module looks like this:
module myModule
implicit none
save
abstract interface
subroutine functype1(x,f)
import dp
real(kind=dp), dimension(:),intent(in) :: x
real(kind=dp), dimension(:),intent(out):: f
end subroutine
subroutine functype2(x,M)
import dp
real(kind=dp), dimension(:),intent(in) :: x
real(kind=dp), dimension(:,:),intent(out):: M
end subroutine
end interface
contains
function taylorExpansion(func,funcdiff)
procedure(functype1) :: func ! The mathematical function f
procedure(functype2) :: funcdiff ! The function evaluating the derivative/gradient of f
! ...
! (further implementation)
! ...
end function
The problem is now that I want functype1 to be kind of general: sometimes the input is just a real, sometimes it's an array of reals. Is it possible to do this smoothly? (At the moment I'm forced to pass an array of size 1 to func1 instead of a real, which is quite clumsy)
Another way to formulate this is: is it possible to make a type which is a real OR an array of reals? This way both calls would be possible:
program testprog
use myModule
implicit none
save
call taylorExpansion(xsquared,xdiff) ! functype1 can accept reals
call taylorExpansion(vectornorm,vectornormdiff) ! functype1 can also accept vectors
contains
subroutine xsquared(x,fx)
real(kind=dp) :: x
real(kind=dp) :: fx
fx = x**2
end subroutine
subroutine twox(x,fx)
real(kind=dp) :: x
real(kind=dp) :: fx
fx = 2*x
end subroutine
subroutine vectornorm(x,fx)
real(kind=dp), dimension(:) :: x
real(kind=dp) :: fx=0.0
integer i
do i = 1,size(x)
fx = fx + x(i)**2
end do
end subroutine
subroutine vectornormdiff(x,fx)
real(kind=dp), dimension(:) :: x
real(kind=dp), dimension(:) :: fx
integer i
do = 1,size(x)
fx(i) = 2*x(i)
end do
end subroutine
end program