Skip to content

Commit

Permalink
Fix eltype determination in det (#44582)
Browse files Browse the repository at this point in the history
Co-authored-by: Andreas Noack <[email protected]>
  • Loading branch information
dkarrasch and andreasnoack committed Mar 26, 2022
1 parent 5dc6155 commit 9b21691
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
4 changes: 2 additions & 2 deletions stdlib/LinearAlgebra/src/generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1539,9 +1539,9 @@ julia> det(M)
2.0
```
"""
function det(A::AbstractMatrix{T}) where T
function det(A::AbstractMatrix{T}) where {T}
if istriu(A) || istril(A)
S = typeof((one(T)*zero(T) + zero(T))/one(T))
S = promote_type(T, typeof((one(T)*zero(T) + zero(T))/one(T)))
return convert(S, det(UpperTriangular(A)))
end
return det(lu(A; check = false))
Expand Down
29 changes: 29 additions & 0 deletions stdlib/LinearAlgebra/test/generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,35 @@ n = 5 # should be odd
@test logabsdet(x)[1] logabsdet(X)[1]
@test logabsdet(x)[2] logabsdet(X)[2]
end

@testset "det with nonstandard Number type" begin
struct MyDual{T<:Real} <: Real
val::T
eps::T
end
Base.:+(x::MyDual, y::MyDual) = MyDual(x.val + y.val, x.eps + y.eps)
Base.:*(x::MyDual, y::MyDual) = MyDual(x.val * y.val, x.eps * y.val + y.eps * x.val)
Base.:/(x::MyDual, y::MyDual) = x.val / y.val
Base.:(==)(x::MyDual, y::MyDual) = x.val == y.val && x.eps == y.eps
Base.zero(::MyDual{T}) where {T} = MyDual(zero(T), zero(T))
Base.zero(::Type{MyDual{T}}) where {T} = MyDual(zero(T), zero(T))
Base.one(::MyDual{T}) where {T} = MyDual(one(T), zero(T))
Base.one(::Type{MyDual{T}}) where {T} = MyDual(one(T), zero(T))
# the following line is required for BigFloat, IDK why it doesn't work via
# promote_rule like for all other types
Base.promote_type(::Type{MyDual{BigFloat}}, ::Type{BigFloat}) = MyDual{BigFloat}
Base.promote_rule(::Type{MyDual{T}}, ::Type{S}) where {T,S<:Real} =
MyDual{promote_type(T, S)}
Base.promote_rule(::Type{MyDual{T}}, ::Type{MyDual{S}}) where {T,S} =
MyDual{promote_type(T, S)}
Base.convert(::Type{MyDual{T}}, x::MyDual) where {T} =
MyDual(convert(T, x.val), convert(T, x.eps))
if elty <: Real
@show elty
@show istriu(triu(MyDual.(A, zero(A))))

This comment has been minimized.

Copy link
@staticfloat

staticfloat Apr 4, 2022

Member

@dkarrasch I think these @show lines slipped through from debugging. Can you clean them up?

This comment has been minimized.

Copy link
@dkarrasch

dkarrasch Apr 5, 2022

Author Member

🤦 Of course, sorry for that!

@test det(triu(MyDual.(A, zero(A)))) isa MyDual
end
end
end

@testset "diag" begin
Expand Down

0 comments on commit 9b21691

Please sign in to comment.