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 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 working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions