Mercurial > hg > octave-lyh
diff scripts/statistics/base/ols.m @ 11436:e151e23f73bc
Overhaul base statistics functions and documentation of same.
Add or improve input validation.
Add input validation tests.
Add functional tests.
Improve or re-write documentation strings.
author | Rik <octave@nomad.inbox5.com> |
---|---|
date | Mon, 03 Jan 2011 21:23:08 -0800 |
parents | a8ce6bdecce5 |
children | fd0a3ac60b0e |
line wrap: on
line diff
--- a/scripts/statistics/base/ols.m +++ b/scripts/statistics/base/ols.m @@ -48,9 +48,17 @@ ## ## @table @var ## @item beta -## The OLS estimator for @var{b}, @code{@var{beta} = pinv (@var{x}) * -## @var{y}}, where @code{pinv (@var{x})} denotes the pseudoinverse of -## @var{x}. +## The OLS estimator for @math{b}. +## @tex +## $beta$ is calculated directly via $(x^Tx)^{-1} x^T y$ if the matrix $x^Tx$ is +## of full rank. +## @end tex +## @ifnottex +## @var{beta} is calculated directly via @code{inv (x'*x) * x' * y} if the +## matrix @code{x'*x} is of full rank. +## @end ifnottex +## Otherwise, @code{@var{beta} = pinv (@var{x}) * @var{y}} where +## @code{pinv (@var{x})} denotes the pseudoinverse of @var{x}. ## ## @item sigma ## The OLS estimator for the matrix @var{s}, @@ -66,34 +74,63 @@ ## @item r ## The matrix of OLS residuals, @code{@var{r} = @var{y} - @var{x}*@var{beta}}. ## @end table +## @seealso{gls, pinv} ## @end deftypefn ## Author: Teresa Twaroch <twaroch@ci.tuwien.ac.at> ## Created: May 1993 ## Adapted-By: jwe -function [BETA, SIGMA, R] = ols (Y, X) +function [beta, sigma, r] = ols (y, x) if (nargin != 2) print_usage (); endif - [nr, nc] = size (X); - [ry, cy] = size (Y); - if (nr != ry) - error ("ols: incorrect matrix dimensions"); + if (! (isnumeric (x) && isnumeric (y))) + error ("ols: X and Y must be numeric matrices or vectors"); + endif + + if (ndims (x) != 2 || ndims (y) != 2) + error ("ols: X and Y must be 2-D matrices or vectors"); endif - Z = X' * X; - r = rank (Z); + [nr, nc] = size (x); + [ry, cy] = size (y); + if (nr != ry) + error ("ols: number of rows of X and Y must be equal"); + endif + + z = x' * x; + r = rank (z); if (r == nc) - BETA = inv (Z) * X' * Y; + beta = inv (z) * x' * y; else - BETA = pinv (X) * Y; + beta = pinv (x) * y; + endif + + if (isargout (2) || isargout (3)) + r = y - x * beta; + endif + if (isargout (2)) + sigma = r' * r / (nr - r); endif - R = Y - X * BETA; - SIGMA = R' * R / (nr - r); +endfunction + +%!test +%! x = [1:5]'; +%! y = 3*x + 2; +%! x = [x, ones(5,1)]; +%! assert (ols(y,x), [3; 2], 50*eps) -endfunction +%% Test input validation +%!error ols (); +%!error ols (1); +%!error ols (1, 2, 3); +%!error ols ([true, true], [1, 2]); +%!error ols ([1, 2], [true, true]); +%!error ols (ones (2,2,2), ones (2,2)); +%!error ols (ones (2,2), ones (2,2,2)); +%!error ols (ones(1,2), ones(2,2));