1

I couldn't find much when I searched for standard deviations and population variances on fortran 95. So I'm wondering if someone could help me? Thanks for your time.

Here is what I did, it compiled fine but it turned out giving wrong values:

    SUBROUTINE ComputeStats(num, sum, avg, variance, sdv)

        REAL, INTENT(IN):: num(10)
        REAL, INTENT(OUT):: sum
        REAL, INTENT(OUT):: avg, variance, sdv

        DO i=1, 10
            sum=sum+num(i)
        END DO

        avg=sum/10

        DO i=1, 10
            variance=(((num(i)-avg)**2.0)/10)
            variance=variance+i
            sdv=variance**0.5
        END DO

    END SUBROUTINE
EuropaDust
  • 333
  • 4
  • 12
  • 1
    As an aside, the first loop can be replaced with the SUM intrinsic, e.g. "mysum = sum(num)" (calling the variable mysum in order to avoid confusing wrt. using the same name as the intrinsic function). – janneb Apr 05 '11 at 06:39
  • On the first run through the first do-loop, the variable sum is still undefined. It is therefore incorrect to use it on the right hand side of an assignment statement. Put `sum = 0` before the start of the loop. (Many compilers initialize memory to zero, but the standard doesn't guarantee that, so don't rely on it.) – eriktous Apr 05 '11 at 11:03

2 Answers2

3

You don't calculate the variance correctly.

       variance = 0
       DO i=1, 10
         variance = variance + (((num(i)-avg)**2.0)/10)
       END DO

This gives you the right variance for e.g. 1,1,1,1,1,1,1,1,1,1 which is 0, not 10.

Benjamin Bannier
  • 55,163
  • 11
  • 60
  • 80
0

A simple subroutine for finding the standard deviation of an array

subroutine find_std(n,arr,std_dev)
integer,intent(in)::n
real,intent(in),dimension(n)::arr
real,intent(out)::std_dev
real::variance, avg
integer::i
avg=sum(arr)/n
variance=0.
do i=1,n
  variance=variance+(arr(i)-avg))**2
end do
variance=variance/n
std_dev=sqrt(variance)
end subroutine

The size of the array is passed here as the first argument (n). We can circumvent this by using an assumed-shape array and putting the subroutine under an explicit interface like module or an interface block.

subroutine find_std(arr,std_dev)
real,intent(in),dimension(:)::arr
real,intent(out)::std_dev
real::variance, avg
integer::n,i
n=size(arr)
avg=sum(arr)/n
variance=0.
do i=1,n
  variance=variance+(arr(i)-avg)**2
end do
variance=variance/n
std_dev=sqrt(variance)
end subroutine
srinivasu u
  • 1,393
  • 11
  • 12