Skip to content

Commit 9b21691

Browse files
Fix eltype determination in det (#44582)
Co-authored-by: Andreas Noack <[email protected]>
1 parent 5dc6155 commit 9b21691

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

stdlib/LinearAlgebra/src/generic.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,9 +1539,9 @@ julia> det(M)
15391539
2.0
15401540
```
15411541
"""
1542-
function det(A::AbstractMatrix{T}) where T
1542+
function det(A::AbstractMatrix{T}) where {T}
15431543
if istriu(A) || istril(A)
1544-
S = typeof((one(T)*zero(T) + zero(T))/one(T))
1544+
S = promote_type(T, typeof((one(T)*zero(T) + zero(T))/one(T)))
15451545
return convert(S, det(UpperTriangular(A)))
15461546
end
15471547
return det(lu(A; check = false))

stdlib/LinearAlgebra/test/generic.jl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,35 @@ n = 5 # should be odd
7676
@test logabsdet(x)[1] logabsdet(X)[1]
7777
@test logabsdet(x)[2] logabsdet(X)[2]
7878
end
79+
80+
@testset "det with nonstandard Number type" begin
81+
struct MyDual{T<:Real} <: Real
82+
val::T
83+
eps::T
84+
end
85+
Base.:+(x::MyDual, y::MyDual) = MyDual(x.val + y.val, x.eps + y.eps)
86+
Base.:*(x::MyDual, y::MyDual) = MyDual(x.val * y.val, x.eps * y.val + y.eps * x.val)
87+
Base.:/(x::MyDual, y::MyDual) = x.val / y.val
88+
Base.:(==)(x::MyDual, y::MyDual) = x.val == y.val && x.eps == y.eps
89+
Base.zero(::MyDual{T}) where {T} = MyDual(zero(T), zero(T))
90+
Base.zero(::Type{MyDual{T}}) where {T} = MyDual(zero(T), zero(T))
91+
Base.one(::MyDual{T}) where {T} = MyDual(one(T), zero(T))
92+
Base.one(::Type{MyDual{T}}) where {T} = MyDual(one(T), zero(T))
93+
# the following line is required for BigFloat, IDK why it doesn't work via
94+
# promote_rule like for all other types
95+
Base.promote_type(::Type{MyDual{BigFloat}}, ::Type{BigFloat}) = MyDual{BigFloat}
96+
Base.promote_rule(::Type{MyDual{T}}, ::Type{S}) where {T,S<:Real} =
97+
MyDual{promote_type(T, S)}
98+
Base.promote_rule(::Type{MyDual{T}}, ::Type{MyDual{S}}) where {T,S} =
99+
MyDual{promote_type(T, S)}
100+
Base.convert(::Type{MyDual{T}}, x::MyDual) where {T} =
101+
MyDual(convert(T, x.val), convert(T, x.eps))
102+
if elty <: Real
103+
@show elty
104+
@show istriu(triu(MyDual.(A, zero(A))))
105+
@test det(triu(MyDual.(A, zero(A)))) isa MyDual
106+
end
107+
end
79108
end
80109

81110
@testset "diag" begin

0 commit comments

Comments
 (0)