% Used to make the plots for the conjugate gradient example % Example 4.9 function []=main() steepmeth = 'steep'; cgmeth = 'cg '; gradmeth = 'grad '; J1=optcg(gradmeth); J2=optcg(steepmeth); figure(1); clf; loglog(J1); hold on loglog(J2,'--'); legend('Conjugate Gradient','Gradient'); xlabel('k'); function [J] = optcg(method) steepmeth = 'steep'; cgmeth = 'cg '; gradmeth = 'grad '; % plot the test function x=-2:0.001:2; y=testfcn(x); %figure(1); hold off %plot(x,y); % define the samples randn('seed', 1); % make sure its repeatable M = 100; samp = randn(M, 1); samp(find(samp>2)) = 2; samp(find(samp<-2)) = -2; yi = testfcn(samp); %hold on %plot(samp, ones(length(samp),1), 'o'); % initialize the parameter estimates p = 25; A = zeros(p, 1); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% tol = 1e-10; done = 0; its = 1; maxits = 100; J=zeros(maxits, 1); % 1) find initial direction d = -zeta(k) along the gradient zeta = zeros(p, 1); for i=1:M zetai = makezeta(samp(i), A); e = yi(i) - approx(samp(i), A); zeta = zeta - zetai*e; end dir = -zeta; % 2) set A(k+1) which minimizes J along k (this is the main loop) while (~done) a = 0; rat = 2; Ja = cost(A, samp, yi) J(its) = Ja; b = 0; if ((method == cgmeth)|(method == steepmeth)) for i=-20:10 c = rat^i; Jc = cost(A+c*dir, samp, yi); if (Jc > Ja) break; end; b = c; end if (b==0) b = (a+c)/2; Jb = cost(A+b*dir, samp, yi); if (Jb > Ja) error('need to change bracket'); end; if (Jb > Jc) error('need to change bracket'); end; end; Aprev = A; A = A + myfmin('minfcn', a, b, c, A, samp, yi, dir)*dir; else A = A + 0.01*dir; % back-prop end; % 3) calculate zeta(k+1) zeta2 = zeros(p, 1); for i=1:M zetai = makezeta(samp(i), A); e = yi(i) - approx(samp(i), A); zeta2 = zeta2 - zetai*e; end % 4) check for stop condition %if (norm(A - Aprev) < tol) break; end; if (its >= maxits) break; end; % 5) set new search direction dir = -zeta2; % steepest descent if (method == cgmeth) % eta = zeta2'*zeta2 / (zeta'*zeta); eta = (zeta2 - zeta)'*zeta2 / (zeta'*zeta); dir = -zeta2 + eta*dir; else dir = -zeta2; % steepest descent/gradient end its = its+1 end; % while(~done) if (method==gradmeth) figure(2); hold off; plot(samp, yi, 'o'); hold on; l = length(x); ytest=zeros(l,1); for j=1:l ytest(j) = approx(x(j), A); end plot(x, ytest); hold off; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % find xmin which minimized J(x) given a abs(b-a)) t1 = b; t2 = b + R*(c-b); else t1 = b - R*(b-a); t2 = b; end J1 = feval(J, t1, varargin{:}); J2 = feval(J, t2, varargin{:}); z = [a, t1, t2, c]; while (abs(c-a) > tol) if (J2 < J1) a = t1; t1 = t2; t2 = t2 + R*(c - t2); J1 = J2; J2 = feval(J, t2, varargin{:}); else c = t2; t2 = t1; t1 = t1 - R*(t1 - a); J2 = J1; J1 = feval(J, t1, varargin{:}); end n = n + 1; if (n >= maxit) warning('Maximum numer of iterations reached'); break; end; z = [z; [a, t1, t2, c]]; end %while if (J1 < J2) xmin = t1; else xmin = t2; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Evaluate the approximator (assumes x is a scalar) function [y] = approx(x, A) p = length(A); % number of linear coef. sigma = 0.1; c = 1:p; c = 4*(c(:)-1)/(p-1) - 2; tmp1 = (x - c)./sigma; tmp2 = exp(-(tmp1.^2)); y = (A(:))'*tmp2; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define the basis functions (assumes x is a scalar) function [zeta] = makezeta(x, A) p = length(A); % number of linear coef. sigma = 0.1; c = 1:p; c = 4*(c(:)-1)/(p-1) - 2; % define zeta for linear coef. zeta = zeros(p,1); for i=1:p tmp = (x-c(i))/sigma; zeta(i) = exp(-(tmp^2)); end zeta; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define the test function function [y] = testfcn(x) y = cos(pi./(0.5+abs(x))); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define the 1-dimensional function to minimize function [J] = minfcn(gamma, A, xi, yi, d) J = cost(A + gamma*d, xi, yi); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Define the cost function function [J] = cost(A, xi, yi) M = length(yi); J = 0; for i=1:M J = J + (yi(i) - approx(xi(i), A))^2; end