Changeset 644 for branches


Ignore:
Timestamp:
01/17/13 17:08:05 (3 years ago)
Author:
mmckerns
Message:

shuffing methods within constraints and penalty to better logically group;
mystic 'ctype' constraints moved to coupler;
move original mystic.constriants to mystic.symbolic;
add documentation to penalty, constraints, coupler

Location:
branches/decorate
Files:
1 added
6 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • branches/decorate/_symbolic.py

    r623 r644  
    1111from mystic.tools import permutations 
    1212from mystic.tools import list_or_tuple_or_ndarray 
    13 #from wrapper import isbounded 
    14 #from penalty import issolution 
    1513 
    1614def _classify_variables(constraints, variables='x', nvars=None):  
     
    615613        ...     x1 - x3 = 2. 
    616614        ...     x3 = x4*2.''' 
    617         >>> print _solve_linear(constraints, target=['x4','x3']) 
     615        >>> print solve(constraints, target=['x4','x3']) 
    618616        x4 = -1.0 + 0.5*x1 
    619617        x3 = -2.0 + x1 
  • branches/decorate/constraints.py

    r631 r644  
    11#!/usr/bin/env python 
    22 
     3"""Tools for building and applying constraints and penalties. 
     4""" 
     5 
     6__all__ = ['with_penalty','with_constraint','as_penalty','as_constraint', 
     7           'with_mean','with_variance','with_spread','normalized', 
     8           'issolution','solve'] 
     9 
    310from mystic.math.measures import * 
    4 from wrapper import * 
    511from mystic.math import almostEqual 
    612 
    7 def with_constraint(ctype, *args, **kwds): 
     13def with_penalty(ptype, *args, **kwds): 
     14    """convert a condition to a penalty function of the chosen type 
     15 
     16condition f(x) is satisfied when f(x) == 0.0 for equality constraints 
     17and f(x) <= 0.0 for inequality constraints. ptype is a mystic.penalty type. 
     18 
     19    For example: 
     20    >>> @with_penalty(quadratic_equality, kwds={'target':5.0}) 
     21    ... def penalty(x, target): 
     22    ...   return mean(x) - target 
     23    >>>  
     24    >>> penalty([1,2,3,4,5]) 
     25    400.0 
     26    >>> penalty([3,4,5,6,7]) 
     27    7.8886090522101181e-29 
     28    """ 
     29    def dec(condition): 
     30      @ptype(condition, *args, **kwds) 
     31      def penalty(x): 
     32          return 0.0 
     33      return penalty 
     34    return dec 
     35 
     36 
     37def with_constraint(ctype, *args, **kwds): #XXX: is this *at all* useful? 
    838    """convert a set transformation to a constraints solver of the chosen type 
    939 
    1040transformation f(x) is a mapping between x and x', where x' = f(x). 
    11 ctype is a mystic.constraints type [inner, outer, inner_proxy, outer_proxy]. 
     41ctype is a mystic.coupler type [inner, outer, inner_proxy, outer_proxy]. 
     42 
     43    For example: 
     44    >>> @with_constraint(inner, kwds={'target':5.0}) 
     45    ... def constraint(x, target): 
     46    ...   return impose_mean(target, x) 
     47    ...  
     48    >>> x = constraint([1,2,3,4,5]) 
     49    >>> print x 
     50    [3.0, 4.0, 5.0, 6.0, 7.0] 
     51    >>> mean(x) 
     52    5.0 
    1253    """ 
    1354    def dec(condition): 
     
    1657          return x 
    1758      return constraint 
    18     return dec 
    19  
    20  
    21 def outer(outer=lambda x:x, args=None, kwds=None): 
    22     """wrap a function around another function: convert y = f(x) to y' = c(f(x)) 
    23  
    24 This is useful, for example, in nesting one constraint in another constraint. 
    25     """ 
    26     if args is None: args=() 
    27     if kwds is None: kwds={} 
    28     def dec(f): 
    29         def func(x, *argz, **kwdz): 
    30             return outer(f(x, *argz, **kwdz), *args, **kwds) 
    31         return func 
    32     return dec 
    33  
    34  
    35 def inner(inner=lambda x:x, args=None, kwds=None): 
    36     """nest a function within another function: convert y = f(x) to y' = f(c(x)) 
    37  
    38 This is useful, for example, in nesting constraints in a cost function; 
    39 thus, the constraints will be enforced at every cost function evaluation. 
    40     """ 
    41     if args is None: args=() 
    42     if kwds is None: kwds={} 
    43     def dec(f): 
    44         def func(x, *argz, **kwdz): 
    45             return f(inner(x, *args, **kwds), *argz, **kwdz) 
    46         return func 
    47     return dec 
    48  
    49  
    50 def inner_proxy(inner=lambda x:x, args=None, kwds=None): 
    51     """nest a function within another function: convert y = f(x) to y' = f(c(x)) 
    52  
    53 This is useful, for example, in nesting constraints in a cost function; 
    54 thus, the constraints will be enforced at every cost function evaluation. 
    55  
    56 This function does not preserve decorated function signature, but passes args 
    57 and kwds to the inner function. 
    58     """ 
    59     if args is None: args=() 
    60     if kwds is None: kwds={} 
    61     def dec(f): 
    62         def func(*argz, **kwdz): 
    63             return f(inner(*argz, **kwdz), *args, **kwds) 
    64         return func 
    65     return dec 
    66  
    67  
    68 def outer_proxy(outer=lambda x:x, args=None, kwds=None): 
    69     """wrap a function around another function: convert y = f(x) to y' = c(f(x)) 
    70  
    71 This is useful, for example, in nesting one constraint in another constraint. 
    72   
    73 This function does not preserve decorated function signature, but passes args 
    74 and kwds to the outer function. 
    75     """ 
    76     if args is None: args=() 
    77     if kwds is None: kwds={} 
    78     def dec(f): 
    79         def func(x, *argz, **kwdz): 
    80             return outer(f(x, *args, **kwds), *argz, **kwdz) 
    81         return func 
    8259    return dec 
    8360 
     
    9875 
    9976def with_mean(target): 
    100     """ ... """ 
     77    """bind a mean constraint to a given constraints function. 
     78 
     79Inputs: 
     80    target -- the target mean 
     81 
     82A constraints function takes an iterable x as input, returning a modified x. 
     83This function is an "outer" coupling of "impose_mean" onto another constraints 
     84function c(x), such that:  x' = impose_mean(target, c(x)). 
     85 
     86    For example: 
     87    >>> @with_mean(5.0) 
     88    ... def constraint(x): 
     89    ...   x[-1] = x[0] 
     90    ...   return x 
     91    ...  
     92    >>> x = constraint([1,2,3,4]) 
     93    >>> print x 
     94    [4.25, 5.25, 6.25, 4.25] 
     95    >>> mean(x) 
     96    5.0 
     97    """ 
    10198    def decorate(constraints): 
    10299        def factory(x, *args, **kwds): 
     
    112109 
    113110def with_variance(target): 
    114     """ ... """ 
     111    """bind a variance constraint to a given constraints function. 
     112 
     113Inputs: 
     114    target -- the target variance 
     115 
     116A constraints function takes an iterable x as input, returning a modified x. 
     117This function is an "outer" coupling of "impose_variance" onto another 
     118constraints function c(x), such that:  x' = impose_variance(target, c(x)). 
     119 
     120    For example: 
     121    >>> @with_variance(1.0) 
     122    ... def constraint(x): 
     123    ...   x[-1] = x[0] 
     124    ...   return x 
     125    ...  
     126    >>> x = constraint([1,2,3]) 
     127    >>> print x 
     128    [0.6262265521467858, 2.747546895706428, 0.6262265521467858] 
     129    >>> variance(x) 
     130    0.99999999999999956 
     131    """ 
    115132    def decorate(constraints): 
    116133        def factory(x, *args, **kwds): 
     
    126143 
    127144def with_spread(target): 
    128     """ ... """ 
     145    """bind a range constraint to a given constraints function. 
     146 
     147Inputs: 
     148    target -- the target range 
     149 
     150A constraints function takes an iterable x as input, returning a modified x. 
     151This function is an "outer" coupling of "impose_spread" onto another constraints 
     152function c(x), such that:  x' = impose_spread(target, c(x)). 
     153 
     154    For example: 
     155    >>> @with_spread(10.0) 
     156    ... def constraint(x): 
     157    ...   return [i**2 for i in x] 
     158    ...  
     159    >>> x = constraint([1,2,3,4]) 
     160    >>> print x 
     161    [3.1666666666666665, 5.1666666666666661, 8.5, 13.166666666666666] 
     162    >>> spread(x) 
     163    10.0 
     164    """ 
    129165    def decorate(constraints): 
    130166        def factory(x, *args, **kwds): 
     
    141177from numpy import sum 
    142178def normalized(mass=1.0): #XXX: order matters when multiple decorators 
    143     """ ... """ 
     179    """bind a normalization constraint to a given constraints function. 
     180 
     181Inputs: 
     182    mass -- the target sum of normalized weights 
     183 
     184A constraints function takes an iterable x as input, returning a modified x. 
     185This function is an "outer" coupling of "normalize" onto another constraints 
     186function c(x), such that:  x' = normalize(c(x), mass). 
     187 
     188    For example: 
     189    >>> @normalized() 
     190    ... def constraint(x): 
     191    ...   return x 
     192    ...  
     193    >>> constraint([1,2,3]) 
     194    [0.16666666666666666, 0.33333333333333331, 0.5] 
     195    """ 
    144196    def decorate(constraints): 
    145197        def factory(x, *args, **kwds): 
     
    154206 
    155207 
     208def issolution(constraints, guess, tol=1e-3): 
     209    """Returns whether the guess is a solution to the constraints 
     210 
     211Input: 
     212    constraints -- a constraints solver function or a penalty function 
     213    guess -- list of parameter values prposed to solve the constraints 
     214    tol -- residual error magnitude for which constraints are considered solved 
     215    """ 
     216    if hasattr(constraints, 'error'): 
     217        error = constraints.error(guess) 
     218    else: # is a constraints solver 
     219        error = 0.0 
     220        constrained = constraints(guess) 
     221        for i in range(len(guess)): 
     222            error += (constrained[i] - guess[i])**2  #XXX: better rnorm ? 
     223        error = error**0.5 
     224 
     225    if error <= tol: return True 
     226    return False 
     227 
     228 
     229#XXX: nice if penalty.error could give error for each condition... or total 
     230 
     231 
     232def solve(constraints, guess=None, nvars=None, solver=None, \ 
     233          lower_bounds=None, upper_bounds=None, termination=None): 
     234    """Use optimization to find a solution to a set of constraints. 
     235 
     236Inputs: 
     237    constraints -- a constraints solver function or a penalty function 
     238 
     239Additional Inputs: 
     240    guess -- list of parameter values proposed to solve the constraints. 
     241    lower_bounds -- list of lower bounds on solution values. 
     242    upper_bounds -- list of upper bounds on solution values. 
     243    nvars -- number of parameter values. 
     244    solver -- the mystic solver to use in the optimization 
     245    termination -- the mystic termination to use in the optimization 
     246 
     247NOTE: The resulting constraints will likely be more expensive to evaluate 
     248    and less accurate than writing the constraints solver from scratch. 
     249    """ 
     250    ndim = 1 #XXX: better, increase in while loop catching IndexError ? 
     251    if nvars is not None: ndim = nvars 
     252    elif guess is not None: ndim = len(guess) 
     253    elif lower_bounds is not None: ndim = len(lower_bounds) 
     254    elif upper_bounds is not None: ndim = len(upper_bounds) 
     255 
     256    def cost(x): return 1. 
     257 
     258    #XXX: don't allow solver string as a short-cut? 
     259    if solver is None or solver == 'diffev': 
     260        from mystic.solvers import DifferentialEvolutionSolver as TheSolver 
     261        solver = TheSolver(ndim, min(40, ndim*5)) 
     262    elif solver == 'diffev2': 
     263        from mystic.solvers import DifferentialEvolutionSolver2 as TheSolver 
     264        solver = TheSolver(ndim, min(40, ndim*5)) 
     265    elif solver == 'fmin_powell': #XXX: better as the default? (it's not random) 
     266        from mystic.solvers import PowellDirectionalSolver as TheSolver 
     267        solver = TheSolver(ndim) 
     268    elif solver == 'fmin': 
     269        from mystic.solvers import NelderMeadSimplexSolver as TheSolver 
     270        solver = TheSolver(ndim) 
     271     
     272    if termination is None: 
     273        from mystic.termination import ChangeOverGeneration as COG 
     274        termination = COG() 
     275    if guess != None: 
     276        solver.SetInitialPoints(guess) #XXX: nice if 'diffev' also had methods 
     277    else: 
     278        solver.SetRandomInitialPoints(lower_bounds, upper_bounds) 
     279    if lower_bounds or upper_bounds: 
     280        solver.SetStrictRanges(lower_bounds, upper_bounds) 
     281    if hasattr(constraints, 'iter') and hasattr(constraints, 'error'): 
     282        solver.SetPenalty(constraints) #i.e. is a penalty function 
     283    else: # is a constraints solver 
     284        solver.SetConstraints(constraints) 
     285    solver.Solve(cost, termination) 
     286    soln = solver.bestSolution 
     287 
     288    from numpy import ndarray, array 
     289    if isinstance(soln, ndarray) and not isinstance(guess, ndarray): 
     290        soln = soln.tolist() 
     291    elif isinstance(guess, ndarray) and not isinstance(soln, ndarray): 
     292        soln = array(soln)  #XXX: or always return a list ? 
     293 
     294    return soln #XXX: check with 'issolution' ? 
     295 
     296 
     297def as_constraint(penalty, *args, **kwds): 
     298    """Convert a penalty function to a constraints solver. 
     299 
     300Inputs: 
     301    penalty -- a penalty function 
     302 
     303Additional Inputs: 
     304    lower_bounds -- list of lower bounds on solution values. 
     305    upper_bounds -- list of upper bounds on solution values. 
     306    nvars -- number of parameter values. 
     307    solver -- the mystic solver to use in the optimization 
     308    termination -- the mystic termination to use in the optimization 
     309    """ 
     310    def constraint(x): #XXX: better to enable args kwds for penalty ? 
     311        return solve(penalty, x, *args, **kwds) 
     312    return constraint 
     313 
     314 
     315def as_penalty(constraint, ptype=None, *args, **kwds): 
     316    """Convert a constraints solver to a penalty function. 
     317 
     318Inputs: 
     319    constraint -- a constraints solver 
     320    ptype -- penalty function type [default: quadratic_equality] 
     321 
     322Additional Inputs: 
     323    args -- arguments for the constraints solver [default: ()] 
     324    kwds -- keyword arguments for the constraints solver [default: {}] 
     325    k -- penalty multiplier 
     326    h -- iterative multiplier 
     327    """ 
     328    def rnorm(x, *argz, **kwdz): 
     329        error = 0.0 
     330        constrained = constraint(x, *argz, **kwdz) 
     331        for i in range(len(x)): 
     332            error += (constrained[i] - x[i])**2  #XXX: better rnorm ? 
     333        error = error**0.5 
     334        return error 
     335 
     336    if ptype is None: 
     337        from penalty import quadratic_equality 
     338        ptype = quadratic_equality 
     339 
     340    @ptype(rnorm, *args, **kwds) #XXX: yes to k,h... but otherwise? 
     341    def penalty(x): 
     342        return 0.0 
     343 
     344    return penalty 
     345 
     346 
    156347# EOF 
  • branches/decorate/penalty.py

    r610 r644  
    22 
    33""" 
     4Penalty Methods 
     5 
     6These methods can be used to convert a function into a penalty function. 
     7 
     8Suppose a given condition f(x) is satisfied when f(x) == 0.0 
     9for equality constraints, and f(x) <= 0.0 for inequality constraints. 
     10This condition f(x) can be used as the basis for a mystic.penalty 
     11function. 
     12 
     13    For example: 
     14    >>> def penalty_mean(x, target): 
     15    ...   return mean(x) - target 
     16    ...  
     17    >>> @quadratic_equality(condition=penalty_mean, kwds={'target':5.0}) 
     18    ... def penalty(x): 
     19    ...   return 0.0 
     20    ...  
     21    >>> penalty([1,2,3,4,5]) 
     22    400.0 
     23    >>> penalty([3,4,5,6,7]) 
     24    7.8886090522101181e-29 
     25 
     26 
    427References: 
    528   [1] http://en.wikipedia.org/wiki/Penalty_method 
     
    1235""" 
    1336 
    14 def with_penalty(ptype, *args, **kwds): 
    15     """convert a condition to a penalty function of the chosen type 
    16  
    17 condition f(x) is satisfied when f(x) == 0.0 for equality constraints 
    18 and f(x) <= 0.0 for inequality constraints. ptype is a mystic.penalty type. 
    19     """ 
    20     def dec(condition): 
    21       @ptype(condition, *args, **kwds) 
    22       def penalty(x): 
    23           return 0.0 
    24       return penalty 
    25     return dec 
    26  
    27  
    2837from numpy import inf, log 
    2938def quadratic_equality(condition=lambda x:0., args=None, kwds=None, k=100, h=5): 
     
    409418 
    410419 
    411 #################################################### 
    412 def proxify(penalty=lambda x:0.0, args=None, kwds=None): 
    413     """penalize a function with another function: y = f(x) to y' = f(x) + p(x) 
    414      
    415 This is useful, for example, in penalizing a cost function where the constraints 
    416 are violated; thus, the satisfying the constraints will be preferred at every 
    417 cost function evaluation. 
    418  
    419 This function does not preserve decorated function signature, but passes args 
    420 and kwds to the penalty function. 
    421     """ 
    422     if args is None: args=() 
    423     if kwds is None: kwds={} 
    424     def dec(f): 
    425         def func(x, *argz, **kwdz): 
    426             return f(x, *args, **kwds) + penalty(x, *argz, **kwdz) 
    427         return func 
    428     return dec 
    429  
    430 def penalize(penalty=lambda x:0.0, args=None, kwds=None): 
    431     """penalize a function with another function: y = f(x) to y' = f(x) + p(x) 
    432      
    433 This is useful, for example, in penalizing a cost function where the constraints 
    434 are violated; thus, the satisfying the constraints will be preferred at every 
    435 cost function evaluation. 
    436     """ 
    437     if args is None: args=() 
    438     if kwds is None: kwds={} 
    439     def dec(f): 
    440         def func(x, *argz, **kwdz): 
    441             return f(x, *argz, **kwdz) + penalty(x, *args, **kwds) 
    442         return func 
    443     return dec 
    444  
    445 #XXX: can do multiple @penalize; but better is compound penalty with And,Or,..? 
    446 #XXX: create a counter for n += 1 ? 
    447  
    448  
    449 def issolution(constraints, candidate, tol=1e-3): 
    450     """Returns whether the candidate is a solution to the constraints 
    451  
    452 Input: 
    453     constraints -- a constraints solver function or a penalty function 
    454     candidate -- list of parameter values prposed to solve the constraints 
    455     tol -- residual error magnitude for which constraints are considered solved 
    456     """ 
    457     if hasattr(constraints, 'error'): 
    458         error = constraints.error(candidate) 
    459     else: # is a constraints solver 
    460         error = 0.0 
    461         constrained = constraints(candidate) 
    462         for i in range(len(candidate)): 
    463             error += (constrained[i] - candidate[i])**2  #XXX: better rnorm ? 
    464         error = error**0.5 
    465  
    466     if error <= tol: return True 
    467     return False 
    468  
    469  
    470 #XXX: nice if penalty.error could give error for each condition... or total 
    471  
    472  
    473 def solve(constraints, guess=None, nvars=None, solver=None, \ 
    474           lower_bounds=None, upper_bounds=None, termination=None): 
    475     """Use optimization to find a solution to a set of constraints. 
    476  
    477 Inputs: 
    478     constraints -- a constraints solver function or a penalty function 
    479  
    480 Additional Inputs: 
    481     guess -- list of parameter values proposed to solve the constraints. 
    482     lower_bounds -- list of lower bounds on solution values. 
    483     upper_bounds -- list of upper bounds on solution values. 
    484     nvars -- number of parameter values. 
    485     solver -- the mystic solver to use in the optimization 
    486     termination -- the mystic termination to use in the optimization 
    487  
    488 NOTE: The resulting constraints will likely be more expensive to evaluate 
    489     and less accurate than writing the constraints solver from scratch. 
    490     """ 
    491     ndim = 1 #XXX: better, increase in while loop catching IndexError ? 
    492     if nvars is not None: ndim = nvars 
    493     elif guess is not None: ndim = len(guess) 
    494     elif lower_bounds is not None: ndim = len(lower_bounds) 
    495     elif upper_bounds is not None: ndim = len(upper_bounds) 
    496  
    497     def cost(x): return 1. 
    498  
    499     #XXX: don't allow solver string as a short-cut? 
    500     if solver is None or solver == 'diffev': 
    501         from mystic.solvers import DifferentialEvolutionSolver as TheSolver 
    502         solver = TheSolver(ndim, min(40, ndim*5)) 
    503     elif solver == 'diffev2': 
    504         from mystic.solvers import DifferentialEvolutionSolver2 as TheSolver 
    505         solver = TheSolver(ndim, min(40, ndim*5)) 
    506     elif solver == 'fmin_powell': #XXX: better as the default? (it's not random) 
    507         from mystic.solvers import PowellDirectionalSolver as TheSolver 
    508         solver = TheSolver(ndim) 
    509     elif solver == 'fmin': 
    510         from mystic.solvers import NelderMeadSimplexSolver as TheSolver 
    511         solver = TheSolver(ndim) 
    512      
    513     if termination is None: 
    514         from mystic.termination import ChangeOverGeneration as COG 
    515         termination = COG() 
    516     if guess != None: 
    517         solver.SetInitialPoints(guess) #XXX: nice if 'diffev' also had methods 
    518     else: 
    519         solver.SetRandomInitialPoints(lower_bounds, upper_bounds) 
    520     if lower_bounds or upper_bounds: 
    521         solver.SetStrictRanges(lower_bounds, upper_bounds) 
    522     if hasattr(constraints, 'iter') and hasattr(constraints, 'error'): 
    523         solver.SetPenalty(constraints) #i.e. is a penalty function 
    524     else: # is a constraints solver 
    525         solver.SetConstraints(constraints) 
    526     solver.Solve(cost, termination) 
    527     soln = solver.bestSolution 
    528  
    529     from numpy import ndarray, array 
    530     if isinstance(soln, ndarray) and not isinstance(guess, ndarray): 
    531         soln = soln.tolist() 
    532     elif isinstance(guess, ndarray) and not isinstance(soln, ndarray): 
    533         soln = array(soln)  #XXX: or always return a list ? 
    534  
    535     return soln #XXX: check with 'issolution' ? 
    536  
    537  
    538 def as_constraint(penalty, *args, **kwds): 
    539     """Convert a penalty function to a constraints solver. 
    540  
    541 Inputs: 
    542     penalty -- a penalty function 
    543  
    544 Additional Inputs: 
    545     lower_bounds -- list of lower bounds on solution values. 
    546     upper_bounds -- list of upper bounds on solution values. 
    547     nvars -- number of parameter values. 
    548     solver -- the mystic solver to use in the optimization 
    549     termination -- the mystic termination to use in the optimization 
    550     """ 
    551     def constraint(x): #XXX: better to enable args kwds for penalty ? 
    552         return solve(penalty, x, *args, **kwds) 
    553     return constraint 
    554  
    555  
    556 def as_penalty(constraint, ptype=None, *args, **kwds): 
    557     """Convert a constraints solver to a penalty function. 
    558  
    559 Inputs: 
    560     constraint -- a constraints solver 
    561     ptype -- penalty function type [default: quadratic_equality] 
    562  
    563 Additional Inputs: 
    564     args -- arguments for the constraints solver [default: ()] 
    565     kwds -- keyword arguments for the constraints solver [default: {}] 
    566     k -- penalty multiplier 
    567     h -- iterative multiplier 
    568     """ 
    569     def rnorm(x, *argz, **kwdz): 
    570         error = 0.0 
    571         constrained = constraint(x, *argz, **kwdz) 
    572         for i in range(len(x)): 
    573             error += (constrained[i] - x[i])**2  #XXX: better rnorm ? 
    574         error = error**0.5 
    575         return error 
    576  
    577     if ptype is None: ptype = quadratic_equality 
    578  
    579     @ptype(rnorm, *args, **kwds) #XXX: yes to k,h... but otherwise? 
    580     def penalty(x): 
    581         return 0.0 
    582  
    583     return penalty 
    584  
    585  
    586420# EOF  
  • branches/decorate/symbolic.py

    r623 r644  
    33# originally coded by Alta Fang, 2010 
    44# refactored by mmckerns@caltech.edu, 2012 
    5  
     5"""Tools for working with symbolic constraints. 
     6""" 
    67from __future__ import division 
     8 
     9__all__ = ['linear_symbolic','replace_variables','get_variables','solve', 
     10           'penalty_parser','constraints_parser','generate_conditions', 
     11           'generate_solvers','generate_penalty','generate_constraint'] 
     12 
    713from numpy import ndarray, asarray 
    814from _symbolic import solve 
     
    655661    # allow for single ctype, list of ctypes, or nested list 
    656662    if ctype is None: 
    657         from constraints import inner #XXX: outer ? 
     663        from coupler import inner #XXX: outer ? 
    658664        ctype = list((inner,))*len(conditions) 
    659665    elif not list_or_tuple_or_ndarray(ctype): 
  • branches/decorate/test_constraints.py

    r610 r644  
    1 from penalty import * 
     1from constraints import * 
     2from penalty import quadratic_equality 
     3from coupler import inner 
    24from mystic.math import almostEqual 
    35 
     
    5355 
    5456  from mystic.math.measures import mean 
    55   from constraints import with_mean 
    56  
    5757  @with_mean(1.0) 
    5858  def constraint(x): 
     
    108108 
    109109  from mystic.math.measures import mean, spread 
    110   from constraints import with_mean, with_spread 
    111  
    112110  @with_spread(5.0) 
    113111  @with_mean(5.0) 
     
    148146  assert round(mean(y)) == 5.0 
    149147  assert round(cost(y)) == 4*(5.0) 
     148 
     149 
     150def test_with_mean(): 
     151 
     152  from mystic.math.measures import mean, impose_mean 
     153 
     154  @with_mean(5.0) 
     155  def mean_of_squared(x): 
     156    return [i**2 for i in x] 
     157 
     158  from numpy import array 
     159  x = array([1,2,3,4,5]) 
     160  y = impose_mean(5, [i**2 for i in x]) 
     161  assert mean(y) == 5.0 
     162  assert mean_of_squared(x) == y 
     163 
     164 
     165def test_with_mean_spread(): 
     166 
     167  from mystic.math.measures import mean, spread, impose_mean, impose_spread 
     168 
     169  @with_spread(50.0) 
     170  @with_mean(5.0) 
     171  def constrained_squared(x): 
     172    return [i**2 for i in x] 
     173 
     174  from numpy import array 
     175  x = array([1,2,3,4,5]) 
     176  y = impose_spread(50.0, impose_mean(5.0,[i**2 for i in x])) 
     177  assert almostEqual(mean(y), 5.0, tol=1e-15) 
     178  assert almostEqual(spread(y), 50.0, tol=1e-15) 
     179  assert constrained_squared(x) == y 
     180 
     181 
     182def test_constrained_solve(): 
     183 
     184  from mystic.math.measures import mean, spread 
     185  @with_spread(5.0) 
     186  @with_mean(5.0) 
     187  def constraints(x): 
     188    return x 
     189 
     190  def cost(x): 
     191    return abs(sum(x) - 5.0) 
     192 
     193  from mystic.solvers import fmin_powell 
     194  from numpy import array 
     195  x = array([1,2,3,4,5]) 
     196  y = fmin_powell(cost, x, constraints=constraints, disp=False) 
     197 
     198  assert almostEqual(mean(y), 5.0, tol=1e-15) 
     199  assert almostEqual(spread(y), 5.0, tol=1e-15) 
     200  assert almostEqual(cost(y), 4*(5.0), tol=1e-6) 
     201 
     202 
     203def test_with_constraint(): 
     204 
     205  from mystic.math.measures import mean, impose_mean 
     206 
     207  @with_constraint(inner, kwds={'target':5.0}) 
     208  def mean_of_squared(x, target): 
     209    return impose_mean(target, [i**2 for i in x]) 
     210 
     211  from numpy import array 
     212  x = array([1,2,3,4,5]) 
     213  y = impose_mean(5, [i**2 for i in x]) 
     214  assert mean(y) == 5.0 
     215  assert mean_of_squared(x) == y 
    150216 
    151217 
     
    157223  test_as_penalty() 
    158224  test_with_penalty() 
     225  test_with_mean() 
     226  test_with_mean_spread() 
     227  test_constrained_solve() 
     228  test_with_constraint() 
    159229 
    160230 
  • branches/decorate/test_coupler.py

    r609 r644  
    1 from constraints import * 
     1from coupler import * 
    22from mystic.math import almostEqual 
    33 
     
    115115 
    116116 
    117 def test_with_mean(): 
    118  
    119   from mystic.math.measures import impose_mean 
    120  
    121   @with_mean(5.0) 
    122   def mean_of_squared(x): 
    123     return [i**2 for i in x] 
    124  
    125   from numpy import array 
    126   x = array([1,2,3,4,5]) 
    127   y = impose_mean(5, [i**2 for i in x]) 
    128   assert mean(y) == 5.0 
    129   assert mean_of_squared(x) == y 
    130  
    131  
    132 def test_with_mean_spread(): 
    133  
    134   from mystic.math.measures import impose_mean, impose_spread 
    135  
    136   @with_spread(50.0) 
    137   @with_mean(5.0) 
    138   def constrained_squared(x): 
    139     return [i**2 for i in x] 
    140  
    141   from numpy import array 
    142   x = array([1,2,3,4,5]) 
    143   y = impose_spread(50.0, impose_mean(5.0,[i**2 for i in x])) 
    144   assert almostEqual(mean(y), 5.0, tol=1e-15) 
    145   assert almostEqual(spread(y), 50.0, tol=1e-15) 
    146   assert constrained_squared(x) == y 
    147  
    148  
    149 def test_constrained_solve(): 
    150  
    151   @with_spread(5.0) 
    152   @with_mean(5.0) 
    153   def constraints(x): 
    154     return x 
    155  
    156   def cost(x): 
    157     return abs(sum(x) - 5.0) 
    158  
    159   from mystic.solvers import fmin_powell 
    160   from numpy import array 
    161   x = array([1,2,3,4,5]) 
    162   y = fmin_powell(cost, x, constraints=constraints, disp=False) 
    163  
    164   assert almostEqual(mean(y), 5.0, tol=1e-15) 
    165   assert almostEqual(spread(y), 5.0, tol=1e-15) 
    166   assert almostEqual(cost(y), 4*(5.0), tol=1e-6) 
    167  
    168  
    169117def test_constrain(): 
    170118 
     
    195143 
    196144 
    197 def test_with_constraint(): 
    198  
    199   from mystic.math.measures import impose_mean 
    200  
    201   @with_constraint(inner, kwds={'target':5.0}) 
    202   def mean_of_squared(x, target): 
    203     return impose_mean(target, [i**2 for i in x]) 
    204  
    205   from numpy import array 
    206   x = array([1,2,3,4,5]) 
    207   y = impose_mean(5, [i**2 for i in x]) 
    208   assert mean(y) == 5.0 
    209   assert mean_of_squared(x) == y 
    210  
    211  
    212145if __name__ == '__main__': 
    213146  test_outer() 
     
    218151  test_inner_constraints() 
    219152  test_proxified_constraints() 
    220   test_with_mean() 
    221   test_with_mean_spread() 
    222   test_constrained_solve() 
    223153  test_constrain() 
    224   test_with_constraint() 
    225154 
    226155 
  • branches/decorate/test_restarts.py

    r608 r644  
    22from restarts import sumt 
    33from penalty import * 
     4from constraints import * 
    45from mystic.tools import random_seed 
    56random_seed(123) 
  • branches/decorate/test_symbolic.py

    r623 r644  
    11from symbolic import * 
    22from mystic.math import almostEqual 
    3 from penalty import as_constraint 
     3from constraints import as_constraint 
    44 
    55def test_generate_penalty(): 
Note: See TracChangeset for help on using the changeset viewer.