Example #1
0
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
Example #2
0
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
Example #3
0
 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)
Example #4
0
 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)