Mercurial > octave
changeset 24591:bccb203494f6
lscov.m: Accept V vector input in row or column orientation (bug #52874).
* lscov.m: Re-wrap docstring to 80 characters. Explain that input V
may be a n-element vector or an n-by-n matrix. Validate maximum
number of input arguments. Change input validation for V to accept
a row or column vector of n elements. Add BIST input validation tests.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 12 Jan 2018 10:20:31 -0800 |
parents | b6818c2b0483 |
children | 6c3b7ca0cb90 |
files | scripts/linear-algebra/lscov.m |
diffstat | 1 files changed, 43 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/scripts/linear-algebra/lscov.m Fri Jan 12 08:08:46 2018 -0800 +++ b/scripts/linear-algebra/lscov.m Fri Jan 12 10:20:31 2018 -0800 @@ -24,26 +24,26 @@ ## ## Compute a generalized linear least squares fit. ## -## Estimate @var{x} under the model @var{b} = @var{A}@var{x} + @var{w}, -## where the noise @var{w} is assumed to follow a normal distribution -## with covariance matrix @math{{\sigma^2} V}. +## Estimate @var{x} under the model @var{b} = @var{A}@var{x} + @var{w}, where +## the noise @var{w} is assumed to follow a normal distribution with covariance +## matrix @math{{\sigma^2} V}. ## -## If the size of the coefficient matrix @var{A} is n-by-p, the -## size of the vector/array of constant terms @var{b} must be n-by-k. +## If the size of the coefficient matrix @var{A} is n-by-p, the size of the +## vector/array of constant terms @var{b} must be n-by-k. ## -## The optional input argument @var{V} may be a n-by-1 vector of positive -## weights (inverse variances), or a n-by-n symmetric positive semidefinite -## matrix representing the covariance of @var{b}. If @var{V} is not -## supplied, the ordinary least squares solution is returned. +## The optional input argument @var{V} may be an n-element vector of positive +## weights (inverse variances), or an n-by-n symmetric positive semi-definite +## matrix representing the covariance of @var{b}. If @var{V} is not supplied, +## the ordinary least squares solution is returned. ## ## The @var{alg} input argument, a guidance on solution method to use, is ## currently ignored. ## ## Besides the least-squares estimate matrix @var{x} (p-by-k), the function -## also returns @var{stdx} (p-by-k), the error standard deviation of -## estimated @var{x}; @var{mse} (k-by-1), the estimated data error covariance -## scale factors (@math{\sigma^2}); and @var{S} (p-by-p, or p-by-p-by-k if k -## > 1), the error covariance of @var{x}. +## also returns @var{stdx} (p-by-k), the error standard deviation of estimated +## @var{x}; @var{mse} (k-by-1), the estimated data error covariance scale +## factors (@math{\sigma^2}); and @var{S} (p-by-p, or p-by-p-by-k if k > 1), +## the error covariance of @var{x}. ## ## Reference: @nospell{Golub and Van Loan} (1996), ## @cite{Matrix Computations (3rd Ed.)}, Johns Hopkins, Section 5.6.3 @@ -55,31 +55,45 @@ function [x, stdx, mse, S] = lscov (A, b, V = [], alg) - if (nargin < 2 || (rows (A) != rows (b))) + if (nargin < 2 || nargin > 4) print_usage (); endif + if (rows (A) != rows (b)) + error ("lscov: A and B must have the same number of rows"); + endif + + + if (nargin == 4) + warning ("lscov: algorithm selection input ALG is not yet implemented, using default"); + endif + n = rows (A); p = columns (A); k = columns (b); if (! isempty (V)) - if (rows (V) != n || ! any (columns (V) == [1 n])) - error ("lscov: V should be a square matrix or a vector with the same number of rows as A"); - endif if (isvector (V)) - ## n-by-1 vector of inverse variances + ## n-element vector of inverse variances + if (numel (V) != n) + error ("lscov: vector V must have n (number of row in A) elements "); + endif + v = diag (sqrt (V)); A = v * A; b = v * b; else ## n-by-n covariance matrix + if (size (V) != [n, n]) + error ("lscov: matrix V must be square with the same number of rows as A"); + endif + try ## Ordinarily V will be positive definite B = chol (V)'; catch - ## If V is only positive semidefinite, use its + ## If V is only positive semi-definite, use its ## eigendecomposition to find a factor B such that V = B*B' [B, lambda] = eig (V); image_dims = (diag (lambda) > 0); @@ -182,7 +196,7 @@ %! assert(S2(:, :, 2), 4*S, eps); %!test -%! ## Artificial example with positive semidefinite weight matrix +%! ## Artificial example with positive semi-definite weight matrix %! x = (0:0.2:2)'; %! y = round(100*sin(x) + 200*cos(x)); %! X = [ones(size(x)) sin(x) cos(x)]; @@ -190,3 +204,12 @@ %! V(end, end-1) = V(end-1, end) = 1; %! [b, seb, mseb, S] = lscov (X, y, V); %! assert(b, [0 100 200]', 0.2); + +%!error lscov () +%!error lscov (1) +%!error lscov (1,2,3,4,5) +%!error <A and B must have the same number of rows> lscov (ones (2,2),1) +%!warning <algorithm selection input ALG is not yet implemented> +%! lscov (1,1, [], "chol"); +%!error <vector V must have n .* elements> lscov (1,2, [1, 2]) +%!error <matrix V must be square> lscov (1,2, [1 2 3; 4 5 6])