- Timestamp:
- 12/10/12 11:53:49 (3 years ago)
- Location:
- branches/decorate
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/decorate/constraints.py
r603 r608 76 76 77 77 78 # EOF -
branches/decorate/penalty.py
r606 r608 419 419 420 420 421 def issolution(penalty, candidate, tol=1e-3): 422 """check if the candidate is a solution to penalty constraints 423 424 penalty: a penalty function 425 candidate: a candidate solution 426 """ 427 if penalty.error(candidate) <= tol: return True 421 def issolution(constraints, candidate, tol=1e-3): 422 """Returns whether the candidate is a solution to the constraints 423 424 Input: 425 constraints -- a constraints solver function or a penalty function 426 candidate -- list of parameter values prposed to solve the constraints 427 tol -- residual error magnitude for which constraints are considered solved 428 """ 429 if hasattr(constraints, 'error'): 430 error = constraints.error(candidate) 431 else: # is a constraints solver 432 error = 0.0 433 constrained = constraints(candidate) 434 for i in range(len(candidate)): 435 error += (constrained[i] - candidate[i])**2 #XXX: better rnorm ? 436 error = error**0.5 437 438 if error <= tol: return True 428 439 return False 429 440 441 430 442 #XXX: nice if penalty.error could give error for each condition... or total 431 443 432 444 445 def solve(constraints, guess=None, nvars=None, solver=None, \ 446 lower_bounds=None, upper_bounds=None, termination=None): 447 """Use optimization to find a solution to a set of constraints. 448 449 Inputs: 450 constraints -- a constraints solver function or a penalty function 451 452 Additional Inputs: 453 guess -- list of parameter values proposed to solve the constraints. 454 lower_bounds -- list of lower bounds on solution values. 455 upper_bounds -- list of upper bounds on solution values. 456 nvars -- number of parameter values. 457 solver -- the mystic solver to use in the optimization 458 termination -- the mystic termination to use in the optimization 459 460 NOTE: The resulting constraints will likely be more expensive to evaluate 461 and less accurate than writing the constraints solver from scratch. 462 """ 463 ndim = 1 #XXX: better, increase in while loop catching IndexError ? 464 if nvars is not None: ndim = nvars 465 elif guess is not None: ndim = len(guess) 466 elif lower_bounds is not None: ndim = len(lower_bounds) 467 elif upper_bounds is not None: ndim = len(upper_bounds) 468 469 def cost(x): return 1. 470 471 #XXX: don't allow solver string as a short-cut? 472 if solver is None or solver == 'diffev': 473 from mystic.solvers import DifferentialEvolutionSolver as TheSolver 474 solver = TheSolver(ndim, min(40, ndim*5)) 475 elif solver == 'diffev2': 476 from mystic.solvers import DifferentialEvolutionSolver2 as TheSolver 477 solver = TheSolver(ndim, min(40, ndim*5)) 478 elif solver == 'fmin_powell': #XXX: better as the default? (it's not random) 479 from mystic.solvers import PowellDirectionalSolver as TheSolver 480 solver = TheSolver(ndim) 481 elif solver == 'fmin': 482 from mystic.solvers import NelderMeadSimplexSolver as TheSolver 483 solver = TheSolver(ndim) 484 485 if termination is None: 486 from mystic.termination import ChangeOverGeneration as COG 487 termination = COG() 488 if guess != None: 489 solver.SetInitialPoints(guess) #XXX: nice if 'diffev' also had methods 490 else: 491 solver.SetRandomInitialPoints(lower_bounds, upper_bounds) 492 if lower_bounds or upper_bounds: 493 solver.SetStrictRanges(lower_bounds, upper_bounds) 494 if hasattr(constraints, 'iter') and hasattr(constraints, 'error'): 495 solver.SetPenalty(constraints) #i.e. is a penalty function 496 else: # is a constraints solver 497 solver.SetConstraints(constraints) 498 solver.Solve(cost, termination) 499 soln = solver.bestSolution 500 501 from numpy import ndarray, array 502 if isinstance(soln, ndarray) and not isinstance(guess, ndarray): 503 soln = soln.tolist() 504 elif isinstance(guess, ndarray) and not isinstance(soln, ndarray): 505 soln = array(soln) #XXX: or always return a list ? 506 507 return soln #XXX: check with 'issolution' ? 508 509 510 def as_constraint(penalty, *args, **kwds): 511 """Convert a penalty function to a constraints solver. 512 513 Inputs: 514 penalty -- a penalty function 515 516 Additional Inputs: 517 lower_bounds -- list of lower bounds on solution values. 518 upper_bounds -- list of upper bounds on solution values. 519 nvars -- number of parameter values. 520 solver -- the mystic solver to use in the optimization 521 termination -- the mystic termination to use in the optimization 522 """ 523 def constraint(x): #XXX: better to enable args kwds for penalty ? 524 return solve(penalty, x, *args, **kwds) 525 return constraint 526 527 528 def as_penalty(constraint, ptype=None, *args, **kwds): 529 """Convert a constraints solver to a penalty function. 530 531 Inputs: 532 constraint -- a constraints solver 533 ptype -- penalty function type [default: quadratic_equality] 534 535 Additional Inputs: 536 args -- arguments for the constraints solver [default: ()] 537 kwds -- keyword arguments for the constraints solver [default: {}] 538 k -- penalty multiplier 539 h -- iterative multiplier 540 """ 541 def rnorm(x, *argz, **kwdz): 542 error = 0.0 543 constrained = constraint(x, *argz, **kwdz) 544 for i in range(len(x)): 545 error += (constrained[i] - x[i])**2 #XXX: better rnorm ? 546 error = error**0.5 547 return error 548 549 if ptype is None: ptype = quadratic_equality 550 551 @ptype(rnorm, *args, **kwds) #XXX: yes to k,h... but otherwise? 552 def penalty(x): 553 return 0.0 554 555 return penalty 556 557 433 558 # EOF -
branches/decorate/restarts.py
r605 r608 1 # XXX: solver restart live, from log... restart from saved population as initial2 # XXX: extract solver restart loop for penalties from constraints.py line 17853 # XXX: extract solver restart loop for collapse from collapse_code.py line 674 5 # XXX: capture and restart from full population6 # XXX: restart from RandomInputs + bestSolution7 8 #def live_restart(solver):9 #def log_restart(logs):10 #def penalty_restart(solver):11 #def collapse_restart(solver):12 13 1 14 2 def sumt(cost, solver, term, eps = 1e-4, max_SUMT_iters = 10, **kwds): … … 44 32 45 33 if randomstate: 34 import random 46 35 random.setstate(randomstate) 47 36 48 37 # 'Clear' some of the attributes of the solver 49 solver.population = [[0.0 for i in range(solver.nDim)] for j in range(solver.nPop)] #XXX no38 solver.population = [[0.0 for i in range(solver.nDim)] for j in range(solver.nPop)] 50 39 solver.generations = 0 51 40 solver.bestEnergy = 0.0 … … 53 42 solver.trialSolution = [0.0] * solver.nDim 54 43 solver._init_popEnergy = inf 55 solver.popEnergy = [solver._init_popEnergy] * solver.nPop #XXX: no44 solver.popEnergy = [solver._init_popEnergy] * solver.nPop 56 45 solver.energy_history = [] 57 46 58 #XXX: needs __init__ to correct the above 'XXX' 59 #dim = solver.nDim 60 #simplex = dim + 1 61 #solver.popEnergy = [0.0] * simplex 62 #solver.population = [[0.0 for i in range(dim)] for j in range(simplex)] 47 # individual solver __init__ 48 if solver.__class__.__name__ == 'NelderMeadSimplexSolver': 49 simplex = solver.nDim + 1 50 solver.popEnergy = [solver._init_popEnergy] * simplex 51 solver.population = [[0.0 for i in range(solver.nDim)] for j in range(simplex)] 52 elif solver.__class__.__name__ == 'PowellDirectionalSolver': 53 solver._direc = None 54 elif solver.__class__.__name__ in ['DifferentialEvolutionSolver','DifferentialEvolutionSolver2']: 55 solver.genealogy = [ [] for j in range(solver.nPop)] 56 else: pass 63 57 64 58 # Perform the 'inner' optimization -
branches/decorate/test_penalty.py
r604 r608 1 1 from penalty import * 2 #from mystic.math import almostEqual2 from mystic.math import almostEqual 3 3 4 4 def test_penalize(): … … 29 29 30 30 31 def test_solve(): 32 33 from mystic.math.measures import mean 34 def mean_constraint(x, target): 35 return mean(x) - target 36 37 def parameter_constraint(x): 38 return x[-1] - x[0] 39 40 @quadratic_equality(condition=mean_constraint, kwds={'target':5.0}) 41 @quadratic_equality(condition=parameter_constraint) 42 def penalty(x): 43 return 0.0 44 45 x = solve(penalty, guess=[2,3,1]) 46 47 assert round(mean_constraint(x, 5.0)) == 0.0 48 assert round(parameter_constraint(x)) == 0.0 49 assert issolution(penalty, x) 50 51 52 def test_solve_constraint(): 53 54 from mystic.math.measures import mean 55 from constraints import with_mean 56 57 @with_mean(1.0) 58 def constraint(x): 59 x[-1] = x[0] 60 return x 61 62 x = solve(constraint, guess=[2,3,1]) 63 64 assert almostEqual(mean(x), 1.0, tol=1e-15) 65 assert x[-1] == x[0] 66 assert issolution(constraint, x) 67 68 69 def test_as_constraint(): 70 71 from mystic.math.measures import mean, spread 72 def mean_constraint(x, target): 73 return mean(x) - target 74 75 def range_constraint(x, target): 76 return spread(x) - target 77 78 @quadratic_equality(condition=range_constraint, kwds={'target':5.0}) 79 @quadratic_equality(condition=mean_constraint, kwds={'target':5.0}) 80 def penalty(x): 81 return 0.0 82 83 ndim = 3 84 constraints = as_constraint(penalty, solver='fmin_powell') 85 #XXX: this is expensive to evaluate, as there are nested optimizations 86 87 from numpy import arange 88 x = arange(ndim) 89 _x = constraints(x) 90 91 assert round(mean(_x)) == 5.0 92 assert round(spread(_x)) == 5.0 93 94 def cost(x): 95 return abs(sum(x) - 5.0) 96 97 npop = ndim*3 98 from mystic.solvers import fmin_powell, diffev 99 y = diffev(cost, x, npop, constraints=constraints, disp=False, gtol=10) 100 101 assert round(mean(y)) == 5.0 102 assert round(spread(y)) == 5.0 103 assert round(cost(y)) == 5.0*(ndim-1) 104 105 106 def test_as_penalty(): 107 108 from mystic.math.measures import mean, spread 109 from constraints import with_mean, with_spread 110 111 @with_spread(5.0) 112 @with_mean(5.0) 113 def constraint(x): 114 return x 115 116 penalty = as_penalty(constraint) 117 118 from numpy import array 119 x = array([1,2,3,4,5]) 120 121 def cost(x): 122 return abs(sum(x) - 5.0) 123 124 from mystic.solvers import fmin_powell 125 y = fmin_powell(cost, x, penalty=penalty, disp=False) 126 127 assert round(mean(y)) == 5.0 128 assert round(spread(y)) == 5.0 129 assert round(cost(y)) == 4*(5.0) 130 131 31 132 32 133 if __name__ == '__main__': 33 134 test_penalize() 135 test_solve() 136 test_solve_constraint() 137 test_as_constraint() 138 test_as_penalty() 34 139 35 140 -
branches/decorate/test_restarts.py
r606 r608 5 5 random_seed(123) 6 6 7 def test_sumt1(verbose=False): 8 7 def test_sumt1(solver, verbose=False): 9 8 def constraint1(x): 10 9 x1,x2 = x[0],x[1] … … 27 26 print "constraints equations:%s" % (constraints_string.rstrip(),) 28 27 29 def cost func(x):28 def cost(x): 30 29 x1 = x[0] 31 30 x2 = x[1] 32 31 return x1**4 - 2.*x1**2*x2 + x1**2 + x1*x2**2 - 2.*x1 + 4. 33 32 34 ndim = 2 35 x0 = [3., 2.] 36 npop = 25 37 from mystic.solvers import DifferentialEvolutionSolver 38 from mystic.solvers import NelderMeadSimplexSolver 33 #XXX: Rand1Bin needs randomstate to work properly when no random_seed ? 34 #import random 35 #randomstate = random.getstate() #XXX: this should be an internal 36 solver.SetPenalty(penalty) 39 37 from mystic.termination import VTR 40 #solver = DifferentialEvolutionSolver(ndim, npop)41 solver = NelderMeadSimplexSolver(ndim)42 solver.SetInitialPoints(x0)43 solver.SetPenalty(penalty)44 38 term = VTR() 45 end_solver = sumt(costfunc, solver, term, disp=verbose)46 soln = end_solver.Solution()39 _solver = sumt(cost, solver, term, disp=verbose)#, randomstate=randomstate) 40 soln = _solver.Solution() 47 41 satisfied = issolution(penalty, soln) 48 42 if verbose: … … 53 47 54 48 55 def test_sumt2( verbose=False):49 def test_sumt2(solver, verbose=False): 56 50 def constraint1(x): 57 51 x1,x2,x3 = x[0],x[1],x[2] … … 80 74 print "constraints equations:%s" % (constraints_string.rstrip(),) 81 75 82 def cost func(x):76 def cost(x): 83 77 return (x[0] - 1.)**2 + (x[1]-2.)**2 + (x[2]-3.)**4 84 78 85 ndim = 386 x0 = [0.]*ndim87 from mystic.solvers import DifferentialEvolutionSolver88 from mystic.solvers import NelderMeadSimplexSolver79 #XXX: Rand1Bin needs randomstate to work properly when no random_seed ? 80 #import random 81 #randomstate = random.getstate() #XXX: this should be an internal 82 solver.SetPenalty(penalty) 89 83 from mystic.termination import VTR 90 #solver = DifferentialEvolutionSolver(ndim, npop)91 solver = NelderMeadSimplexSolver(ndim)92 solver.SetInitialPoints(x0)93 solver.SetPenalty(penalty)94 84 term = VTR() 95 end_solver = sumt(costfunc, solver, term, disp=verbose)96 soln = end_solver.Solution()85 _solver = sumt(cost, solver, term, disp=verbose)#, randomstate=randomstate) 86 soln = _solver.Solution() 97 87 satisfied = issolution(penalty, soln) 98 88 if verbose: … … 104 94 105 95 if __name__ == '__main__': 106 test_sumt1() 107 test_sumt2() 96 from mystic.solvers import DifferentialEvolutionSolver 97 from mystic.solvers import DifferentialEvolutionSolver2 98 from mystic.solvers import PowellDirectionalSolver 99 from mystic.solvers import NelderMeadSimplexSolver 100 verbose = True 101 102 x0 = [3., 2.]; ndim = 2; npop = 25 103 #solver = DifferentialEvolutionSolver(ndim, npop) 104 #solver = DifferentialEvolutionSolver2(ndim, npop) 105 #solver = PowellDirectionalSolver(ndim) 106 solver = NelderMeadSimplexSolver(ndim) 107 solver.SetInitialPoints(x0) 108 test_sumt1(solver, verbose=verbose) 109 110 x0 = [0., 0., 0.]; ndim = 3; npop = 40 111 #solver = DifferentialEvolutionSolver(ndim, npop) 112 #solver = DifferentialEvolutionSolver2(ndim, npop) 113 #solver = PowellDirectionalSolver(ndim) 114 solver = NelderMeadSimplexSolver(ndim) 115 solver.SetInitialPoints(x0) 116 test_sumt2(solver, verbose=verbose) 108 117 109 118 -
branches/decorate/wrapper.py
r603 r608 1 1 #XXX: be mindful if the decorators restrict to functions that expect arrays 2 2 # compare against the originals for restrictions 3 4 #XXX: when_decorated registers methods to 'populate up' when is decorated ? 5 3 6 4 7 def wrap(outer=lambda x:x, args=None, kwds=None): #XXX: *args, **kwds ?
Note: See TracChangeset
for help on using the changeset viewer.