Skip to content

Conversation

@mberz
Copy link

@mberz mberz commented Nov 18, 2025

This might fix the bug reported in scipy/scipy#23101.

It seems that

res[0] = T(1);
should depend on the sign of z.

This is an edge case for abs(z)=1, imag(z)=0 (see

assoc_legendre_p_pm1(norm, j, m, z, branch_cut, res[1]);
)

I've implemented a test which catches the original issue in scipy/scipy#24017.

I am not sure if this is a proper solution to the problem or only a workaround. I did not find references in the code of the Legendre functions which were used for the original implementation.

Copy link
Member

@lucascolley lucascolley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks @mberz ! I've confirmed that the test fails on main and passes on this branch:

scipy on 🎋 bug/assoc_legendre is 📦 v1.17.0.dev0 via 🐍 via 🧚 v0.59.0 took 4spixi run test -t scipy.special.tests.test_legendre "--" -k "assoc_legendre_bug"
✨ Pixi task (build in build): spin build --setup-args=-Dblas=blas --setup-args=-Dlapack=lapack --setup-args=-Duse-g77-abi=true: (Build SciPy (default settings))                                                                           $ meson compile -j 8 -C build
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/build/bin/ninja -C /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build -j 8
ninja: Entering directory `/Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build'
[2/338] Generating subprojects/highs/src/HConfig.h with a custom command
$ meson install --only-changed -C build --destdir ../build-install --tags=runtime,python-runtime,tests,devel
                                                                                                                      ✨ Pixi task (test in test): spin test --no-build -t scipy.special.tests.test_legendre -- -k assoc_legendre_bug: (Test SciPy (default settings))                                                                                            $ export PYTHONPATH="/Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build-install/usr/lib/python3.14/site-packages"
$ /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/test/bin/python3.14 -P -c 'import scipy'
$ cd /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build-install/usr/lib/python3.14/site-packages
$ /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/test/bin/python3.14 -P -m pytest -m 'not slow' -k assoc_legendre_bug --pyargs scipy.special.tests.test_legendre
================================================ test session starts =================================================
platform darwin -- Python 3.14.0, pytest-9.0.0, pluggy-1.6.0
rootdir: /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy
configfile: pytest.ini
plugins: hypothesis-6.147.0, xdist-3.8.0, timeout-2.4.0
collected 417 items / 416 deselected / 1 selected

scipy/special/tests/test_legendre.py F                                                                         [100%]

====================================================== FAILURES ======================================================
_____________________________________ TestAssocLegendreP.test_assoc_legendre_bug _____________________________________

self = <scipy.special.tests.test_legendre.TestAssocLegendreP object at 0x11a0bf750>

    def test_assoc_legendre_bug(self):
        """
        This test detects the bug reported in
        https://github.com/scipy/scipy/issues/23101
        """
        z = np.array([-1, -.5, 0, .5, 1])
        expected = assoc_legendre_p_1_0(z)
        result = assoc_legendre_p(1, 0, z)
>       assert_allclose(np.squeeze(result), expected)
E       AssertionError:
E       Not equal to tolerance rtol=1e-07, atol=0
E
E       Mismatched elements: 1 / 5 (20%)
E       Max absolute difference among violations: 2.
E       Max relative difference among violations: 2.
E        ACTUAL: array([ 1. , -0.5,  0. ,  0.5,  1. ])
E        DESIRED: array([-1. , -0.5,  0. ,  0.5,  1. ])

expected   = array([-1. , -0.5,  0. ,  0.5,  1. ])
result     = array([[ 1. , -0.5,  0. ,  0.5,  1. ]])
self       = <scipy.special.tests.test_legendre.TestAssocLegendreP object at 0x11a0bf750>
z          = array([-1. , -0.5,  0. ,  0.5,  1. ])

scipy/special/tests/test_legendre.py:79: AssertionError
============================================== short test summary info ===============================================
FAILED scipy/special/tests/test_legendre.py::TestAssocLegendreP::test_assoc_legendre_bug - AssertionError:
========================================= 1 failed, 416 deselected in 0.52s ==========================================

scipy on 🎋 bug/assoc_legendre is 📦 v1.17.0.dev0 via 🐍 via 🧚 v0.59.0 took 5scd subprojects/xsf/

xsf on 🎋 HEAD (33768a0) is 📦 v0.1.3 via △ v4.1.2 via 🧚 v0.59.0gpc
? Select a pull request 76	OPEN Bugfix/Workaround sign error Asso. Legendre Function at z=-1 [mberz:bugfix/legendre_sign_error]
remote: Enumerating objects: 11, done.
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 11 (delta 5), reused 10 (delta 5), pack-reused 0 (from 0)
Unpacking objects: 100% (11/11), 1.97 KiB | 155.00 KiB/s, done.
From https://github.com/scipy/xsf
 * [new ref]         refs/pull/76/head -> bugfix/legendre_sign_error
Previous HEAD position was 33768a0 REL: bump version to 0.1.3 (#67)
Switched to branch 'bugfix/legendre_sign_error'

xsf on 🎋 bugfix/legendre_sign_error is 📦 v0.1.3 via △ v4.1.2 via 🧚 v0.59.0 took 6scd ../..

scipy on 🎋 bug/assoc_legendre [🔨] is 📦 v1.17.0.dev0 via 🐍 via 🧚 v0.59.0pixi run test -t scipy.special.tests.test_legendre "--" -k "assoc_legendre_bug"
✨ Pixi task (build in build): spin build --setup-args=-Dblas=blas --setup-args=-Dlapack=lapack --setup-args=-Duse-g77-abi=true: (Build SciPy (default settings))                                                                                                                                                         $ meson compile -j 8 -C build
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/build/bin/ninja -C /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build -j 8
ninja: Entering directory `/Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build'
[12/12] Linking target scipy/special/_special_ufuncs.cpython-314-darwin.so
$ meson install --only-changed -C build --destdir ../build-install --tags=runtime,python-runtime,tests,devel
                                                                                                                                                             ✨ Pixi task (test in test): spin test --no-build -t scipy.special.tests.test_legendre -- -k assoc_legendre_bug: (Test SciPy (default settings))             $ export PYTHONPATH="/Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build-install/usr/lib/python3.14/site-packages"
$ /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/test/bin/python3.14 -P -c 'import scipy'
$ cd /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/build-install/usr/lib/python3.14/site-packages
$ /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy/.pixi/envs/test/bin/python3.14 -P -m pytest -m 'not slow' -k assoc_legendre_bug --pyargs scipy.special.tests.test_legendre
==================================================================== test session starts ====================================================================
platform darwin -- Python 3.14.0, pytest-9.0.0, pluggy-1.6.0
rootdir: /Users/lucascolley/ghq/github.com/rgommers/pixi-dev-scipystack/scipy/scipy
configfile: pytest.ini
plugins: hypothesis-6.147.0, xdist-3.8.0, timeout-2.4.0
collected 417 items / 416 deselected / 1 selected

scipy/special/tests/test_legendre.py .                                                                                                                [100%]

============================================================= 1 passed, 416 deselected in 0.39s =============================================================

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants