Simple question about functions

I was wondering if there was a way of squaring a vector or a scalar with the same function? Basically, i’m wondering if these two functions:

function f(x)
real(kind=8) :: f, x
f = x**2/2
end function
end program test

function square(x)
real(kind=8),allocatable :: x(:), square(: )
square = 0.5*x**2
end function

could be fused into one?


Welcome to the forum. Yes, there is, using elemental functions, for a scalar and conformable array arguments of any rank. Here is an example:

module m
implicit none
integer, parameter :: dp = kind(1.0d0)
elemental function half_square(x) result(y)
real(kind=dp), intent(in) :: x
real(kind=dp)             :: y
y = 0.5_dp*x**2
end function half_square
end module m
program main
use m, only: dp, half_square
implicit none
print*,half_square(real([1,4,9],kind=dp)) ! output: 0.5 8. 40.5
end program main

Ily, Fortran also supports many vector (array) operations. For example, your task can be accomplished without writing any function body:

program main
   real, allocatable :: x(:), y(:)
   x = [2.0,4.0,5.0]
   y = x*x*0.5
   print *,y

And here a nitpick: real(kind=8) may fail or, perhaps worse, mean something else than you expect, because the kind numbers, like 8 above, are not fixed between compilers. @Beliavsky showed a way to achieve double precision that ought to work with any compiler. Others exist as well.
The adagium is: never use literal constants for kinds, but use instead parameters.

1 Like