Changeset 849


Ignore:
Timestamp:
12/28/15 10:11:04 (5 months ago)
Author:
mmckerns
Message:

added synchronized to tools, which enables easy input synchronization

File:
1 edited

Legend:

Unmodified
Added
Removed
  • mystic/mystic/tools.py

    r839 r849  
    3434    - masked: generate a masked function, given a function and mask provided 
    3535    - partial: generate a function where some input has fixed values 
     36    - synchronized: generate a function, where some input tracks another input 
    3637    - insert_missing: return a sequence with the 'missing' elements inserted 
    3738    - clipped: generate a function where values outside of bounds are clipped 
     
    568569 
    569570 
     571def synchronized(mask): 
     572    """generate a function, where some input tracks another input 
     573 
     574mask should be a dictionary of positional index and tracked index (e.g. {0:1}), 
     575where keys and values should be different integers. However, if a tuple is 
     576provided instead of the tracked index (e.g. {0:(1,lambda x:2*x)} or {0:(1,2)}), 
     577the second member of the tuple will be used to scale the tracked index. 
     578 
     579functions are expected to take a single argument, a n-dimensional list or array, 
     580where the mask will be applied to the input array. 
     581 
     582For example, 
     583    >>> @synchronized({0:1,3:-1}) 
     584    ... def same(x): 
     585    ...     return x 
     586    ... 
     587    >>> same([-5,9]) 
     588    [9, 9] 
     589    >>> same([0,1,2,3,4]) 
     590    [1, 1, 2, 4, 4] 
     591    >>> same([0,9,2,3,6]) 
     592    [9, 9, 2, 6, 6] 
     593    >>>  
     594    >>> @synchronized({0:(1,lambda x:1/x),3:(1,-1)}) 
     595    ... def doit(x): 
     596    ...   return x 
     597    ...  
     598    >>> doit([-5.,9.]) 
     599    [0.1111111111111111, 9.0] 
     600    >>> doit([0.,1.,2.,3.,4.]) 
     601    [1.0, 1.0, 2.0, -1.0, 4.0] 
     602    >>> doit([0.,9.,2.,3.,6.]) 
     603    [0.1111111111111111, 9.0, 2.0, -9.0, 6.0] 
     604    """ 
     605    def dec(f): 
     606        def func(x, *args, **kwds): 
     607            for i,j in mask.items(): 
     608                try: x[i] = x[j] 
     609                except TypeError: # value is tuple with f(x) or constant 
     610                  j0,j1 = (j[:2] + (1,))[:2] 
     611                  try: x[i] = j1(x[j0]) if callable(j1) else j1*x[j0] 
     612                  except IndexError: pass 
     613                except IndexError: pass 
     614            return f(x, *args, **kwds) 
     615        func.__wrapped__ = f 
     616        func.__doc__ = f.__doc__ 
     617        func.mask = mask 
     618        return func 
     619    return dec 
     620 
     621 
    570622def suppress(x, tol=1e-8, clip=True): 
    571623    """suppress small values less than tol""" 
     
    578630    x[mask] = 0.0 
    579631    return x.tolist() 
     632 
    580633 
    581634def suppressed(tol=1e-8, exit=False, clip=True): 
     
    611664        return func 
    612665    return dec 
     666 
    613667 
    614668def clipped(min=None, max=None, exit=False): 
Note: See TracChangeset for help on using the changeset viewer.