1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for model minimisation/optimisation."""
24
25
26 from multi import Processor_box
27 from pipe_control.mol_res_spin import return_spin, spin_loop
28 from pipe_control import pipes
29 from specific_analyses.api import return_api
30 from status import Status; status = Status()
31 from user_functions.data import Uf_tables; uf_tables = Uf_tables()
32
33
34 -def calc(verbosity=1):
84
85
86 -def grid_search(lower=None, upper=None, inc=None, constraints=True, verbosity=1):
87 """The grid search function.
88
89 @param lower: The lower bounds of the grid search which must be equal to the number of
90 parameters in the model.
91 @type lower: array of numbers
92 @param upper: The upper bounds of the grid search which must be equal to the number of
93 parameters in the model.
94 @type upper: array of numbers
95 @param inc: The increments for each dimension of the space for the grid search. The
96 number of elements in the array must equal to the number of parameters in
97 the model.
98 @type inc: array of int
99 @param constraints: If True, constraints are applied during the grid search (elinating parts of
100 the grid). If False, no constraints are used.
101 @type constraints: bool
102 @param verbosity: The amount of information to print. The higher the value, the greater
103 the verbosity.
104 @type verbosity: int
105 """
106
107
108 pipes.test()
109
110
111 api = return_api()
112
113
114 api.overfit_deselect()
115
116
117 processor_box = Processor_box()
118 processor = processor_box.processor
119
120
121 if hasattr(cdp, 'sim_state') and cdp.sim_state == 1:
122
123 for i in range(cdp.sim_number):
124
125 if status.current_analysis:
126 status.auto_analysis[status.current_analysis].mc_number = i
127 else:
128 status.mc_number = i
129
130
131 api.grid_search(lower=lower, upper=upper, inc=inc, constraints=constraints, verbosity=verbosity-1, sim_index=i)
132
133
134 if verbosity and not processor.is_queued():
135 print("Simulation " + repr(i+1))
136
137
138 if status.current_analysis:
139 status.auto_analysis[status.current_analysis].mc_number = None
140 else:
141 status.mc_number = None
142
143
144 else:
145 api.grid_search(lower=lower, upper=upper, inc=inc, constraints=constraints, verbosity=verbosity)
146
147
148 processor.run_queue()
149
150
151 -def minimise(min_algor=None, line_search=None, hessian_mod=None, hessian_type=None, func_tol=None, grad_tol=None, max_iter=None, constraints=True, scaling=True, verbosity=1, sim_index=None):
152 """Minimisation function.
153
154 @keyword min_algor: The minimisation algorithm to use.
155 @type min_algor: str
156 @keyword line_search: The line search algorithm which will only be used in combination with the line search and conjugate gradient methods. This will default to the More and Thuente line search.
157 @type line_search: str or None
158 @keyword hessian_mod: The Hessian modification. This will only be used in the algorithms which use the Hessian, and defaults to Gill, Murray, and Wright modified Cholesky algorithm.
159 @type hessian_mod: str or None
160 @keyword hessian_type: The Hessian type. This will only be used in a few trust region algorithms, and defaults to BFGS.
161 @type hessian_type: str or None
162 @keyword func_tol: The function tolerance which, when reached, terminates optimisation. Setting this to None turns of the check.
163 @type func_tol: None or float
164 @keyword grad_tol: The gradient tolerance which, when reached, terminates optimisation. Setting this to None turns of the check.
165 @type grad_tol: None or float
166 @keyword max_iter: The maximum number of iterations for the algorithm.
167 @type max_iter: int
168 @keyword constraints: If True, constraints are used during optimisation.
169 @type constraints: bool
170 @keyword scaling: If True, diagonal scaling is enabled during optimisation to allow the problem to be better conditioned.
171 @type scaling: bool
172 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity.
173 @type verbosity: int
174 @keyword sim_index: The index of the simulation to optimise. This should be None if normal optimisation is desired.
175 @type sim_index: None or int
176 """
177
178
179 pipes.test()
180
181
182 api = return_api()
183
184
185 if constraints:
186 min_options = [min_algor]
187
188
189 min_algor = api.constraint_algorithm()
190 else:
191 min_options = []
192 if line_search != None:
193 min_options.append(line_search)
194 if hessian_mod != None:
195 min_options.append(hessian_mod)
196 if hessian_type != None:
197 min_options.append(hessian_type)
198 min_options = tuple(min_options)
199
200
201 api.overfit_deselect()
202
203
204 processor_box = Processor_box()
205 processor = processor_box.processor
206
207
208 if sim_index != None:
209 api.minimise(min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iter, constraints=constraints, scaling=scaling, verbosity=verbosity, sim_index=sim_index)
210
211
212 elif hasattr(cdp, 'sim_state') and cdp.sim_state == 1:
213 for i in range(cdp.sim_number):
214
215 if status.current_analysis:
216 status.auto_analysis[status.current_analysis].mc_number = i
217 else:
218 status.mc_number = i
219
220
221 api.minimise(min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iter, constraints=constraints, scaling=scaling, verbosity=verbosity-1, sim_index=i)
222
223
224 if verbosity and not processor.is_queued():
225 print("Simulation " + repr(i+1))
226
227
228 if status.current_analysis:
229 status.auto_analysis[status.current_analysis].mc_number = None
230 else:
231 status.mc_number = None
232
233
234 else:
235 api.minimise(min_algor=min_algor, min_options=min_options, func_tol=func_tol, grad_tol=grad_tol, max_iterations=max_iter, constraints=constraints, scaling=scaling, verbosity=verbosity)
236
237
238 processor.run_queue()
239
240
242 """Function for resetting the minimisation statistics.
243
244 @param data_pipe: The name of the data pipe to reset the minimisation statisics of. This
245 defaults to the current data pipe.
246 @type data_pipe: str
247 @param spin: The spin data container if spin specific data is to be reset.
248 @type spin: SpinContainer
249 """
250
251
252 if data_pipe == None:
253 data_pipe = pipes.cdp_name()
254
255
256 dp = pipes.get_pipe(data_pipe)
257
258
259
260
261
262
263 if hasattr(dp, 'chi2'):
264 dp.chi2 = None
265
266
267 if hasattr(dp, 'iter'):
268 dp.iter = None
269
270
271 if hasattr(dp, 'f_count'):
272 dp.f_count = None
273
274
275 if hasattr(dp, 'g_count'):
276 dp.g_count = None
277
278
279 if hasattr(dp, 'h_count'):
280 dp.h_count = None
281
282
283 if hasattr(dp, 'warning'):
284 dp.warning = None
285
286
287
288
289
290
291 for spin in spin_loop():
292
293 if hasattr(spin, 'chi2'):
294 spin.chi2 = None
295
296
297 if hasattr(spin, 'iter'):
298 spin.iter = None
299
300
301 if hasattr(spin, 'f_count'):
302 spin.f_count = None
303
304
305 if hasattr(spin, 'g_count'):
306 spin.g_count = None
307
308
309 if hasattr(spin, 'h_count'):
310 spin.h_count = None
311
312
313 if hasattr(spin, 'warning'):
314 spin.warning = None
315
316
317 -def set(val=None, error=None, param=None, scaling=None, spin_id=None):
318 """Set global or spin specific minimisation parameters.
319
320 @keyword val: The parameter values.
321 @type val: number
322 @keyword param: The parameter names.
323 @type param: str
324 @keyword scaling: Unused.
325 @type scaling: float
326 @keyword spin_id: The spin identification string.
327 @type spin_id: str
328 """
329
330
331 if spin_id == None:
332
333 if param == 'chi2':
334 cdp.chi2 = val
335
336
337 elif param == 'iter':
338 cdp.iter = val
339
340
341 elif param == 'f_count':
342 cdp.f_count = val
343
344
345 elif param == 'g_count':
346 cdp.g_count = val
347
348
349 elif param == 'h_count':
350 cdp.h_count = val
351
352
353 else:
354
355 spin = return_spin(spin_id)
356
357
358 if param == 'chi2':
359 spin.chi2 = val
360
361
362 elif param == 'iter':
363 spin.iter = val
364
365
366 elif param == 'f_count':
367 spin.f_count = val
368
369
370 elif param == 'g_count':
371 spin.g_count = val
372
373
374 elif param == 'h_count':
375 spin.h_count = val
376