Solved

Posted on 2011-10-28

I want to calculate the rolling 20 day standard deviation on Fortran. I was able to write the following code, but I think I am not adding the sum squares correctly or I am not calculating the SD in the correct fashion that I need to include the averge somewhere. How can change this code so it will work.

SUM(1)=0

SUMSQ(1)=0

Do I4=1,20

SUM(1)=SUM(1)+X(I4)

SUMSQ(1)=SUMSQ(1)+X(I4)**2

Enddo

Do I4=21,M1+19

SUM(I4-19)=SUM(I4-20)+X(I4)-X(I4-20)

SUMSQ(I4-19)=SUMSQ(I4-20)+X(I4)**2 -X(I4-20)**2

End Do

DO I4=1,M1

AVG(I4) =SUM(I4)/20

SD(I4)=SQRT((SUMSQ(I4))/19)

Write(15,*) SD(I4),AVG(I4),SUMSQ(I4)

END DO

SUM(1)=0

SUMSQ(1)=0

Do I4=1,20

SUM(1)=SUM(1)+X(I4)

SUMSQ(1)=SUMSQ(1)+X(I4)**2

Enddo

Do I4=21,M1+19

SUM(I4-19)=SUM(I4-20)+X(I4

SUMSQ(I4-19)=SUMSQ(I4-20)+

End Do

DO I4=1,M1

AVG(I4) =SUM(I4)/20

SD(I4)=SQRT((SUMSQ(I4))/19

Write(15,*) SD(I4),AVG(I4),SUMSQ(I4)

END DO

10 Comments

When only 2 days have passed, then the average should be only the average of those 2 days, right?

I recommend the following changes. (I don't know FORTRAN at all; I even had to look up how to do comments so this isn't tested, but the algorithm is correct and the math is right so I think it's good).

```
SUM(1)=X(1)
SUMSQ(1)=X(1)**2
AVG(1)=X(1) !start the averages too
AVGSQ(1)=X(1)**2
Do I4=2,20 !start at 2 since 1 is done already
SUM(I4)=SUM(I4-1)+X(I4)
SUMSQ(I4)=SUMSQ(I4-1)+X(I4)**2
AVG(I4)=SUM(I4)/I4 !calculate it as the average of all so far
AVGSQ(I4)=SUMSQ(I4)/I4
END DO
Do I4=21,M1 !now we just do the rest
SUM(I4)=SUM(I4-20)+X(I4)-X(I4-20)
SUMSQ(I4)=SUMSQ(I4-20)+X(I4)**2 -X(I4-20)**2
AVG(I4)=SUM(I4)/20 !These are just /20
AVGSQ(I4)=SUMSQ(I4)/20
End Do
DO I4=1,M1
SD(I4)=SQRT(AVGSQ(I4) - AVG(I4)**2)
Write(15,*) SD(I4),AVG(I4),SUMSQ(I4)
END DO
```

I tried to run it but the standard deviations are wrong for some reason.

I think this might be the issue, the average for standard deviation (SD) 1 (which is the standard deviation from day 1 to day 20) would be the average of Day 1 to Day 20.

So, I think your answer to the previous question was mostly correct, but we might want to chahnge the SD's calculation only, otherwise I think the loops are fine.

I hope I was able to explain myself :)

If you want to ignore the first 19 days and only start reporting when you have 20 data points, then just start the last loop at 20 instead of 1.

```
nroll = 20
m1 = SIZE(x)
! compute all the averages with a varying window size
DO i4 = 1, m1
nval = MIN(m1, nroll)
i3 = i4 - nval + 1
avg(i4) = SUM(x(i3:i4))/nval
avgsq(i4) = SUM(x(i3:i4)**2)/nval
ENDDO
! unchanged with respect to Tommy's
DO I4=1,M1
SD(I4)=SQRT(AVGSQ(I4) - AVG(I4)**2)
Write(15,*) SD(I4),AVG(I4),SUMSQ(I4)
END DO
```

Title | # Comments | Views | Activity |
---|---|---|---|

hasOne challenge | 59 | 66 | |

Arduino EDI - Programming language | 3 | 36 | |

vb6 connector to SQL Server | 2 | 23 | |

Looking for VB6 code to read SQL table export it to ascii | 8 | 0 |

This is an explanation of a simple data model to help parse a JSON feed

A short article about problems I had with the new location API and permissions in Marshmallow

Join the community of 500,000 technology professionals and ask your questions.

Connect with top rated Experts

**14** Experts available now in Live!