Changeset 175
- Timestamp:
- 08/09/09 13:04:00 (7 years ago)
- Location:
- branches/alta/mystic-0.1a2/mystic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/alta/mystic-0.1a2/mystic/anneal_solver.py
r160 r175 20 20 - StepMonitor = Sow() 21 21 - enable_signal_handler() 22 - termination = A nnealTermination()22 - termination = AveragePopulationImprovement(tolerance) 23 23 24 24 Usage … … 189 189 return 190 190 191 # Replace uses of this with Sow()?192 191 class _state(object): 193 192 def __init__(self): … … 238 237 T0 -- Initial Temperature (estimated as 1.2 times the largest 239 238 cost-function deviation over random points in the range) 240 [default=None]241 Tf -- Final goal temperature242 [default=1e-12]243 maxaccept -- Maximum changes to accept244 239 [default=None] 245 240 learn_rate -- scale constant for adjusting guesses … … 252 247 dwell -- The number of times to search the space at each temperature. 253 248 [default=50] 254 disp -- Non-zero to print convergence messages. 255 [default=0] 249 250 Optional Termination Conditions: 251 Tf -- Final goal temperature 252 [default=1e-12] 253 maxaccept -- Maximum changes to accept 254 [default=None] 256 255 """ 257 256 #allow for inputs that don't conform to AbstractSolver interface … … 259 258 x0 = self.population[0] 260 259 261 callback = None262 260 schedule = "fast" 263 261 T0 = None 264 Tf = 1e-12265 262 boltzmann = 1.0 266 263 learn_rate = 0.5 … … 269 266 m = 1.0 270 267 n = 1.0 271 disp = 0 272 self._maxaccept = None 273 274 if kwds.has_key('callback'): callback = kwds['callback'] 268 269 Tf = 1e-12 # or None? 270 self._maxaccept = None 271 272 self.disp = 0 273 self.callback = None 274 275 275 if kwds.has_key('schedule'): schedule = kwds['schedule'] 276 276 if kwds.has_key('T0'): T0 = kwds['T0'] 277 if kwds.has_key('Tf'): Tf = kwds['Tf']278 277 if kwds.has_key('boltzmann'): boltzmann = kwds['boltzmann'] 279 278 if kwds.has_key('learn_rate'): learn_rate = kwds['learn_rate'] … … 282 281 if kwds.has_key('m'): m = kwds['m'] 283 282 if kwds.has_key('n'): n = kwds['n'] 284 if kwds.has_key('disp'): disp = kwds['disp'] 283 284 if kwds.has_key('Tf'): Tf = kwds['Tf'] 285 285 if kwds.has_key('maxaccept'): self._maxaccept = kwds['maxaccept'] 286 287 if kwds.has_key('disp'): self.disp = kwds['disp'] 288 if kwds.has_key('callback'): self.callback = kwds['callback'] 289 286 290 #------------------------------------------------------------- 287 291 … … 293 297 if self._useStrictRange: 294 298 x0 = self._clipGuessWithinRangeBoundary(x0) 299 # Note: wrap_bounds changes the results slightly from the original 295 300 func = wrap_bounds(func, self._strictMin, self._strictMax) 296 301 … … 314 319 self.bestSolution = x0 315 320 else: 316 self.bestSolution = None 321 #self.bestSolution = None 322 self.bestSolution = x0 317 323 self.bestEnergy = 300e8 318 324 … … 327 333 schedule.T = schedule.T0 328 334 fqueue = [100, 300, 500, 700] 335 self.population = asarray(fqueue)*1.0 329 336 iters = 0 330 337 while 1: 338 StepMonitor(self.bestSolution, self.bestEnergy) 331 339 for n in range(dwell): 332 340 current_state.x = schedule.update_guess(last_state.x) … … 348 356 af = asarray(fqueue)*1.0 349 357 358 # Update monitors/variables 350 359 self.population = af 351 360 self.energy_history.append(self.bestEnergy) 352 StepMonitor(self.bestSolution[:], self.bestEnergy) 353 354 if callback is not None: 355 callback(self.bestSolution) 361 362 if self.callback is not None: 363 self.callback(self.bestSolution) 356 364 357 365 # Stopping conditions … … 373 381 if (Tf is not None) and (schedule.T < Tf): 374 382 break 375 if (self._maxfun is not None) and (schedule.feval > self._maxfun): 383 # if (self._maxfun is not None) and (schedule.feval > self._maxfun): 384 # retval = 1 385 # break 386 if (self._maxfun is not None) and (fcalls[0] > self._maxfun): 376 387 retval = 1 377 388 break … … 382 393 break 383 394 395 signal.signal(signal.SIGINT,signal.default_int_handler) 396 384 397 # Store some information. Is there a better way to do this? 385 398 self.generations = iters # Number of iterations … … 387 400 self.accept = schedule.accepted # Number of tests accepted 388 401 389 signal.signal(signal.SIGINT,signal.default_int_handler)390 391 402 # code below here pushes output to scipy.optimize interface 392 403 393 if disp:404 if self.disp: 394 405 if retval == 1: 395 406 print "Warning: Maximum number of function evaluations has "\ … … 452 463 retval -- Flag indicating stopping condition: 453 464 1 : Maximum function evaluations 454 2 : Maximum coolingiterations reached465 2 : Maximum iterations reached 455 466 3 : Maximum accepted query locations reached 456 467 allvecs -- a list of solutions at each iteration. … … 458 469 459 470 from mystic.tools import Sow 471 from mystic.termination import AveragePopulationImprovement 460 472 stepmon = Sow() 461 473 evalmon = Sow() 462 from mystic.termination import AnnealTermination 463 474 464 475 x0 = asarray(x0) 465 466 476 solver = AnnealSolver(len(x0)) 467 477 solver.SetInitialPoints(x0) … … 470 480 471 481 # Default bounds cause errors when function is not 1-dimensional 472 lower = asarray(lower) 473 upper = asarray(upper) 474 solver.SetStrictRanges(lower,upper) 475 solver.Solve(func,termination=AnnealTermination(feps),\ 482 solver.SetStrictRanges(lower,upper) 483 484 solver.Solve(func,termination=AveragePopulationImprovement(tolerance=feps),\ 476 485 EvaluationMonitor=evalmon,StepMonitor=stepmon,\ 477 486 ExtraArgs=args, callback=callback,\ … … 483 492 484 493 # code below here pushes output to scipy.optimize interface 485 x = list(solver.bestSolution)486 #x = solver.bestSolution494 #x = list(solver.bestSolution) 495 x = solver.bestSolution 487 496 fval = solver.bestEnergy 488 497 fcalls = len(evalmon.x) … … 493 502 allvecs.append(stepmon.x[i]) 494 503 495 # to be fixed ?504 # to be fixed 496 505 T = solver.T 497 506 accept = solver.accept … … 516 525 return retlist 517 526 527 if __name__=='__main__': 528 help(__name__) 529 530 # end of file -
branches/alta/mystic-0.1a2/mystic/snobfit_solver.py
r174 r175 27 27 - StepMonitor = Sow() 28 28 - enable_signal_handler() 29 - termination = SnobfitTermination(rtol, ftol, generations) 29 - termination = FglobTermination(fglob, tolerance, generations) for fglob !=0. 30 = VTRChangeOverGenerations(costtolerance,gentolerance,generations) 31 for fglob == 0 32 33 where fglob is the user-specified global function value (default=0). 30 34 31 35 Usage … … 123 127 p -- probability of generating a evaluation point of Class 4. 124 128 fac -- Factor for multiplicative perturbation of the data. 125 fglob -- the user specified global function value.126 129 127 130 """ … … 130 133 self.p = 0.5 131 134 self.fac = 0.0 132 self.fglob = 0133 self.disp = False134 135 self.callback = None 136 self.disp = 0 135 137 136 138 # Initialize some variables depending on input 137 139 if kwds.has_key('p'): self.p = kwds['p'] 138 140 if kwds.has_key('fac'): self.fac = kwds['fac'] 139 if kwds.has_key(' fglob'): self.fglob = kwds['fglob']141 if kwds.has_key('callback'): self.callback = kwds['callback'] 140 142 if kwds.has_key('disp'): self.disp = kwds['disp'] 141 if kwds.has_key('callback'): self.callback = kwds['callback'] 143 144 # For convenience (and uncertainty calculations): 145 self.func = func 142 146 143 147 #------------------------------------------------------------- … … 145 149 self._EARLYEXIT = False 146 150 147 fcalls, func = wrap_function(func, ExtraArgs, EvaluationMonitor)151 fcalls, self.func = wrap_function(self.func, ExtraArgs, EvaluationMonitor) 148 152 if self._useStrictRange: 149 #for i in range(self.nPop): 150 # self.population[i] = self._clipGuessWithinRangeBoundary(self.population[i]) 151 #func = wrap_bounds(func, self._strictMin, self._strictMax) 152 153 # Fix for when bounds were set after initial points. 154 # Snobfit's initialization uses the bounds not just for clipping, so 155 # the above code wouldn't really be quite right. 156 # Problem with this: what if SetRandomInitialPoints was called and 157 # the self.population[0] was something weird? 153 for i in range(self.nPop): 154 self.population[i] = self._clipGuessWithinRangeBoundary(self.population[i]) 155 self.func = wrap_bounds(self.func, self._strictMin, self._strictMax) 156 157 # Fix for when bounds were set after initial points: reinitialize 158 # This may give different results from if SetStrictRanges was called first 158 159 x0 = self.population[0] 159 160 self.SetInitialPoints(x0) … … 164 165 #------------------------------------------------------------- 165 166 166 # to be fixed167 self.func = func168 169 167 x0 = self.population[0] 170 168 self.x = self.population 171 169 170 self.fglob = 0 171 172 172 # The number of safeguarded nearest neighbors 173 173 self.snn = self.nPop - 1 … … 178 178 # Other initializations 179 179 self.constraint = None 180 (self.f, self.df) = self._setInitial_fdf( func)180 (self.f, self.df) = self._setInitial_fdf() 181 181 self.nx = self.x.shape[0] 182 182 self.setInit() … … 210 210 if fcalls[0] == initfcalls: 211 211 # initial call 212 self.fit( func,initialCall=True)212 self.fit(initialCall=True) 213 213 214 214 else: 215 215 # continuation call 216 self.fit( func,x=x, f=f)216 self.fit(x=x, f=f) 217 217 218 218 [xopt, fopt] = (self.xbest, self.fbest) … … 220 220 for j in xrange( self.nPop ): 221 221 x[j,:] = self.request[j,0:self.nDim] 222 f[j] = func(x[j,:])222 f[j] = self.func(x[j,:]) 223 223 224 224 # update function call counter 225 #ncall += self.nPop # <-- original snobfit function call counter225 #ncall += self.nPop 226 226 227 227 # best of the new function values … … 232 232 fopt = fbestn 233 233 xopt = x[jbest,:] 234 235 if self.callback is not None:236 self.callback(x[jbest])237 234 238 235 # Monitor progress … … 242 239 self.popEnergy = self.f 243 240 self.energy_history.append(self.bestEnergy) 241 242 if self.callback is not None: 243 #self.callback(x[jbest]) 244 self.callback(self.bestSolution) 244 245 245 246 i += 1 … … 270 271 271 272 # Overwrite abstract_solver's SetRandomInitialPoints() 272 273 273 274 # If SetStrictRange was called first, use those bounds. 274 275 # If SetInitialPoints was called first, temporarily use defaults, … … 282 283 self._useStrictRange = False 283 284 else: 284 # Defaults copied from abstract_solver. They do not make a difference285 # becauseSolve() will re-initialize with new min and max285 # Defaults copied from abstract_solver. 286 # Solve() will re-initialize with new min and max 286 287 if min is None: min = [-1e3]*self.nDim 287 288 if max is None: max = [1e3]*self.nDim 288 289 self.population = self._setInitRecommendedEvalPoints(min,max) 289 self.population = self._setInitRecommendedEvalPoints(min,max) 290 print self.population 291 # def SetInitialPoints(self,x0): 292 # self.population = self._setInitRecommendedEvalPoints(self._strictMin,self._strictMax) 293 # self.population[0] = x0 290 294 291 ################################################################################# 292 295 ############################################################################ 293 296 # Helper methods for SnobfitSolver 294 297 295 def _setInitRecommendedEvalPoints(self, min,max):298 def _setInitRecommendedEvalPoints(self,min,max): 296 299 """ 297 300 Snobfit's initialization of the population … … 301 304 ) + \ 302 305 numpy.array( [min] ).repeat(self.nPop,axis=0) 303 304 #x = numpy.append( [x0], x, axis=0 ) 306 # x = numpy.append( [x0], x, axis=0 ) 305 307 return x 306 308 307 def _setInitial_fdf(self , func):309 def _setInitial_fdf(self): 308 310 """ 309 311 The computation of the function values of the first set of the … … 319 321 320 322 for i in xrange(self.nPop): 321 f[i] = func( self.x[i,:] )323 f[i] = self.func( self.x[i,:] ) 322 324 df[i] = max(3*self.fac, numpy.sqrt(eps)) 323 325 … … 683 685 684 686 685 def _calc_SplitPoint(self, j, x1, x2 , func):687 def _calc_SplitPoint(self, j, x1, x2): 686 688 """ 687 689 Compute the split point 688 690 """ 689 _lambda = self._calc_Lambda( func(self.x[j,:]),690 func(self.x[j+1,:])691 _lambda = self._calc_Lambda(self.func(self.x[j,:]), 692 self.func(self.x[j+1,:]) 691 693 ) 692 694 return _lambda*x1 + (1.0 - _lambda)*x2 693 695 694 696 695 def _split(self, x, f, df, xl0, xu0, nspl , func):697 def _split(self, x, f, df, xl0, xu0, nspl): 696 698 """ Split a box 697 699 … … 764 766 j = numpy.argmax( y[1:len(y)]-y[0:len(y)-1] ) 765 767 if self.constraint is None: 766 ymid = self._calc_SplitPoint(j, y[j], y[j+1] , func)768 ymid = self._calc_SplitPoint(j, y[j], y[j+1]) 767 769 else: 768 770 ymid = 0.5*(y[j]+y[j+1]) … … 804 806 k = numpy.argmax( d ) 805 807 if self.constraint is None: 806 ymid = self._calc_SplitPoint(k, y[k], y[k+1] , func)808 ymid = self._calc_SplitPoint(k, y[k], y[k+1]) 807 809 else: 808 810 ymid = 0.5*(y[k] + y[k+1]) … … 984 986 fnew, # new function values and 985 987 dfnew, # their variations 986 func987 988 ): 988 989 """ … … 1130 1131 xl[j,:], 1131 1132 xu[j,:], 1132 self.nsplit[j,:], 1133 func 1133 self.nsplit[j,:] 1134 1134 ) 1135 1135 k = self._sumFind( x0 == \ … … 1341 1341 # Step 3 1342 1342 #------------------------------------ 1343 def branch(self , func):1343 def branch(self): 1344 1344 """ 1345 1345 All current boxes containing more than one point are split … … 1357 1357 self.u, 1358 1358 self.v, 1359 numpy.zeros( self.nDim), 1360 func 1359 numpy.zeros( self.nDim) 1361 1360 ) 1362 1361 else: … … 1538 1537 1539 1538 1540 def updateWorkspace(self , func):1539 def updateWorkspace(self): 1541 1540 """ update the current work space """ 1542 1541 oldxbest = self.xbest … … 1547 1546 self.xnew, 1548 1547 self.fnew, 1549 self.dfnew, 1550 func 1548 self.dfnew 1551 1549 ) 1552 1550 … … 2110 2108 2111 2109 2112 def _q(self, f, f0, Delta):2113 return ( f - f0 ) / ( Delta + abs(f - f0) )2114 2115 2116 2117 2110 # ----------------------------------------------------------------- 2118 2111 2119 def fit(self, func,x=None, f=None, df=None, initialCall=False):2112 def fit(self, x=None, f=None, df=None, initialCall=False): 2120 2113 """ 2121 2114 One call of snobfit … … 2141 2134 self.update_uv() # Step 1 2142 2135 self.update_input() # Step 2 2143 self.branch( func) # step 32136 self.branch() # step 3 2144 2137 2145 2138 (fmax, fmin) = self._getExtrmeFunc() … … 2162 2155 self.dfnew = numpy.ones(len(f))*max(3*self.fac,numpy.sqrt(eps)) 2163 2156 2164 self.updateWorkspace( func)2157 self.updateWorkspace() 2165 2158 2166 2159 if isEmpty(self.near): # This is equal go to Step 11 … … 2187 2180 # matrix, uncertainty: 2188 2181 # Note: uncertainty() sometimes returns NaN or causes errors.... 2182 2183 def _q(self, f, f0, Delta): 2184 return ( f - f0 ) / ( Delta + abs(f - f0) ) 2189 2185 2190 2186 def _calcCovarAtSolution(self, x, f, df=None): … … 2202 2198 self.dfnew = numpy.ones(len(f))*max(3*self.fac,numpy.sqrt(eps)) 2203 2199 2204 self.updateWorkspace( self.func)2200 self.updateWorkspace() 2205 2201 2206 2202 # Current best solution … … 2304 2300 return uct 2305 2301 2306 2307 2308 2302 ############################################################################### 2309 2303 # If using an instance of SoftConstraints (constraint is not None), … … 2343 2337 self.p = 0.5 2344 2338 self.fac = 0.0 2339 self.disp = 0 2340 self.callback = None 2341 2342 # Fix me? SnobfitSoftSolver requires fglob to be entered in both 2343 # termination and Solve().... 2345 2344 self.fglob = 0 2346 self.disp = False2347 self.callback = None2348 2345 2349 2346 # Initialize some variables depending on input … … 2351 2348 if kwds.has_key('fac'): self.fac = kwds['fac'] 2352 2349 if kwds.has_key('fglob'): self.fglob = kwds['fglob'] 2350 if kwds.has_key('callback'): self.callback = kwds['callback'] 2353 2351 if kwds.has_key('disp'): self.disp = kwds['disp'] 2354 if kwds.has_key('callback'): self.callback = kwds['callback']2355 2352 2356 2353 # SoftConstraints requires a constraint passed to Solve().... 2357 2354 if kwds.has_key('constraint'): self.constraint = kwds['constraint'] 2355 2356 # Make func an instance variable 2357 self.func = func 2358 2358 2359 2359 #------------------------------------------------------------- … … 2361 2361 self._EARLYEXIT = False 2362 2362 2363 fcalls, func = wrap_function(func, ExtraArgs, EvaluationMonitor)2363 fcalls, self.func = wrap_function(self.func, ExtraArgs, EvaluationMonitor) 2364 2364 if self._useStrictRange: 2365 #for i in range(self.nPop):2366 #self.population[i] = self._clipGuessWithinRangeBoundary(self.population[i])2367 #func = wrap_bounds(func, self._strictMin, self._strictMax)2365 for i in range(self.nPop): 2366 self.population[i] = self._clipGuessWithinRangeBoundary(self.population[i]) 2367 self.func = wrap_bounds(self.func, self._strictMin, self._strictMax) 2368 2368 2369 2369 # Fix for when bounds were set after initial points. 2370 # Snobfit's initialization uses the bounds not just for clipping, so2371 # the above code wouldn't really be quite right.2372 # Problem with this: what if SetRandomInitialPoints was called and2373 # the self.population[0] was something weird?2374 2370 x0 = self.population[0] 2375 2371 self.SetInitialPoints(x0) … … 2390 2386 # Other initialization 2391 2387 self.x = self.population 2392 (self.f, self.df) = self._setInitial_fdf( func)2388 (self.f, self.df) = self._setInitial_fdf() 2393 2389 self.nx = self.x.shape[0] 2394 2390 self.setInit() … … 2402 2398 # Function call counter 2403 2399 #ncall = self.nPop 2404 initfcalls = fcalls[0]2405 2400 2406 2401 xopt = inf … … 2414 2409 _f = vector( self.nPop ) 2415 2410 for j in xrange( self.nPop ): 2416 _f[j] = func( _x[j] )2411 _f[j] = self.func( _x[j] ) 2417 2412 2418 2413 … … 2436 2431 self.bestEnergy = self._init_popEnergy 2437 2432 2433 initfcalls = fcalls[0] 2434 2438 2435 # Repeat until the limit on function calls is reached 2439 2436 #while ncall < self._maxiter: … … 2445 2442 if fcalls[0] == initfcalls: 2446 2443 # initial call 2447 self.fit( func,initialCall=True)2444 self.fit(initialCall=True) 2448 2445 2449 2446 else: 2450 2447 # continuation call 2451 self.fit( func,x=x, f=fm)2448 self.fit(x=x, f=fm) 2452 2449 2453 2450 [xopt, fopt] = (self.xbest, self.fbest) … … 2459 2456 for j in xrange( self.nPop ): 2460 2457 x[j,:] = self.request[j,0:self.nDim] 2461 f[j] = func(x[j,:])2458 f[j] = self.func(x[j,:]) 2462 2459 FF = self.constraint.F(x[j,:]) 2463 2460 F[j] = FF … … 2496 2493 fopt = fbestn 2497 2494 xopt = x[jbest,:] 2498 2499 if self.callback is not None :2500 self.callback(x[jbest])2501 2495 2502 2496 if fopt < 0 and change == 0: … … 2517 2511 x = _x.copy() 2518 2512 2519 _fopt = func(xopt)2513 _fopt = self.func(xopt) 2520 2514 2521 2515 # Monitor progress … … 2526 2520 self.energy_history.append(self.bestEnergy) 2527 2521 2522 if self.callback is not None : 2523 #self.callback(x[jbest]) 2524 self.callback(self.bestSolution) 2525 2528 2526 i+=1 2529 2527 … … 2531 2529 break 2532 2530 2533 import signal2534 2531 self.generations = i 2535 2532 … … 2538 2535 # code below here pushes output to scipy.optimize interface 2539 2536 fval = self.bestEnergy 2540 warnflag = 02541 2537 2542 2538 if fcalls[0] >= self._maxfun: … … 2688 2684 uncertainty -- list - Returned if retuct is True. The uncertainty of 2689 2685 the fitting parameters. 2690 2691 2686 """ 2692 2687 2693 2688 from mystic.tools import Sow 2689 from mystic.termination import FglobTermination, VTRChangeOverGenerations 2690 2694 2691 stepmon = Sow() 2695 2692 evalmon = Sow() 2696 from mystic.termination import SnobfitTermination2697 2693 2698 2694 if constraint is None: … … 2707 2703 solver = SnobfitSoftSolver(len(x0)) 2708 2704 2705 if fglob != 0: 2706 termination = FglobTermination(fglob=fglob, tolerance=rtol, generations=nstop) 2707 else: 2708 termination = VTRChangeOverGenerations(costtolerance=ftol, gentolerance=0,\ 2709 generations=nstop) 2710 2709 2711 # Bounds are required 2710 2712 solver.SetStrictRanges(bounds[0],bounds[1]) … … 2712 2714 solver.enable_signal_handler() 2713 2715 solver.SetEvaluationLimits(maxiter,maxfun) 2714 solver.Solve(func,termination =SnobfitTermination(rtol, ftol, nstop),\2716 solver.Solve(func,termination,\ 2715 2717 EvaluationMonitor=evalmon,StepMonitor=stepmon,\ 2716 2718 ExtraArgs=args,disp=disp, callback=callback,\ … … 2721 2723 fval = solver.bestEnergy 2722 2724 warnflag = 0 2723 fcalls = len(evalmon.x) # Different from ncalls of original snobfit2725 fcalls = len(evalmon.x) 2724 2726 iterations = len(stepmon.x) 2725 2727 allvecs = [] -
branches/alta/mystic-0.1a2/mystic/termination.py
r169 r175 60 60 return _ 61 61 62 def SnobfitTermination(rtol=1e-6, ftol=1e-6, generations=250):62 def FglobTermination(fglob=0, tolerance=1e-6, generations = None): 63 63 """ 64 Parameters:65 rtol -- a relative error for checking stopping criterion. 66 ftol -- acceptable relative error in func(xopt) for convergence.67 generations 64 Input Parameters: 65 fglob -- User-specified global function value 66 tolerance -- a relative error for checking stopping criterion. 67 generations -- number of times no improvement is tolerated. 68 68 69 Terminate if no improvement after iterations = generations or if 70 abs((fopt-fglob)/fglob) < rtol for fglob != 0, abs(fopt) < ftol 71 for fglob == 0""" 69 Terminate if abs((bestEnergy-fglob)/fglob < tolerance)""" 72 70 73 71 def _(inst): 74 answer = False 75 hist = inst.energy_history 76 if len(hist) > generations and (hist[-generations]-hist[-1]) < 0: 77 answer = True 78 else: 79 fopt = inst.bestEnergy 80 if inst.fglob: 81 if abs((fopt-inst.fglob)/inst.fglob) < rtol: 82 answer = True 83 else: # safeguard if functions with fglob=0 are added by user 84 if abs(fopt) < ftol: 85 answer = True 86 return answer 72 if generations: 73 hist = inst.energy_history 74 lg = len(hist) 75 return lg > generations and (hist[-generations]-hist[-1]) < 0 76 return fglob != 0 and \ 77 abs((inst.bestEnergy-fglob)/fglob) < tolerance 87 78 return _ 88 79 89 def AnnealTermination(feps=1e-6): 90 """Terminate if abs((population-x0)/x0) < feps""" 80 def VTRChangeOverGenerations(costtolerance = 0.005, gentolerance = 1e-6, \ 81 generations = 250): 82 """Terminate if change in cost is < gentolerance over a number of 83 generations, or cost of last iteration is < costtolerance: 84 85 cost[-g] - cost[-1] < gentolerance, where g=generations or 86 cost[-1] < costtolerance.""" 87 def _(inst): 88 hist = inst.energy_history 89 lg = len(hist) 90 return (lg > generations and (hist[-generations]-hist[-1]) < gentolerance)\ 91 or ( hist[-1] < costtolerance ) 92 return _ 93 94 def AveragePopulationImprovement(tolerance=1e-6): 95 """Terminate if abs((population-population[0])/population[0]) < tolerance""" 91 96 def _(inst): 92 97 sim = inst.population 93 return all(abs((sim-sim[0])/sim[0]) < feps)98 return all(abs((sim-sim[0])/sim[0]) < tolerance) 94 99 return _ 95 100 96 def GradientTermination(gtol=1e-5, norm=Inf): 97 """Terminate if abs(gfk)**norm**1/norm <= gtol 98 where gfk is the gradient value""" 101 def GradientTermination(tolerance=1e-5, norm=Inf): 102 """Terminate based on the current gradient value gfk.""" 99 103 def _(inst): 100 104 gfk = inst.gfk … … 105 109 else: 106 110 gnorm= numpy.sum(abs(gfk)**norm,axis=0)**(1.0/norm) 107 return gnorm <= gtol111 return gnorm <= tolerance 108 112 109 113 return _ 110 114 111 def XTermination(tolerance=1e-5): # Rename me?115 def SolutionImprovement(tolerance=1e-5): 112 116 """Terminate if the difference between the last two 113 best solutions abs(bestSolution - trialSolution)is less than tolerance."""117 best solutions, abs(bestSolution - trialSolution), is less than tolerance.""" 114 118 def _(inst): 115 119 update = inst.bestSolution - inst.trialSolution
Note: See TracChangeset
for help on using the changeset viewer.