Thanks for the responses,
@antoine-levitt I don’t think this is the case, otherwise my code would converge as fast as MATLAB did.
Thanks @amontoison, it is good to see a gmres solver that almost reproduces the results of MATLABS solver, having tried this it occasionally throws the following error.
ERROR: LoadError: BoundsError: attempt to access 1-element Array{Float64,1} at index [0]
Stacktrace:
[1] getindex at .\array.jl:729 [inlined]
[2] #gmres#15(::Array{Float64,1}, ::LinearOperators.opEye, ::LinearOperators.opEye, ::Float64, ::Float64, ::Int64, ::Bool, ::Bool, ::typeof(Krylov.gmres), ::LinearOperators.LinearOperator{Complex{Float64},getfield(Krylov, Symbol("##34#37")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}},getfield(Krylov, Symbol("##35#38")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}},getfield(Krylov, Symbol("##36#39")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}}}, ::Array{Float64,1}) at C:\Users\timmm\.julia\packages\Krylov\ybdMT\src\gmres.jl:139
[3] (::getfield(Krylov, Symbol("#kw##gmres")))(::NamedTuple{(:rtol, :x0, :itmax),Tuple{Float64,Array{Float64,1},Int64}}, ::typeof(Krylov.gmres), ::LinearOperators.LinearOperator{Complex{Float64},getfield(Krylov, Symbol("##34#37")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}},getfield(Krylov, Symbol("##35#38")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}},getfield(Krylov, Symbol("##36#39")){SparseArrays.SparseMatrixCSC{Float64,Int64},Array{Float64,1}}}, ::Array{Float64,1}) at .\none:0
[4] #gmres#50(::Base.Iterators.Pairs{Symbol,Any,Tuple{Symbol,Symbol,Symbol},NamedTuple{(:rtol, :x0, :itmax),Tuple{Float64,Array{Float64,1},Int64}}}, ::Function, ::SparseArrays.SparseMatrixCSC{Float64,Int64}, ::Array{Float64,1}) at C:\Users\timmm\.julia\packages\Krylov\ybdMT\src\variants.jl:15
[5] (::getfield(Krylov, Symbol("#kw##gmres")))(::NamedTuple{(:rtol, :x0, :itmax),Tuple{Float64,Array{Float64,1},Int64}}, ::typeof(Krylov.gmres), ::SparseArrays.SparseMatrixCSC{Float64,Int64}, ::Array{Float64,1}) at .\none:0
[6] fischer_newton(::Array{Float64,2}, ::Array{Float64,2}) at C:\Users\timmm\.julia\packages\FischerNewton\myRMj\src\fischer_newton.jl:190
I also tried your DQGMRES and this works well (without errors). I am using this for the moment.
@rveltz I have tried out the KrylovKit.GMRES also and it gives the same (at least to 8 significant figures) error compared to MATLAB on the matrix I was using as Alexis showed for the Krylov.gmres implementation. This also works well.
Testscript comparing KrylovKit
and Krylov
:
using FischerNewton
using IterativeSolvers
using KrylovKit
using Krylov
using LinearAlgebra
using SparseArrays
using Test
using Profile
using InteractiveUtils
G=pathof(FischerNewton);
G=splitdir(G); #remove file name
G=G[1];
G=splitdir(G); #out of src
G=G[1];
if Sys.iswindows()
G=string(G,"\\test\\Matricies.mat")
else
G=string(G,"/test/Matricies.mat")
end
println(G)
#Inputs - Loading influence matricies
using MAT
file = matopen(G)
A=read(file, "A")
b=read(file, "b")
#Reshape to N length array (not two dims)
b=reshape(b,length(b));
x0=zeros(length(b))
restart=10;
alg = GMRES( krylovdim = restart, maxiter = 10, tol = 1e-6)
@time x_itsolver1, stats1 = @inferred linsolve(A,b,x0,alg)
@info stats1
r1 = norm(b - A * x_itsolver1)/norm(b)
@info r1
x_itsolver2=copy(x0);
@time for i = 1 : restart
(x2,stats2) = Krylov.gmres(A, b, rtol=1e-6, x0=x0, itmax=10)
if i==restart
@info stats2
x_itsolver2.=x2;
end
end
r2 = norm(b - A * x_itsolver2)/norm(b)
@info r2
dqgmres_tol = 1.0e-6
@time (x_itsolver3,stats3) = Krylov.dqgmres(A, b,atol=dqgmres_tol,itmax=restart)
@info stats3
r3 = norm(b - A * x_itsolver3)/norm(b)
@info r3
x_matlab=
[43189395.5369333;
65338300.3629727;
52631061.5842138;
54775644.5591780;
36174129.5940650;
32348224.0211539;
39287541.3646495;
54096387.5483277;
78831593.1510365;
70208640.7061015]
println("KrylovKit.GMRES")
for i = 1:10
println(x_itsolver1[i] / x_matlab[i] * 100)
end
println("Krylov.gmres")
for i = 1:10
println(x_itsolver2[i] / x_matlab[i] * 100)
end
println("Krylov.dqgmres")
for i = 1:10
println(x_itsolver3[i] / x_matlab[i] * 100)
end
Results:
RelativeResidual(res) being: norm(b-A*x)/norm(b)
MATLAB:
[dx,~,res] = gmres( A, b,10, 1e-6,10);
Elapsed time is 0.156341 seconds.
res=2.7714e-06
KrylovKit.GMRES:
0.262323 seconds (304 allocations: 2.472 MiB)
res=8.920428143716319e-9
#Percentage of MATLAB result
100.00008918762342
100.00015135484918
100.00015326343437
100.00010172365623
100.00035426225628
100.00047258280402
100.00040060447817
100.00031282868942
100.0002048190644
100.0001515897469
Krylov.gmres
0.307856 seconds (12.16 k allocations: 1.670 MiB)
res=8.920428259577072e-9
#Percentage of MATLAB result
100.00008918762344
100.00015135484917
100.00015326343438
100.00010172365617
100.00035426225634
100.00047258280395
100.0004006044781
100.00031282868933
100.00020481906455
100.00015158974686
Krylov.dqgmres
0.029348 seconds (56 allocations: 285.250 KiB)
res=0.061037625187066416
#Percentage of MATLAB result
95.52770715094722
92.80799500742638
92.10843453121275
95.62006975408465
74.37649780267117
62.92173932512013
69.1012186757328
77.87726417413496
87.86140357012935
92.27859017728767