From c8e8b20c7da1da0a51d600a2e16a00f0888be052 Mon Sep 17 00:00:00 2001 From: Hendrik Ranocha Date: Fri, 5 Feb 2021 09:58:33 +0100 Subject: [PATCH] specialize copyto! for Q from qr This fixes some performance problems reported in #38972 and #37102 (multiplying `Q` by a `Diagonal` or `UniformScaling`). --- stdlib/LinearAlgebra/src/qr.jl | 6 ++++++ stdlib/LinearAlgebra/test/qr.jl | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/stdlib/LinearAlgebra/src/qr.jl b/stdlib/LinearAlgebra/src/qr.jl index a76577bb63a0d5..a0de58e4c73ffb 100644 --- a/stdlib/LinearAlgebra/src/qr.jl +++ b/stdlib/LinearAlgebra/src/qr.jl @@ -533,6 +533,12 @@ function getindex(Q::AbstractQ, i::Integer, j::Integer) return dot(x, lmul!(Q, y)) end +# specialization avoiding the fallback using slow `getindex` +function copyto!(dest::AbstractMatrix, src::LinearAlgebra.AbstractQ) + copyto!(dest, I) + lmul!(src, dest) +end + ## Multiplication by Q ### QB lmul!(A::QRCompactWYQ{T,S}, B::StridedVecOrMat{T}) where {T<:BlasFloat, S<:StridedMatrix} = diff --git a/stdlib/LinearAlgebra/test/qr.jl b/stdlib/LinearAlgebra/test/qr.jl index b4e6d383bb2622..c61dcaf5de43a9 100644 --- a/stdlib/LinearAlgebra/test/qr.jl +++ b/stdlib/LinearAlgebra/test/qr.jl @@ -322,4 +322,13 @@ end end end +@testset "QR factorization of Q" begin + for T in (Float32, Float64, ComplexF32, ComplexF64) + Q1, R1 = qr(randn(T,5,5)) + Q2, R2 = qr(Q1) + @test Q1 ≈ Q2 + @test R2 ≈ I + end +end + end # module TestQR