From 3e61526211524542584022aa9712851e28c657d0 Mon Sep 17 00:00:00 2001 From: Mohamed Tarek Date: Sat, 2 Sep 2023 06:44:43 +1000 Subject: [PATCH] fix AMG with matrix input (#41) * fix AMG with matrix input * bump version --- Project.toml | 2 +- src/amg.jl | 10 ++++++++-- test/runtests.jl | 18 ++++++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index bd07d64..84be81c 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "Preconditioners" uuid = "af69fa37-3177-5a40-98ee-561f696e4fcd" -version = "0.6" +version = "0.6.1" [deps] AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c" diff --git a/src/amg.jl b/src/amg.jl index 37fac7f..7d73792 100644 --- a/src/amg.jl +++ b/src/amg.jl @@ -25,13 +25,19 @@ AMGPreconditioner(A::AbstractMatrix; kwargs...) = AMGPreconditioner(RugeStuben, AMGPreconditioner{T}(A::AbstractMatrix; kwargs...) where T = AMGPreconditioner(T, A; kwargs...) @inline function \(p::AMGPreconditioner, b) - x = copy(b); + x = copy(b) return ldiv!(x, AMG.Preconditioner(p.ml, p.cycle), b) end @inline *(p::AMGPreconditioner, b) = AMG.Preconditioner(p.ml, p.cycle) * b @inline ldiv!(p::AMGPreconditioner, b) = b .= p \ b -@inline function ldiv!(x, p::AMGPreconditioner, b) +@inline function ldiv!(x::AbstractVector, p::AMGPreconditioner, b::AbstractVector) x .= b return ldiv!(x, AMG.Preconditioner(p.ml, p.cycle), b) end +@inline function ldiv!(x::AbstractMatrix, p::AMGPreconditioner, b::AbstractMatrix) + foreach(zip(eachcol(x), eachcol(b))) do (_x, _b) + ldiv!(_x, p, _b) + end + return x +end @inline mul!(b, p::AMGPreconditioner, x) = mul!(b, AMG.Preconditioner(p.ml, p.cycle), x) diff --git a/test/runtests.jl b/test/runtests.jl index 8d328ef..aa83c5a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,9 +1,9 @@ -using LinearAlgebra: I, diag, ldiv!, norm, Symmetric, Hermitian +using LinearAlgebra: I, diag, ldiv!, norm, Symmetric, Hermitian, eigen using SparseArrays: sprand using Preconditioners: CholeskyPreconditioner, DiagonalPreconditioner using Preconditioners: RugeStuben, SmoothedAggregation using Preconditioners: UpdatePreconditioner!, AMGPreconditioner -using IterativeSolvers: cg +using IterativeSolvers: cg, lobpcg using Random: seed! using Test: @test, @testset, @test_throws using OffsetArrays: OffsetMatrix, OffsetVector @@ -68,3 +68,17 @@ end test_matrix(Symmetric(A), F, atol) test_matrix(Hermitian(A), F, atol) end + +@testset "AMG + LOBPCG" begin + A = sprand(1000, 1000, 0.01) + A = A + A' + 30I + X0 = randn(1000,1) + tol = 1e-3 + F = lobpcg(A, false, X0, tol=tol, maxiter=200, P=AMGPreconditioner{SmoothedAggregation}(A)) + @test eigen(Matrix(A)).values[1] ≈ F.λ[1] atol = 1e-3 + + X0 = randn(1000,2) + tol = 1e-3 + F = lobpcg(A, false, X0, tol=tol, maxiter=200, P=AMGPreconditioner{SmoothedAggregation}(A)) + @test eigen(Matrix(A)).values[1:2] ≈ F.λ atol = 1e-3 +end