From f62581ba698b3feace96ead855ecafbdbbc65790 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Sun, 22 May 2022 12:02:33 +0100 Subject: [PATCH 1/4] ci: workflow for caching of binder build added. --- .github/workflows/binder.yml | 15 +++++++++++++++ .github/workflows/pytest.yml | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/binder.yml diff --git a/.github/workflows/binder.yml b/.github/workflows/binder.yml new file mode 100644 index 00000000..460f0fef --- /dev/null +++ b/.github/workflows/binder.yml @@ -0,0 +1,15 @@ +name: binder +on: + push: + branches: + - develop + +jobs: + Create-MyBinderOrg-Cache: + runs-on: ubuntu-latest + steps: + - name: cache binder build on mybinder.org + uses: jupyterhub/repo2docker-action@master + with: + NO_PUSH: true + MYBINDERORG_TAG: ${{ github.event.ref }} # This builds the container on mybinder.org with the branch that was pushed on. diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 4c074906..9db158d3 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -13,15 +13,15 @@ jobs: pytest: runs-on: ${{ matrix.os }} strategy: - fail-fast: true + fail-fast: true matrix: os: [ubuntu-latest] python-version: ["3.7", "3.8", "3.9", "3.10"] include: - os: macos-latest - python-version: 3.9 + python-version: 3.9 - os: windows-latest - python-version: 3.9 + python-version: 3.9 steps: - name: Checkout source From 9ad0146d961be40b8c08f0f66266705c6e32ff97 Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 25 May 2022 14:32:49 +0100 Subject: [PATCH 2/4] fix: pinv replaced by inv for inversion of hessian in fit module, exceptions and warnings added. --- pyerrors/fits.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pyerrors/fits.py b/pyerrors/fits.py index 420d3da0..4faf237d 100644 --- a/pyerrors/fits.py +++ b/pyerrors/fits.py @@ -263,10 +263,18 @@ def total_least_squares(x, y, func, silent=False, **kwargs): output.chisquare_by_expected_chisquare) fitp = out.beta + hess = jacobian(jacobian(odr_chisquare))(np.concatenate((fitp, out.xplus.ravel()))) + condn = np.linalg.cond(hess) + if condn > 1e8: + warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) try: - hess_inv = np.linalg.pinv(jacobian(jacobian(odr_chisquare))(np.concatenate((fitp, out.xplus.ravel())))) + hess_inv = np.linalg.inv(hess) except TypeError: raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None + except np.linalg.LinAlgError: + raise Exception("Cannot invert hessian matrix.") + except Exception: + raise Exception("Unkown error in connection with Hessian inverse.") def odr_chisquare_compact_x(d): model = func(d[:n_parms], d[n_parms:n_parms + m].reshape(x_shape)) @@ -541,10 +549,18 @@ def _standard_fit(x, y, func, silent=False, **kwargs): output.chisquare_by_expected_chisquare) fitp = fit_result.x + hess = jacobian(jacobian(chisqfunc))(fitp) + condn = np.linalg.cond(hess) + if condn > 1e8: + warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) try: - hess_inv = np.linalg.pinv(jacobian(jacobian(chisqfunc))(fitp)) + hess_inv = np.linalg.inv(hess) except TypeError: raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None + except np.linalg.LinAlgError: + raise Exception("Cannot invert hessian matrix.") + except Exception: + raise Exception("Unkown error in connection with Hessian inverse.") if kwargs.get('correlated_fit') is True: def chisqfunc_compact(d): From 967ddb0ecd1f99e61ea5113336365e7134b2826c Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 25 May 2022 14:51:46 +0100 Subject: [PATCH 3/4] fix: no-autograd exception in fits works again. --- pyerrors/fits.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/pyerrors/fits.py b/pyerrors/fits.py index 4faf237d..98437221 100644 --- a/pyerrors/fits.py +++ b/pyerrors/fits.py @@ -263,14 +263,15 @@ def total_least_squares(x, y, func, silent=False, **kwargs): output.chisquare_by_expected_chisquare) fitp = out.beta - hess = jacobian(jacobian(odr_chisquare))(np.concatenate((fitp, out.xplus.ravel()))) + try: + hess = jacobian(jacobian(odr_chisquare))(np.concatenate((fitp, out.xplus.ravel()))) + except TypeError: + raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None condn = np.linalg.cond(hess) if condn > 1e8: warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) try: hess_inv = np.linalg.inv(hess) - except TypeError: - raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None except np.linalg.LinAlgError: raise Exception("Cannot invert hessian matrix.") except Exception: @@ -549,14 +550,15 @@ def _standard_fit(x, y, func, silent=False, **kwargs): output.chisquare_by_expected_chisquare) fitp = fit_result.x - hess = jacobian(jacobian(chisqfunc))(fitp) + try: + hess = jacobian(jacobian(chisqfunc))(fitp) + except TypeError: + raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None condn = np.linalg.cond(hess) if condn > 1e8: warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) try: hess_inv = np.linalg.inv(hess) - except TypeError: - raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None except np.linalg.LinAlgError: raise Exception("Cannot invert hessian matrix.") except Exception: From 48636fedb24a7815d77cd2bb086ea737860c7d2e Mon Sep 17 00:00:00 2001 From: Fabian Joswig Date: Wed, 25 May 2022 15:20:31 +0100 Subject: [PATCH 4/4] docs: warning about ill conditioned hessian more detailed. --- pyerrors/fits.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyerrors/fits.py b/pyerrors/fits.py index 98437221..512a57cb 100644 --- a/pyerrors/fits.py +++ b/pyerrors/fits.py @@ -269,7 +269,8 @@ def total_least_squares(x, y, func, silent=False, **kwargs): raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None condn = np.linalg.cond(hess) if condn > 1e8: - warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) + warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.\n \ + Maybe try rescaling the problem such that all parameters are of O(1).".format(condn), RuntimeWarning) try: hess_inv = np.linalg.inv(hess) except np.linalg.LinAlgError: @@ -556,7 +557,8 @@ def _standard_fit(x, y, func, silent=False, **kwargs): raise Exception("It is required to use autograd.numpy instead of numpy within fit functions, see the documentation for details.") from None condn = np.linalg.cond(hess) if condn > 1e8: - warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.".format(condn), RuntimeWarning) + warnings.warn("Hessian matrix might be ill-conditioned ({0:1.2e}), error propagation might be unreliable.\n \ + Maybe try rescaling the problem such that all parameters are of O(1).".format(condn), RuntimeWarning) try: hess_inv = np.linalg.inv(hess) except np.linalg.LinAlgError: