Ejemplo n.º 1
0
def bounded(seq, bounds, index=None, clip=True, nearest=True):
    """bound a sequence by bounds = [min,max]

    For example:
    >>> sequence = [0.123, 1.244, -4.755, 10.731, 6.207]
    >>> 
    >>> bounded(sequence, (0,5))
    array([0.123, 1.244, 0.   , 5.   , 5.   ])
    >>> 
    >>> bounded(sequence, (0,5), index=(0,2,4))
    array([ 0.123,  1.244,  0.   , 10.731,  5.   ])
    >>> 
    >>> bounded(sequence, (0,5), clip=False)
    array([0.123     , 1.244     , 3.46621839, 1.44469038, 4.88937466])
    >>> 
    >>> bounds = [(0,5),(7,10)]
    >>> my.constraints.bounded(sequence, bounds)
    array([ 0.123,  1.244,  0.   , 10.   ,  7.   ])
    >>> my.constraints.bounded(sequence, bounds, nearest=False)
    array([ 0.123,  1.244,  7.   , 10.   ,  5.   ])
    >>> my.constraints.bounded(sequence, bounds, nearest=False, clip=False) 
    array([0.123     , 1.244     , 0.37617154, 8.79013111, 7.40864242])
    >>> my.constraints.bounded(sequence, bounds, clip=False)
    array([0.123     , 1.244     , 2.38186577, 7.41374049, 9.14662911])
    >>> 
"""
    seq = array(seq) #XXX: asarray?
    if bounds is None or not bounds: return seq
    if isinstance(index, int): index = (index,)
    if not hasattr(bounds[0], '__len__'): bounds = (bounds,)
    bounds = asfarray(bounds).T  # is [(min,min,...),(max,max,...)]
    # convert None to -inf or inf
    bounds[0][isnan(bounds[0])] = -inf
    bounds[1][isnan(bounds[1])] = inf
    # find indicies of the elements that are out of bounds
    at = where(sum((lo <= seq)&(seq <= hi) for (lo,hi) in bounds.T).astype(bool) == False)[-1]
    # find the intersection of out-of-bound and selected indicies
    at = at if index is None else intersect1d(at, index)
    if not len(at): return seq
    if clip:
        if nearest: # clip at closest bounds
            seq_at = seq[at]
            seq[at] = _clip(seq_at, *(b[abs(seq_at.reshape(-1,1)-b).argmin(axis=1)] for b in bounds))
        else: # clip in randomly selected interval
            picks = choice(len(bounds.T), size=at.shape)
            seq[at] = _clip(seq[at], bounds[0][picks], bounds[1][picks])
        return seq
    # limit to +/- 1e300 #XXX: better defaults?
    bounds[0][bounds[0] < -1e300] = -1e300
    bounds[1][bounds[1] > 1e300] = 1e300
    if nearest:
        seq_at = seq[at]
        seq[at] = choose(array([abs(seq_at.reshape(-1,1) - b).min(axis=1) for b in bounds.T]).argmin(axis=0), [uniform(0,1, size=at.shape) * (hi - lo) + lo for (lo,hi) in bounds.T])
    else: # randomly choose a value in one of the intervals
        seq[at] = choose(choice(len(bounds.T), size=at.shape), [uniform(0,1, size=at.shape) * (hi - lo) + lo for (lo,hi) in bounds.T])
    return seq
Ejemplo n.º 2
0
def bounded(seq, bounds, index=None, clip=True, nearest=True):
    """bound a sequence by bounds = [min,max]

    For example:
    >>> sequence = [0.123, 1.244, -4.755, 10.731, 6.207]
    >>> 
    >>> bounded(sequence, (0,5))
    array([0.123, 1.244, 0.   , 5.   , 5.   ])
    >>> 
    >>> bounded(sequence, (0,5), index=(0,2,4))
    array([ 0.123,  1.244,  0.   , 10.731,  5.   ])
    >>> 
    >>> bounded(sequence, (0,5), clip=False)
    array([0.123     , 1.244     , 3.46621839, 1.44469038, 4.88937466])
    >>> 
    >>> bounds = [(0,5),(7,10)]
    >>> my.constraints.bounded(sequence, bounds)
    array([ 0.123,  1.244,  0.   , 10.   ,  7.   ])
    >>> my.constraints.bounded(sequence, bounds, nearest=False)
    array([ 0.123,  1.244,  7.   , 10.   ,  5.   ])
    >>> my.constraints.bounded(sequence, bounds, nearest=False, clip=False) 
    array([0.123     , 1.244     , 0.37617154, 8.79013111, 7.40864242])
    >>> my.constraints.bounded(sequence, bounds, clip=False)
    array([0.123     , 1.244     , 2.38186577, 7.41374049, 9.14662911])
    >>> 
"""
    seq = array(seq) #XXX: asarray?
    if bounds is None or not bounds: return seq
    if isinstance(index, int): index = (index,)
    if not hasattr(bounds[0], '__len__'): bounds = (bounds,)
    bounds = asfarray(bounds).T  # is [(min,min,...),(max,max,...)]
    # convert None to -inf or inf
    bounds[0][bounds[0] == None] = -inf
    bounds[1][bounds[1] == None] = inf
    # find indicies of the elements that are out of bounds
    at = where(sum((lo <= seq)&(seq <= hi) for (lo,hi) in bounds.T).astype(bool) == False)[-1]
    # find the intersection of out-of-bound and selected indicies
    at = at if index is None else intersect1d(at, index)
    if not len(at): return seq
    if clip:
        if nearest: # clip at closest bounds
            seq_at = seq[at]
            seq[at] = _clip(seq_at, *(b[abs(seq_at.reshape(-1,1)-b).argmin(axis=1)] for b in bounds))
        else: # clip in randomly selected interval
            picks = choice(len(bounds.T), size=at.shape)
            seq[at] = _clip(seq[at], bounds[0][picks], bounds[1][picks])
        return seq
    # limit to +/- 1e300 #XXX: better defaults?
    bounds[0][bounds[0] < -1e300] = -1e300
    bounds[1][bounds[1] > 1e300] = 1e300
    if nearest:
        seq_at = seq[at]
        seq[at] = choose(array([abs(seq_at.reshape(-1,1) - b).min(axis=1) for b in bounds.T]).argmin(axis=0), [uniform(0,1, size=at.shape) * (hi - lo) + lo for (lo,hi) in bounds.T])
    else: # randomly choose a value in one of the intervals
        seq[at] = choose(choice(len(bounds.T), size=at.shape), [uniform(0,1, size=at.shape) * (hi - lo) + lo for (lo,hi) in bounds.T])
    return seq