@@ -6,7 +6,7 @@ export UmfpackLU
66
77import Base: (\ ), getproperty, show, size
88using LinearAlgebra
9- import LinearAlgebra: Factorization, det, lu, lu!, ldiv!
9+ import LinearAlgebra: Factorization, checksquare, det, logabsdet , lu, lu!, ldiv!
1010
1111using SparseArrays
1212using SparseArrays: getcolptr
@@ -279,6 +279,26 @@ function deserialize(s::AbstractSerializer, t::Type{UmfpackLU{Tv,Ti}}) where {Tv
279279 return obj
280280end
281281
282+ # compute the sign/parity of a permutation
283+ function _signperm (p)
284+ n = length (p)
285+ result = 0
286+ todo = trues (n)
287+ while any (todo)
288+ k = findfirst (todo)
289+ todo[k] = false
290+ result += 1 # increment element count
291+ j = p[k]
292+ while j != k
293+ result += 1 # increment element count
294+ todo[j] = false
295+ j = p[j]
296+ end
297+ result += 1 # increment cycle count
298+ end
299+ return ifelse (isodd (result), - 1 , 1 )
300+ end
301+
282302# # Wrappers for UMFPACK functions
283303
284304# generate the name of the C function according to the value and integer types
@@ -406,6 +426,23 @@ for itype in UmfpackIndexTypes
406426 mx, mz, C_NULL , lu. numeric, umf_info)
407427 complex (mx[], mz[])
408428 end
429+ function logabsdet (F:: UmfpackLU{T, $itype} ) where {T<: Union{Float64,ComplexF64} } # return log(abs(det)) and sign(det)
430+ n = checksquare (F)
431+ issuccess (F) || return log (zero (real (T))), zero (T)
432+ U = F. U
433+ Rs = F. Rs
434+ p = F. p
435+ q = F. q
436+ s = _signperm (p)* _signperm (q)* one (real (T))
437+ P = one (T)
438+ abs_det = zero (real (T))
439+ @inbounds for i in 1 : n
440+ dg_ii = U[i, i] / Rs[i]
441+ P *= sign (dg_ii)
442+ abs_det += log (abs (dg_ii))
443+ end
444+ return abs_det, s * P
445+ end
409446 function umf_lunz (lu:: UmfpackLU{Float64,$itype} )
410447 lnz = Ref {$itype} ()
411448 unz = Ref {$itype} ()
0 commit comments