Reputation: 25
I'm working on this problem of getting the area under a tan curve using Simpson's rule. However, I keep getting errors I don't understand - even on different compilers like gfortran and ifort.
I realize that I could make pi a parameter in the main body of the program, but I'd rather just find out where I'm going wrong. Any help would be very much appreciated.
module consts
!Declare pi as a global variable
real(4),parameter :: pi=3.1415927
end module
PROGRAM simpson
use consts
implicit none
REAL :: area, h, sumo, sume
INTEGER (kind=4) :: i, j, k !Loop index, Counter, Number of points
REAL (kind=4) :: rad, TanTab(0) !Radian variable to be calculated in Subroutine, Result array
!k = number of steps
WRITE(6,*) "Please enter number of steps required (odd number)"
READ(5,*) k
IF(MOD(k,2) == 1) THEN
CONTINUE
ELSE
WRITE(*,*) "Hey, I said as an odd number"
READ(5,*) k
ENDIF
h = (60.0)/(k-1) ! Defining step size in relation to number of sampling points
DO i=1,61,1
! Get table of tan
call degtorad((i-1)*1.0, rad)
TanTab(j) = tan(rad)
j=j+1
write(*,*) "Tan(", i, ")", TanTab(i)
write(*,*) "Tan(", j, ")", TanTab(j)
ENDDO
DO j=1,k-1,h
IF(MOD(k,2) == 1) THEN
sumo = sumo + TanTab(j) !sum of odd functions
ELSE
sume = sume + TanTab(j) !sum of even functions
area = (h/3)*( (4*sumo) + (2*sume) + tan(1.047))
WRITE(6,*) area
ENDIF
ENDDO
END PROGRAM simpson
Upvotes: 0
Views: 538
Reputation: 10195
You have more mistakes in your code:
You should start using debugger and learn how to find problems in your code. The working version is here:
PROGRAM simpson
implicit none
REAL :: area, h, sumo, sume
INTEGER (kind=4) :: i!Loop index
integer, parameter :: k = 100
REAL (kind=4) :: rad, TanTab(k+1) !Radian variable to be calculated in Subroutine, Result array
sumo = 0.0
sume = 0.0
area = 0.0
h = 0.0174532925 * 60.0/real(k) ! Defining step size in relation to number of sampling points
DO i=1,k+1
rad = 0.0174532925 * 60.0 * real(i-1) /real(k)
TanTab(i) = tan(rad)
! write(*,*) "Tan(", i-1, ")", TanTab(i)
ENDDO
DO i=2,k
IF(MOD(i,2) == 1) THEN
sumo = sumo + TanTab(i) !sum of odd functions
ELSE
sume = sume + TanTab(i) !sum of even functions
ENDIF
ENDDO
! by simson
area = (h/3)*( TanTab(1) + (2*sume) + (4*sumo) + TanTab(k+1))
WRITE(*,*) area
! by integration
area = log(1.0) - log(cos(0.0174532925 * 60.0))
WRITE(*,*) area
END PROGRAM simpson
Upvotes: 1
Reputation: 29401
Some things to think about: The loop DO i=1,61,1
suggests that you should be setting TanTab(i)
, not TanTab(j)
. Why bother with the additional variable j
that increments as i
does? And since the loop goes from 1 to 61 suggests that you should declare TanTab
as real, dimension (1:61) :: TabTab
, otherwise its not going to be large enough to store the values. But then your next loop, DO j=1,k-1,h
is different. Are you sure that it is accessing TabTab (j)
in a consistent manner?
Upvotes: 0
Reputation: 78374
I can see one probably cause of a crash at run time, sparking a segmentation violation:
You use j
in the line
TanTab(j) = tan(rad)
before you assign a value to it. Fortran doesn't do any automatic initialisation of variables.
I can also see something very fishy. You declare tantab
to have dimension 0
:
REAL (kind=4) :: rad, TanTab(0)
Now Fortran will happily access elements of arrays outside their declared bounds and sometimes (sometimes for a very long time) the users of a program won't notice the problem. If you compile your code with the option -check bounds
(that's the Intel version, other compilers have the same facility, consult your documentation) and then try running your code you should get a run-time error.
And I agree with @AlexanderVogt (I usually do) about your use of a real variable for the loop index. Don't do that.
Upvotes: 1