From a7a098b8611a574e3b2973043c96c5ebe5084267 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Thu, 9 Mar 2023 15:32:27 +0000 Subject: [PATCH] fix: chisquare, dof and p-value also calculated when dof is 0. Test for dof and chisquare_over_dof added. --- pyerrors/fits.py | 8 ++++---- tests/fits_test.py | 27 +++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pyerrors/fits.py b/pyerrors/fits.py index 20a5ee32..e2fa6a14 100644 --- a/pyerrors/fits.py +++ b/pyerrors/fits.py @@ -358,11 +358,11 @@ def least_squares(x, y, func, priors=None, silent=False, **kwargs): if not fit_result.success: raise Exception('The minimization procedure did not converge.') - if x_all.shape[-1] - n_parms > 0: - output.chisquare = chisquare - output.dof = x_all.shape[-1] - n_parms + len(loc_priors) + output.chisquare = chisquare + output.dof = x_all.shape[-1] - n_parms + len(loc_priors) + output.p_value = 1 - scipy.stats.chi2.cdf(output.chisquare, output.dof) + if output.dof > 0: output.chisquare_by_dof = output.chisquare / output.dof - output.p_value = 1 - scipy.stats.chi2.cdf(output.chisquare, output.dof) else: output.chisquare_by_dof = float('nan') diff --git a/tests/fits_test.py b/tests/fits_test.py index 03c57595..f9f9c773 100644 --- a/tests/fits_test.py +++ b/tests/fits_test.py @@ -1080,6 +1080,33 @@ def test_resplot_lists_in_dict(): fitp = pe.fits.least_squares(xd, yd, fd, resplot=True) +def test_fit_dof(): + + def func(a, x): + return a[1] * anp.exp(-x * a[0]) + + dof = [] + cd = [] + for dim in [2, 3]: + + x = np.arange(dim) + y = 2 * np.exp(-0.3 * x) + np.random.normal(0.0, 0.3, dim) + yerr = [0.3] * dim + + oy = [] + for i, item in enumerate(x): + oy.append(pe.pseudo_Obs(y[i], yerr[i], 'test')) + + for priors in [None, {0: "0(2)"}]: + fr = pe.least_squares(x, oy, func, silent=True, priors=priors) + dof.append(fr.dof) + cd.append(fr.chisquare_by_dof) + + assert np.allclose(dof, [0, 1, 1, 2]) + assert cd[0] != cd[0] # Check for nan + assert np.all(np.array(cd[1:]) > 0) + + def fit_general(x, y, func, silent=False, **kwargs): """Performs a non-linear fit to y = func(x) and returns a list of Obs corresponding to the fit parameters.