Modifying the value of a float-like object

C or L Smith smiles at worksmail.net
Fri Apr 24 17:09:14 EDT 2009


I happened across the recent discussion and found it very interesting as I have been dusting off and trying to get ready a module that I had made that created a number class that handled numeric values and uncertainties in computations by computing (via overloaded operators) a new value and uncertainty after every operation. It treats all errors as uncorrelated, however.

Can you use a dictionary of values that gets initialized in the function where you are doing the calculation to act as your modifiable float? The idea is:
* collect the variable, value and uncertainties in a dictionary
* for some number of iterations, 
--tweak all the values
--send them to your function
--have the function start by evaluating those values in its own context then...
--perform the computation as normal and return the result...
--which is accumulated
* compute the average and deviation of the results that were accumulated.

Here's a working example. 

Lot's to learn from the recipe that you posted. Thanks!

/chris

###
def meanstdv(x):
    from math import sqrt
    mean = std = 0
    y=x[:]
    y.sort()
    while len(y)>1:
        y.append(y.pop(0)+y.pop(0))
    mean = y[0] / float(len(x))
    for a in x:
        std += (a - mean)**2
    std = sqrt(std / float(len(x)-1))
    return mean, std

def makecontext( cmds=''):
  #execute cmds in clean context (e.g. from math import *)
  context = {}
  for c in cmds:
    if c:
      exec(c, context)
  return context

def func(context):
    #initialize vars in context into this function's context
    for _k,_v in context.items():
        try:
            exec('%s=%s'%(_k,str(_v)))
        except:
            pass

    #now do the calculation and return a result
    z=x+y
    return z

# these are the input variables with values and uncertainties
vuexpr='''
x=1.2,.1
y=2.3,.2
'''

# load them into a dictionary
vudict={}
for li in vuexpr.strip().splitlines():
    expr,u=li.split(',')
    vname,vval=expr.split('=')
    vudict[vname]=(eval(vval),eval(u))

import random
# accumulate the results
computed_vals=[]
for i in range(1000):
    init=[]
    for vname,(vval,u) in vudict.items():
        expr='%s=%s'%(vname,random.normalvariate(vval,u))
        init.append(expr)
    computed_vals.append(func(makecontext(init)))

# report the ave, dev of computed value
print meanstdv(computed_vals)

###### output
>>> (3.4963200469919222, 0.22218528738467364)
>>> # using my own routines...
>>> a=phys(1.2,.1);b=phys(2.3,.2); a+b
(3.5,0.22360679775)
>>> print _
3.5(2)




More information about the Python-list mailing list