Skip to content

Commit f9933b6

Browse files
committed
Merge pull request #13166 from JuliaLang/anj/symdet
Add det(Symmetric/Hermitian) based on bkfact.
2 parents ea9baec + 2312244 commit f9933b6

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

base/linalg/bunchkaufman.jl

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,31 @@ function A_ldiv_B!{T<:BlasComplex}(B::BunchKaufman{T}, R::StridedVecOrMat{T})
5050
(issym(B) ? LAPACK.sytrs! : LAPACK.hetrs!)(B.uplo, B.LD, B.ipiv, R)
5151
end
5252

53+
function det(F::BunchKaufman)
54+
M = F.LD
55+
p = F.ipiv
56+
n = size(F.LD, 1)
57+
58+
i = 1
59+
d = one(eltype(F))
60+
while i <= n
61+
if p[i] > 0
62+
# 1x1 pivot case
63+
d *= M[i,i]
64+
i += 1
65+
else
66+
# 2x2 pivot case. Make sure not to square before the subtraction by scaling with the off-diagonal element. This is safe because the off diagonal is always large for 2x2 pivots.
67+
if F.uplo == 'U'
68+
d *= M[i, i + 1]*(M[i,i]/M[i, i + 1]*M[i + 1, i + 1] - (issym(F) ? M[i, i + 1] : conj(M[i, i + 1])))
69+
else
70+
d *= M[i + 1,i]*(M[i, i]/M[i + 1, i]*M[i + 1, i + 1] - (issym(F) ? M[i + 1, i] : conj(M[i + 1, i])))
71+
end
72+
i += 2
73+
end
74+
end
75+
return d
76+
end
77+
5378
## reconstruct the original matrix
5479
## TODO: understand the procedure described at
5580
## http://www.nag.com/numeric/FL/nagdoc_fl22/pdf/F07/f07mdf.pdf

base/linalg/symmetric.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,16 @@ A_mul_B!{T<:BlasComplex,S<:StridedMatrix}(C::StridedMatrix{T}, A::StridedMatrix{
117117
*(A::HermOrSym, B::HermOrSym) = full(A)*full(B)
118118
*(A::StridedMatrix, B::HermOrSym) = A*full(B)
119119

120-
factorize(A::HermOrSym) = bkfact(A.data, symbol(A.uplo), issym(A))
120+
bkfact(A::HermOrSym) = bkfact(A.data, symbol(A.uplo), issym(A))
121+
factorize(A::HermOrSym) = bkfact(A)
122+
123+
# Is just RealHermSymComplexHerm, but type alias seems to be broken
124+
det{T<:Real,S}(A::Union{Hermitian{T,S}, Symmetric{T,S}, Hermitian{Complex{T},S}}) = real(det(bkfact(A)))
125+
det{T<:Real}(A::Symmetric{T}) = det(bkfact(A))
126+
det(A::Symmetric) = det(bkfact(A))
127+
121128
\{T,S<:StridedMatrix}(A::HermOrSym{T,S}, B::StridedVecOrMat) = \(bkfact(A.data, symbol(A.uplo), issym(A)), B)
129+
122130
inv{T<:BlasFloat,S<:StridedMatrix}(A::Hermitian{T,S}) = Hermitian{T,S}(inv(bkfact(A.data, symbol(A.uplo))), A.uplo)
123131
inv{T<:BlasFloat,S<:StridedMatrix}(A::Symmetric{T,S}) = Symmetric{T,S}(inv(bkfact(A.data, symbol(A.uplo), true)), A.uplo)
124132

test/linalg/symmetric.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ let n=10
101101
# cond
102102
@test cond(Hermitian(asym)) cond(asym)
103103

104+
# det
105+
@test det(asym) det(Hermitian(asym, :U))
106+
@test det(asym) det(Hermitian(asym, :L))
107+
if eltya <: Real
108+
@test det(asym) det(Symmetric(asym, :U))
109+
@test det(asym) det(Symmetric(asym, :L))
110+
end
111+
@test det(a + a.') det(Symmetric(a + a.', :U))
112+
@test det(a + a.') det(Symmetric(a + a.', :L))
113+
104114
# rank
105115
let A = a[:,1:5]*a[:,1:5]'
106116
@test rank(A) == rank(Hermitian(A))

0 commit comments

Comments
 (0)