-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
RFC:QR decomposition in julia #5526
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -607,7 +607,6 @@ export | |
eigvecs, | ||
expm, | ||
eye, | ||
factorize!, | ||
factorize, | ||
givens, | ||
hessfact!, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,7 +66,6 @@ export | |
sqrtm, | ||
eye, | ||
factorize, | ||
factorize!, | ||
givens, | ||
gradient, | ||
hessfact, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was initially ambivalent about making all the special matrices and factorizations immutable, but I'm increasingly convinced that this is the right thing to do. |
||
LD::Matrix{T} | ||
ipiv::Vector{BlasInt} | ||
uplo::Char | ||
|
@@ -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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
|
||
|
@@ -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}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I die a little every time I have to read this polyalgorithm. "A convenient factorization" belies a monstrous Kaonashi. |
||
m, n = size(A) | ||
if m == n | ||
if m == 1 return A[1] end | ||
|
@@ -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 | ||
|
@@ -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) | ||
|
@@ -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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good riddance.