Reference Issues/PRs
Fixes #15667.
What does this implement/fix? Explain your changes.
_pinv2_old in sklearn/cross_decomposition/_pls.py is a copy of SciPy < 1.3 pinv2, used by the NIPALS power method in mode B (CCA). It was kept because the old rank cutoff, s > factor * eps * max(s) with factor = 1e3 for single and 1e6 for double precision, could not be set through cond/rcond after scipy/scipy#10067.
Since SciPy 1.7, scipy.linalg.pinv takes atol/rtol and discards singular values s <= atol + rtol * max(s). So the old cutoff is pinv(a, atol=0, rtol=factor * eps). This PR replaces the vendored function with a short _pinv wrapper that does that. The minimum supported SciPy is 1.11.4, so atol/rtol are always available.
factor and eps follow the precision the SVD runs in, as before (the old code keyed them on u.dtype.char). In practice fit validates X and y to float64, so only the double-precision branch is reached.
No behaviour change is intended, so there is no changelog entry.
How I checked it:
- Compared the old and new functions on float32 and float64 matrices: full rank, rank deficient, tall, wide, duplicated columns, singular values just above and below the cutoff, a graded spectrum, scaled inputs, plus 2000 random matrices of mixed shape and rank.
- With SciPy 1.11.4 / NumPy 1.26.4 the outputs are bit-identical.
- With SciPy 1.18.1 / NumPy 2.5.4 they agree to rounding (max relative difference about 2e-16 for float64 and 2e-7 for float32), and the kept rank was the same in every case.
ruff check and ruff format --check (ruff 0.12.2) pass on the changed file.
pytest sklearn/cross_decomposition/tests/ passes locally (62 passed; 4 skipped only because pandas isn't installed in my env).
Introduce yourself
Hi everyone, I'm Subham from Delhi. I have about 2 years of experience across different tech stacks, mainly TypeScript, Next.js, Node.js, MongoDB and Postgres, plus Python for ML work. I use scikit-learn a lot, so I wanted to start contributing to it, beginning with smaller maintenance issues like this one. Looking forward to learning from everyone here!
AI usage disclosure
I used AI assistance for:
- Code generation (e.g., when writing an implementation or fixing a bug)
- Test/benchmark generation
- Research and understanding
I used Claude Code to help write and check this change.
I reviewed the diff, understand it, and can explain it.
Any other comments?