function [me, st, md, no] = nanstats(D)
%NANSTATS Statistical operations that ignore NaNs.
%
% [mean, std, median, nans] = nanstats(D)
%
% Input and output arguments:
% D (struct) data or map struct
% (matrix) size dlen x dim
%
% me (double) columnwise mean
% st (double) columnwise standard deviation
% md (double) columnwise median
% no (vector) columnwise number of samples (finite, not-NaN)
% Contributed to SOM Toolbox vs2, February 2nd, 2000 by Juha Vesanto
% http://www.cis.hut.fi/projects/somtoolbox/
% Version 2.0beta juuso 300798
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% check arguments
(nargchk(1, 1, nargin)); % check no. of input args is correct
if isstruct(D),
if strcmp(D.type,'som_map'), D = D.codebook;
else D = D.data;
end
end
[dlen dim] = size(D);
me = zeros(dim,1)+NaN;
md = me;
st = me;
no = me;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% computation
for i = 1:dim,
ind = find(~isnan(D(:, i)) & ~isinf(D(:,i))); % indices of non-NaN/Inf elements
n = length(ind); % no of non-NaN/Inf elements
me(i) = sum(D(ind, i)); % compute average
if n == 0, me(i) = NaN; else me(i) = me(i) / n; end
md(i) = median(D(ind, i)); % compute median
st(i) = sum((me(i) - D(ind, i)).^2); % compute standard deviation
if n == 0, st(i) = NaN;
elseif n == 1, st(i) = 0;
else st(i) = sqrt(st(i) / (n - 1));
end
no(i) = n; % number of samples (finite, not-NaN)
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%