- Timestamp:
- 12/04/12 16:08:04 (3 years ago)
- Location:
- branches/decorate
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/decorate/penalty.py
r599 r602 1 1 from numpy import inf, log 2 def quadratic_equality( k=100, h=5):2 def quadratic_equality(condition=lambda x:0., args=None, kwds=None, k=100, h=5): 3 3 """apply a quadratic penalty if the given equality constraint is violated 4 4 … … 8 8 the condition f(x) is satisfied when f(x) == 0.0 9 9 """ 10 if args is None: args=() 11 if kwds is None: kwds={} 10 12 _n = [0] 11 13 def iter(i=None): … … 16 18 return _n[0] 17 19 def dec(f): 18 def func(x, *arg s, **kwds):19 pf = f(x, *args, **kwds)20 def func(x, *argz, **kwdz): 21 pf = condition(x, *args, **kwds) 20 22 _k = k * pow(h,_n[0]) 21 return float(_k)*pf**2 23 return float(_k)*pf**2 + f(x, *argz, **kwdz) 22 24 func.iter = iter 23 25 func._get_iter = get_iter … … 25 27 return dec 26 28 27 def barrier_inequality( k=100, h=5):29 def barrier_inequality(condition=lambda x:0., args=None, kwds=None, k=100, h=5): 28 30 """apply a infinite barrier if the given inequality constraint is violated, 29 31 and a logarithmic penalty if the inequality constraint is satisfied … … 35 37 the condition f(x) is satisfied when f(x) <= 0.0 36 38 """ 39 if args is None: args=() 40 if kwds is None: kwds={} 37 41 _n = [0] 38 42 def iter(i=None): … … 43 47 return _n[0] 44 48 def dec(f): 45 def func(x, *arg s, **kwds):46 pf = f(x, *args, **kwds)49 def func(x, *argz, **kwdz): 50 pf = condition(x, *args, **kwds) 47 51 if pf > 0: # inequality constraint is violated 48 52 return inf 49 53 # inequality constraint is satisfied 50 54 _k = k * pow(h,_n[0]) 51 return -.5/_k*log(-pf) #XXX: use 2*k or k=200?55 return -.5/_k*log(-pf) + f(x, *argz, **kwdz) #XXX: use 2*k or k=200? 52 56 func.iter = iter 53 57 func._get_iter = get_iter … … 55 59 return dec 56 60 57 def quadratic_inequality( k=100, h=5):61 def quadratic_inequality(condition=lambda x:0., args=None, kwds=None, k=100, h=5): 58 62 """apply a quadratic penalty if the given inequality constraint is violated 59 63 … … 63 67 the condition f(x) is satisfied when f(x) <= 0.0 64 68 """ 69 if args is None: args=() 70 if kwds is None: kwds={} 65 71 _n = [0] 66 72 def iter(i=None): … … 71 77 return _n[0] 72 78 def dec(f): 73 def func(x, *arg s, **kwds):74 pf = f(x, *args, **kwds)79 def func(x, *argz, **kwdz): 80 pf = condition(x, *args, **kwds) 75 81 _k = k * pow(h,_n[0]) 76 return float(2*_k)*max(0., pf)**2 #XXX: use 2*k or k=200?82 return float(2*_k)*max(0., pf)**2 + f(x, *argz, **kwdz) #XXX: use 2*k or k=200? 77 83 func.iter = iter 78 84 func._get_iter = get_iter … … 80 86 return dec 81 87 82 def lagrange_inequality( k=20, h=5):88 def lagrange_inequality(condition=lambda x:0., args=None, kwds=None, k=20, h=5): 83 89 """apply a quadratic penalty if the given inequality constraint is violated 84 90 … … 89 95 the condition f(x) is satisfied when f(x) <= 0.0 90 96 """ 97 if args is None: args=() 98 if kwds is None: kwds={} 91 99 _n = [0] 92 100 def iter(i=None): … … 97 105 return _n[0] 98 106 def dec(f): 99 def func(x, *arg s, **kwds):100 pf = f(x, *args, **kwds)107 def func(x, *argz, **kwdz): 108 pf = condition(x, *args, **kwds) 101 109 beta = 0.; _k = k 102 110 for i in range(_n[0]): … … 104 112 _k *= h 105 113 mpf = max(-beta/(2.*_k), pf) 106 return float(_k)*mpf**2 + beta*mpf 114 return float(_k)*mpf**2 + beta*mpf + f(x, *argz, **kwdz) 107 115 func.iter = iter 108 116 func._get_iter = get_iter … … 110 118 return dec 111 119 112 def lagrange_equality( k=20, h=5):120 def lagrange_equality(condition=lambda x:0., args=None, kwds=None, k=20, h=5): 113 121 """apply a quadratic penalty if the given equality constraint is violated 114 122 … … 119 127 the condition f(x) is satisfied when f(x) = 0.0 120 128 """ 129 if args is None: args=() 130 if kwds is None: kwds={} 121 131 _n = [0] 122 132 def iter(i=None): … … 127 137 return _n[0] 128 138 def dec(f): 129 def func(x, *arg s, **kwds):130 pf = f(x, *args, **kwds)139 def func(x, *argz, **kwdz): 140 pf = condition(x, *args, **kwds) 131 141 lam = 0.; _k = k 132 142 for i in range(_n[0]): 133 143 lam += 2.*_k*pf 134 144 _k *= h 135 return float(_k)*pf**2 + lam*pf 145 return float(_k)*pf**2 + lam*pf + f(x, *argz, **kwdz) 136 146 func.iter = iter 137 147 func._get_iter = get_iter … … 141 151 142 152 #################################################### 143 def penalize(penalty=lambda x:0.0): 144 """ ... """ 153 def proxify(penalty=lambda x:0.0): 154 """penalize a function with another function: y = f(x) to y' = f(x) + p(x) 155 156 This is useful, for example, in penalizing a cost function where the constraints 157 are violated; thus, the satisfying the constraints will be preferred at every 158 cost function evaluation. 159 160 This function does not preserve decorated function signature, but passes args 161 and kwds to the inner function. The decorated function should require a 162 single parameter as input. 163 """ 145 164 def dec(f): 146 165 def func(x, *args, **kwds): 147 return f(x, *args, **kwds) + penalty(x) 166 return f(x) + penalty(x, *args, **kwds) 167 return func 168 return dec 169 170 def penalize(penalty=lambda x:0.0, args=None, kwds=None): #XXX: *args, **kwds ? 171 """penalize a function with another function: y = f(x) to y' = f(x) + p(x) 172 173 This is useful, for example, in penalizing a cost function where the constraints 174 are violated; thus, the satisfying the constraints will be preferred at every 175 cost function evaluation. 176 """ 177 if args is None: args=() 178 if kwds is None: kwds={} 179 def dec(f): 180 def func(x, *argz, **kwdz): 181 return f(x, *argz, **kwdz) + penalty(x, *args, **kwds) 148 182 return func 149 183 return dec -
branches/decorate/test_penalty.py
r600 r602 5 5 6 6 from mystic.math.measures import mean, spread 7 @quadratic_equality() 8 def mean_constraint(x): 9 return mean(x) - 5.0 7 def mean_constraint(x, target): 8 return mean(x) - target 10 9 11 @quadratic_equality() 12 def range_constraint(x): 13 return spread(x) - 5.0 10 def range_constraint(x, target): 11 return spread(x) - target 14 12 15 @ penalize(penalty=range_constraint)#XXX: @quadratic_equality(range_constraint)16 @ penalize(penalty=mean_constraint) #XXX: @quadratic_equality(mean_constraint)13 @quadratic_equality(condition=range_constraint, kwds={'target':5.0}) 14 @quadratic_equality(condition=mean_constraint, kwds={'target':5.0}) 17 15 def cost(x): #XXX: def penalty(x): return x 18 16 return abs(sum(x) - 5.0) #XXX: # ...then give penalty to solver -
branches/decorate/test_wrapper.py
r600 r602 20 20 from mystic.math.measures import impose_mean 21 21 22 @nested(inner=impose_mean) 23 def mean_then_squared(x): #FIXME: doesn't preserve function signature 22 def impose_constraints(x, mean, weights=None): 23 return impose_mean(mean, x, weights) 24 25 @nested(inner=impose_constraints, kwds={'mean':5.0}) 26 def mean_then_squared(x): 27 return [i**2 for i in x] 28 29 from numpy import array 30 x = array([1,2,3,4,5]) 31 assert mean_then_squared(x) == [i**2 for i in impose_mean(5,x)] 32 33 34 def test_proxified_constraint(): 35 36 from mystic.math.measures import impose_mean 37 38 @proxify(inner=impose_mean) 39 def mean_then_squared(x): #XXX: proxy doesn't preserve function signature 24 40 return [i**2 for i in x] 25 41 … … 38 54 return x 39 55 40 @nested(inner=impose_constraints) 41 def constrained_squared(x): #FIXME: doesn't preserve function signature 56 @nested(inner=impose_constraints, kwds={'mean':5.0, 'spread':50.0}) 57 def constrained_squared(x): 58 return [i**2 for i in x] 59 60 from numpy import array 61 x = array([1,2,3,4,5]) 62 y = impose_spread(50.0, impose_mean(5.0,x)) 63 assert constrained_squared(x) == [i**2 for i in y] 64 65 66 def test_proxified_constraints(): 67 68 from mystic.math.measures import impose_mean, impose_spread 69 70 def impose_constraints(x, mean=0.0, spread=1.0): 71 x = impose_mean(mean, x) 72 x = impose_spread(spread, x) 73 return x 74 75 @proxify(inner=impose_constraints) 76 def constrained_squared(x): #XXX: proxy doesn't preserve function signature 42 77 return [i**2 for i in x] 43 78 … … 188 223 from mystic.math.measures import mean, spread 189 224 from mystic.math.measures import impose_mean, impose_spread 190 def mean_constraint(x ):191 return impose_mean( 5.0, x)192 193 def range_constraint(x ):194 return impose_spread( 5.0, x)195 196 @nested(inner=range_constraint ) #XXX: @with_range(5.0)197 @nested(inner=mean_constraint )#XXX: @with_mean(5.0)225 def mean_constraint(x, mean=0.0): 226 return impose_mean(mean, x) 227 228 def range_constraint(x, spread=1.0): 229 return impose_spread(spread, x) 230 231 @nested(inner=range_constraint, kwds={'spread':5.0}) #XXX: @with_range(5.0) 232 @nested(inner=mean_constraint, kwds={'mean':5.0}) #XXX: @with_mean(5.0) 198 233 def constraints(x): 199 234 return x … … 216 251 test_nested() 217 252 test_nested_constraint() 253 test_proxified_constraint() 218 254 test_nested_constraints() 255 test_proxified_constraints() 219 256 test_monitored() 220 257 test_counted() -
branches/decorate/wrapper.py
r598 r602 2 2 # compare against the originals for restrictions 3 3 4 def nested(inner=lambda x:x ):4 def nested(inner=lambda x:x, args=None, kwds=None): #XXX: *args, **kwds ? 5 5 """nest a function within another function: convert y = f(x) to y' = f(c(x)) 6 6 … … 8 8 thus, the constraints will be enforced at every cost function evaluation. 9 9 """ 10 def dec(f): 11 def func(*args, **kwds): #FIXME: doesn't preserve function signature 10 if args is None: args=() 11 if kwds is None: kwds={} 12 def dec(f): 13 def func(x, *argz, **kwdz): 14 return f(inner(x, *args, **kwds), *argz, **kwdz) 15 return func 16 return dec 17 18 19 def proxify(inner=lambda x:x): 20 """nest a function within another function: convert y = f(x) to y' = f(c(x)) 21 22 This is useful, for example, in nesting constraints in a cost function; 23 thus, the constraints will be enforced at every cost function evaluation. 24 25 This function does not preserve decorated function signature, but passes args 26 and kwds to the inner function. The decorated function should require a 27 single parameter as input. 28 """ 29 def dec(f): 30 def func(*args, **kwds): 12 31 return f(inner(*args, **kwds)) 13 32 return func
Note: See TracChangeset
for help on using the changeset viewer.