function [c, xm, xc] = nancov(x, flag); %NANCOV Sample covariance matrix of available data, ignoring NaNs. % % NANCOV(X) returns the covariance matrix of X estimated from all % available data in X, ignoring NaN-elements that indicate missing % values. If X is a vector, NANCOV(X) returns the variance. For % matrices, where each row is an observation and each column a % variable, NANCOV(X) is the covariance matrix estimate from all % available data. % % NANCOV(X) normalizes each covariance matrix element by (Nt-1) % where Nt is the number of available product terms contributing to % the covariance matrix element. % % NANCOV(X,0) normalizes by Nt and produces the second moment % matrix of the observations about their mean. NANCOV(X,1) is the % same as NANCOV(X). % % If all terms in the sum of the product and/or cross-product terms % contributing to a covariance matrix element are missing, the % covariance matrix element is set to zero. % % Because the covariance matrix elements are normalized with % different normalization factors, depending on how many terms % contribute to them, the covariance matrix is not necessarily % positive semidefinite. % % [C, M, XC] = NANCOV(X) returns the covariance matrix estimate % C from all available data, the mean M of the available data, % and the centered data matrix XC with the mean removed from % each column. % % See also COV, CENTER, NANSTD, NANMEAN, NANSUM. error(nargchk(1,2,nargin)) % check number of input arguments if isempty(x) % check for empty input. sx = NaN; return end if ndims(x) > 2, error('Data must be vector or 2-D array.'); end if nargin < 2, flag = 1; end % default: normalize by nt-1 if length(x)==prod(size(x)) % if x is vector, make sure x = x(:); % it is a row vector end % center data [xc,xm] = center(x); [m,n] = size(xc); % replace NaNs with zeros. inan = find(isnan(xc)); xc(inan)= zeros(size(inan)); nonnan = ones(m,n); % indicator matrix showing where there nonnan(inan) = zeros(size(inan)); % are non-missing elements in xc nt = nonnan' * nonnan - flag; % normalization factor for each % covariance matrix element % set covariance to 0 when there are no terms to form sum k = find(nt < 1); nt(k) = 1; c = xc' * xc ./ nt;