Repository navigation
Give sparse \ and qr(A) \ b the eltype of dense \ - #1124
Open
ViralBShah wants to merge 2 commits into
Open
ViralBShah wants to merge 2 commits into
ViralBShah wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1124 +/- ##
==========================================
+ Coverage 94.73% 94.74% +0.01%
==========================================
Files 16 16
Lines 10325 10334 +9
==========================================
+ Hits 9781 9791 +10
+ Misses 544 543 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The QR and LQ branches of `A \ B` returned the eltype of the factor, so the result type depended on the shape of `A` and was not inferable. Convert their solution as the LU branch does, and factorize a matrix of a narrower eltype than the solution in the wider one so that the solve keeps the precision of `B`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ense `\` A QR factorization of a narrower eltype than the solution is converted to the wider one before the solve, as dense `\` converts its factorization, rather than rounding the right-hand side. The transposed complex Hermitian `\` takes a matrix right-hand side as well as a vector. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
\ the eltype of dense \ for tall and wide matrices\ and qr(A) \ b the eltype of dense \
ViralBShah
force-pushed
the
vs/backslash-eltype-shape
branch
from
October 26, 2026 15:04
97ad8e7 to
7407317
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The eltype of sparse
A \ Bdepended on the shape ofA: a tall or wideFloat32matrix with aFloat64right-hand side gaveFloat32, where a square one and dense\giveFloat64, and anInttall matrix with aFloat32right-hand side gaveFloat64where dense givesFloat32. So\was not inferable, and the least squares solve roundedbtoFloat32. The same rounding happened at the factorization level inqr(A) \ bandqr(A)' \ b, andtranspose(A) \ Bof a complex HermitianComplexF32matrix with a matrixBgaveComplexF64.Before
After
Before
After
Only the LU branch of
_sparse_factorizeconverted its solution totypeof(one(eltype(A)) \ one(eltype(B))). The QR and LQ branches, including theqr(A')branch of the adjoint and transpose methods, returned the eltype of the factor, which SPQR gives the eltype of the matrix. They now convert the same way. Converting the result alone would keep theFloat32solve, sinceqrof aFloat32matrix factorizes in double precision and rounds the factor back, and its solve convertsBto the factor's eltype. So before the QR or LQ factorization, a matrix of a narrower eltype than the solution is converted to the wider one. That costs nothing extra, becauseqrmakes that copy anyway. A matrix and right-hand side of the same eltype factorize as before. The conversion is skipped for an abstract eltype, which has noone, sotall \ Any[...]still works.At the factorization level,
qr(A) \ bandqr(A)' \ b(andtranspose(qr(A)) \ b, which goes through the adjoint) convertedbto the eltype of the factor. When dense\gives a wider solution, they now convert the factorization to that precision with the existingQRSparse{T}(F)constructor, as dense\does withFactorization{T}(F). This copies the factor's arrays exactly and does not refactorize, so the accuracy is that of theFloat32factorization, as for dense. A real factorization stays real for a complex right-hand side and keeps the reinterpreting solve. The factor is not converted when the target is not a BLAS float, such asBigFloat, or whenbhas an abstract eltype; those cases behave as before.A \ bdoes not take this path, because its factor already has the solution's precision.The transposed complex Hermitian
\method was defined for aVectoronly, so a matrix right-hand side went to LinearAlgebra's generic\. It now takesVecOrMat, and the matrix goes through the sparse Hermitian solve as the vector does. This touches dispatch.Potential breakage: code that works today gets a different result eltype. A tall or wide
Float32matrix with aFloat64right-hand side returnedVector{Float32}fromA \ b,qr(A) \ bandqr(A)' \ b, and now returnsVector{Float64}, with the solve done in the promoted precision.transpose(A) \ Bof a complex HermitianComplexF32matrix with a matrixBreturnedMatrix{ComplexF64}and now returnsMatrix{ComplexF32}.Left out: at the factorization level,
luandcholeskystill differ from dense.luof aFloat32orComplexF32matrix is anUmfpackLU{Float64}orUmfpackLU{ComplexF64}, solu(A) \ breturns double precision where dense keeps single. The factor does not record the original eltype, so this cannot be fixed by converting the solution.cholesky(A) \ bof aFloat32matrix keeps a single-precision CHOLMOD factor and returnsFloat32for aFloat64b, where dense returnsFloat64. Converting a CHOLMOD factor is not the same small change.A \ bis not affected by either. #999 changes the sparse right-hand side\beside this code. Its rectangular branch calls the dense right-hand side\, so it gets this fix, and the diffs touch different lines.🤖 Generated with Claude Code