Skip to content

Commit

Permalink
Merge pull request #5526 from JuliaLang/anj/qr
Browse files Browse the repository at this point in the history
RFC:QR decomposition in julia
  • Loading branch information
andreasnoack committed Jan 31, 2014
2 parents 840485a + 186287a commit 8a94301
Show file tree
Hide file tree
Showing 12 changed files with 686 additions and 398 deletions.
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ Library improvements

* Balancing options for eigenvector calculations for general matrices ([#5428]).

* Mutating linear algebra functions no longer promote ([#5526]).

* Sparse linear algebra

* Faster sparse `kron` ([#4958]).
Expand Down Expand Up @@ -147,6 +149,8 @@ Library improvements

* LU factorization ([#5381] and [#5430])

* QR factorization ([#5526])

* New function `deleteat!` deletes a specified index or indices and
returns the updated collection

Expand Down Expand Up @@ -177,6 +181,8 @@ Deprecated or removed

* `myindexes` has been renamed to `localindexes` ([#5475])

* `factorize!` is deprecated in favor of `factorize`. ([#5526])

[#4042]: https://github.com/JuliaLang/julia/issues/4042
[#5164]: https://github.com/JuliaLang/julia/issues/5164
[#4026]: https://github.com/JuliaLang/julia/issues/4026
Expand Down Expand Up @@ -220,6 +226,7 @@ Deprecated or removed
[#5025]: https://github.com/JuliaLang/julia/pull/5025
[#4888]: https://github.com/JuliaLang/julia/pull/4888
[#5475]: https://github.com/JuliaLang/julia/pull/5475
[#5526]: https://github.com/JuliaLang/julia/pull/5526

Julia v0.2.0 Release Notes
==========================
Expand Down
1 change: 1 addition & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ export PipeString
@deprecate cholpfact(A) cholfact(A, :U, pivot=true)
@deprecate symmetrize!(A) Base.LinAlg.copytri!(A, 'U')
@deprecate symmetrize!(A, uplo) Base.LinAlg.copytri!(A, uplo)
@deprecate factorize!(A) factorize(A)

deprecated_ls() = run(`ls -l`)
deprecated_ls(args::Cmd) = run(`ls -l $args`)
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,6 @@ export
eigvecs,
expm,
eye,
factorize!,
factorize,
givens,
hessfact!,
Expand Down
1 change: 0 additions & 1 deletion base/linalg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export
sqrtm,
eye,
factorize,
factorize!,
givens,
gradient,
hessfact,
Expand Down
8 changes: 4 additions & 4 deletions base/linalg/bunchkaufman.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
## LD for BunchKaufman, UL for CholeskyDense, LU for LUDense and
## define size methods for Factorization types using it.

type BunchKaufman{T<:BlasFloat} <: Factorization{T}
immutable BunchKaufman{T} <: Factorization{T}
LD::Matrix{T}
ipiv::Vector{BlasInt}
uplo::Char
Expand All @@ -18,10 +18,10 @@ function bkfact!{T<:BlasComplex}(A::StridedMatrix{T}, uplo::Symbol=:U, symmetric
LD, ipiv = (symmetric ? LAPACK.sytrf! : LAPACK.hetrf!)(string(uplo)[1] , A)
BunchKaufman(LD, ipiv, string(uplo)[1], symmetric)
end
bkfact!(A::StridedMatrix, args...) = bkfact!(float(A), args...)
bkfact{T<:BlasFloat}(A::StridedMatrix{T}, args...) = bkfact!(copy(A), args...)
bkfact(A::StridedMatrix, args...) = bkfact(float(A), args...)
bkfact{T<:BlasFloat}(A::StridedMatrix{T}, uplo::Symbol=:U, symmetric::Bool=issym(A)) = bkfact!(copy(A), uplo, symmetric)
bkfact{T}(A::StridedMatrix{T}, uplo::Symbol=:U, symmetric::Bool=issym(A)) = bkfact!(convert(Matrix{promote_type(Float32,typeof(sqrt(one(T))))},A),uplo,symmetric)

convert{T}(::Type{BunchKaufman{T}},B::BunchKaufman) = BunchKaufman(convert(Matrix{T},B.LD),B.ipiv,B.uplo,B.symmetric)
size(B::BunchKaufman) = size(B.LD)
size(B::BunchKaufman,d::Integer) = size(B.LD,d)
issym(B::BunchKaufman) = B.symmetric
Expand Down
81 changes: 38 additions & 43 deletions base/linalg/dense.jl
Original file line number Diff line number Diff line change
Expand Up @@ -287,29 +287,21 @@ function rcswap!{T<:Number}(i::Integer, j::Integer, X::StridedMatrix{T})
end
end

function sqrtm{T<:Real}(A::StridedMatrix{T}, cond::Bool)
issym(A) && return sqrtm(Symmetric(A), cond)

function sqrtm{T<:Real}(A::StridedMatrix{T})
issym(A) && return sqrtm(Symmetric(A))
n = chksquare(A)
SchurF = schurfact!(complex(A))
SchurF = schurfact(complex(A))
R = full(sqrtm(Triangular(SchurF[:T])))
retmat = SchurF[:vectors]*R*SchurF[:vectors]'
retmat2= all(imag(retmat) .== 0) ? real(retmat) : retmat
cond ? (retmat2, norm(R)^2/norm(SchurF[:T])) : retmat2
all(imag(retmat) .== 0) ? real(retmat) : retmat
end
function sqrtm{T<:Complex}(A::StridedMatrix{T}, cond::Bool)
ishermitian(A) && return sqrtm(Hermitian(A), cond)

function sqrtm{T<:Complex}(A::StridedMatrix{T})
ishermitian(A) && return sqrtm(Hermitian(A))
n = chksquare(A)
SchurF = schurfact(A)
R = full(sqrtm(Triangular(SchurF[:T])))
retmat = SchurF[:vectors]*R*SchurF[:vectors]'
cond ? (retmat, norm(R)^2/norm(SchurF[:T])) : retmat
SchurF[:vectors]*R*SchurF[:vectors]'
end

sqrtm{T<:Integer}(A::StridedMatrix{T}, cond::Bool) = sqrtm(float(A), cond)
sqrtm{T<:Integer}(A::StridedMatrix{Complex{T}}, cond::Bool) = sqrtm(complex128(A), cond)
sqrtm(A::StridedMatrix) = sqrtm(A, false)
sqrtm(a::Number) = (b = sqrt(complex(a)); imag(b) == 0 ? real(b) : b)
sqrtm(a::Complex) = sqrt(a)

Expand All @@ -327,7 +319,7 @@ function inv(A::Matrix)
return inv(lufact(A))
end

function factorize!{T}(A::Matrix{T})
function factorize{T}(A::Matrix{T})
m, n = size(A)
if m == n
if m == 1 return A[1] end
Expand Down Expand Up @@ -377,9 +369,9 @@ function factorize!{T}(A::Matrix{T})
end
if utri1
if (herm & (T <: Complex)) | sym
return ldltd!(SymTridiagonal(diag(A), diag(A, -1)))
return ldltd(SymTridiagonal(diag(A), diag(A, -1)))
end
return lufact!(Tridiagonal(diag(A, -1), diag(A), diag(A, 1)))
return lufact(Tridiagonal(diag(A, -1), diag(A), diag(A, 1)))
end
end
if utri
Expand All @@ -388,32 +380,36 @@ function factorize!{T}(A::Matrix{T})
if herm
if T <: BlasFloat
C, info = LAPACK.potrf!('U', copy(A))
elseif typeof(one(T)/one(T)) <: BlasFloat
C, info = LAPACK.potrf!('U', float(A))
else
error("Unable to factorize hermitian $(typeof(A)). Try converting to other element type or use explicit factorization.")
else
S = typeof(one(T)/one(T))
if S <: BlasFloat
C, info = LAPACK.potrf!('U', convert(Matrix{S}, A))
else
C, info = S <: Real ? LAPACK.potrf!('U', complex128(A)) : LAPACK.potrf!('U', complex128(A))
end
end
if info == 0 return Cholesky(C, 'U') end
return factorize!(Hermitian(A))
return factorize(Hermitian(A))
end
if sym
if T <: BlasFloat
C, info = LAPACK.potrf!('U', copy(A))
elseif eltype(one(T)/one(T)) <: BlasFloat
C, info = LAPACK.potrf!('U', float(A))
else
error("Unable to factorize symmetric $(typeof(A)). Try converting to other element type or use explicit factorization.")
S = eltype(one(T)/one(T))
if S <: BlasFloat
C, info = LAPACK.potrf!('U', convert(Matrix{S},A))
else
C, info = S <: Real ? LAPACK.potrf!('U', float64(A)) : LAPACK.potrf!('U', complex(A))
end
end
if info == 0 return Cholesky(C, 'U') end
return factorize!(Symmetric(A))
return factorize(Symmetric(A))
end
return lufact!(A)
return lufact(A)
end
return qrfact!(A,pivot=true)
qrfact(A,pivot=T<:BlasFloat)
end

factorize(A::AbstractMatrix) = factorize!(copy(A))

(\)(a::Vector, B::StridedVecOrMat) = (\)(reshape(a, length(a), 1), B)
function (\)(A::StridedMatrix, B::StridedVecOrMat)
m, n = size(A)
Expand All @@ -424,32 +420,31 @@ function (\)(A::StridedMatrix, B::StridedVecOrMat)
istriu(A) && return \(Triangular(A, :U),B)
return \(lufact(A),B)
end
return qrfact(A,pivot=true)\B
return qrfact(A,pivot=eltype(A)<:BlasFloat)\B
end

## Moore-Penrose inverse
function pinv{T<:BlasFloat}(A::StridedMatrix{T})
m, n = size(A)
(m == 0 || n == 0) && return Array(T, n, m)
SVD = svdfact(A, true)
Sinv = zeros(T, length(SVD[:S]))
index = SVD[:S] .> eps(real(one(T)))*max(m,n)*maximum(SVD[:S])
Sinv[index] = 1.0 ./ SVD[:S][index]
function pinv{T}(A::StridedMatrix{T})
SVD = svdfact(A, thin=true)
S = eltype(SVD[:S])
m, n = size(A)
(m == 0 || n == 0) && return Array(S, n, m)
Sinv = zeros(S, length(SVD[:S]))
index = SVD[:S] .> eps(real(float(one(T))))*max(m,n)*maximum(SVD[:S])
Sinv[index] = one(S) ./ SVD[:S][index]
return SVD[:Vt]'scale(Sinv, SVD[:U]')
end
pinv{T<:Integer}(A::StridedMatrix{T}) = pinv(float(A))
pinv(a::StridedVector) = pinv(reshape(a, length(a), 1))
pinv(x::Number) = one(x)/x

## Basis for null space
function null{T<:BlasFloat}(A::StridedMatrix{T})
function null{T}(A::StridedMatrix{T})
m, n = size(A)
(m == 0 || n == 0) && return eye(T, n)
SVD = svdfact(A, false)
SVD = svdfact(A, thin=false)
indstart = sum(SVD[:S] .> max(m,n)*maximum(SVD[:S])*eps(eltype(SVD[:S]))) + 1
return SVD[:V][:,indstart:end]
end
null{T<:Integer}(A::StridedMatrix{T}) = null(float(A))
null(a::StridedVector) = null(reshape(a, length(a), 1))

function cond(A::StridedMatrix, p::Real=2)
Expand Down
Loading

0 comments on commit 8a94301

Please sign in to comment.