PageRenderTime 37ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/MatlabCode/branches/Greg's Branch/hessian.m

http://horwitzlab.googlecode.com/
MATLAB | 189 lines | 111 code | 11 blank | 67 comment | 2 complexity | 5d106b3347819982aaaede7889ad268e MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. function [hess,err] = hessian(fun,x0)
  2. % hessian: estimate elements of the Hessian matrix (array of 2nd partials)
  3. % usage: [hess,err] = hessian(fun,x0)
  4. %
  5. % Hessian is NOT a tool for frequent use on an expensive
  6. % to evaluate objective function, especially in a large
  7. % number of dimensions. Its computation will use roughly
  8. % O(6*n^2) function evaluations for n parameters.
  9. %
  10. % arguments: (input)
  11. % fun - SCALAR analytical function to differentiate.
  12. % fun must be a function of the vector or array x0.
  13. % fun does not need to be vectorized.
  14. %
  15. % x0 - vector location at which to compute the Hessian.
  16. %
  17. % arguments: (output)
  18. % hess - nxn symmetric array of second partial derivatives
  19. % of fun, evaluated at x0.
  20. %
  21. % err - nxn array of error estimates corresponding to
  22. % each second partial derivative in hess.
  23. %
  24. %
  25. % Example usage:
  26. % Rosenbrock function, minimized at [1,1]
  27. % rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
  28. %
  29. % [h,err] = hessian(rosen,[1 1])
  30. % h =
  31. % 842 -420
  32. % -420 210
  33. % err =
  34. % 1.0662e-12 4.0061e-10
  35. % 4.0061e-10 2.6654e-13
  36. %
  37. %
  38. % Example usage:
  39. % cos(x-y), at (0,0)
  40. % Note: this hessian matrix will be positive semi-definite
  41. %
  42. % hessian(@(xy) cos(xy(1)-xy(2)),[0 0])
  43. % ans =
  44. % -1 1
  45. % 1 -1
  46. %
  47. %
  48. % See also: derivest, gradient, gradest, hessdiag
  49. %
  50. %
  51. % Author: John D'Errico
  52. % e-mail: woodchips@rochester.rr.com
  53. % Release: 1.0
  54. % Release date: 2/10/2007
  55. % parameters that we might allow to change
  56. params.StepRatio = 2;
  57. params.RombergTerms = 3;
  58. % get the size of x0 so we can reshape
  59. % later.
  60. sx = size(x0);
  61. % was a string supplied?
  62. if ischar(fun)
  63. fun = str2func(fun);
  64. end
  65. % total number of derivatives we will need to take
  66. nx = length(x0);
  67. % get the diagonal elements of the hessian (2nd partial
  68. % derivatives wrt each variable.)
  69. [hess,err] = hessdiag(fun,x0);
  70. % form the eventual hessian matrix, stuffing only
  71. % the diagonals for now.
  72. hess = diag(hess);
  73. err = diag(err);
  74. if nx<2
  75. % the hessian matrix is 1x1. all done
  76. return
  77. end
  78. % get the gradient vector. This is done only to decide
  79. % on intelligent step sizes for the mixed partials
  80. [grad,graderr,stepsize] = gradest(fun,x0);
  81. % Get params.RombergTerms+1 estimates of the upper
  82. % triangle of the hessian matrix
  83. dfac = params.StepRatio.^(-(0:params.RombergTerms)');
  84. for i = 2:nx
  85. for j = 1:(i-1)
  86. dij = zeros(params.RombergTerms+1,1);
  87. for k = 1:(params.RombergTerms+1)
  88. dij(k) = fun(x0 + swap2(zeros(sx),i, ...
  89. dfac(k)*stepsize(i),j,dfac(k)*stepsize(j))) + ...
  90. fun(x0 + swap2(zeros(sx),i, ...
  91. -dfac(k)*stepsize(i),j,-dfac(k)*stepsize(j))) - ...
  92. fun(x0 + swap2(zeros(sx),i, ...
  93. dfac(k)*stepsize(i),j,-dfac(k)*stepsize(j))) - ...
  94. fun(x0 + swap2(zeros(sx),i, ...
  95. -dfac(k)*stepsize(i),j,dfac(k)*stepsize(j)));
  96. end
  97. dij = dij/4/prod(stepsize([i,j]));
  98. dij = dij./(dfac.^2);
  99. % Romberg extrapolation step
  100. [hess(i,j),err(i,j)] = rombextrap(params.StepRatio,dij,[2 4]);
  101. hess(j,i) = hess(i,j);
  102. err(j,i) = err(i,j);
  103. end
  104. end
  105. end % mainline function end
  106. % =======================================
  107. % sub-functions
  108. % =======================================
  109. function vec = swap2(vec,ind1,val1,ind2,val2)
  110. % swaps val as element ind, into the vector vec
  111. vec(ind1) = val1;
  112. vec(ind2) = val2;
  113. end % sub-function end
  114. % ============================================
  115. % subfunction - romberg extrapolation
  116. % ============================================
  117. function [der_romb,errest] = rombextrap(StepRatio,der_init,rombexpon)
  118. % do romberg extrapolation for each estimate
  119. %
  120. % StepRatio - Ratio decrease in step
  121. % der_init - initial derivative estimates
  122. % rombexpon - higher order terms to cancel using the romberg step
  123. %
  124. % der_romb - derivative estimates returned
  125. % errest - error estimates
  126. % amp - noise amplification factor due to the romberg step
  127. srinv = 1/StepRatio;
  128. % do nothing if no romberg terms
  129. nexpon = length(rombexpon);
  130. rmat = ones(nexpon+2,nexpon+1);
  131. switch nexpon
  132. case 0
  133. % rmat is simple: ones(2,1)
  134. case 1
  135. % only one romberg term
  136. rmat(2,2) = srinv^rombexpon;
  137. rmat(3,2) = srinv^(2*rombexpon);
  138. case 2
  139. % two romberg terms
  140. rmat(2,2:3) = srinv.^rombexpon;
  141. rmat(3,2:3) = srinv.^(2*rombexpon);
  142. rmat(4,2:3) = srinv.^(3*rombexpon);
  143. case 3
  144. % three romberg terms
  145. rmat(2,2:4) = srinv.^rombexpon;
  146. rmat(3,2:4) = srinv.^(2*rombexpon);
  147. rmat(4,2:4) = srinv.^(3*rombexpon);
  148. rmat(5,2:4) = srinv.^(4*rombexpon);
  149. end
  150. % qr factorization used for the extrapolation as well
  151. % as the uncertainty estimates
  152. [qromb,rromb] = qr(rmat,0);
  153. % the noise amplification is further amplified by the Romberg step.
  154. % amp = cond(rromb);
  155. % this does the extrapolation to a zero step size.
  156. ne = length(der_init);
  157. rombcoefs = rromb\(qromb'*der_init);
  158. der_romb = rombcoefs(1,:)';
  159. % uncertainty estimate of derivative prediction
  160. s = sqrt(sum((der_init - rmat*rombcoefs).^2,1));
  161. rinv = rromb\eye(nexpon+1);
  162. cov1 = sum(rinv.^2,2); % 1 spare dof
  163. errest = s'*12.7062047361747*sqrt(cov1(1));
  164. end % rombextrap