Skip to content

Commit e7da27f

Browse files
committed
Use pivoting as the default in LU regardless of the element type.
For types that weren't subtypes of AbstractFloat, we used to try to LU factorize without pivoting and only use pivoting when it failed. This caused large numerical errors when computing the LU for element types which promoted to float like numbers such as most integers. The behavior was never documented and is error prone. Hence, this PR removes the behavior.
1 parent 64be75f commit e7da27f

File tree

2 files changed

+14
-28
lines changed

2 files changed

+14
-28
lines changed

stdlib/LinearAlgebra/src/lu.jl

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,6 @@ function generic_lufact!(A::StridedMatrix{T}, ::Val{Pivot} = Val(true);
179179
return LU{T,typeof(A)}(A, ipiv, convert(BlasInt, info))
180180
end
181181

182-
# floating point types doesn't have to be promoted for LU, but should default to pivoting
183-
function lu(A::Union{AbstractMatrix{T}, AbstractMatrix{Complex{T}}},
184-
pivot::Union{Val{false}, Val{true}} = Val(true);
185-
check::Bool = true) where {T<:AbstractFloat}
186-
lu!(copy(A), pivot; check = check)
187-
end
188-
189182
function lutype(T::Type)
190183
# In generic_lufact!, the elements of the lower part of the matrix are
191184
# obtained using the division of two matrix elements. Hence their type can
@@ -274,26 +267,10 @@ julia> l == F.L && u == F.U && p == F.p
274267
true
275268
```
276269
"""
277-
function lu(A::AbstractMatrix{T}, pivot::Union{Val{false}, Val{true}};
270+
function lu(A::AbstractMatrix{T}, pivot::Union{Val{false}, Val{true}}=Val(true);
278271
check::Bool = true) where T
279272
S = lutype(T)
280-
AA = similar(A, S)
281-
copyto!(AA, A)
282-
lu!(AA, pivot; check = check)
283-
end
284-
# We can't assume an ordered field so we first try without pivoting
285-
function lu(A::AbstractMatrix{T}; check::Bool = true) where T
286-
S = lutype(T)
287-
AA = similar(A, S)
288-
copyto!(AA, A)
289-
F = lu!(AA, Val(false); check = false)
290-
if issuccess(F)
291-
return F
292-
else
293-
AA = similar(A, S)
294-
copyto!(AA, A)
295-
return lu!(AA, Val(true); check = check)
296-
end
273+
lu!(copy_oftype(A, S), pivot; check = check)
297274
end
298275

299276
lu(S::LU) = S

stdlib/LinearAlgebra/test/lu.jl

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,19 @@ include("trickyarithmetic.jl")
301301
@testset "lu with type whose sum is another type" begin
302302
A = TrickyArithmetic.A[1 2; 3 4]
303303
ElT = TrickyArithmetic.D{TrickyArithmetic.C,TrickyArithmetic.C}
304-
B = lu(A)
304+
B = lu(A, Val(false))
305305
@test B isa LinearAlgebra.LU{ElT,Matrix{ElT}}
306-
C = lu(A, Val(false))
307-
@test C isa LinearAlgebra.LU{ElT,Matrix{ElT}}
306+
end
307+
308+
@testset "Issue #30917. Determinant of integer matrix" begin
309+
@test det([1 1 0 0 1 0 0 0
310+
1 0 1 0 0 1 0 0
311+
1 0 0 1 0 0 1 0
312+
0 1 1 1 0 0 0 0
313+
0 1 0 0 0 0 1 1
314+
0 0 1 0 1 0 0 1
315+
0 0 0 1 1 1 0 0
316+
0 0 0 0 1 1 0 1]) 6
308317
end
309318

310319
end # module TestLU

0 commit comments

Comments
 (0)