From 304bf5bb9e2cf1850798ba1575524a9edb5697a0 Mon Sep 17 00:00:00 2001 From: fernandezfran Date: Thu, 15 Jun 2023 23:42:48 -0300 Subject: [PATCH] numerical method for uncertainties estimations --- galpynostatic/model.py | 17 ++++++----------- tests/conftest.py | 28 ++++++++++++++-------------- tests/test_model.py | 8 ++++---- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/galpynostatic/model.py b/galpynostatic/model.py index 503a8b2..1455afd 100644 --- a/galpynostatic/model.py +++ b/galpynostatic/model.py @@ -201,7 +201,7 @@ def fit(self, X, y, sample_weight=None): self.mse_ = mse[idx] self.dcoeff_err_, self.k0_err_ = _estimate_uncertainties( - self, X, y, ("dcoeff_", "k0_"), 1e-6 + self, X, y, ("dcoeff_", "k0_"), np.cbrt(np.finfo(float).eps) ) return self @@ -301,9 +301,7 @@ def plot(self): def _estimate_uncertainties(greg, X, y, attrs, delta): """Uncertainties of `attrs` estimations.""" - residuals = y - greg.predict(X) - - sigmas = np.zeros(len(attrs)) + jacobian = np.zeros((len(attrs), len(y))) for i, attr in enumerate(attrs): param = greg.__dict__[attr] @@ -313,13 +311,10 @@ def _estimate_uncertainties(greg, X, y, attrs, delta): greg.__dict__[attr] = (1 - delta) * param lower = greg.predict(X) - diff = upper - lower - mask = diff != 0 + jacobian[i] = (upper - lower) / (2 * delta * param) - derivative = diff[mask] / (2 * delta * param) + hessian = np.dot(jacobian, jacobian.T) - ws = residuals[mask] / 2 - norm = np.sum(ws**2) / (len(ws) - 1) - sigmas[i] = norm * np.sum((ws / derivative) ** 2) + covariance = np.var((y - greg.predict(X)) ** 2) * np.linalg.inv(hessian) - return np.sqrt(sigmas) / len(residuals) + return np.sqrt(np.diag(covariance)) diff --git a/tests/conftest.py b/tests/conftest.py index 5eab73d..6a3406a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,8 +70,8 @@ def nishikawa(): ), "dcoeff": 1.0e-9, "k0": 1.0e-6, - "dcoeff_err": 6.034833e-12, - "k0_err": 2.977453e-08, + "dcoeff_err": 1.08424e-10, + "k0_err": 4.790873e-07, "mse": 0.00469549, "soc": np.array([0.937788, 0.878488, 0.81915, 0.701, 0.427025]), "r2": 0.8443919, @@ -109,8 +109,8 @@ def mancini(): "dc": None, "dcoeff": 1.0e-10, "k0": 1.0e-6, - "dcoeff_err": 8.774595e-14, - "k0_err": 3.971127e-08, + "dcoeff_err": 3.755249e-13, + "k0_err": 1.031205e-07, "mse": 0.00069059, "soc": np.array( [ @@ -148,8 +148,8 @@ def he(): ), "dcoeff": 1.0e-11, "k0": 1.0e-8, - "dcoeff_err": 1.004282e-13, - "k0_err": 1.051095e-10, + "dcoeff_err": 1.80632e-12, + "k0_err": 1.5790638e-09, "mse": 0.006482, "soc": np.array( [0.978918, 0.906247, 0.815342, 0.633649, 0.179112] @@ -186,8 +186,8 @@ def wang(): ), "dcoeff": 1.0e-8, "k0": 1.0e-6, - "dcoeff_err": 2.594406e-11, - "k0_err": 3.213356e-09, + "dcoeff_err": 2.667671e-09, + "k0_err": 3.22267e-07, "mse": 0.000863, "soc": np.array( [0.985938, 0.974779, 0.952477, 0.885544, 0.774095, 0.550382] @@ -231,8 +231,8 @@ def lei(): ), "dcoeff": 1.0e-13, "k0": 1.0e-8, - "dcoeff_err": 4.695216e-16, - "k0_err": 5.017805e-10, + "dcoeff_err": 2.834146e-15, + "k0_err": 3.682211e-09, "mse": 0.006019, "soc": np.array( [0.918072, 0.799457, 0.604216, 0.325994, 0.112047, 0.046371] @@ -276,8 +276,8 @@ def bak(): ), "dcoeff": 1.0e-13, "k0": 1.0e-8, - "dcoeff_err": 1.033602e-14, - "k0_err": 1.614446e-09, + "dcoeff_err": 4.23587e-12, + "k0_err": 6.579867e-07, "mse": 0.016352, "soc": np.array( [0.993918, 0.981223, 0.965346, 0.933609, 0.838375, 0.679639] @@ -303,8 +303,8 @@ def dokko(): "dc": None, "dcoeff": 1.0e-9, "k0": 1.0e-6, - "dcoeff_err": 2.999896e-11, - "k0_err": 5.388039e-08, + "dcoeff_err": 1.472138e-10, + "k0_err": 5.238026e-07, "mse": 0.02627097, "soc": np.array( [ diff --git a/tests/test_model.py b/tests/test_model.py index 352b791..028f08f 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -53,14 +53,14 @@ def test_fit(self, experiment, request, spherical): greg = greg.fit(experiment["C_rates"], experiment["soc"]) np.testing.assert_almost_equal( - greg.dcoeff_, experiment["ref"]["dcoeff"], 14 + greg.dcoeff_, experiment["ref"]["dcoeff"], 13 ) np.testing.assert_almost_equal( - greg.dcoeff_err_, experiment["ref"]["dcoeff_err"], 14 + greg.dcoeff_err_, experiment["ref"]["dcoeff_err"], 13 ) - np.testing.assert_almost_equal(greg.k0_, experiment["ref"]["k0"], 12) + np.testing.assert_almost_equal(greg.k0_, experiment["ref"]["k0"], 11) np.testing.assert_almost_equal( - greg.k0_err_, experiment["ref"]["k0_err"], 12 + greg.k0_err_, experiment["ref"]["k0_err"], 11 ) np.testing.assert_almost_equal(greg.mse_, experiment["ref"]["mse"], 6)