# Real time GMRES convergence and stop callback

6 views (last 30 days)
Fabio Freschi on 10 Aug 2021
Commented: Fabio Freschi on 2 Sep 2021
Dear Matlab users,
I usually solve large linear problems using gmres. These simulations could last for several tens of hours. The problem comes from the solution of a coupled electromagnetic problem, where the system matrix is block partitioned, with some dense and some sparse blocks. the matrix A is not assembled but it a function providing the product A*x is passed to gmres. I can provide a preconditioner, but its creation is time consuming, so I use an approximate version with several degrees of approximation.
In some cases the solver converges very slowly, in the sense that the convergence profile becomes flat but not enough to activate the stagnation check. In these cases it would be helpful to stop the simulation and accept the approximate solution as it is, or change the preconditioner and restart the simulation.
The problem is that I can notice this problem only if the gmres stops because the maximum number of iterations is reached. This is really annoying, because I could waste days of computations, without a real improvement of the solution.
To overcome this problem I decided to modify gmres in order to have a plot in real time of the convergence. I also added a callback to the figure to have the current solution back to the workspace. The code is pretty simple:
1. I open the figure before starting the outer loop of gmres
h = figure;
c = uicontrol(h,'Style','togglebutton','String','Stop');
FontSize = 10;
2. just inside the inner loop I make the plot
% plot
figure(h), hold on
% total iteration count
iter = (outiter-1)*inner+initer;
% convergenge plot
plot(1:iter,log10(resvec(1:iter)/n2minv_b),'r-','LineWidth',2);
% target value
plot(1:1:maxit,log10(tol)*ones(1,maxit),'b--','LineWidth',2);
% figure appearance setup
axis([0 maxit log10(tol/10) 1])
set(gca,'FontSize',FontSize);
xlabel('iteration #','FontSize',FontSize)
ylabel('log10||error||','FontSize',FontSize);
title('gmres')
drawnow, hold off
% stop if button is pressed
if (c.Value == 1)
initer = initer-1;
flag = 3;
break
end
The result seems to work fine, as shown in the picture below:
But I have some questions
1. this approach is not "clean", because I must modify a built-in function and I also must locally copy the dependent files (in this case iterapp, iterchk, itermsg). Are there other possibilities? Any comment regarding my solution or possible improvements?
2. I would prefer to add the previous code as a function, so that I can share the same code with other iterative solvers. However, the break command would not work inside a function. Is there a workaround to solve this problem?
3. Does anyone have a similar problem? It would be nice that Mathworks would include the possibility of using a callback (like gmres in scipy) or calling a function (like in the ODE solvers) after each successful iteration.
4. Can I share the modified version in FEX? I am worried about copyright issues.
Kind regards
Fabio Freschi
Fabio Freschi on 2 Sep 2021
Also the answer to the item 4 only is accepted

R2020b

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!