0

My code works except for when I am trying to use a function to calculate the average of a set of values from an array. I omitted the large part of my program because without doing these steps everything runs fine. Thank you!

Inside my main program I have

averagecalc=average(array(stepsize),stepsize)
WRITE(*,*) averagecalc

Out of my main program I have

FUNCTION average(array(),stepsize)
    REAL,INTENT(IN),DIMENSION(stepsize)::array
    INTEGER,INTENT(IN)::stepsize
    average=SUM(array(stepsize))/stepsize
END FUNCTION

My full program is

PROGRAM subroutines
IMPLICIT NONE

!variables
INTEGER:: i,stepsize,j,counts
 CHARACTER:: choice
REAL,EXTERNAL:: functions,average
REAL:: a,function1,function2,function3,x,upperbound,lowerbound,averages,sums,averagecalc
REAL,ALLOCATABLE::array(:)

!formats
101 FORMAT(A)     !single text element only
102 FORMAT()      ! <description>

!-------Variable Definitions-------!
!     INTEGER:
!         i: used as a counter
!         stepsize: the number of steps the user inputs
!         j: used as a counter
!         counts: used to keep track of steps
!
!     CHARACTER:
!         choice:
!     REAL,EXTERNAL:
!             functions:
!             average:
!     REAL:
!
!
!
!
!
!
!
!
!
!
!----------------------------------!


!<Begin Coding Here>


!Taking in information on which equation and bounds and stepsize
 CALL section1(lowerbound,upperbound,stepsize,choice)





!Calculating equations based on choices and allocating array,writing out array
ALLOCATE(array(stepsize))
x=lowerbound
counts=0
WRITE(*,101) '       |----------------------|'
WRITE(*,101) '       |Step  |     x |   f(x)|'
WRITE(*,101) '       |----------------------|'
DO i=1,stepsize
  IF(choice.EQ.'A') THEN
      array(i)=function1(x)
  ELSE IF(choice.EQ.'B') THEN
      array(i)=function2(x)
  ELSE IF(choice.EQ.'C') THEN
      array(i)=function3(x)
  END IF
  counts=counts+1
  WRITE(*,'(I10,F10.3,F10.3)') counts,x,array(i)
  x=x+(upperbound-lowerbound)/stepsize
END DO





!Writing the averages
averagecalc=average(array(stepsize),stepsize)
WRITE(*,*) averagecalc



END PROGRAM subroutines
!------------------------------------------------SECTION 1-------------------------------------------------
SUBROUTINE section1(lowerbound,upperbound,stepsize,choice)
IMPLICIT NONE
REAL,INTENT(OUT)::lowerbound,upperbound
INTEGER,INTENT(OUT):: stepsize
 CHARACTER,INTENT(OUT):: choice
101 FORMAT(A)     !single text element only
102 FORMAT()      ! <description>

WRITE(*,101) 'Please choose one of the following choices with a capital letter;'
WRITE(*,*)
WRITE(*,101) 'A) f(x)=x^2+2*x+4'
WRITE(*,*)
WRITE(*,101) 'B) f(x)=|x+4|'
WRITE(*,*)
WRITE(*,101) 'C) f(x)=sin(x)+42'
  READ(*,*) choice
IF(choice.EQ.'A') THEN
      WRITE(*,*)
  ELSE IF(choice.EQ.'B') THEN
      WRITE(*,*)
  ELSE IF(choice.EQ.'C') THEN
      WRITE(*,*)
  ELSE 
      STOP 'Please enter either A, B, or C'
END IF

WRITE(*,101) 'Please enter a lower bound'
  READ(*,*) lowerbound
WRITE(*,101) 'Please enter a upper bound'
  READ(*,*) upperbound    
WRITE(*,101) 'Please enter a step size'
  READ(*,*) stepsize
END SUBROUTINE section1




!-------------------------------------------------------functions------------------------------------------
FUNCTION function1(x)
  REAL,INTENT(IN)::x
  function1=((x**2)+(2*x)+4)
END FUNCTION
FUNCTION function2(x)
  REAL,INTENT(IN)::x
  function2=ABS(x+4)
END FUNCTION
FUNCTION function3(x)
  REAL,INTENT(IN)::x
  function3=sin(x)+42
END FUNCTION







!---------------------------------------average value--------------------------
FUNCTION average(array(),stepsize)
  REAL,INTENT(IN),DIMENSION(stepsize)::array
  INTEGER,INTENT(IN)::stepsize
  average=SUM(array(stepsize))/stepsize
END FUNCTION
  • 1
    What do you really want to compute? What is the error? – innoSPG Apr 01 '14 at 23:39
  • 2
    With modern Fortran you will do better to place your subroutines and functions in a module and then `use` that module from the main program. That way the compiler will "know" how to call the subroutines and functions. As a practical matter, if you have everything in one file, place the module before the main program. Here is an example: http://stackoverflow.com/questions/6511711/computing-the-cross-product-of-two-vectors-in-fortran-90 – M. S. B. Apr 01 '14 at 23:51
  • I wonder if the OP meant "two main programs" rather than "to main programs" in the title. If so the thread title can be edited. – Fortranner Apr 02 '14 at 13:36

1 Answers1

1

There is at least one syntactic error in your code which will prevent compilation, in this line

FUNCTION average(array(),stepsize)

where the empty parentheses after array are not permitted. Personally I wouldn't delete them, I'd rewrite the function somewhat like

real function average(array)
    real, dimension(:), intent(in) :: average
    average = sum(array)/size(array)
end function average

Passing the size of the array as a separate argument is unnecessary in modern Fortran, and rather suggests, as your previous question did, that you are sending your questions through a wormhole from about 1979.

As you've constructed your source file the compiler can't check that the arguments passed to your procedures match the procedure definitions. Either follow the advice you have already had to place them into a module and use-associate them, or:

  • move the line end program subroutines to the end of the source file; AND
  • in the location you move that line from insert the line contains

These two steps will allow the compiler to check procedure interfaces.

Finally, you have two semantic errors in your program, one serious, one less so.

One, you have a variable named stepsize whose use and description make it clear that this is actually a number of steps. You even prompt the user to enter a step size but treat the response as a number of steps. That's just wrong.

Two, you have a program named subroutines. What ?!

Finally, and I mean it this time, if you ask further questions here on SO I suggest:

  • that you actually ask a question, your posting above doesn't;
  • if you have a question about code which won't compile then report the error messages your compiler raises;
  • while whitespace is, in general, a good thing, lots of empty lines in snippets posted on SO just make your readers task more laborious; I don't see anywhere in this question where multiple blank lines couldn't be replaced by a single blank line without improving your post's readability.
High Performance Mark
  • 77,191
  • 7
  • 105
  • 161