Skip to content

SciPy v1.16.0 gives different numerical results and Singular matrix E in LSQ subproblem #2593

@matthewfeickert

Description

@matthewfeickert

Summary

As found in PR #2592, scipy v1.16.0 gives different numerical results than scipy v1.15.3 for tests/test_calculator.py and for tests/test_optim.py it fails with

E           pyhf.exceptions.FailedMinimization: Singular matrix E in LSQ subproblem

OS / Environment

PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

Steps to Reproduce

$ uv pip install --upgrade -e '.[develop]
$ uv pip install --upgrade 'numpy<2.0' scipy
$ pytest --ignore tests/benchmarks --ignore tests/test_notebooks.py tests/
=========================================================================================== test session starts ============================================================================================
platform linux -- Python 3.12.11, pytest-8.4.1, pluggy-1.6.0
Matplotlib: 3.10.3
Freetype: 2.6.1
benchmark: 5.1.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /home/feickert/Code/GitHub/scikit-hep/pyhf
configfile: pyproject.toml
plugins: mock-3.14.1, requests-mock-1.12.1, mpl-0.17.0, console-scripts-1.4.1, socket-0.7.0, anyio-4.9.0, benchmark-5.1.0
collected 1518 items                                                                                                                                                                                       

tests/contrib/test_contrib_utils.py .....                                                                                                                                                            [  0%]
tests/contrib/test_viz.py .........                                                                                                                                                                  [  0%]
tests/test_backend_consistency.py ....                                                                                                                                                               [  1%]
tests/test_backends.py ............                                                                                                                                                                  [  1%]
tests/test_calculator.py ...FF.                                                                                                                                                                      [  2%]
tests/test_cli.py ..                                                                                                                                                                                 [  2%]
tests/test_combined_modifiers.py ................................................                                                                                                                    [  5%]
tests/test_compat.py ...                                                                                                                                                                             [  5%]
tests/test_constraints.py ............                                                                                                                                                               [  6%]
tests/test_custom_mods.py ..                                                                                                                                                                         [  6%]
tests/test_events.py .......                                                                                                                                                                         [  7%]
tests/test_examples.py .                                                                                                                                                                             [  7%]
tests/test_export.py ...........................                                                                                                                                                     [  9%]
tests/test_import.py ......................                                                                                                                                                          [ 10%]
tests/test_infer.py ...........................................................................................                                                                                      [ 16%]
tests/test_init.py ......                                                                                                                                                                            [ 16%]
tests/test_interpolate.py .........................................................................................................                                                                  [ 23%]
tests/test_jit.py ................................                                                                                                                                                   [ 25%]
tests/test_mixins.py ...                                                                                                                                                                             [ 26%]
tests/test_modifiers.py ............                                                                                                                                                                 [ 26%]
tests/test_optim.py .sss.s.......................................................................................FFFFF.FFFFF.sssss.sssss...................                                          [ 35%]
tests/test_paramsets.py .........                                                                                                                                                                    [ 36%]
tests/test_paramviewer.py .............                                                                                                                                                              [ 37%]
tests/test_patchset.py ...........................                                                                                                                                                   [ 39%]
tests/test_pdf.py ............................sssss.........................sssss.......sssss............FFFFF.....                                                                                  [ 45%]
tests/test_probability.py .........................                                                                                                                                                  [ 47%]
tests/test_public_api.py ...................................................................                                                                                                         [ 51%]
tests/test_public_api_repr.py ...............................                                                                                                                                        [ 53%]
tests/test_regression.py FFF.F.                                                                                                                                                                      [ 53%]
tests/test_schema.py .........................................................................                                                                                                       [ 58%]
tests/test_scripts.py ..............................................................                                                                                                                 [ 62%]
tests/test_simplemodels.py .............xxxx..xxxx.                                                                                                                                                  [ 64%]
tests/test_tensor.py .................................................................................................xx...s..sss.............xx.............................................sss.ss. [ 75%]
...................................                                                                                                                                                                  [ 78%]
tests/test_tensorviewer.py ......                                                                                                                                                                    [ 78%]
tests/test_teststats.py ..F.F..............                                                                                                                                                          [ 79%]
tests/test_toys.py ......                                                                                                                                                                            [ 80%]
tests/test_utils.py ..................                                                                                                                                                               [ 81%]
tests/test_validation.py .....F..F..F................                                                                                                                                                [ 83%]
tests/test_workspace.py ............................................................................................................................................................................ [ 94%]
.................................................................................                                                                                                                    [100%]

================================================================================================= FAILURES =================================================================================================
____________________________________________________________________________ test_asymptotic_calculator_has_fitted_pars[qtilde] ____________________________________________________________________________

test_stat = 'qtilde'

    @pytest.mark.parametrize('test_stat', ['qtilde', 'q', 'q0'])
    def test_asymptotic_calculator_has_fitted_pars(test_stat):
        model = pyhf.simplemodels.uncorrelated_background([1], [1], [1])
        data = [2, 1]  # [main, aux]
    
        calc = pyhf.infer.calculators.AsymptoticCalculator(data, model, test_stat=test_stat)
        calc.teststatistic(0 if test_stat == 'q0' else 1)
    
        assert hasattr(calc, 'fitted_pars')
        fitted_pars = calc.fitted_pars
        assert hasattr(fitted_pars, 'asimov_pars')
        assert hasattr(fitted_pars, 'fixed_poi_fit_to_data')
        assert hasattr(fitted_pars, 'fixed_poi_fit_to_asimov')
        assert hasattr(fitted_pars, 'free_fit_to_data')
        assert hasattr(fitted_pars, 'free_fit_to_asimov')
    
        rtol = 1e-5
        if test_stat == 'q0':
            assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.asimov_pars
            )
            assert pytest.approx([0.0, 1.5], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.fixed_poi_fit_to_data
            )
            assert pytest.approx([0.0, 1.5], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.fixed_poi_fit_to_asimov
            )
            assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.free_fit_to_data
            )
            assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.free_fit_to_asimov
            )
        else:
            assert pytest.approx([0.0, 1.5], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.asimov_pars
            )
            assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.fixed_poi_fit_to_data
            )
            assert pytest.approx([1.0, 1.1513553], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.fixed_poi_fit_to_asimov
            )
            assert pytest.approx([1.0, 1.0], rel=rtol) == pyhf.tensorlib.tolist(
                fitted_pars.free_fit_to_data
            )
            # lower tolerance for amd64 and arm64 to agree
            # FIXME: SciPy v1.16.0 gives a different result from SciPy v1.15.3
>           assert pytest.approx(
                [7.6470499e-05, 1.4997178], rel=1e-3
            ) == pyhf.tensorlib.tolist(fitted_pars.free_fit_to_asimov)
E           assert approx([7.647...± 0.00149972]) == [7.6321607829...7178921881127]
E             
E             comparison failed. Mismatched elements: 1 / 2:
E             Max absolute difference: 1.488911703012493e-07
E             Max relative difference: 0.0019508390157801656
E             Index | Obtained              | Expected               
E             0     | 7.632160782969875e-05 | 7.6470499e-05 ± 7.6e-08

calc       = <pyhf.infer.calculators.AsymptoticCalculator object at 0x7c782ca5e720>
data       = [2, 1]
fitted_pars = HypoTestFitResults(asimov_pars=array([0.        , 1.50000576]), free_fit_to_data=array([1., 1.]), free_fit_to_asimov=a...e-05, 1.49971789e+00]), fixed_poi_fit_to_data=array([1., 1.]), fixed_poi_fit_to_asimov=array([1.        , 1.15135536]))
model      = <pyhf.pdf.Model object at 0x7c76fc3c6900>
rtol       = 1e-05
test_stat  = 'qtilde'

tests/test_calculator.py:89: AssertionError
-------------------------------------------------------------------------------------------- Captured log call ---------------------------------------------------------------------------------------------
INFO     pyhf.pdf:pdf.py:782 Validating spec against schema: model.json
INFO     pyhf.pdf:pdf.py:478 adding modifier mu (1 new nuisance parameters)
INFO     pyhf.pdf:pdf.py:478 adding modifier uncorr_bkguncrt (1 new nuisance parameters)

File Upload (optional)

No response

Expected Results

For the tests to run with the same numerical results within accepted floating point precision.

Actual Results

>           raise exceptions.FailedMinimization(result)
E           pyhf.exceptions.FailedMinimization: Singular matrix E in LSQ subproblem

pyhf Version

pyhf, version 0.7.1.dev308

Code of Conduct

  • I agree to follow the Code of Conduct

Metadata

Metadata

Labels

bugSomething isn't workingneeds-triageNeeds a maintainer to categorize and assign

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions