-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
fixed symtridiagonal +/- bidiagonal #28534
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fixed symtridiagonal +/- bidiagonal #28534
Conversation
|
Thanks so much for tackling this! Here's an alternate patch that passes both the existing tests and the new ones you added: diff --git a/stdlib/LinearAlgebra/src/special.jl b/stdlib/LinearAlgebra/src/special.jl
index 70014837e0..984c9271df 100644
--- a/stdlib/LinearAlgebra/src/special.jl
+++ b/stdlib/LinearAlgebra/src/special.jl
@@ -79,54 +79,6 @@ macro commutative(myexpr)
esc(Expr(:block, myexpr, reversed_call))
end
-for op in (:+, :-)
- SpecialMatrices = [:Diagonal, :Bidiagonal, :Tridiagonal, :Matrix]
- for (idx, matrixtype1) in enumerate(SpecialMatrices) # matrixtype1 is the sparser matrix type
- for matrixtype2 in SpecialMatrices[idx+1:end] # matrixtype2 is the denser matrix type
- @eval begin # TODO quite a few of these conversions are NOT defined
- ($op)(A::($matrixtype1), B::($matrixtype2)) = ($op)(convert(($matrixtype2), A), B)
- ($op)(A::($matrixtype2), B::($matrixtype1)) = ($op)(A, convert(($matrixtype2), B))
- end
- end
- end
-
- for matrixtype1 in (:SymTridiagonal,) # matrixtype1 is the sparser matrix type
- for matrixtype2 in (:Tridiagonal, :Matrix) # matrixtype2 is the denser matrix type
- @eval begin
- ($op)(A::($matrixtype1), B::($matrixtype2)) = ($op)(convert(($matrixtype2), A), B)
- ($op)(A::($matrixtype2), B::($matrixtype1)) = ($op)(A, convert(($matrixtype2), B))
- end
- end
- end
-
- for matrixtype1 in (:Diagonal, :Bidiagonal) # matrixtype1 is the sparser matrix type
- for matrixtype2 in (:SymTridiagonal,) # matrixtype2 is the denser matrix type
- @eval begin
- ($op)(A::($matrixtype1), B::($matrixtype2)) = ($op)(convert(($matrixtype2), A), B)
- ($op)(A::($matrixtype2), B::($matrixtype1)) = ($op)(A, convert(($matrixtype2), B))
- end
- end
- end
-
- for matrixtype1 in (:Diagonal,)
- for (matrixtype2,matrixtype3) in ((:UpperTriangular,:UpperTriangular),
- (:UnitUpperTriangular,:UpperTriangular),
- (:LowerTriangular,:LowerTriangular),
- (:UnitLowerTriangular,:LowerTriangular))
- @eval begin
- ($op)(A::($matrixtype1), B::($matrixtype2)) = ($op)(($matrixtype3)(A), B)
- ($op)(A::($matrixtype2), B::($matrixtype1)) = ($op)(A, ($matrixtype3)(B))
- end
- end
- end
- for matrixtype in (:SymTridiagonal,:Tridiagonal,:Bidiagonal,:Matrix)
- @eval begin
- ($op)(A::AbstractTriangular, B::($matrixtype)) = ($op)(copyto!(similar(parent(A)), A), B)
- ($op)(A::($matrixtype), B::AbstractTriangular) = ($op)(A, copyto!(similar(parent(B)), B))
- end
- end
-end
-
rmul!(A::AbstractTriangular, adjB::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) =
(B = adjB.parent; rmul!(full!(A), adjoint(B)))
*(A::AbstractTriangular, adjB::Adjoint{<:Any,<:Union{QRCompactWYQ,QRPackedQ}}) = |
|
In other words: the fallback definitions for array + and - simply assert the sizes are correct and then use broadcasting… and while I've not put together nearly as complete a table as you have in #28883, I think broadcasting mostly does the right thing. |
|
Well... how about that. Nice find haha. I am going to add a few more tests and then push these changes to #28883. |
… from binops of special.jl so that broadcasting takes over. Cleaned up some of the tests for special.jl
|
@mbauman Your fix worked in all cases except Bidiagonal since there is an input parameter and not a special type for upper and lower. |
|
I still need to update this for UnitUpperTriangular/UnitLowerTriangular and add tests for the correct types. |
|
I am moving all development of this to #28883. |
SymTridiagonal + Bidiagonal matrices fail because the output is forced to Symtridiagonal. Now it correctly promotes to Tridiagonal matrices. This does not consider the case where the Bidiagonal matrix is diagonal.
Before:
Now: