%% Iterative Solution to Linear System
% Solve a square linear system using gmres with default settings, and then adjust the tolerance and number of iterations used in the solution process.
%
% Create a random sparse matrix A with 50% density. Also create a random vector b for the right-hand side of \textrm{Ax}=b.

rng default
A = sprand(400,400,.5);
A = A'*A;
b = rand(400,1);

%
% Solve \textrm{Ax}=b using gmres. The output display includes the value of the relative residual error \frac{\left\|\textrm{Ax}-b\right\|}{\left\|b\right\|}.

x = gmres(A,b);

% By default gmres uses 10 iterations and a tolerance of 1e-6, and the algorithm is unable to converge in those 10 iterations for this matrix. Since the residual is still large, it is a good indicator that more iterations (or a preconditioner matrix) are needed. You also can reduce the tolerance to make it easier for the algorithm to converge.
%
% Solve the system again using a tolerance of 1e-4 and 100 iterations.

tol = 1e-4;
maxit = 100;
x = gmres(A,b,[],tol,maxit);

% Even with a looser tolerance and more iterations the residual error does not improve much. When an iterative algorithm stalls in this manner it is a good indication that a preconditioner matrix is needed. However, gmres also has an input that controls the number of inner iterations. By specifying a value for the inner iterations, gmres does more work per outer iteration.
%
% Solve the system again using a restart value of 100 and a maxit value of 250. Rather than doing 100 iterations once, gmres performs 100 iterations between restarts and repeats this 250 times.

restart = 100;
maxit = 250;
x = gmres(A,b,restart,tol,maxit);

% In this case specifying a large restart value for gmres enables it to converge to a solution within the allowed number of iterations. However, large restart values can consume a lot of memory when A is also large.
%
% Copyright 2019 The MathWorks, Inc.
%
%