def collapse_weight(stepmon, tolerance=0.005, generations=50, mask=None): '''return a dict of {measure:indices} where the product_measure exhibits a dimensional collapse in weight. Dimensional collapse in weight is defined by: max(weight[i]) <= tolerance over N generations. collapse will be ignored at (measure,indices) as specified in the mask. Format of mask will determine the return value for this function. Default mask format is dict of {measure: indices}, with alternate formatting available as a set of tuples of (measure,index). ''' #XXX: not mentioned, 'where' format also available np = _m.numpy # reject bad masks if mask is None: pass elif type(mask) is set: for i in mask: if not hasattr(i, '__len__') or len(i) != 2: msg = "bad element '%s' in mask" % str(i) raise ValueError(msg) if type(i[0]) is not int or type(i[1]) is not int: msg = "bad element '%s' in mask" % str(i) raise ValueError(msg) elif type(mask) is dict: for (i, j) in getattr(mask, 'iteritems', mask.items)(): if type(j) is not set or type(i) is not int: msg = "bad entry '%s:%s' in mask" % (str(i), str(j)) raise ValueError(msg) for k in j: # items in the set if hasattr(k, '__len__'): msg = "bad entry '%s:%s' in mask" % (str(i), str(j)) raise ValueError(msg) elif hasattr(mask, '__len__') and len(mask) == 2: if np.array(mask).ndim != 2: msg = "%s is not a valid mask" % str(mask) raise TypeError(msg) elif hasattr(mask, '__len__') and not len(mask): mask = type(mask)(((), ())) #XXX: HACK to get empty where mask else: msg = "%s is not a valid mask" % str(mask) raise TypeError(msg) # is the max weight less than tolerance across all generations? weights = _m._weights(stepmon, generations).max(axis=0) <= tolerance # identify mask format and build filter mask, pairs = _weight_filter(mask) # get weight collapse in 'where' notation wts = (tuple(i) for i in np.where(weights) if len(i)) # apply mask and selected format... if pairs: # return explicit 'pairs' {(measure,index)} import itertools return mask(set(getattr(itertools, 'izip', zip)(*wts))) if pairs is None: # return 'where' format [measures,indices] return mask(wts) # returns a dict of {measure:indices} wts = np.array(tuple(wts)) if not wts.size: return {} return mask( dict((i, set(wts[1][wts[0] == i])) for i in range(1 + wts[0][-1]) if i in wts[0]))
def collapse_weight(stepmon, tolerance=0.005, generations=50, mask=None): '''return a dict of {measure:indices} where the product_measure exhibits a dimensional collapse in weight. Dimensional collapse in weight is defined by: max(weight[i]) <= tolerance over N generations. collapse will be ignored at (measure,indices) as specified in the mask. Format of mask will determine the return value for this function. Default mask format is dict of {measure: indices}, with alternate formatting available as a set of tuples of (measure,index). ''' #XXX: not mentioned, 'where' format also available np = _m.numpy # reject bad masks if mask is None: pass elif type(mask) is set: for i in mask: if not hasattr(i, '__len__') or len(i) != 2: msg = "bad element '%s' in mask" % str(i) raise ValueError(msg) if type(i[0]) is not int or type(i[1]) is not int: msg = "bad element '%s' in mask" % str(i) raise ValueError(msg) elif type(mask) is dict: for (i,j) in getattr(mask, 'iteritems', mask.items)(): if type(j) is not set or type(i) is not int: msg = "bad entry '%s:%s' in mask" % (str(i),str(j)) raise ValueError(msg) for k in j: # items in the set if hasattr(k, '__len__'): msg = "bad entry '%s:%s' in mask" % (str(i),str(j)) raise ValueError(msg) elif hasattr(mask, '__len__') and len(mask) == 2: if np.array(mask).ndim != 2: msg = "%s is not a valid mask" % str(mask) raise TypeError(msg) elif hasattr(mask, '__len__') and not len(mask): mask = type(mask)(((),())) #XXX: HACK to get empty where mask else: msg = "%s is not a valid mask" % str(mask) raise TypeError(msg) # is the max weight less than tolerance across all generations? weights = _m._weights(stepmon, generations).max(axis=0) <= tolerance # identify mask format and build filter mask, pairs = _weight_filter(mask) # get weight collapse in 'where' notation wts = (tuple(i) for i in np.where(weights) if len(i)) # apply mask and selected format... if pairs: # return explicit 'pairs' {(measure,index)} import itertools return mask(set(getattr(itertools, 'izip', zip)(*wts))) if pairs is None: # return 'where' format [measures,indices] return mask(wts) # returns a dict of {measure:indices} wts = np.array(tuple(wts)) if not wts.size: return {} return mask(dict((i,set(wts[1][wts[0]==i])) for i in range(1+wts[0][-1]) if i in wts[0]))