GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — MNT Use scipy.linalg.pinv instead of vendored pinv2 in CCA by devxsubh · Pull Request #35351 · scikit-learn/scikit-learn

Conversation

@devxsubh

@devxsubh devxsubh commented Nov 8, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

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?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@devxsubh
MNT Use scipy.linalg.pinv instead of vendored pinv2 in CCA (scikit-le…
3b86e5c
…arn#15667)

_pinv2_old was a copy of scipy < 1.3 pinv2, kept because its rank cutoff
(factor * eps * max(s), factor 1e3 for single and 1e6 for double
precision) could not be expressed with pinv2's cond/rcond after
scipy/scipy#10067. Since SciPy 1.7, pinv accepts atol/rtol, so the same
cutoff is pinv(a, atol=0, rtol=factor * eps).
@github-actions github-actions Bot added the module:cross_decomposition label Nov 8, 2026
@github-actions

github-actions Bot commented Nov 8, 2026

Copy link
Copy Markdown

Thank you for opening your first pull request to scikit-learn! 🎉

To help get your contribution reviewed, please make sure that:

  • You have filled out the pull request template.

  • The pull request addresses an existing issue that is ready for contribution (e.g. not tagged as 'Needs Triage', 'Needs Decision', ...). If you are proposing a new feature, please open an issue to discuss it first.

  • There are no other open pull requests already targeting the same issue.

  • You have followed the pull request checklist. In particular, linting and tests should pass.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the size/S label Nov 8, 2026

This branch has not been deployed

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

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

module:cross_decomposition size/S

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

CCA sets condition in pinv2 to match with scipy < 1.3

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@devxsubh
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.