X-Git-Url: http://gitweb.michael.orlitzky.com/?p=octave.git;a=blobdiff_plain;f=optimization%2Fvanilla_cgm.m;h=b511b484dfaab2ecba7fa6b8702be5080f977ba9;hp=3a72b144fc6e623f76e9148817b7f50ec487177d;hb=e12c489da09259a1365ae199fb6d7cbe64c9eb19;hpb=3b53099a4e07530a498d6aa959defa6f01244154 diff --git a/optimization/vanilla_cgm.m b/optimization/vanilla_cgm.m index 3a72b14..b511b48 100644 --- a/optimization/vanilla_cgm.m +++ b/optimization/vanilla_cgm.m @@ -36,26 +36,33 @@ function [x, k] = vanilla_cgm(A, b, x0, tolerance, max_iterations) % % All vectors are assumed to be *column* vectors. % + + sqrt_n = floor(sqrt(length(x0))); + k = 0; - x = x0; % Eschew the 'k' suffix on 'x' for simplicity. - rk = A*x - b; % The first residual must be computed the hard way. + xk = x0; + rk = A*xk - b; % The first residual must be computed the hard way. pk = -rk; - for k = [ 0 : max_iterations ] - if (norm(rk) < tolerance) - % Success. - return; + while (k <= max_iterations && norm(rk, 'inf') > tolerance) + alpha_k = step_length_positive_definite(rk, A, pk); + x_next = xk + alpha_k*pk; + + % Avoid accumulated roundoff errors. + if (mod(k, sqrt_n) == 0) + r_next = A*x_next - b; + else + r_next = rk + (alpha_k * A * pk); end - alpha_k = step_length_cgm(rk, A, pk); - x_next = x + alpha_k*pk; - r_next = rk + alpha_k*A*pk; beta_next = (r_next' * r_next)/(rk' * rk); p_next = -r_next + beta_next*pk; k = k + 1; - x = x_next; + xk = x_next; rk = r_next; pk = p_next; end + + x = xk; end