X-Git-Url: https://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=iterative%2Fclassical_iteration.m;fp=iterative%2Fclassical_iteration.m;h=4e43ff14aa14af57ee1b712dda412ce65026359e;hb=40a26bb2dfcf53296d9996b88008a605ad59573c;hp=0000000000000000000000000000000000000000;hpb=2357d986b4d33f5d18681a97c246a141e94667c5;p=octave.git diff --git a/iterative/classical_iteration.m b/iterative/classical_iteration.m new file mode 100644 index 0000000..4e43ff1 --- /dev/null +++ b/iterative/classical_iteration.m @@ -0,0 +1,44 @@ +function [x, iterations, residual_norms] = ... + classical_iteration(A, b, x0, M_of_A, tolerance, max_iterations) + + save_residual_norms = false; + if (nargout > 2) + save_residual_norms = true; + residual_norms = []; + end + + % This creates a diagonal matrix from the diagonal entries of A. + M = M_of_A(A); + N = M - A; + + % Avoid recomputing this at the beginning of each iteration. + b_norm = norm(b, 'inf'); + relative_tolerance = tolerance*b_norm; + + k = 0; + xk = x0; + rk = b - A*xk; + rk_norm = norm(rk, 'inf'); + + while (rk_norm > relative_tolerance && k < max_iterations) + % This is almost certainly slower than updating the individual + % components of xk, but it's "fast enough." + x_next = M \ (N*xk + b); + r_next = b - A*x_next; + + k = k + 1; + xk = x_next; + rk = r_next; + + % We store the current residual norm so that, if we're saving + % them, we don't need to recompute it at the beginning of the next + % iteration. + rk_norm = norm(rk, 'inf'); + if (save_residual_norms) + residual_norms = [ residual_norms; rk_norm ]; + end + end + + iterations = k; + x = xk; +end