Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-iminuit for openSUSE:Factory checked in at 2023-09-08 21:15:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-iminuit (Old) and /work/SRC/openSUSE:Factory/.python-iminuit.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-iminuit" Fri Sep 8 21:15:44 2023 rev:30 rq:1109631 version:2.24.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-iminuit/python-iminuit.changes 2023-07-03 17:41:57.608427054 +0200 +++ /work/SRC/openSUSE:Factory/.python-iminuit.new.1766/python-iminuit.changes 2023-09-08 21:16:37.176783464 +0200 @@ -1,0 +2,10 @@ +Thu Sep 7 08:27:08 UTC 2023 - Markéta Machová <mmach...@suse.com> + +- Update to 2.24.0 + * Fix CostSum.visualize bug + * Fix _safe_log on systems which use 32 bit floats + * Iteration limit in smart sampling to fix behavior for step functions + * Clarify meaning of 2d contours in minuit.draw_mnmatrix + * Support interval type and check compatibility with pydantic + +------------------------------------------------------------------- Old: ---- iminuit-2.22.0.tar.gz New: ---- iminuit-2.24.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-iminuit.spec ++++++ --- /var/tmp/diff_new_pack.y27wiE/_old 2023-09-08 21:16:38.316824208 +0200 +++ /var/tmp/diff_new_pack.y27wiE/_new 2023-09-08 21:16:38.320824351 +0200 @@ -19,7 +19,7 @@ %define modname iminuit %{?sle15_python_module_pythons} Name: python-%{modname} -Version: 2.22.0 +Version: 2.24.0 Release: 0 Summary: Python bindings for MINUIT2 License: MIT @@ -79,12 +79,13 @@ %python_expand %fdupes %{buildroot}%{$python_sitearch} %check +# https://github.com/scikit-hep/iminuit/issues/940 +donttest="((test_bad_function or test_disp) and minimize)" # A tolerance issue on 32-bit %ifarch %ix86 -%pytest_arch -k 'not test_matrix' -%else -%pytest_arch +donttest+=" or test_matrix" %endif +%pytest_arch -k "not ($donttest)" %files %{python_files} %doc README.rst ++++++ iminuit-2.22.0.tar.gz -> iminuit-2.24.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/.github/workflows/release.yml new/iminuit-2.24.0/.github/workflows/release.yml --- old/iminuit-2.22.0/.github/workflows/release.yml 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/.github/workflows/release.yml 2022-11-09 13:37:21.000000000 +0100 @@ -63,7 +63,7 @@ - if: ${{ matrix.arch == 'aarch64' }} uses: docker/setup-qemu-action@v2 - - uses: pypa/cibuildwheel@v2.13.0 + - uses: pypa/cibuildwheel@v2.14.1 env: CIBW_BUILD: ${{ matrix.py }}-* CIBW_ARCHS: ${{ matrix.arch }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/.pre-commit-config.yaml new/iminuit-2.24.0/.pre-commit-config.yaml --- old/iminuit-2.22.0/.pre-commit-config.yaml 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/.pre-commit-config.yaml 2022-11-09 13:37:21.000000000 +0100 @@ -33,14 +33,14 @@ exclude: ^doc/_static/.*.svg # Python formatting -- repo: https://github.com/psf/black - rev: 23.3.0 +- repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.7.0 hooks: - id: black # Ruff linter, replacement for flake8, pydocstyle, isort -- repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.0.272' +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: 'v0.0.284' hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] @@ -62,7 +62,7 @@ # Python type checking - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v1.3.0' + rev: 'v1.5.0' hooks: - id: mypy additional_dependencies: [numpy] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/.readthedocs.yaml new/iminuit-2.24.0/.readthedocs.yaml --- old/iminuit-2.22.0/.readthedocs.yaml 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/.readthedocs.yaml 2022-11-09 13:37:21.000000000 +0100 @@ -12,7 +12,7 @@ build: os: ubuntu-22.04 tools: - python: "3.10" + python: "3.9" python: install: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/PKG-INFO new/iminuit-2.24.0/PKG-INFO --- old/iminuit-2.22.0/PKG-INFO 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/PKG-INFO 2022-11-09 13:37:21.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: iminuit -Version: 2.22.0 +Version: 2.24.0 Summary: Jupyter-friendly Python frontend for MINUIT2 in C++ Maintainer: Hans Dembinski Maintainer-Email: Unknown <hans.dembin...@gmail.com> @@ -77,6 +77,8 @@ Requires-Dist: boost_histogram; extra == "test" Requires-Dist: resample; extra == "test" Requires-Dist: unicodeitplus; extra == "test" +Requires-Dist: pydantic; extra == "test" +Requires-Dist: annotated_types; extra == "test" Requires-Dist: sphinx<7; extra == "doc" Requires-Dist: sphinx-rtd-theme; extra == "doc" Requires-Dist: nbsphinx; extra == "doc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/doc/changelog.rst new/iminuit-2.24.0/doc/changelog.rst --- old/iminuit-2.22.0/doc/changelog.rst 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/doc/changelog.rst 2022-11-09 13:37:21.000000000 +0100 @@ -5,6 +5,20 @@ Changelog ========= +2.24.0 (August 15, 2023) +------------------------ +- Iteration limit in smart sampling to fix behavior for step functions (`#928 <https://github.com/scikit-hep/iminuit/pull/928>`_) +- Clarify meaning of 2d contours in minuit.draw_mnmatrix (`#927 <https://github.com/scikit-hep/iminuit/pull/927>`_) +- Support interval type and check compatibility with pydantic (`#922 <https://github.com/scikit-hep/iminuit/pull/922>`_) + +2.23.0 (July 28, 2023) +---------------------- +- Fix ``CostSum.visualize`` bug (`#918 <https://github.com/scikit-hep/iminuit/pull/918>`_) +- Fix ``_safe_log`` on systems which use 32 bit floats (`#915 <https://github.com/scikit-hep/iminuit/pull/915>`_), (`#919 <https://github.com/scikit-hep/iminuit/pull/919>`_) +- Skip test_interactive and friends when ipywidgets is not installed (`#917 <https://github.com/scikit-hep/iminuit/pull/917>`_) +- Turn negative zero into positive zero in ``pdg_format`` (`#916 <https://github.com/scikit-hep/iminuit/pull/916>`_) +- Remove warning in ``test_cost.py`` by using ``pytest.warns`` instead of ``pytest.raises`` (`#914 <https://github.com/scikit-hep/iminuit/pull/914>`_) + 2.22.0 (June 22, 2023) ---------------------- - Hide confusing notes in docs: "not to be initialized by users." (`#906 <https://github.com/scikit-hep/iminuit/pull/906>`_) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/doc/faq.rst new/iminuit-2.24.0/doc/faq.rst --- old/iminuit-2.22.0/doc/faq.rst 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/doc/faq.rst 2022-11-09 13:37:21.000000000 +0100 @@ -7,11 +7,12 @@ FAQ === -Disclaimer: Read the excellent MINUIT2 user guide! --------------------------------------------------- +Disclaimer: Read the excellent MINUIT user guide! +------------------------------------------------- -Many technical questions are nicely covered by the user guide of MINUIT2, -:download:`MINUIT User's guide <mnusersguide.pdf>`. We will frequently refer to it here. +Many technical questions are nicely covered by the `Minuit reference manual <https://cds.cern.ch/record/2296388>`_ of the original MINUIT in Fortran, on which MINUIT2 is based. Still relevant is chapter 5, which covers all the questions that one encounters when using Minuit in practice. If you have trouble with the fit, there is advice in sections 5.6 and 5.7 on how to fix common issues. + +Another source is the :download:`MINUIT User's guide <mnusersguide.pdf>`, which covers the C++ Minuit2 library on which iminuit is based. It also contains advice on troubleshooting, we will frequently refer to it here. However, the Fortran manual usually goes into more detail and is therefore preferred. I don't understand :meth:`Minuit.hesse`, :meth:`Minuit.minos`, :attr:`Minuit.errordef`; what do these do? ----------------------------------------------------------------------------------------------------------- @@ -27,7 +28,7 @@ I want to cite iminuit in my paper. Help? ------------------------------------------------ -We use the excellent Zenodo service to make each iminuit release citable. You can either cite iminuit as a software or you can cite the exact version that was used for your analysis. For more details, see :ref:`citation`. +We use Zenodo to make each iminuit release citable. You can either cite iminuit as a software or you can cite the exact version that was used for your analysis. For more details, see :ref:`citation`. Can I have parameter limits that depend on each other (e.g. x^2 + y^2 < 3)? --------------------------------------------------------------------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/doc/reference.rst new/iminuit-2.24.0/doc/reference.rst --- old/iminuit-2.22.0/doc/reference.rst 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/doc/reference.rst 2022-11-09 13:37:21.000000000 +0100 @@ -27,11 +27,13 @@ Minuit.fval Minuit.nfit Minuit.mnprofile - Minuit.draw_mnprofile + Minuit.mncontour + Minuit.visualize + Minuit.draw_mnmatrix -Minuit ------- +Main interface +-------------- .. autoclass:: Minuit :members: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/pyproject.toml new/iminuit-2.24.0/pyproject.toml --- old/iminuit-2.22.0/pyproject.toml 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/pyproject.toml 2022-11-09 13:37:21.000000000 +0100 @@ -5,7 +5,7 @@ [project] name = "iminuit" description = "Jupyter-friendly Python frontend for MINUIT2 in C++" -version = "2.22.0" +version = "2.24.0" maintainers = [ { name = "Hans Dembinski" }, { email = "hans.dembin...@gmail.com" }, @@ -33,10 +33,7 @@ "Operating System :: Unix", "Operating System :: MacOS", ] -dependencies = [ - "numpy >= 1.21", - "typing_extensions;python_version < '3.9'" -] +dependencies = ["numpy >= 1.21", "typing_extensions;python_version < '3.9'"] [project.urls] repository = "http://github.com/scikit-hep/iminuit" @@ -49,7 +46,7 @@ # ipywidgets 8.0.5 and 8.0.6 are broken # see https://github.com/jupyter-widgets/ipywidgets/issues/3731 "ipywidgets<8.0.5", - "ipykernel", # needed by ipywidgets 8.0.6 + "ipykernel", # needed by ipywidgets 8.0.6 "joblib", "jacobi", "matplotlib", @@ -61,31 +58,27 @@ "tabulate", "boost_histogram", "resample", - "unicodeitplus" + "unicodeitplus", + "pydantic", + "annotated_types", ] doc = [ "sphinx<7", - "sphinx-rtd-theme", # needs sphinx<7 + "sphinx-rtd-theme", # needs sphinx<7 "nbsphinx", "nbconvert", "nbformat", "jupyter_client", "ipykernel", - # There are some problems with current jax versions "jax", - "jaxlib" + "jaxlib", ] [tool.scikit-build] minimum-version = "0.3" build-dir = "build/{wheel_tag}" -sdist.exclude = [ - "extern/root", -] -sdist.include = [ - "extern/root/math/minuit2/inc", - "extern/root/math/minuit2/src", -] +sdist.exclude = ["extern/root"] +sdist.include = ["extern/root/math/minuit2/inc", "extern/root/math/minuit2/src"] [tool.pytest.ini_options] minversion = "6.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/src/iminuit/cost.py new/iminuit-2.24.0/src/iminuit/cost.py --- old/iminuit-2.22.0/src/iminuit/cost.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/src/iminuit/cost.py 2022-11-09 13:37:21.000000000 +0100 @@ -113,10 +113,12 @@ CHISQUARE = 1.0 NEGATIVE_LOG_LIKELIHOOD = 0.5 +_TINY_FLOAT = np.finfo(float).tiny + def _safe_log(x): # guard against x = 0 - return np.log(x + 1e-323) + return np.log(np.maximum(_TINY_FLOAT, x)) def _unbinned_nll(x): @@ -724,8 +726,9 @@ n = sum(hasattr(comp, "visualize") for comp in self) - w, h = plt.rcParams["figure.figsize"] - fig, ax = plt.subplots(1, n, figsize=(w, h * n)) + fig = plt.gcf() + fig.set_figwidth(n * fig.get_figwidth() / 1.5) + _, ax = plt.subplots(1, n, num=fig.number) if component_kwargs is None: component_kwargs = {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/src/iminuit/minuit.py new/iminuit-2.24.0/src/iminuit/minuit.py --- old/iminuit-2.22.0/src/iminuit/minuit.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/src/iminuit/minuit.py 2022-11-09 13:37:21.000000000 +0100 @@ -1434,13 +1434,14 @@ Names of parameters to generate Minos errors for. If no positional arguments are given, Minos is run for each parameter. cl : float or None, optional - Confidence level for the confidence interval. If not set or None, a - standard 68.3 % confidence interval is produced. Setting this to another - value requires the scipy module to be installed. If 0 < cl < 1, the value - is interpreted as the confidence level (a probability). If cl >= 1, it is - interpreted as number of standard deviations. For example, cl=3 produces a - 3 sigma interval. Values other than 0.68, 0.9, 0.95, 0.99, 1, 2, 3, 4, 5 - require the scipy module. + Confidence level of the interval. If not set or None, a standard 68 % + interval is computed (default). If 0 < cl < 1, the value is interpreted as + the confidence level (a probability). For convenience, values cl >= 1 are + interpreted as the probability content of a central symmetric interval + covering that many standard deviations of a normal distribution. For + example, cl=1 is interpreted as 68.3 %, and cl=2 is 84.3 %, and so on. Using + values other than 0.68, 0.9, 0.95, 0.99, 1, 2, 3, 4, 5 require the scipy + module. ncall : int or None, optional Limit the number of calls made by Minos. If None, an adaptive internal heuristic of the Minuit2 library is used (Default: None). @@ -1915,7 +1916,11 @@ scan point. This scan produces a statistical confidence region according to the `profile likelihood method <https://en.wikipedia.org/wiki/Likelihood_function>`_ with a confidence level `cl`, which is asymptotically equal to the coverage - probability of the confidence region. + probability of the confidence region according to `Wilks' theorem + <https://en.wikipedia.org/wiki/Wilks%27_theorem>`. Note that 1D projections of + the 2D confidence region are larger than 1D Minos intervals computed for the + same confidence level. This is not an error, but a consequence of Wilks' + theorem. The calculation is expensive since a numerical minimisation has to be performed at various points. @@ -1929,9 +1934,12 @@ cl : float or None, optional Confidence level of the contour. If not set or None, a standard 68 % contour is computed (default). If 0 < cl < 1, the value is interpreted as the - confidence level (a probability). If cl >= 1, it is interpreted as number of - standard deviations. For example, cl=3 produces a 3 sigma contour. Values - other than 0.68, 0.9, 0.95, 0.99, 1, 2, 3, 4, 5 require the scipy module. + confidence level (a probability). For convenience, values cl >= 1 are + interpreted as the probability content of a central symmetric interval + covering that many standard deviations of a normal distribution. For + example, cl=1 is interpreted as 68.3 %, and cl=2 is 84.3 %, and so on. Using + values other than 0.68, 0.9, 0.95, 0.99, 1, 2, 3, 4, 5 require the scipy + module. size : int, optional Number of points on the contour to find (default: 100). Increasing this makes the contour smoother, but requires more computation time. @@ -2081,8 +2089,12 @@ This draws a matrix of Minos likelihood scans, meaning that the likelihood is minimized with respect to the parameters that are not scanned over. The diagonal cells of the matrix show the 1D scan, the off-diagonal cells show 2D scans for - all unique pairs of parameters. The 2D scans show confidence regions. See - :meth:`mncontour` for details on the interpretation of these regions. + all unique pairs of parameters. + + The projected edges of the 2D contours do not align with the 1D intervals, + because of Wilks' theorem. The levels for 2D confidence regions are higher. For + more information on the interpretation of 2D confidence regions, see + :meth:`mncontour`. Parameters ---------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/src/iminuit/pdg_format.py new/iminuit-2.24.0/src/iminuit/pdg_format.py --- old/iminuit-2.22.0/src/iminuit/pdg_format.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/src/iminuit/pdg_format.py 2022-11-09 13:37:21.000000000 +0100 @@ -180,6 +180,9 @@ if i > 0: for k in mask: items[k] = items[k][:-i] + # turn negative zero into positive zero + if items[0] == "-0": + items[0] = "0" return items diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/src/iminuit/typing.py new/iminuit-2.24.0/src/iminuit/typing.py --- old/iminuit-2.22.0/src/iminuit/typing.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/src/iminuit/typing.py 2022-11-09 13:37:21.000000000 +0100 @@ -71,3 +71,13 @@ """Annotation compatible with annotated-types.""" le: float + + +@dataclasses.dataclass +class Interval: + """Annotation compatible with annotated-types.""" + + gt: Optional[float] = None + ge: Optional[float] = None + lt: Optional[float] = None + le: Optional[float] = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/src/iminuit/util.py new/iminuit-2.24.0/src/iminuit/util.py --- old/iminuit-2.22.0/src/iminuit/util.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/src/iminuit/util.py 2022-11-09 13:37:21.000000000 +0100 @@ -1276,15 +1276,22 @@ lim[0] = c.start if c.stop is not None: lim[1] = c.stop - # Minuit does not distinguish between closed and open intervals - elif hasattr(c, "gt"): - lim[0] = c.gt - elif hasattr(c, "ge"): - lim[0] = c.ge - elif hasattr(c, "lt"): - lim[1] = c.lt - elif hasattr(c, "le"): - lim[1] = c.le + # Minuit does not distinguish between closed and open intervals. + # We use a chain of ifs so that the code also works with the + # `Interval` class, which contains several of those attributes + # and which can be None. + gt = getattr(c, "gt", None) + ge = getattr(c, "ge", None) + lt = getattr(c, "lt", None) + le = getattr(c, "le", None) + if gt is not None: + lim[0] = gt + if ge is not None: + lim[0] = ge + if lt is not None: + lim[1] = lt + if le is not None: + lim[1] = le return tuple(lim) @@ -1535,7 +1542,8 @@ return segments -def _smart_sampling(f, xmin, xmax, start=5, tol=5e-3): +def _smart_sampling(f, xmin, xmax, start=5, tol=5e-3, maxiter=20, maxtime=10): + t0 = monotonic() x = np.linspace(xmin, xmax, start) ynew = f(x) ymin = np.min(ynew) @@ -1543,10 +1551,23 @@ y = {xi: yi for (xi, yi) in zip(x, ynew)} a = x[:-1] b = x[1:] + niter = 0 while len(a): - if len(y) > 10000: - warnings.warn("Too many points", RuntimeWarning) # pragma: no cover - break # pragma: no cover + niter += 1 + if niter > maxiter: + msg = ( + f"Iteration limit {maxiter} in smart sampling reached, " + f"produced {len(y)} points" + ) + warnings.warn(msg, RuntimeWarning) + break + if monotonic() - t0 > maxtime: + msg = ( + f"Time limit {maxtime} in smart sampling reached, " + f"produced {len(y)} points" + ) + warnings.warn(msg, RuntimeWarning) + break xnew = 0.5 * (a + b) ynew = f(xnew) ymin = min(ymin, np.min(ynew)) @@ -1558,10 +1579,11 @@ + np.fromiter((y[bi] for bi in b), float) ) dy = np.abs(ynew - yint) + dx = np.abs(b - a) - mask = dy > tol * (ymax - ymin) - - # intervals which do not pass interpolation test + # in next iteration, handle intervals which do not + # pass interpolation test and are not too narrow + mask = (dy > tol * (ymax - ymin)) & (dx > tol * abs(xmax - xmin)) a = a[mask] b = b[mask] xnew = xnew[mask] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_cost.py new/iminuit-2.24.0/tests/test_cost.py --- old/iminuit-2.22.0/tests/test_cost.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_cost.py 2022-11-09 13:37:21.000000000 +0100 @@ -237,7 +237,7 @@ # manual spacing c.visualize((1, 2), model_points=np.linspace(1, 1000)) - with pytest.raises( + with pytest.warns( np.VisibleDeprecationWarning, match="keyword 'nbins' is deprecated" ): c.visualize((1, 2), nbins=20) @@ -1125,7 +1125,7 @@ assert multinominal_chi2(zero, zero) == 0 assert multinominal_chi2(zero, one) == 0 - assert multinominal_chi2(one, zero) == pytest.approx(1487, abs=1) + assert multinominal_chi2(one, zero) == pytest.approx(1416, abs=1) n = np.array([(0.0, 0.0)]) assert_allclose(multinominal_chi2(n, zero), 0) assert_allclose(multinominal_chi2(n, one), 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_describe.py new/iminuit-2.24.0/tests/test_describe.py --- old/iminuit-2.22.0/tests/test_describe.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_describe.py 2022-11-09 13:37:21.000000000 +0100 @@ -1,5 +1,5 @@ from iminuit.util import describe, make_func_code -from iminuit.typing import Annotated, Gt, Lt, Ge, Le +from iminuit.typing import Annotated, Gt, Lt, Ge, Le, Interval from math import ldexp import platform from functools import wraps @@ -195,6 +195,7 @@ c: Annotated[float, 0:], d: Annotated[float, Ge(1)], e: Annotated[float, Le(2)], + f: Annotated[float, Interval(gt=2, lt=3)], ): ... @@ -206,6 +207,7 @@ "c": (0, np.inf), "d": (1, np.inf), "e": (-np.inf, 2), + "f": (2, 3), } class Foo: @@ -219,6 +221,50 @@ assert r == {"x": None, "a": (0, 1), "b": None} +def test_with_pydantic_types(): + tp = pytest.importorskip("pydantic.types") + + def foo( + x: NDArray, + a: tp.PositiveFloat, + b: tp.NonNegativeFloat, + c: float, + d: Annotated[float, tp.annotated_types.Gt(1)], + e: Annotated[float, tp.annotated_types.Interval(gt=0, lt=1)], + ): + ... + + r = describe(foo, annotations=True) + assert r == { + "x": None, + "a": (0, np.inf), + "b": (0, np.inf), + "c": None, + "d": (1, np.inf), + "e": (0, 1), + } + + +def test_with_annotated_types(): + tp = pytest.importorskip("annotated_types") + + def foo( + x: NDArray, + a: float, + b: Annotated[float, tp.Gt(1)], + c: Annotated[float, tp.Interval(gt=0, lt=1)], + ): + ... + + r = describe(foo, annotations=True) + assert r == { + "x": None, + "a": None, + "b": (1, np.inf), + "c": (0, 1), + } + + class Foo(float): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_draw.py new/iminuit-2.24.0/tests/test_draw.py --- old/iminuit-2.22.0/tests/test_draw.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_draw.py 2022-11-09 13:37:21.000000000 +0100 @@ -137,7 +137,7 @@ @pytest.mark.filterwarnings("ignore::DeprecationWarning") def test_interactive(): - import ipywidgets + ipywidgets = pytest.importorskip("ipywidgets") def cost(a, b): return a**2 + b**2 @@ -223,6 +223,8 @@ @pytest.mark.filterwarnings("ignore::DeprecationWarning") def test_interactive_raises(): + pytest.importorskip("ipywidgets") + def raiser(args): raise ValueError @@ -237,6 +239,8 @@ @pytest.mark.filterwarnings("ignore::DeprecationWarning") def test_interactive_with_array_func(): + pytest.importorskip("ipywidgets") + def cost(par): return par[0] ** 2 + (par[1] / 2) ** 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_issue.py new/iminuit-2.24.0/tests/test_issue.py --- old/iminuit-2.22.0/tests/test_issue.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_issue.py 2022-11-09 13:37:21.000000000 +0100 @@ -1,11 +1,9 @@ -from iminuit import Minuit -from iminuit.util import IMinuitWarning -import pickle -import pytest import numpy as np def test_issue_424(): + from iminuit import Minuit + def fcn(x, y, z): return (x - 1) ** 2 + (y - 4) ** 2 / 2 + (z - 9) ** 2 / 3 @@ -20,6 +18,10 @@ def test_issue_544(): + import pytest + from iminuit import Minuit + from iminuit.util import IMinuitWarning + def fcn(x, y): return x**2 + y**2 @@ -30,6 +32,8 @@ def test_issue_648(): + from iminuit import Minuit + class F: first = True @@ -45,6 +49,8 @@ def test_issue_643(): + from iminuit import Minuit + def fcn(x, y, z): return (x - 2) ** 2 + (y - 3) ** 2 + (z - 4) ** 2 @@ -64,6 +70,8 @@ def test_issue_669(): + from iminuit import Minuit + def fcn(x, y): return x**2 + (y / 2) ** 2 @@ -84,15 +92,21 @@ assert match +# cannot define this inside function, pickle will not allow it def fcn(par): return np.sum(par**2) +# cannot define this inside function, pickle will not allow it def grad(par): return 2 * par def test_issue_687(): + import pickle + import numpy as np + from iminuit import Minuit + start = np.zeros(3) m = Minuit(fcn, start) @@ -107,10 +121,13 @@ def test_issue_694(): - stats = pytest.importorskip("scipy.stats") - + import pytest + import numpy as np + from iminuit import Minuit from iminuit.cost import ExtendedUnbinnedNLL + stats = pytest.importorskip("scipy.stats") + xmus = 1.0 xmub = 5.0 xsigma = 1.0 @@ -142,3 +159,32 @@ break else: assert False + + +def test_issue_923(): + from iminuit import Minuit + from iminuit.cost import LeastSquares + import numpy as np + import pytest + + # implicitly needed by visualize + pytest.importorskip("matplotlib") + + def model(x, c1): + c2 = 100 + res = np.zeros(len(x)) + mask = x < 47 + res[mask] = c1 + res[~mask] = c2 + return res + + xtest = np.linspace(0, 74) + ytest = xtest * 0 + 1 + ytesterr = ytest + + least_squares = LeastSquares(xtest, ytest, ytesterr, model) + + m = Minuit(least_squares, c1=1) + m.migrad() + # this used to trigger an endless (?) loop + m.visualize() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_pdg_format.py new/iminuit-2.24.0/tests/test_pdg_format.py --- old/iminuit-2.22.0/tests/test_pdg_format.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_pdg_format.py 2022-11-09 13:37:21.000000000 +0100 @@ -81,6 +81,8 @@ assert _strip(["0.11", "0.20"]) == ["0.11", "0.20"] assert _strip(["10.0", "20.0"]) == ["10", "20"] assert _strip(["1.200", "3.40"]) == ["1.20", "3.4"] + assert _strip(["0.000", "0.000"]) == ["0", "0"] + assert _strip(["-0.00", "0.00"]) == ["0", "0"] def test_term_format(): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_repr.py new/iminuit-2.24.0/tests/test_repr.py --- old/iminuit-2.22.0/tests/test_repr.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_repr.py 2022-11-09 13:37:21.000000000 +0100 @@ -1,6 +1,6 @@ -# flake8: noqa E501 +# flake8: noqa: E501 from iminuit import Minuit -from iminuit.util import Params, Param, Matrix, FMin, MError +from iminuit.util import Param, Matrix, FMin, MError from iminuit import _repr_html, _repr_text import pytest from argparse import Namespace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_tabulate.py new/iminuit-2.24.0/tests/test_tabulate.py --- old/iminuit-2.22.0/tests/test_tabulate.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_tabulate.py 2022-11-09 13:37:21.000000000 +0100 @@ -33,7 +33,7 @@ == """ x y -- --- --- -x 1 -0 -y -0 4 +x 1 0 +y 0 4 """ ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iminuit-2.22.0/tests/test_util.py new/iminuit-2.24.0/tests/test_util.py --- old/iminuit-2.22.0/tests/test_util.py 2022-11-09 13:37:21.000000000 +0100 +++ new/iminuit-2.24.0/tests/test_util.py 2022-11-09 13:37:21.000000000 +0100 @@ -711,8 +711,30 @@ def test_smart_sampling_2(): - with pytest.warns(RuntimeWarning): - util._smart_sampling(np.log, 1e-10, 1, tol=1e-10) + # should not raise a warning + x, y = util._smart_sampling(np.log, 1e-10, 1, tol=1e-5) + assert 0 < len(x) < 1000 + + +def test_smart_sampling_3(): + def step(x): + return np.where(x > 0.5, 0, 1) + + with pytest.warns(RuntimeWarning, match="Iteration limit"): + x, y = util._smart_sampling(step, 0, 1, tol=0) + assert 0 < len(x) < 80 + + +def test_smart_sampling_4(): + from time import sleep + + def step(x): + sleep(0.1) + return np.where(x > 0.5, 0, 1) + + with pytest.warns(RuntimeWarning, match="Time limit"): + x, y = util._smart_sampling(step, 0, 1, maxtime=0) + assert 0 < len(x) < 10 @pytest.mark.parametrize(