def impose_collapse(pairs, samples, weights): """collapse the weight and position of each pair (i,j) in pairs Collapse is defined as weight[j] += weight[i] and weights[i] = 0, with samples[j] = samples[i]. Inputs: samples -- a list of sample points weights -- a list of sample weights pairs -- set of tuples of indices (i,j) where collapse occurs For example: >>> impose_collapse({(0,1),(0,2)},[1,2,3,4,5],[.2,.2,.2,.2,.2]) ([1.5999999999999996, 1.5999999999999996, 1.5999999999999996, 4.5999999999999996, 5.5999999999999996], [0.6000000000000001, 0.0, 0.0, 0.2, 0.2]) >>> impose_collapse({(0,1),(3,4)},[1,2,3,4,5],[.2,.2,.2,.2,.2]) ([1.3999999999999999, 1.3999999999999999, 3.3999999999999999, 4.4000000000000004, 4.4000000000000004], [0.4, 0.0, 0.2, 0.4, 0.0]) Note: is 'mean-preserving' for samples and 'norm-preserving' for weights """ samples, weights = list(samples), list(weights) # don't edit inputs m = mean(samples, weights) # allow negative indexing pairs = zip(*tuple( tuple(len(weights) + i if i < 0 else i for i in j) for j in zip(*pairs))) #XXX: any vectorized way to do this? from mystic.tools import connected for i, j in connected(pairs).iteritems(): v = weights[i] for k in j: v += weights[k] weights[k] = type(v)(0.0) samples[k] = samples[i] weights[i] = v return impose_mean(m, samples, weights), weights
def impose_collapse(pairs, samples, weights): """collapse the weight and position of each pair (i,j) in pairs Collapse is defined as weight[j] += weight[i] and weights[i] = 0, with samples[j] = samples[i]. Inputs: samples -- a list of sample points weights -- a list of sample weights pairs -- set of tuples of indices (i,j) where collapse occurs For example: >>> impose_collapse({(0,1),(0,2)},[1,2,3,4,5],[.2,.2,.2,.2,.2]) ([1.5999999999999996, 1.5999999999999996, 1.5999999999999996, 4.5999999999999996, 5.5999999999999996], [0.6000000000000001, 0.0, 0.0, 0.2, 0.2]) >>> impose_collapse({(0,1),(3,4)},[1,2,3,4,5],[.2,.2,.2,.2,.2]) ([1.3999999999999999, 1.3999999999999999, 3.3999999999999999, 4.4000000000000004, 4.4000000000000004], [0.4, 0.0, 0.2, 0.4, 0.0]) Note: is 'mean-preserving' for samples and 'norm-preserving' for weights """ samples, weights = list(samples), list(weights) # don't edit inputs m = mean(samples, weights) # allow negative indexing pairs = zip(*tuple(tuple(len(weights)+i if i<0 else i for i in j) for j in zip(*pairs))) #XXX: any vectorized way to do this? from mystic.tools import connected for i,j in connected(pairs).iteritems(): v = weights[i] for k in j: v += weights[k] weights[k] = type(v)(0.0) samples[k] = samples[i] weights[i] = v return impose_mean(m, samples, weights), weights
def func(x, *args, **kwds): x = copy.copy(x) #XXX: inefficient for i,j in connected(mask).iteritems(): for k in j: try: x[k] = x[i] except IndexError: pass pairs = list(mask) #XXX: inefficient while pairs: # deal with the offset indx,trac = zip(*pairs) trac = set(trac) for i in trac: try: x[i] += offset except IndexError: pass indx = trac.intersection(indx) pairs = [m for m in pairs if m[0] in indx] return f(x, *args, **kwds)