annotate BP/cgsolve.m @ 1:2a2abf5092f8

Organized into test file and lib files Changed sklearn cholesky function to behave as the others: tol does not override number of atoms, but the two conditions work together
author nikcleju
date Thu, 20 Oct 2011 21:06:06 +0000
parents 8346c92b698f
children
rev   line source
nikcleju@0 1 % cgsolve.m
nikcleju@0 2 %
nikcleju@0 3 % Solve a symmetric positive definite system Ax = b via conjugate gradients.
nikcleju@0 4 %
nikcleju@0 5 % Usage: [x, res, iter] = cgsolve(A, b, tol, maxiter, verbose)
nikcleju@0 6 %
nikcleju@0 7 % A - Either an NxN matrix, or a function handle.
nikcleju@0 8 %
nikcleju@0 9 % b - N vector
nikcleju@0 10 %
nikcleju@0 11 % tol - Desired precision. Algorithm terminates when
nikcleju@0 12 % norm(Ax-b)/norm(b) < tol .
nikcleju@0 13 %
nikcleju@0 14 % maxiter - Maximum number of iterations.
nikcleju@0 15 %
nikcleju@0 16 % verbose - If 0, do not print out progress messages.
nikcleju@0 17 % If and integer greater than 0, print out progress every 'verbose' iters.
nikcleju@0 18 %
nikcleju@0 19 % Written by: Justin Romberg, Caltech
nikcleju@0 20 % Email: jrom@acm.caltech.edu
nikcleju@0 21 % Created: October 2005
nikcleju@0 22 %
nikcleju@0 23
nikcleju@0 24 function [x, res, iter] = cgsolve(A, b, tol, maxiter, verbose)
nikcleju@0 25
nikcleju@0 26 if (nargin < 5), verbose = 1; end
nikcleju@0 27
nikcleju@0 28 implicit = isa(A,'function_handle');
nikcleju@0 29
nikcleju@0 30 x = zeros(length(b),1);
nikcleju@0 31 r = b;
nikcleju@0 32 d = r;
nikcleju@0 33 delta = r'*r;
nikcleju@0 34 delta0 = b'*b;
nikcleju@0 35 numiter = 0;
nikcleju@0 36 bestx = x;
nikcleju@0 37 bestres = sqrt(delta/delta0);
nikcleju@0 38 while ((numiter < maxiter) && (delta > tol^2*delta0))
nikcleju@0 39
nikcleju@0 40 % q = A*d
nikcleju@0 41 if (implicit), q = A(d); else q = A*d; end
nikcleju@0 42
nikcleju@0 43 alpha = delta/(d'*q);
nikcleju@0 44 x = x + alpha*d;
nikcleju@0 45
nikcleju@0 46 if (mod(numiter+1,50) == 0)
nikcleju@0 47 % r = b - Aux*x
nikcleju@0 48 if (implicit), r = b - A(x); else r = b - A*x; end
nikcleju@0 49 else
nikcleju@0 50 r = r - alpha*q;
nikcleju@0 51 end
nikcleju@0 52
nikcleju@0 53 deltaold = delta;
nikcleju@0 54 delta = r'*r;
nikcleju@0 55 beta = delta/deltaold;
nikcleju@0 56 d = r + beta*d;
nikcleju@0 57 numiter = numiter + 1;
nikcleju@0 58 if (sqrt(delta/delta0) < bestres)
nikcleju@0 59 bestx = x;
nikcleju@0 60 bestres = sqrt(delta/delta0);
nikcleju@0 61 end
nikcleju@0 62
nikcleju@0 63 if ((verbose) && (mod(numiter,verbose)==0))
nikcleju@0 64 disp(sprintf('cg: Iter = %d, Best residual = %8.3e, Current residual = %8.3e', ...
nikcleju@0 65 numiter, bestres, sqrt(delta/delta0)));
nikcleju@0 66 end
nikcleju@0 67
nikcleju@0 68 end
nikcleju@0 69
nikcleju@0 70 if (verbose)
nikcleju@0 71 disp(sprintf('cg: Iterations = %d, best residual = %14.8e', numiter, bestres));
nikcleju@0 72 end
nikcleju@0 73 x = bestx;
nikcleju@0 74 res = bestres;
nikcleju@0 75 iter = numiter;
nikcleju@0 76