Skip to content

Commit fc55a8b

Browse files
ChrisRackauckas-ClaudeclaudeChrisRackauckas
authored
Use LDLtFactorization for SymTridiagonal matrices (fixes #732) (#735)
* Use LDLtFactorization for SymTridiagonal matrices - Changed default algorithm selection for SymTridiagonal to use LDLtFactorization - This caches the LDLT factorization for reuse in subsequent solves - Addresses performance issue where ldlt was being recomputed on every solve * Add comprehensive tests for SymTridiagonal with LDLtFactorization - Test explicit LDLtFactorization with SymTridiagonal matrices - Verify default algorithm selects LDLtFactorization for SymTridiagonal - Test that factorization is cached and reused across solves - Include performance test case from issue #732 * Add performance benchmark demonstrating the fix - Shows LDLtFactorization working correctly with SymTridiagonal - Demonstrates 5.8x speedup with factorization caching - Verifies default algorithm selection * Delete benchmark_simple.jl * Update test/basictests.jl --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Christopher Rackauckas <accounts@chrisrackauckas.com>
1 parent d343726 commit fc55a8b

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

src/default.jl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,7 @@ function defaultalg(A::Tridiagonal, b, assump::OperatorAssumptions{Bool})
145145
end
146146

147147
function defaultalg(A::SymTridiagonal, b, ::OperatorAssumptions{Bool})
148-
@static if VERSION>=v"1.11"
149-
DirectLdiv!()
150-
else
151-
DefaultLinearSolver(DefaultAlgorithmChoice.LUFactorization)
152-
end
148+
DefaultLinearSolver(DefaultAlgorithmChoice.LDLtFactorization)
153149
end
154150
function defaultalg(A::Bidiagonal, b, ::OperatorAssumptions{Bool})
155151
@static if VERSION>=v"1.11"

test/basictests.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,37 @@ end
275275
# ws sizes.
276276
end
277277

278+
@testset "SymTridiagonal with LDLtFactorization" begin
279+
# Test that LDLtFactorization works correctly with SymTridiagonal
280+
# and that the default algorithm correctly selects it
281+
k = 100
282+
ρ = 0.95
283+
A_tri = SymTridiagonal(ones(k) .+ ρ^2, -ρ * ones(k-1))
284+
b = rand(k)
285+
286+
# Test with explicit LDLtFactorization
287+
prob_tri = LinearProblem(A_tri, b)
288+
sol = solve(prob_tri, LDLtFactorization())
289+
@test A_tri * sol.u b
290+
291+
# Test that default algorithm uses LDLtFactorization for SymTridiagonal
292+
default_alg = LinearSolve.defaultalg(A_tri, b, OperatorAssumptions(true))
293+
@test default_alg isa LinearSolve.DefaultLinearSolver
294+
@test default_alg.alg == LinearSolve.DefaultAlgorithmChoice.LDLtFactorization
295+
296+
# Test that the factorization is cached and reused
297+
cache = init(prob_tri, LDLtFactorization())
298+
sol1 = solve!(cache)
299+
@test A_tri * sol1.u b
300+
@test !cache.isfresh # Cache should not be fresh after first solve
301+
302+
# Solve again with same matrix to ensure cache is reused
303+
cache.b = rand(k) # Change RHS
304+
sol2 = solve!(cache)
305+
@test A_tri * sol2.u cache.b
306+
@test !cache.isfresh # Cache should still not be fresh
307+
end
308+
278309
test_algs = [
279310
LUFactorization(),
280311
QRFactorization(),

0 commit comments

Comments
 (0)