Skip to content

Commit

Permalink
naive implementation of modified/relaxed factorization
Browse files Browse the repository at this point in the history
  • Loading branch information
t-bltg committed Dec 13, 2021
1 parent 370f0bc commit 6aec246
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
30 changes: 25 additions & 5 deletions src/LimitedLDLFactorizations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Compute the limited-memory LDLᵀ factorization of A without pivoting.
gradually increased from this initial value until success.
- `droptol::Tv=Tv(0)`: to further sparsify `L`, all elements with magnitude smaller
than `droptol` are dropped.
- `β::Number=0`: Standard (0), Relaxed (0 < β < 1) or Modified (1) factorization.
- `row_relax::Bool=true`: row / col relaxation switch.
"""
function lldl(A::SparseMatrixCSC{Tv, Ti}; kwargs...) where {Tv <: Number, Ti <: Integer}
lldl(tril(A, -1), diag(A), amd(A); kwargs...)
Expand Down Expand Up @@ -84,11 +86,14 @@ function lldl(
memory::Int = 0,
α::Tv = Tv(0),
droptol::Tv = Tv(0),
β::Number = 0,
row_relax::Bool = true,
) where {Tv <: Number, Ti <: Integer}
memory < 0 && error("limited-memory parameter must be nonnegative")
n = size(T, 1)
n != size(T, 2) && error("input matrix must be square")
n != length(adiag) && error("inconsistent size of diagonal")
0 <= β <= 1 || error("invalid relaxation factor β=")

nnzT = nnz(T)
np = n * memory
Expand Down Expand Up @@ -202,11 +207,14 @@ function lldl(
rowind,
colptr,
w,
wa1, # scratch
indr,
indf,
list,
list;
memory = Ti(memory),
droptol = droptol,
β = Tv(β),
row_relax = row_relax,
)

# Increase shift if the factorization didn't succeed.
Expand Down Expand Up @@ -237,11 +245,14 @@ function attempt_lldl!(
rowind::Vector{Ti},
colptr::Vector{Ti},
w::Vector{Tv},
wa1::Vector{Tv},
indr::Vector{Ti},
indf::Vector{Ti},
list::Vector{Ti};
memory::Ti = 0,
droptol::Tv = Tv(0),
β::Tv = Tv(0),
row_relax::Bool = true,
) where {Ti <: Integer, Tv <: Number}
n = size(d, 1)
np = n * memory
Expand Down Expand Up @@ -342,6 +353,7 @@ function attempt_lldl!(
new_col_start = colptr[col]
new_col_end = new_col_start + nz_to_keep - one(Ti)
l = new_col_start
fill!(wa1, 0)
@inbounds @simd for k = new_col_start:new_col_end
k1 = indr[kth + k - new_col_start]
val = w[k1]
Expand All @@ -350,15 +362,23 @@ function attempt_lldl!(
lvals[l] = val
rowind[l] = k1
l += one(Ti)
elseif β > 0
wa1[row_relax ? k1 : k] += val
end
end
new_col_end = l - one(Ti)

# Variant II of diagonal elements update.
@inbounds @simd for k = kth:nzcol
k1 = indr[k]
wk1 = w[k1]
d[k1] -= dcol * wk1 * wk1
if β > 0
@inbounds @simd for k = kth:nzcol
k1 = indr[k]
d[k1] -= dcol * w[k1]^2 + β * wa1[row_relax ? k1 : k]
end
else
@inbounds @simd for k = kth:nzcol
k1 = indr[k]
d[k1] -= dcol * w[k1]^2
end
end

if new_col_start < new_col_end
Expand Down
36 changes: 19 additions & 17 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,25 @@ using AMD, Metis, LimitedLDLFactorizations
@test nnzl5 nnzl0
@test LLDL.α == 0

LLDL = lldl(A, perm, memory = 10)
@test nnz(LLDL) nnzl5
@test LLDL.α == 0
L = LLDL.L + I
@test norm(L * diagm(0 => LLDL.D) * L' - A[perm, perm]) sqrt(eps()) * norm(A)

sol = ones(A.n)
b = A * sol
x = LLDL \ b
@test x sol

y = similar(b)
ldiv!(y, LLDL, b)
@test y sol

ldiv!(LLDL, b)
@test b sol
for β (0., .5, 1.)
LLDL = lldl(A, perm, memory = 10, β = β)
@test nnz(LLDL) nnzl5
@test LLDL.α == 0
L = LLDL.L + I
@test norm(L * diagm(0 => LLDL.D) * L' - A[perm, perm]) sqrt(eps()) * norm(A)

sol = ones(A.n)
b = A * sol
x = LLDL \ b
@test x sol

y = similar(b)
ldiv!(y, LLDL, b)
@test y sol

ldiv!(LLDL, b)
@test b sol
end
end
end

Expand Down

0 comments on commit 6aec246

Please sign in to comment.