Skip to content

Add a new truncation strategy to protect degenerate clusters - #312

Open
kshyatt wants to merge 6 commits into
mainfrom
ksh/degen
Open

kshyatt wants to merge 6 commits into
mainfrom
ksh/degen

Conversation

@kshyatt

@kshyatt kshyatt commented Oct 22, 2026

Copy link
Copy Markdown
Member

Should address #101 and part of QuantumKitHub/TensorKit.jl#588

I added a keyword so users can pick whether to bias towards getting rid of the whole group of degenerate values or keeping them.

σs = abs.(collect(view(values, perm)))
start = firstindex(σs)
for k in eachindex(σs)
if k == lastindex(σs) || σs[k] - σs[k + 1] > max(strategy.atol, strategy.rtol * σs[k])

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is probably not GPU friendly yet but I think that can be handled in a separate PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

One thing I am wondering about for this functionality, is if there is ever a case where absolute tolerance makes sense. Like, suppose atol = 1e-6. Then by construction, all singular values smaller than $10^{-6}$ are grouped together. With mode == :up, if the truncation in strategy.strategy leads to a truncation at values smaller than atol, effectively there will be no truncation.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Indeed I was a bit torn on this question as well, but for now decided to keep atol in case we think of a need for it later. It could make sense I suppose if you know a certain sector has small (like 1e-4) singular values which are never the less bounded from below?

Comment on lines +177 to +178
_ind_to_mask(values::AbstractVector, ::Colon) = trues(length(values))
_ind_to_mask(values::AbstractVector, ind::AbstractVector{Bool}) = BitVector(ind)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is a GPU-CPU related issue found by 🤖 that I don't understand...

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes indeed, this PR wasn't made with the GPU stuff in mind at all, I can handle that in a separate PR imo

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

(I think BitArray just doesn't work on GPU lol)

@kshyatt
kshyatt requested a review from Jutho October 22, 2026 09:55
# walk the values in sorted order `perm`, and make sure each group of consecutive degenerate
# values is either kept or discarded as a whole cluster
function _keep_degenerate!(keep::AbstractVector{Bool}, values::AbstractVector, perm, strategy::TruncationDegenerate)
σs = abs.(collect(view(values, perm)))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't the broadcasted abs. already doing a collect? This may yield a double collection/allocation/

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hm, I'm not sure? If view(values, perm) lives on the GPU for example, would abs collect?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh collect as in back to CPU. No than not. But I thought this PR was CPU only so far?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It sort of accidentally supports the GPU by doing this collect which is a bit of a hack

Comment thread docs/src/user_interface/truncations.md Outdated
@Yue-Zhengyuan Yue-Zhengyuan linked an issue Oct 23, 2026 that may be closed by this pull request
@codecov

codecov Bot commented Oct 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.10345% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/implementations/truncation.jl 95.65% 1 Missing ⚠️
src/interface/truncation.jl 83.33% 1 Missing ⚠️
Files with missing lines Coverage Δ
src/MatrixAlgebraKit.jl 100.00% <ø> (ø)
src/implementations/truncation.jl 83.58% <95.65%> (+3.40%) ⬆️
src/interface/truncation.jl 67.53% <83.33%> (+1.33%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/interface/truncation.jl
Comment thread src/implementations/truncation.jl Outdated

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Degeneracy-aware truncation

3 participants