Reputation: 414
It is my understanding that you can return an array from a function in Fortran, but for some reason my code is only returning the first value in the array I am asking it to return. This is the function:
function polynomialMult(npts,x,y)
integer npts
double precision x(npts), results(npts + 1), y(npts,npts)
polynomialMult = x(1:npts) + 1
end function
and this is where I'm calling it
C(1:numPoints) = polynomialMult(numPoints,x,f)
print *, C(1:numPoints)`
right now it doesn't do anything useful because I am trying to understand the syntax before I write the logic. I saw some stuff about specifying types for functions, but when I write
integer function polynomialMult(npts,x,y)
or whatever I get a compilation error.
Upvotes: 24
Views: 48236
Reputation: 2145
Fortran has a RESULT keyword which really helps with declaring the type of value that a function returns.
Here is an example program which includes a function using the RESULT keyword to declare returning an array -- in this case an array of 3 character strings.
That blah_3_strings
function returns the array return_val
as its result because that is the variable name declared using the result keyword.
program fsyntax
character*20 message1
character*50 threemessages(3)
integer i
message1 = blah_1_string("test1")
write(*,'(A)') message1
write(*,*)
threemessages = blah_3_strings("testA","testB","testC")
do i=1,3
write(*,'(A)') threemessages(i)
enddo
call exit(0)
contains
! ===== traditional style function declaration =====
character*50 function blah_1_string(str1)
character*(*), intent(in) :: str1
blah_1_string = "blah-" // str1
return
endfunction
! ===== function declaration using RESULT keyword =====
function blah_3_strings(str1,str2,str3) result(return_val)
character*(*), intent(in) :: str1,str2,str3
character*50 :: return_val(3)
return_val(1) = "blah-" // str1
return_val(2) = "blah-" // str2
return_val(3) = "blah-" // str3
return
endfunction
endprogram
Focus on the result keyword and the return_val
declaration in the code.
Here is the program output:
blah-test1
blah-testA
blah-testB
blah-testC
Note: The function return type using old traditional function syntax is apparently limited to intrinsic types. It's hard to pin down all the limitations and variations, but has something to do with jamming all of the function type information into one line. Also, most documentation focuses on other reasons why the RESULT keyword exists, such as recursion, but it works for any function declaration really.
Upvotes: 0
Reputation: 47
I agree with the previous responder that the following works:
polynomialMult = x + 1
However, without knowing that polynomialMult and x are arrays, one might assume it is a scalar operation. I prefer to be obvious and do it this way:
polynomialMult(:) = x(:) + 1
I have even insisted that the coders in my group do it this way. I don't like to work hard to understand someone's code--I want it to be obvious what they are doing.
Upvotes: 3
Reputation: 78364
To define a function which returns an array include the function declaration inside the function, like this:
function polynomialMult(npts,x,y)
integer npts
double precision x(npts), results(npts + 1), y(npts,npts)
! Change the next line to whatever you want
double precision, dimension(npts) :: polynomialMult
polynomialMult = x(1:npts) + 1
end function
Your declaration
integer function polynomialMult(npts,x,y)
declares that the function returns an integer. An integer, not an array of integers. I don't think the standard allows function declarations such as:
integer, dimension(10) function polynomialMult(npts,x,y)
but I could be wrong. I always use the form I showed you above.
If you have an up to date Fortran compiler you can do clever things such as return an allocated array. And I suggest you figure out array syntax. For example, your statement:
polynomialMult = x(1:npts) + 1
could more concisely be written:
polynomialMult = x + 1
since Fortran will map the scalar addition to all elements of the array x which you have declared to have only npts
elements.
Passing the sizes of arrays into subroutines is very FORTRAN77 and almost always unnecessary now. Generally you either want to operate on every element in an array (as in the array syntax example) or you should let the subprogram figure out the size of the array it is dealing with.
Upvotes: 34