[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
Solved

# Rolling Standard Deviations on Fortran from the arrays

Posted on 2011-10-28
Medium Priority
343 Views
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
0
Question by:awesomejohn19

LVL 37

Expert Comment

ID: 37046606
SD(I4) = SQRT(SUMSQ(I4) - SUM(I4)**2)
0

LVL 37

Expert Comment

ID: 37046612
Sorry
SD(I4) = SQRT(SUMSQ(I4)/20 - AVG(I4)**2)

0

LVL 37

Assisted Solution

TommySzalapski earned 1000 total points
ID: 37046693
And to fix the error from the other question, I see what you are doing now.
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
``````
0

Author Comment

ID: 37047004
Tommy, thanks for your response. I really appreciate you helping without prior knowledge of fortran.

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 :)

0

LVL 37

Expert Comment

ID: 37047336
The way I set it up, SD(i) is the standard deviation for the last 20 days from day i to day i-19.
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.
0

LVL 5

Expert Comment

ID: 37055504
I add a suggestion: SUM() is an intrinsic fortran function for summing the elements of an array, so it is not a good idea ti use that name for an array, I suggest to use a different name.
0

LVL 5

Accepted Solution

dcesari earned 1000 total points
ID: 37055545
I propose a more compact and universal version, using Fortran 90 notation (here SUM() is really the SUM intrinsic function). It is not optimised as the one proposed, because it recomputes all the sums every time, but if the rolling average extension is really fixed to 20 elements, you will hardly notice the difference in performance on a modern cache-based architecture.
``````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
``````
0

LVL 37

Expert Comment

ID: 37056266
Putting nroll in as a variable was a good idea.
I'm assuming line 6 was meant to be
nval = MIN(i4, nroll)

Yours is a bit more computationally intense but does require less memory and fewer code lines.
0

LVL 5

Expert Comment

ID: 37056282
yes, you're absolutely right, that should read nval = MIN(i4, nroll), thanks
0

LVL 50

Expert Comment

ID: 37230448
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, itâ€™s also â€¦
What do responsible coders do? They don't take detrimental shortcuts. They do take reasonable security precautions, create important automation, implement sufficient logging, fix things they break, and care about users.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). Uâ€¦
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can launâ€¦
###### Suggested Courses
Course of the Month20 days, 10 hours left to enroll