def _no_fit(self, xmin, xmax): # We do not use constraint fits here as this fit is for parameter estimation lg.info() start_params_no = self._get_start_params(self._res_no, self._res_no_err, ratio=1, ignore_ext=True) try: lg.info("Fit non-osc. correlator...") res_no, res_no_err, chi_dof_no, aicc_no, pcov_no = self._no_corr_fitter.corr_fit( xmin, xmax, start_params_no, correlated=False, nstates=self._nstates, nstates_osc=0) self._res_no.append(res_no) self._res_no_err.append(res_no_err) self._chi_dof_no.append(chi_dof_no) self._aicc_no.append(aicc_no) except Exception as e: lg.info("\nWarning. Fit failed:", e, "\n") if lg.isLevel("DEBUG"): traceback.print_exc() self._res_no.append(np.full(2 * self._nstates, np.nan)) self._res_no_err.append(np.full(2 * self._nstates, np.nan)) self._chi_dof_no.append(np.nan) self._aicc_no.append(np.nan)
def func_wrapper(inst, *args, **kwargs): try: res, res_err, chi_dof, aicc, pcov = fit_func( inst, *args, **kwargs) if any(res_err == 0.0): raise ValueError("Fit error is zero!") except Exception as e: lg.info("\nWarning: Fit failed! Exception was:", e, "\n") if lg.isLevel("DEBUG"): traceback.print_exc() res = np.full(inst._nparams, np.nan) res_err = np.full(inst._nparams, np.nan) pcov = np.full((inst._nparams, inst._nparams), np.nan) chi_dof = np.inf aicc = np.inf if inst._btstr_fit: inst._samples.append([[(np.nan, ) * inst._nparams, (np.nan, ) * inst._nparams, np.nan, np.nan] for sitt in range(inst._nfit_samples) ]) return res, res_err, chi_dof, aicc, pcov
def _est_params_one_state(self, xmin, xmax, ind=None): # estimation of starting parameters via linear fit does not work for periodic # boundaries. Therefore we have to fit on the half interval. start_params = [1, 1] est_range = [int(xmin), int(min(xmax, self._Nt / 2))] #For estimating parameters of oscillating correlators, we use this function to estimate #the parameters for the even/odd part. We have to make sure that we use even/odd part #by this routine. lg.info("Estimate parameters: Linear fit for one state...") if ind is None: ind = (self._xdata > est_range[0]) & (self._xdata < est_range[1]) else: ind = (self._xdata > est_range[0]) & (self._xdata < est_range[1]) & ind try: (tmp_start_params, tmp_start_params_cov) = curve_fit( linear, self._xdata[ind], np.log(np.abs(self._ydata[ind])), sigma=1 / self._ydata[ind] * self._edata[ind]) if tmp_start_params[0] > 50 or tmp_start_params[1] > 50: start_params = [1, 1] else: start_params[0] = 1 / self._mult_const * np.exp(tmp_start_params[0])\ * np.exp(-tmp_start_params[1] * self._Nt / 2) * 2 start_params[1] = tmp_start_params[1] except Exception as e: lg.info("Linear fit failed. Error was", e) if lg.isLevel("DEBUG"): traceback.print_exc() start_params = [1, 1] print_res("Final start parameters for uncorrelated fit", start_params, level="INFO") return start_params
def corr_fit(self, xmin=-np.inf, xmax=np.inf, start_params=None, nstates=None, nstates_osc=None, correlated=None, priorsigma=None, priorval=None): if nstates == 0: raise ValueError("Require at least one non-oscillating state") if nstates is None: nstates = self._nstates if nstates_osc is None: nstates_osc = self._nstates_osc if correlated is None: correlated = self._cov_avail #To estimate parameters we usually perform a non-correlated fit before the actual #correlated fit. This is not neccessary if we already get start parameters. #However, for an oscillating fit is is reasonable to perform a non correlated fit #in any case. This is because start parameter estimation is usually performed outside #for oscillating fits. if correlated and start_params is not None: if nstates_osc > 0: skip_uncorr = False else: skip_uncorr = True else: skip_uncorr = False try: start_params, priorval, priorsigma = self.init_start_params( xmin, xmax, start_params, priorval, priorsigma, nstates, nstates_osc) except Exception as e: lg.info("Failed to estimate start parameters. Try direct fit") lg.details("Error was", e) if lg.isLevel("DEBUG"): traceback.print_exc() start_params = None #Save the states of the last fit. This must be ensured, even if the parameter #estimation fails. finally: self._nstates = nstates self._nstates_osc = nstates_osc print_res("Start parameters for %d + %d fit" % (nstates, nstates_osc), start_params, level="INFO") if not skip_uncorr: res, res_err, chi_dof, aicc, pcov = self.simple_corr_fit( xmin, xmax, start_params, correlated=False, priorval=priorval, priorsigma=priorsigma, nstates=nstates, nstates_osc=nstates_osc) start_params = np.copy(res) self._change_order(res, res_err, nstates, nstates_osc) res, res_err = self.remove_mult_const(res, res_err) pcov = self.remove_mult_const_pcov(pcov) lg.info() print_res("Fit result for uncorrelated %d + %d fit" % (nstates, nstates_osc), res, res_err, chi_dof, level="INFO") print_scl("AICc", aicc, level='INFO') if correlated: if not self._cov_avail: raise NotAvailableError("Covariance matrix is not available") res, res_err, chi_dof, aicc, pcov = self.simple_corr_fit( xmin, xmax, start_params=start_params, correlated=True, priorval=priorval, priorsigma=priorsigma, nstates=nstates, nstates_osc=nstates_osc) self._change_order(res, res_err, nstates, nstates_osc) res, res_err = self.remove_mult_const(res, res_err) pcov = self.remove_mult_const_pcov(pcov) lg.info() print_res("Fit result for correlated %d + %d fit" % (nstates, nstates_osc), res, res_err, chi_dof, level="INFO") print_scl("AICc", aicc) return res, res_err, chi_dof, aicc, pcov