Это может быть вопрос новичка, который я задаю. Я довольно новичок в Юлии. Я решаю обобщенную проблему собственных значений в Julia, используя решатель LOBPCG из пакета IterativeSolvers.jl для лапласовых матриц размером от 40Kx40K до 500Kx500K. Пакет предоставляет способ добавить прекондиционер, и в документации упоминается, что 'P' прекондиционер должен перегружать ldiv! функция. Предусловие, которое я выбрал для этой проблемы, взято из пакета Laplacians.jl доктора Даниеля Спилмана. Я намерен использовать Laplacians.KMPLapSolver, основанный на статье Koutis et al. "Подход к оптимальности для решения систем SDD", в качестве предварительного условия. KMPLapSolver возвращает функцию, которую необходимо перевести в формат, совместимый с LOBPCG.
Может ли кто-нибудь дать некоторые рекомендации относительно того, как использовать прекондиционер, отличный от ldiv! для LOBPCG?
Random.seed!(1)
n = 1000
a = wtedChimera(n, 1) #Adjacency Matrix
la = lap(a) #Laplacian Matrix
sddm = copy(la)
sddm = sddm + spdiagm(0=>rand(n)/n) #SDDM Matrix
largest = false
nev = 1
# Without Preconditioner
lobpcg(sddm, largest, nev) #works
# With Preconditioner from Laplacians.jl
lapSolver = KMPLapSolver(a)
lobpcg(sddm, P=lapSolver, largest, nev) #Does not work
Error Thrown:
ERROR: MethodError: no method matching ldiv!(::SubArray{Float64,2,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},UnitRange{Int64}},true}, ::getfield(Laplacians, Symbol("##200#202")){Float64,Int64,Float64,Bool,Array{Int64,1},getfield(Laplacians, Symbol("###200#201#203")){Int64,Array{Int64,1},SparseMatrixCSC{Float64,Int64},getfield(Laplacians, Symbol("##133#135")){Float64,Float64,Float64,Bool,Array{Int64,1},getfield(Laplacians, Symbol("###133#134#136")){Array{Int64,1},getfield(Laplacians, Symbol("##121#123")){getfield(Laplacians, Symbol("###121#122#124")){Array{Int64,1},Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}},SuiteSparse.CHOLMOD.Factor{Float64}}}}}}}, ::SubArray{Float64,2,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},UnitRange{Int64}},true})
Чтобы продолжить эксперимент, я попытался использовать ldiv! в качестве предварительного условия для LOBPCG. Я пробую следующее:
b = randn(n)
b = b .- mean(b)
Y = zeros(n)
P = ldiv!(Y, qr(sddm), b) #Does not work
Error Thrown:
ERROR: MethodError: no method matching ldiv!(::SuiteSparse.SPQR.QRSparse{Float64,Int64}, ::Array{Float64,1})
Можно ли как-нибудь использовать предварительные кондиционеры из пакета Лапласа в LOBPCG? Кроме того, кажется, ldiv! не поддерживает формат SuiteSparse. Есть ли эффективный обходной путь для этого?