Changeset 778


Ignore:
Timestamp:
01/04/15 12:46:09 (17 months ago)
Author:
mmckerns
Message:

add constraints.integer to impose the set of integers on a function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/constraints.py

    r777 r778  
    1010 
    1111__all__ = ['with_penalty','with_constraint','as_penalty','as_constraint', 
    12            'with_mean','with_variance','with_spread','normalized', 
    13            'issolution','solve','discrete'] 
     12           'with_mean','with_variance','with_std','with_spread','normalized', 
     13           'issolution','solve','discrete','integers'] 
    1414 
    1515from mystic.math.measures import * 
     
    488488 
    489489 
     490from numpy import round, abs 
     491def integers(ints=True, index=None): 
     492    """impose the set of integers (by rounding) for the given function 
     493 
     494The function's input will be mapped to the ints, where: 
     495  - if ints is True, return results as ints; otherwise, use floats 
     496  - if index tuple provided, only round at the given indicies 
     497 
     498>>> @integers() 
     499... def identity(x): 
     500...     return x 
     501 
     502>>> identity([0.123, 1.789, 4.000]) 
     503[0, 2, 4] 
     504 
     505>>> @integers(ints=float, index=(0,3,4)) 
     506... def squared(x): 
     507....    return [i**2 for i in x] 
     508 
     509>>> squared([0.12, 0.12, 4.01, 4.01, 8, 8]) 
     510[0.0, 0.0144, 16.080099999999998, 16.0, 64.0, 64.0]""" 
     511    #HACK: allow ints=False or ints=int 
     512    _ints = [(int if ints else float) if isinstance(ints, bool) else ints] 
     513    if isinstance(index, int): index = (index,) 
     514    index = [index] 
     515 
     516    def _index(alist=None): 
     517        index[0] = alist 
     518 
     519    def _type(ints=None): 
     520        _ints[0] = (int if ints else float) if isinstance(ints, bool) else ints 
     521 
     522    def dec(f): 
     523        def func(x,*args,**kwds): 
     524            if isinstance(x, ndarray): xtype = asarray 
     525            else: xtype = type(x) 
     526            ##### ALT ##### 
     527           #pos = range(len(x)) 
     528           #pos = [pos[i] for i in index[0]] if index[0] else pos 
     529           #xp = [float(round(xi) if i in pos else xi) for i,xi in enumerate(x)] 
     530            ############### 
     531            xp = round(x) 
     532            if index[0] is None: 
     533                mask = ones(xp.size, dtype=bool) 
     534            else: 
     535                mask = zeros(xp.size, dtype=bool) 
     536                try: mask[sorted(index[0], key=abs)] = True 
     537                except IndexError: pass 
     538            xp = choose(mask, (x,xp)).astype(_ints[0]) 
     539            ############### 
     540            return f(xtype(xp), *args, **kwds) 
     541        func.index = _index 
     542        func.type = _type 
     543        return func 
     544    return dec 
     545 
     546 
    490547# EOF 
Note: See TracChangeset for help on using the changeset viewer.