olsmatrix.m 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. function f = olsmatrix(X,mode)
  2. % function f = olsmatrix(X,mode)
  3. %
  4. % <X> is samples x parameters
  5. % <mode> (optional) is
  6. % 0 means normal operation
  7. % 1 means use inv instead of \ and omit unit-length normalization.
  8. % the point of this mode is to reduce memory usage (i think).
  9. % default: 0.
  10. %
  11. % what we want to do is to perform OLS regression using <X>
  12. % and obtain the parameter estimates. this is accomplished
  13. % by inv(X'*X)*X'*y = f*y where y is the data (samples x cases).
  14. %
  15. % what this function does is to return <f> which has dimensions
  16. % parameters x samples.
  17. %
  18. % to ensure well-conditioning, we unit-length normalize each column
  19. % of <X> before doing the inv.m operation. also, we actually use
  20. % left-slash (\), which apparently is equivalent to inv.m but faster
  21. % and more accurate (see code for details). if you pass <mode> as 1,
  22. % we omit the normalization and use the inv method instead of the \ method.
  23. %
  24. % also, in the case that one or more regressors in <X> are all zero, then
  25. % without special handling, then this case will result in warnings and
  26. % NaN results. what we do is to explicitly ensure that all-zero regressors
  27. % are ignored and that there are all-zero rows for these regressors
  28. % in <f>. this makes it such that the weights estimated for these
  29. % regressors are simply zero.
  30. %
  31. % see also olsmatrix2.m.
  32. %
  33. % history:
  34. % 2011/06/27 - explicitly ignore 0
  35. % 2011/03/29 - mode 1 now omits unit length normalization.
  36. % 2011/03/28 - add <mode> input.
  37. % 2010/08/05: now, we do not try to detect weird cases with low variance.
  38. % instead, we just blindly unit-length normalize each column.
  39. % input
  40. if ~exist('mode','var') || isempty(mode)
  41. mode = 0;
  42. end
  43. % check
  44. assert(all(~isnan(X(:))));
  45. % deal with degenerate regressors
  46. good = ~all(X==0,1);
  47. % initialize result
  48. f = zeros(size(X,2),size(X,1));
  49. % do it
  50. switch mode
  51. case 0
  52. [X,len] = unitlength(X(:,good),1,[],0);
  53. temp = diag(1./len)*((X'*X)\X'); % hm, suggested by M-Lint
  54. case 1
  55. temp = inv(X(:,good)'*X(:,good))*X(:,good)';
  56. end
  57. % return
  58. if any(good)
  59. f(good,:) = temp;
  60. end