Skip to content

Commit 2b9c38f

Browse files
mschauerandyferris
authored andcommitted
Add logdet (#245)
1 parent eb408b9 commit 2b9c38f

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/det.jl

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@inline det(A::StaticMatrix) = _det(Size(A), A)
2+
@inline logdet(A::StaticMatrix) = _logdet(Size(A), A)
23

34
@inline _det(::Size{(1,1)}, A::StaticMatrix) = @inbounds return A[1]
45

@@ -24,18 +25,25 @@ end
2425
return vecdot(x0, cross(x1, x2))
2526
end
2627

27-
@generated function _det{S}(::Size{S}, A::StaticMatrix)
28-
if S[1] != S[2]
29-
throw(DimensionMismatch("matrix is not square"))
30-
end
31-
return quote # Implementation from Base
32-
@_inline_meta
33-
T = eltype(A)
34-
T2 = typeof((one(T)*zero(T) + zero(T))/one(T))
35-
if istriu(A) || istril(A)
36-
return convert(T2, det(UpperTriangular(A))) # Is this a Julia bug that a convert is not type stable??
28+
@inline _logdet(S::Union{Size{(1,1)},Size{(2,2)},Size{(3,3)}}, A::StaticMatrix) = log(_det(S, A))
29+
30+
for (symb, f) in [(:_det, :det), (:_logdet, :logdet)]
31+
eval(quote
32+
@generated function $symb{S}(::Size{S}, A::StaticMatrix)
33+
if S[1] != S[2]
34+
throw(DimensionMismatch("matrix is not square"))
35+
end
36+
return quote # Implementation from Base
37+
@_inline_meta
38+
T = eltype(A)
39+
T2 = typeof((one(T)*zero(T) + zero(T))/one(T))
40+
if istriu(A) || istril(A)
41+
return convert(T2, $($f)(UpperTriangular(A))) # Is this a Julia bug that a convert is not type stable??
42+
end
43+
AA = convert(Array{T2}, A)
44+
return $($f)(lufact(AA))
45+
end
3746
end
38-
AA = convert(Array{T2}, A)
39-
return det(lufact(AA))
40-
end
47+
end)
4148
end
49+

test/det.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
@testset "Determinant" begin
22
@test det(@SMatrix [1]) === 1
3+
@test logdet(@SMatrix [1]) === 0.0
34
@test det(@SMatrix [0 1; 1 0]) === -1
5+
@test logdet(@SMatrix Complex{Float64}[0 1; 1 0]) == log(det(@SMatrix Complex{Float64}[0 1; 1 0]))
6+
47
@test det(@SMatrix [0 1 0; 1 0 0; 0 0 1]) === -1
58
m = randn(Float64, 4,4)
69
@test det(SMatrix{4,4}(m)) det(m)
710
#triu/tril
811
@test det(@SMatrix [1 2; 0 3]) === 3
912
@test det(@SMatrix [1 2 3 4; 0 5 6 7; 0 0 8 9; 0 0 0 10]) === 400.0
13+
@test logdet(@SMatrix [1 2 3 4; 0 5 6 7; 0 0 8 9; 0 0 0 10]) log(400.0)
1014
@test @inferred(det(ones(SMatrix{10,10,Complex{Float64}}))) == 0
1115

1216
# Unsigned specializations

0 commit comments

Comments
 (0)