def check_history(self): self.problem = pypesto.Problem(self.obj, self.lb, self.ub) optimize_options = pypesto.OptimizeOptions( allow_failed_starts=False ) history_options = pypesto.HistoryOptions( trace_record=True, trace_record_hess=False, trace_save_iter=1, storage_file='tmp/traces/conversion_example_{id}.csv', ) result = pypesto.minimize( problem=self.problem, optimizer=self.optimizer, n_starts=1, startpoint_method=pypesto.startpoint.uniform, options=optimize_options, history_options=history_options ) # disable trace from here on self.obj.history.options.trace_record = False for start in result.optimize_result.list: trace = start.history._trace it_final = int(trace[('fval', np.NaN)].idxmin()) it_start = int(np.where(np.logical_not( np.isnan(trace['fval'].values) ))[0][0]) self.assertTrue(np.isclose( trace['x'].values[0, :], start.x0 ).all()) self.assertTrue(np.isclose( trace['x'].values[it_final, :], start.x ).all()) self.assertTrue(np.isclose( trace['fval'].values[it_start, 0], start.fval0 )) funs = { 'fval': self.obj.get_fval, 'grad': self.obj.get_grad, 'hess': self.obj.get_hess, 'res': self.obj.get_res, 'sres': self.obj.get_sres, 'chi2': lambda x: res_to_chi2(self.obj.get_res(x)), 'schi2': lambda x: sres_to_schi2(*self.obj( x, (0, 1,), pypesto.objective.constants.MODE_RES )) } for var, fun in funs.items(): for it in range(5): if var in ['fval', 'chi2']: if not np.isnan(trace[var].values[it, 0]): self.assertTrue(np.isclose( trace[var].values[it, 0], fun(trace['x'].values[it, :]) )) elif var in ['hess', 'sres', 'res']: if trace[var].values[it, 0] is not None: self.assertTrue(np.isclose( trace[var].values[it, 0], fun(trace['x'].values[it, :]) ).all()) elif self.obj.history.options[f'trace_record_{var}'] \ and not \ np.isnan(trace[var].values[it, :]).all(): self.assertTrue(np.isclose( trace[var].values[it, :], fun(trace['x'].values[it, :]) ).all())
def check_history_consistency(self, start: pypesto.OptimizerResult): def xfull(x_trace): return self.problem.get_full_vector(x_trace, self.problem.x_fixed_vals) if isinstance(start.history, (CsvHistory, Hdf5History)): # get index of optimal parameter ix_admit = [ ix for ix, x in enumerate(start.history.get_x_trace()) if np.all(x >= self.problem.lb) and np.all( x <= self.problem.ub) ] it_final = np.nanargmin(start.history.get_fval_trace(ix_admit)) if isinstance(it_final, np.ndarray): it_final = it_final[0] it_final = ix_admit[it_final] it_start = int( np.where( np.logical_not(np.isnan( start.history.get_fval_trace())))[0][0]) assert np.allclose(xfull(start.history.get_x_trace(it_start)), start.x0), type(start.history) assert np.allclose(xfull(start.history.get_x_trace(it_final)), start.x), type(start.history) assert np.isclose(start.history.get_fval_trace(it_start), start.fval0), type(start.history) funs = { FVAL: self.obj.get_fval, GRAD: self.obj.get_grad, HESS: self.obj.get_hess, RES: self.obj.get_res, SRES: self.obj.get_sres, CHI2: lambda x: res_to_chi2(self.obj.get_res(x)), SCHI2: lambda x: sres_to_schi2(*self.obj( x, ( 0, 1, ), pypesto.C.MODE_RES, )), } for var, fun in funs.items(): for it in range(5): x_full = xfull(start.history.get_x_trace(it)) val = getattr(start.history, f'get_{var}_trace')(it) if not getattr(self.history_options, f'trace_record_{var}', True): assert np.isnan(val) continue if np.all(np.isnan(val)): continue if var in [FVAL, CHI2]: # note that we can expect slight deviations here since # this fval/chi2 may be computed without sensitivities # while the result here may be computed with with # sensitivies activated. If this fails to often, # increase atol/rtol assert np.isclose(val, fun(x_full), rtol=1e-3, atol=1e-4), var elif var in [RES]: # note that we can expect slight deviations here since # this res is computed without sensitivities while the # result here may be computed with with sensitivies # activated. If this fails too often, increase atol/rtol assert np.allclose(val, fun(x_full), rtol=1e-3, atol=1e-4), var elif var in [SRES]: assert np.allclose( val, fun(x_full)[:, self.problem.x_free_indices], ), var elif var in [GRAD, SCHI2]: assert np.allclose( val, self.problem.get_reduced_vector(fun(x_full)), ), var elif var in [HESS]: assert np.allclose( val, self.problem.get_reduced_matrix(fun(x_full)), ), var else: raise RuntimeError('missing test implementation')