From 43cf9c29d483cec45283a0bec6ad36b1c13ce10e Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Tue, 10 Jan 2023 10:27:56 +0000 Subject: [PATCH 1/2] test: test for multi parameter foot feature added. --- tests/roots_test.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/roots_test.py b/tests/roots_test.py index b6e9bdb0..89feba96 100644 --- a/tests/roots_test.py +++ b/tests/roots_test.py @@ -42,3 +42,13 @@ def test_root_no_autograd(): with pytest.raises(Exception): my_root = pe.roots.find_root(my_obs, root_function) + + +def test_root_multi_parameter(): + o1 = pe.pseudo_Obs(1.1, 0.1, "test") + o2 = pe.pseudo_Obs(1.3, 0.12, "test") + + f2 = lambda x, d: d[0] + d[1] * x + + assert f2(-o1 / o2, [o1, o2]) == 0 + assert pe.find_root([o1, o2], f2) == -o1 / o2 From a45e20b51c9f06319acbf0400f91a338ea65d24c Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Tue, 10 Jan 2023 10:28:12 +0000 Subject: [PATCH 2/2] feat: multi parameter root feature added. --- pyerrors/roots.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pyerrors/roots.py b/pyerrors/roots.py index 5f6134b5..334157a7 100644 --- a/pyerrors/roots.py +++ b/pyerrors/roots.py @@ -27,15 +27,17 @@ def find_root(d, func, guess=1.0, **kwargs): Obs `Obs` valued root of the function. ''' - root = scipy.optimize.fsolve(func, guess, d.value) + d_val = np.vectorize(lambda x: x.value)(np.array(d)) + + root = scipy.optimize.fsolve(func, guess, d_val) # Error propagation as detailed in arXiv:1809.01289 - dx = jacobian(func)(root[0], d.value) + dx = jacobian(func)(root[0], d_val) try: - da = jacobian(lambda u, v: func(v, u))(d.value, root[0]) + da = jacobian(lambda u, v: func(v, u))(d_val, root[0]) except TypeError: raise Exception("It is required to use autograd.numpy instead of numpy within root functions, see the documentation for details.") from None deriv = - da / dx - - res = derived_observable(lambda x, **kwargs: (x[0] + np.finfo(np.float64).eps) / (d.value + np.finfo(np.float64).eps) * root[0], [d], man_grad=[deriv]) + res = derived_observable(lambda x, **kwargs: (x[0] + np.finfo(np.float64).eps) / (np.array(d).reshape(-1)[0].value + np.finfo(np.float64).eps) * root[0], + np.array(d).reshape(-1), man_grad=np.array(deriv).reshape(-1)) return res