# How to define a function to do job according to the size of input arrays?

Dear all,

I have a question kind of like function overloading, kind of not exactly like so, and it not elemental function either. It is just that,
How to define a function to do job according to different size of input arrays?

For example, two functions AAA and BBB

``````function AAA(x)
real :: x(1), AAA
! something
end function AAA

function BBB(x)
real :: x(2), BBB
! something completely different from function AAA does.
end function BBB
``````

Is it possible to define a function CCC which can automatically switch between AAA and BBB depending on the size of the input array x?

I mean I can do

``````function CCC(x)
real :: x(:), CCC
if (size(x)==1)  CCC=AAA(x)
if (size(x)==2)  CCC=BBB(x)
end function CCC
``````

Or I can use `select case` instead of the `if then else`.

But is there better more high performance elegant way?

Overloading works on rank, type and kind of the arguments, so that won’t work in this case. If your functions AAA and BBB do more than a simple assignment, then worrying about the performance of whatever dispatching mechanism is futile: it will not be noticeable.

If you are looking for a different way to encode it, you might try this (sketch only):

``````function CCC(x)
real :: x(:)
type(function_pointer), dimension(:) :: pfunction  ! Filled and defined elsewhere

CCC = pfunction(size(x))%function(x)
``````

Missing bits and pieces: the definition of the derived type, filling the elements with pointers to AAA and BBB and possibly others, clipping the index into pfunction to valid values (min(size(x), size(pfunction)), say)

It is not likely to be faster than a simple chain of ifs or (I would prefer that) a select-case. But it is extendible without changing the implementation of CCC.

1 Like

``````module Vec
type :: Vec1_t
real :: x(1)
end type Vec1_t
type :: Vec2_t
real :: x(2)
end type Vec2_t

interface Vec
module interface AAA,BBB
end interface

contains

function AAA(Vec1)
type (vec1_t) :: Vec1
real :: AAA
! something
end function AAA

function BBB(Vec2)
type (vec1_t) :: Vec2
real :: BBB
! something completely different from function AAA does.
end function BBB
end module Vec
``````

You can put the two derived types with the corresponding functions in two different modules.

2 Likes

Yes, that is certainly a solution 1 Like