Changeset 042f065 in sasview
- Timestamp:
- Apr 11, 2014 3:04:20 PM (11 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, release_4.0.1, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- 85f17f6
- Parents:
- 90f49a8
- Location:
- src/sans/fit
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sans/fit/BumpsFitting.py
r90f49a8 r042f065 2 2 BumpsFitting module runs the bumps optimizer. 3 3 """ 4 import sys4 import time 5 5 6 6 import numpy … … 25 25 self.data = data 26 26 self.param_list = param_list 27 self.msg_q = msg_q 28 self.curr_thread = curr_thread 29 self.handler = handler 30 self.fitresult = fitresult 31 self.res = [] 32 self.func_name = "Functor" 27 self.res = None 33 28 self.theory = None 34 self.name = "Fill in proper name!" 29 30 @property 31 def name(self): 32 return self.model.name 35 33 36 34 @property … … 119 117 #print "params", params 120 118 self.res, self.theory = self.data.residuals(self.model.evalDistribution) 121 122 # TODO: this belongs in monitor not residuals calculation 123 if False: # self.fitresult is not None: 119 return self.res 120 121 BOUNDS_PENALTY = 1e6 # cost for going out of bounds on unbounded fitters 122 class MonitoredSasProblem(SasProblem): 123 """ 124 SAS problem definition for optimizers which do not have monitoring or bounds. 125 """ 126 def __init__(self, param_list, model=None, data=None, fitresult=None, 127 handler=None, curr_thread=None, msg_q=None, update_rate=1): 128 """ 129 :param Model: the model wrapper fro sans -model 130 :param Data: the data wrapper for sans data 131 """ 132 SasProblem.__init__(self, param_list, model, data) 133 self.msg_q = msg_q 134 self.curr_thread = curr_thread 135 self.handler = handler 136 self.fitresult = fitresult 137 #self.last_update = time.time() 138 #self.func_name = "Functor" 139 #self.name = "Fill in proper name!" 140 141 def residuals(self, p): 142 """ 143 Cost function for scipy.optimize.leastsq, which does not have a monitor 144 built into the algorithm, and instead relies on a monitor built into 145 the cost function. 146 """ 147 # Note: technically, unbounded fitters and unmonitored fitters are 148 self.setp(x) 149 150 # Compute penalty for being out of bounds which increases the farther 151 # you get out of bounds. This allows derivative following algorithms 152 # to point back toward the feasible region. 153 penalty = self.bounds_penalty() 154 if penalty > 0: 155 self.theory = numpy.ones(self.data.num_points) 156 self.res = self.theory*(penalty/self.data.num_points) + BOUNDS_PENALTY 157 return self.res 158 159 # If no penalty, then we are not out of bounds and we can use the 160 # normal residual calculation 161 SasProblem.residuals(self, p) 162 163 # send update to the application 164 if True: 124 165 #self.fitresult.set_model(model=self.model) 166 # copy residuals into fit results 125 167 self.fitresult.residuals = self.res+0 126 168 self.fitresult.iterations += 1 127 169 self.fitresult.theory = self.theory+0 128 170 129 #fitness = self.chisq(params=params) 130 fitness = self.chisq() 131 self.fitresult.p = params 132 self.fitresult.set_fitness(fitness=fitness) 171 self.fitresult.p = numpy.array(p) # force copy, and coversion to array 172 self.fitresult.set_fitness(fitness=self.chisq()) 133 173 if self.msg_q is not None: 134 174 self.msg_q.put(self.fitresult) … … 149 189 150 190 return self.res 151 __call__ = residuals 152 153 def _DEAD_check_param_range(self): 154 """ 155 Check the lower and upper bound of the parameter value 156 and set res to the inf if the value is outside of the 157 range 158 :limitation: the initial values must be within range. 159 """ 160 161 #time.sleep(0.01) 162 is_outofbound = False 163 # loop through the fit parameters 164 model = self.model 165 for p in self.param_list: 166 value = model.getParam(p) 167 low,high = model.details[p][1:3] 168 if low is not None and numpy.isfinite(low): 169 if p.value == 0: 170 # This value works on Scipy 171 # Do not change numbers below 172 value = _SMALLVALUE 173 # For leastsq, it needs a bit step back from the boundary 174 val = low - value * _SMALLVALUE 175 if value < val: 176 self.res *= 1e+6 177 is_outofbound = True 178 break 179 if high is not None and numpy.isfinite(high): 180 # This value works on Scipy 181 # Do not change numbers below 182 if value == 0: 183 value = _SMALLVALUE 184 # For leastsq, it needs a bit step back from the boundary 185 val = high + value * _SMALLVALUE 186 if value > val: 187 self.res *= 1e+6 188 is_outofbound = True 189 break 190 191 return is_outofbound 191 192 def bounds_penalty(self): 193 from numpy import sum, where 194 p, bounds = self.getp(), self.bounds() 195 return (sum(where(p<bounds[:,0], bounds[:,0]-p, 0)**2) 196 + sum(where(p>bounds[:,1], bounds[:,1]-p, 0)**2) ) 192 197 193 198 class BumpsFit(FitEngine): … … 223 228 ind = fitproblem[0].pars.index(name) 224 229 model.setParam(name, fitproblem[0].vals[ind]) 225 listdata = fitproblem[0].get_data() 226 # Concatenate dList set (contains one or more data)before fitting 227 data = listdata 230 data = fitproblem[0].get_data() 228 231 229 232 self.curr_thread = curr_thread … … 235 238 if handler is not None: 236 239 handler.set_result(result=result) 237 problem = SasProblem(param_list=self.param_list, 238 model=model.model, 239 data=data, 240 handler=handler, 241 fitresult=result, 242 curr_thread=curr_thread, 243 msg_q=msg_q) 244 try: 245 run_bumps(problem, result, ftol) 246 #run_scipy(problem, result, ftol) 247 except: 248 if hasattr(sys, 'last_type') and sys.last_type == KeyboardInterrupt: 249 if handler is not None: 250 msg = "Fitting: Terminated!!!" 251 handler.stop(msg) 252 raise KeyboardInterrupt, msg 253 else: 254 raise 240 241 if True: # bumps 242 def abort_test(): 243 try: curr_thread.isquit() 244 except KeyboardInterrupt: 245 if handler is not None: 246 handler.stop("Fitting: Terminated!!!") 247 return True 248 return False 249 250 problem = SasProblem(param_list=self.param_list, 251 model=model.model, 252 data=data) 253 run_bumps(problem, result, ftol, abort_test) 254 else: 255 problem = SasProblem(param_list=self.param_list, 256 model=model.model, 257 data=data, 258 handler=handler, 259 fitresult=result, 260 curr_thread=curr_thread, 261 msg_q=msg_q) 262 run_levenburg_marquardt(problem, result, ftol) 255 263 256 264 if handler is not None: … … 264 272 return [result] 265 273 266 def run_bumps(problem, result, ftol ):274 def run_bumps(problem, result, ftol, abort_test): 267 275 fitopts = fitters.FIT_OPTIONS[fitters.FIT_DEFAULT] 268 276 fitclass = fitopts.fitclass … … 270 278 options['ftol'] = ftol 271 279 fitdriver = fitters.FitDriver(fitclass, problem=problem, 272 abort_test= lambda: False, **options)280 abort_test=abort_test, **options) 273 281 mapper = SerialMapper 274 282 fitdriver.mapper = mapper.start_mapper(problem, None) … … 289 297 result.theory = problem.theory 290 298 291 def run_ scipy(model, result, ftol):299 def run_levenburg_marquardt(model, result, ftol): 292 300 # This import must be here; otherwise it will be confused when more 293 301 # than one thread exist. -
src/sans/fit/ScipyFitting.py
r95d58d3 r042f065 287 287 : param range: min or max value of the bounds 288 288 """ 289 return 0.1 (limit if limit != 0.0 else 1.0)289 return 0.1 * (limit if limit != 0.0 else 1.0) 290 290 291 291
Note: See TracChangeset
for help on using the changeset viewer.