76 lines
2.0 KiB
Python
76 lines
2.0 KiB
Python
from random import gauss
|
|
from math import sqrt
|
|
from pprint import pprint as pp
|
|
|
|
NMAX=50
|
|
|
|
def statscreator():
|
|
sum_ = sum2 = n = 0
|
|
def stats(x):
|
|
nonlocal sum_, sum2, n
|
|
|
|
sum_ += x
|
|
sum2 += x*x
|
|
n += 1.0
|
|
return sum_/n, sqrt(sum2/n - sum_*sum_/n/n)
|
|
return stats
|
|
|
|
def drop(target, sigma=1.0):
|
|
'Drop ball at target'
|
|
return gauss(target, sigma)
|
|
|
|
def deming(rule, nmax=NMAX):
|
|
''' Simulate Demings funnel in 1D. '''
|
|
|
|
stats = statscreator()
|
|
target = 0
|
|
for i in range(nmax):
|
|
value = drop(target)
|
|
mean, sdev = stats(value)
|
|
target = rule(target, value)
|
|
if i == nmax - 1:
|
|
return mean, sdev
|
|
|
|
def d1(target, value):
|
|
''' Keep Funnel over target. '''
|
|
|
|
return target
|
|
|
|
|
|
def d2(target, value):
|
|
''' The new target starts at the center, 0,0 then is adjusted to
|
|
be the previous target _minus_ the offset of the new drop from the
|
|
previous target. '''
|
|
|
|
return -value # - (target - (target - value)) = - value
|
|
|
|
def d3(target, value):
|
|
''' The new target starts at the center, 0,0 then is adjusted to
|
|
be the previous target _minus_ the offset of the new drop from the
|
|
center, 0.0. '''
|
|
|
|
return target - value
|
|
|
|
def d4(target, value):
|
|
''' (Dumb). The new target is where it last dropped. '''
|
|
|
|
return value
|
|
|
|
|
|
def printit(rule, trials=5):
|
|
print('\nDeming simulation. %i trials using rule %s:\n %s'
|
|
% (trials, rule.__name__.upper(), rule.__doc__))
|
|
for i in range(trials):
|
|
print(' Mean: %7.3f, Sdev: %7.3f' % deming(rule))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
rcomments = [ (d1, 'Should have smallest deviations ~1.0, and be centered on 0.0'),
|
|
(d2, 'Should be centred on 0.0 with larger deviations than D1'),
|
|
(d3, 'Should be centred on 0.0 with larger deviations than D1'),
|
|
(d4, 'Center wanders all over the place, with deviations to match!'),
|
|
]
|
|
for rule, comment in rcomments:
|
|
printit(rule)
|
|
print(' %s\n' % comment)
|