1 function [o,count,SSQ] = sumskipnan(x, DIM, W)
2 % SUMSKIPNAN adds all non-NaN values.
4 % All NaN's are skipped; NaN's are considered as missing values.
5 % SUMSKIPNAN of NaN's only gives O; and the number of valid elements is return.
6 % SUMSKIPNAN is also the elementary function for calculating
7 % various statistics (e.g. MEAN, STD, VAR, RMS, MEANSQ, SKEWNESS,
8 % KURTOSIS, MOMENT, STATISTIC etc.) from data with missing values.
9 % SUMSKIPNAN implements the DIMENSION-argument for data with missing values.
10 % Also the second output argument return the number of valid elements (not NaNs)
12 % Y = sumskipnan(x [,DIM])
13 % [Y,N,SSQ] = sumskipnan(x [,DIM])
14 % [...] = sumskipnan(x, DIM, W)
17 % DIM dimension (default: [])
18 % empty DIM sets DIM to first non singleton dimension
19 % W weight vector for weighted sum, numel(W) must fit size(x,DIM)
21 % N number of valid (not missing) elements
24 % the function FLAG_NANS_OCCURED() returns whether any value in x
25 % is a not-a-number (NaN)
28 % - can deal with NaN's (missing values)
29 % - implements dimension argument.
30 % - computes weighted sum
31 % - compatible with Matlab and Octave
33 % see also: FLAG_NANS_OCCURED, SUM, NANSUM, MEAN, STD, VAR, RMS, MEANSQ,
34 % SSQ, MOMENT, SKEWNESS, KURTOSIS, SEM
37 % This program is free software; you can redistribute it and/or modify
38 % it under the terms of the GNU General Public License as published by
39 % the Free Software Foundation; either version 3 of the License, or
40 % (at your option) any later version.
42 % This program is distributed in the hope that it will be useful,
43 % but WITHOUT ANY WARRANTY; without even the implied warranty of
44 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 % GNU General Public License for more details.
47 % You should have received a copy of the GNU General Public License
48 % along with this program; If not, see <http://www.gnu.org/licenses/>.
50 % $Id: sumskipnan.m 9033 2011-11-08 20:58:07Z schloegl $
51 % Copyright (C) 2000-2005,2009,2011 by Alois Schloegl <alois.schloegl@gmail.com>
52 % This function is part of the NaN-toolbox
53 % http://pub.ist.ac.at/~schloegl/matlab/NaN/
56 global FLAG_NANS_OCCURED;
65 % an efficient implementation in C of the following lines
66 % could significantly increase performance
67 % only one loop and only one check for isnan is needed
68 % An MEX-Implementation is available in sumskipnan.cpp
70 % Outline of the algorithm:
71 % for { k=1,o=0,count=0; k++; k<N}
81 DIM = find(size(x)>1,1);
82 if isempty(DIM), DIM = 1; end;
84 if (DIM<1), DIM = 1; end; %% Hack, because min([])=0 for FreeMat v3.5
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 if (isempty(W) && (~(isa(x,'float') || isa(x,'double')))) || ~flag_implicit_skip_nan(), %%% skip always NaN's
91 error('SUMSKIPNAN: weighted sum of integers not supported, yet');
108 if (length(size(x))<DIM)
109 error('SUMSKIPNAN: DIM argument larger than number of dimensions of x');
110 elseif ~isempty(W) && (size(x,DIM)~=numel(W))
111 error('SUMSKIPNAN: size of weight vector does not match size(x,DIM)');
114 %% mex and oct files expect double
117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118 % use Matlab-MEX function when available
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123 %% using sumskipnan_mex.mex
125 %% !!! hack: FLAG_NANS_OCCURED is an output argument, reserve memory !!!
126 if isempty(FLAG_NANS_OCCURED),
127 FLAG_NANS_OCCURED = logical(0); % default value
131 o = sumskipnan_mex(real(x),DIM,FLAG_NANS_OCCURED,W);
133 io = sumskipnan_mex(imag(x),DIM,FLAG_NANS_OCCURED,W);
138 [o,count] = sumskipnan_mex(real(x),DIM,FLAG_NANS_OCCURED,W);
140 [io,icount] = sumskipnan_mex(imag(x),DIM,FLAG_NANS_OCCURED,W);
141 if any(count(:)-icount(:))
142 error('Number of NaNs differ for REAL and IMAG part');
149 [o,count,SSQ] = sumskipnan_mex(real(x),DIM,FLAG_NANS_OCCURED,W);
151 [io,icount,iSSQ] = sumskipnan_mex(imag(x),DIM,FLAG_NANS_OCCURED,W);
152 if any(count(:)-icount(:))
153 error('Number of NaNs differ for REAL and IMAG part');
164 error('weighted sumskipnan requires sumskipnan_mex');
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 count = sum(x==x,DIM);
172 FLAG_NANS_OCCURED = any(count(:)<size(x,DIM));
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
176 % replace NaN's with zero
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182 x = real(x).^2 + imag(x).^2;
186 %!assert(sumskipnan([1,2],1),[1,2])
187 %!assert(sumskipnan([1,NaN],2),1)
188 %!assert(sumskipnan([1,NaN],2),1)
189 %!assert(sumskipnan([nan,1,4,5]),10)
190 %!assert(sumskipnan([nan,1,4,5]',1,[3;2;1;0]),6)