diff --git a/base/linalg/factorization.jl b/base/linalg/factorization.jl index 3b73ffc6d1c2d..7c88964c0f42e 100644 --- a/base/linalg/factorization.jl +++ b/base/linalg/factorization.jl @@ -77,11 +77,11 @@ qr(A::Union(Number, AbstractMatrix), pivot::Union(Type{Val{false}}, Type{Val{tru _qr(A, pivot, thin=thin) function _qr(A::Union(Number, AbstractMatrix), ::Type{Val{false}}; thin::Bool=true) F = qrfact(A, Val{false}) - full(F[:Q], thin=thin), F[:R] + full(getq(F), thin=thin), F[:R]::Matrix{eltype(F)} end function _qr(A::Union(Number, AbstractMatrix), ::Type{Val{true}}; thin::Bool=true) F = qrfact(A, Val{true}) - full(F[:Q], thin=thin), F[:R], F[:p] + full(getq(F), thin=thin), F[:R]::Matrix{eltype(F)}, F[:p]::Vector{BlasInt} end convert{T}(::Type{QR{T}},A::QR) = QR(convert(AbstractMatrix{T}, A.factors), convert(Vector{T}, A.τ)) @@ -94,19 +94,19 @@ convert{T}(::Type{Factorization{T}}, A::QRPivoted) = convert(QRPivoted{T}, A) function getindex(A::QR, d::Symbol) m, n = size(A) d == :R && return triu!(A.factors[1:min(m,n), 1:n]) - d == :Q && return QRPackedQ(A.factors,A.τ) + d == :Q && return getq(A) throw(KeyError(d)) end function getindex(A::QRCompactWY, d::Symbol) m, n = size(A) d == :R && return triu!(A.factors[1:min(m,n), 1:n]) - d == :Q && return QRCompactWYQ(A.factors,A.T) + d == :Q && return getq(A) throw(KeyError(d)) end function getindex{T}(A::QRPivoted{T}, d::Symbol) m, n = size(A) d == :R && return triu!(A.factors[1:min(m,n), 1:n]) - d == :Q && return QRPackedQ(A.factors,A.τ) + d == :Q && return getq(A) d == :p && return A.jpvt if d == :P p = A[:p] @@ -119,9 +119,10 @@ function getindex{T}(A::QRPivoted{T}, d::Symbol) end throw(KeyError(d)) end + # Type-stable interface to get Q getq(A::QRCompactWY) = QRCompactWYQ(A.factors,A.T) -getq(A::QRPivoted) = QRPackedQ(A.factors,A.τ) +getq(A::Union(QR, QRPivoted)) = QRPackedQ(A.factors,A.τ) immutable QRPackedQ{T,S<:AbstractMatrix} <: AbstractMatrix{T} factors::S diff --git a/test/linalg1.jl b/test/linalg1.jl index 5a0e620c0b99f..986e39121dd59 100644 --- a/test/linalg1.jl +++ b/test/linalg1.jl @@ -59,11 +59,8 @@ debug && println("Bunch-Kaufman factors of a pos-def matrix") debug && println("QR decomposition (without pivoting)") for i = 1:2 let a = i == 1 ? a : sub(a, 1:n - 1, 1:n - 1), b = i == 1 ? b : sub(b, 1:n - 1), n = i == 1 ? n : n - 1 - @inferred qrfact(a) - if eltya <: BlasFloat - @inferred qrfact(a, Val{true}) - end - qra = @inferred qrfact(a, Val{false}) + qra = @inferred qrfact(a) + @inferred qr(a) q, r = qra[:Q], qra[:R] @test_throws KeyError qra[:Z] @test_approx_eq q'*full(q, thin = false) eye(n) @@ -74,6 +71,7 @@ debug && println("QR decomposition (without pivoting)") debug && println("Thin QR decomposition (without pivoting)") qra = @inferred qrfact(a[:,1:n1], Val{false}) + @inferred qr(a[:,1:n1], Val{false}) q,r = qra[:Q], qra[:R] @test_throws KeyError qra[:Z] @test_approx_eq q'*full(q, thin=false) eye(n) @@ -84,6 +82,10 @@ debug && println("Thin QR decomposition (without pivoting)") @test_throws DimensionMismatch q*b[1:n1 + 1] debug && println("(Automatic) Fat (pivoted) QR decomposition") # Pivoting is only implemented for BlasFloats + if eltya <: BlasFloat + @inferred qrfact(a, Val{true}) + @inferred qr(a, Val{true}) + end qrpa = factorize(a[1:n1,:]) q,r = qrpa[:Q], qrpa[:R] @test_throws KeyError qrpa[:Z]