From 730edd49b72f142a4ac27b49d370bd6e11f9f9c2 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Fri, 25 Mar 2022 20:14:50 +0000 Subject: [PATCH] Avoid copy in getindex(::AbstractQ, ...) (#44729) (cherry picked from commit ea82910042ff6e5e34e96a2a8711c3087bc7b209) --- stdlib/LinearAlgebra/src/qr.jl | 5 +++-- stdlib/LinearAlgebra/test/qr.jl | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/stdlib/LinearAlgebra/src/qr.jl b/stdlib/LinearAlgebra/src/qr.jl index 16e066ed1e030..4e1cc83b468f5 100644 --- a/stdlib/LinearAlgebra/src/qr.jl +++ b/stdlib/LinearAlgebra/src/qr.jl @@ -582,8 +582,9 @@ size(F::Union{QR,QRCompactWY,QRPivoted}) = size(getfield(F, :factors)) size(Q::AbstractQ, dim::Integer) = size(getfield(Q, :factors), dim == 2 ? 1 : dim) size(Q::AbstractQ) = size(Q, 1), size(Q, 2) -copy(Q::AbstractQ{T}) where {T} = lmul!(Q, Matrix{T}(I, size(Q))) -getindex(Q::AbstractQ, inds...) = copy(Q)[inds...] +copymutable(Q::AbstractQ{T}) where {T} = lmul!(Q, Matrix{T}(I, size(Q))) +copy(Q::AbstractQ) = copymutable(Q) +getindex(Q::AbstractQ, inds...) = copymutable(Q)[inds...] getindex(Q::AbstractQ, ::Colon, ::Colon) = copy(Q) function getindex(Q::AbstractQ, ::Colon, j::Int) diff --git a/stdlib/LinearAlgebra/test/qr.jl b/stdlib/LinearAlgebra/test/qr.jl index f9acbdb376465..a7b24f08385f2 100644 --- a/stdlib/LinearAlgebra/test/qr.jl +++ b/stdlib/LinearAlgebra/test/qr.jl @@ -449,6 +449,12 @@ end @test Q2[:, :] ≈ M[:, :] @test Q2[:, :, :] ≈ M[:, :, :] end + # Check that getindex works if copy returns itself (#44729) + struct MyIdentity{T} <: LinearAlgebra.AbstractQ{T} end + Base.size(::MyIdentity, dim::Integer) = dim in (1,2) ? 2 : 1 + Base.copy(J::MyIdentity) = J + LinearAlgebra.lmul!(::MyIdentity{T}, M::Array{T}) where {T} = M + @test MyIdentity{Float64}()[1,:] == [1.0, 0.0] end end # module TestQR