Posted by: nealc | November 6, 2009

Running standard deviation

Found this once and then forgot it, so I just found it again.  I’m going to try it out, it would be nice to have some sense of accuracy in option prices coming out of MC. It’s an article on a technique which it claims to be from Knuth ultimately. I don’t get it right away, as it says it’s not obvious that it gives the right answer. but it’s supposed to be accurate and tolerate roundoff etc. it seems to be adding numbers of different magnitudes just as any other technique, which can cause roundoff, but it does seem to only subtract numbers of similar magnitudes.

maybe a good use for a class/object, since it keeps some running variables, which i also have yet to learn in python.

ok its done. python classes are pretty neat. the __str__(self) is nice. but it’s awfully clunky to have to write self.n etc all the time, and i think its inconsistent considering how much automatic scoping python does already. im always worried about aliasing problems in python since there’s automatic references in places where i don’t expect them and this inconsistency isn’t reassuring. but for this particular application the class paradigm is remarkably convenient. and now that i have stdev, i also put in 95% CI and now i have some new useful data.

and another place where i got burned.  if you look in my code below, there’s a spot where i have self.n+0. in the denominator.  without the +0. it was treating it as an int.  i hope one day we get a language which automatically promotes to float when this happens.

what is a python module? it’s just a file with python code in it. but whenever i change my file that contains the running stdev code, and run the calling module, ipython doesn’t reload investigating that led me to ipython’s %pdb on magic function, which is very neat, it automatically launches pdb which i’ve never used before, but which i’ve always wanted to use.

from math import *

class sigmarunner:
    def __init__(self):
        self.n = 0
        self.mean = 0.
        self.s = 0.
        self.mold = 0.
        self.sold = 0.

    def push(self, x):
        self.n += 1

        if self.n == 1:
            self.mold = x
            self.mean = x
            self.mean = self.mold + (x-self.mold)/(self.n+0.)
            self.s = self.sold + (x-self.mold)*(x-self.mean)

            self.mold = self.mean
            self.sold = self.s

    def variance(self):
        return self.n > 1 and (self.s/(self.n-1.)) or 0.

    def stdev(self):
        return sqrt(self.variance())

    def marginerror95(self):
        return 1.96*self.stdev()/sqrt(self.n)
    def conflo95(self):
        return self.mean-self.marginerror95()
    def confhi95(self):
        return self.mean+self.marginerror95()

    def __str__(self):
        return "n=%d mean=%g stdev=%g E=%g" % (self.n, self.mean, self.stdev(), self.marginerror95())

    #def __repr__(self):
        #return "n=%d mean=%g stdev=%g" % (self.n, self.mean, self.stdev())

if __name__=='__main__':
    s = sigmarunner()

    print s
    print s
    print s
    print s
    print s
    print s
    print s

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: