function x = lscov(A,b,V)
%LSCOV	Least squares solution in the presence of known covariance.
%	X = LSCOV(A,b,V) returns the vector X that minimizes
%	(A*X-b)'*inv(V)*(A*X-b). If A is M-by-N, then b must be M-by-1
%	and V must be M-by-M.  The solution X will be N-by-1.  This is
%	the over-determined least squares problem (M > N) with covariance V.
%	The solution is found without inverting V.
%
%	The classical linear algebra solution to this problem is:
%
%	    x = inv(A'*inv(V)*A)*A'*inv(V)*b
%
%	See also SLASH, NNLS, QR.

%	Reference:
%	    G. Strang, "Introduction to Applied Mathematics",
%	    Wellesley-Cambridge, p. 398, 1986.
%	L. Shure 3-31-89
%	Copyright (c) 1984-94 by The MathWorks, Inc.

[m,n] = size(A);

% Error checking
if m <= n, error('Problem must be over-determined.'); end
if size(b,1)~=m, 
  error(['B must be column vector of size ',int2str(m),'-by-1.']);
end
if any(size(V)~=[m m]), 
  error(['V must be a ',int2str(m),'-by-',int2str(m),' matrix.']);
end

[q,r] = qr(A);
efg = q'*V*q;
e = efg(1:n,1:n);
g = efg(n+1:m,n+1:m);
cd = q'*b;
f = efg(1:n,n+1:m);
c = cd(1:n);
d = cd(n+1:m);
r = r(1:n,1:n);
x = r\(c-f*(g\d));
