FILLINVALIDVALUES Fill invalid values in sequence with given method. Syntax: FILLED = FILLINVALIDVALUES(X0, Y0, X, Y, METHOD) FILLED = FILLINVALIDVALUES(X, Y, METHOD) FILLED = FILLINVALIDVALUES(X, Y, VALUE) FILLED = FILLINVALIDVALUES(X, Y) FILLED = FILLINVALIDVALUES(Y, METHOD) FILLED = FILLINVALIDVALUES(Y, VALUE) FILLED = FILLINVALIDVALUES(Y) [FILLED, INVALID] = FILLINVALIDVALUES(...) Description: FILLED = FILLINVALIDVALUES(X0, Y0, X, Y, METHOD) fills invalid values (NaN) in vector Y, using the method specified by string METHOD, which is one of: 'none': do nothing, X0, Y0 and X are ignored and Y is returned. 'previous': previous valid value found in X0 and Y0, if any. 'next': next valid value found in X0 and Y0. 'nearest', 'linear', 'spline', 'pchip' and 'cubic': interpolate values in X0 and Y0 over X using function INTERP1 with given method. FILLED is a copy of vector Y but with invalid values filled. FILLED = FILLINVALIDVALUES(X, Y, METHOD) fills invalid values (NaN) in vector Y, using the method specified by string METHOD, which is one of: 'none': do nothing, X is ignored and Y is returned. 'previous': previous valid value found (if any), X is ignored. 'next': next valid value found (if any), X is ignored. 'nearest', 'linear', 'spline', 'pchip' and 'cubic': interpolate valid values in Y over corresponding entries in independent variable vector X using function INTERP1 with given method. X and Y should have the same dimensions. FILLED is a copy of vector Y but with invalid values filled. FILLED = FILLINVALIDVALUES(X, Y, VALUE) fills invalid values in Y using number VALUE as fill value. X is ignored. FILLED = FILLINVALIDVALUES(X, Y) fills invalid values in Y using 'linear' as default interpolation method. FILLED = FILLINVALIDVALUES(Y, ...) assumes that X = 1:N, where N is the length of Y. Please note that this is only relevant when used with interpolation methods: 'nearest', 'linear', 'spline', 'pchip' or 'cubic'. [FILLED, INVALID] = FILLINVALIDVALUES(...) also returns a logical vector INVALID with the same dimensions as Y, showing whether respective entries in Y are invalid values. Examples: x = [0 2 4 8 10 12 14 16 18 20] y = [0 nan 16 64 nan nan nan 256 324 400] % y = x.^2 % Default linear interpolation over 1:N. filled = fillInvalidValues(y) % Default linear interpolation over given independent coordinates. filled = fillInvalidValues(x, y) % Interpolation using cubic splines given independent coordinates. filled = fillInvalidValues(x, y, 'cubic') % Fill with previous valid value (x not needed but could be there). filled = fillInvalidValues(y, 'previous') filled = fillInvalidValues(x, y, 'previous') % Fill with next valid value (x not needed but could be there). filled = fillInvalidValues(y, 'next') filled = fillInvalidValues(x, y, 'next') % Fill with given value (x not needed but could be there). filled = fillInvalidValues(x, y, 0) filled = fillInvalidValues(y, 0) % Get also the index of invalid entries in Y. [filled, invalid] = fillInvalidValues(x, y) See also: INTERP1 ISNAN Authors: Joan Pau Beltran <joanpau.beltran@socib.cat>
0001 function [filled, invalid] = fillInvalidValues(varargin) 0002 %FILLINVALIDVALUES Fill invalid values in sequence with given method. 0003 % 0004 % Syntax: 0005 % FILLED = FILLINVALIDVALUES(X0, Y0, X, Y, METHOD) 0006 % FILLED = FILLINVALIDVALUES(X, Y, METHOD) 0007 % FILLED = FILLINVALIDVALUES(X, Y, VALUE) 0008 % FILLED = FILLINVALIDVALUES(X, Y) 0009 % FILLED = FILLINVALIDVALUES(Y, METHOD) 0010 % FILLED = FILLINVALIDVALUES(Y, VALUE) 0011 % FILLED = FILLINVALIDVALUES(Y) 0012 % [FILLED, INVALID] = FILLINVALIDVALUES(...) 0013 % 0014 % Description: 0015 % FILLED = FILLINVALIDVALUES(X0, Y0, X, Y, METHOD) fills invalid values (NaN) 0016 % in vector Y, using the method specified by string METHOD, which is one of: 0017 % 'none': do nothing, X0, Y0 and X are ignored and Y is returned. 0018 % 'previous': previous valid value found in X0 and Y0, if any. 0019 % 'next': next valid value found in X0 and Y0. 0020 % 'nearest', 'linear', 'spline', 'pchip' and 'cubic': interpolate values 0021 % in X0 and Y0 over X using function INTERP1 with given method. 0022 % FILLED is a copy of vector Y but with invalid values filled. 0023 % 0024 % FILLED = FILLINVALIDVALUES(X, Y, METHOD) fills invalid values (NaN) in 0025 % vector Y, using the method specified by string METHOD, which is one of: 0026 % 'none': do nothing, X is ignored and Y is returned. 0027 % 'previous': previous valid value found (if any), X is ignored. 0028 % 'next': next valid value found (if any), X is ignored. 0029 % 'nearest', 'linear', 'spline', 'pchip' and 'cubic': interpolate valid 0030 % values in Y over corresponding entries in independent variable 0031 % vector X using function INTERP1 with given method. 0032 % X and Y should have the same dimensions. 0033 % FILLED is a copy of vector Y but with invalid values filled. 0034 % 0035 % FILLED = FILLINVALIDVALUES(X, Y, VALUE) fills invalid values in Y 0036 % using number VALUE as fill value. X is ignored. 0037 % 0038 % FILLED = FILLINVALIDVALUES(X, Y) fills invalid values in Y 0039 % using 'linear' as default interpolation method. 0040 % 0041 % FILLED = FILLINVALIDVALUES(Y, ...) assumes that X = 1:N, where N is the 0042 % length of Y. Please note that this is only relevant when used with 0043 % interpolation methods: 'nearest', 'linear', 'spline', 'pchip' or 'cubic'. 0044 % 0045 % [FILLED, INVALID] = FILLINVALIDVALUES(...) also returns a logical vector 0046 % INVALID with the same dimensions as Y, showing whether respective entries 0047 % in Y are invalid values. 0048 % 0049 % Examples: 0050 % x = [0 2 4 8 10 12 14 16 18 20] 0051 % y = [0 nan 16 64 nan nan nan 256 324 400] % y = x.^2 0052 % % Default linear interpolation over 1:N. 0053 % filled = fillInvalidValues(y) 0054 % % Default linear interpolation over given independent coordinates. 0055 % filled = fillInvalidValues(x, y) 0056 % % Interpolation using cubic splines given independent coordinates. 0057 % filled = fillInvalidValues(x, y, 'cubic') 0058 % % Fill with previous valid value (x not needed but could be there). 0059 % filled = fillInvalidValues(y, 'previous') 0060 % filled = fillInvalidValues(x, y, 'previous') 0061 % % Fill with next valid value (x not needed but could be there). 0062 % filled = fillInvalidValues(y, 'next') 0063 % filled = fillInvalidValues(x, y, 'next') 0064 % % Fill with given value (x not needed but could be there). 0065 % filled = fillInvalidValues(x, y, 0) 0066 % filled = fillInvalidValues(y, 0) 0067 % % Get also the index of invalid entries in Y. 0068 % [filled, invalid] = fillInvalidValues(x, y) 0069 % 0070 % See also: 0071 % INTERP1 0072 % ISNAN 0073 % 0074 % Authors: 0075 % Joan Pau Beltran <joanpau.beltran@socib.cat> 0076 0077 % Copyright (C) 2013-2016 0078 % ICTS SOCIB - Servei d'observacio i prediccio costaner de les Illes Balears 0079 % <http://www.socib.es> 0080 % 0081 % This program is free software: you can redistribute it and/or modify 0082 % it under the terms of the GNU General Public License as published by 0083 % the Free Software Foundation, either version 3 of the License, or 0084 % (at your option) any later version. 0085 % 0086 % This program is distributed in the hope that it will be useful, 0087 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0088 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0089 % GNU General Public License for more details. 0090 % 0091 % You should have received a copy of the GNU General Public License 0092 % along with this program. If not, see <http://www.gnu.org/licenses/>. 0093 0094 error(nargchk(1, 5, nargin, 'struct')); 0095 0096 switch nargin 0097 case 5 0098 method = varargin{5}; 0099 y = varargin{4}; 0100 x = varargin{3}; 0101 y0 = varargin{2}; 0102 x0 = varargin{1}; 0103 case 4 0104 method = 'linear'; 0105 y = varargin{4}; 0106 x = varargin{3}; 0107 y0 = varargin{2}; 0108 x0 = varargin{1}; 0109 case 3 0110 method = varargin{3}; 0111 y = varargin{2}; 0112 x = varargin{1}; 0113 case 2 0114 if ischar(varargin{2}) || isscalar(varargin{2}) 0115 method = varargin{2}; 0116 y = varargin{1}; 0117 x = 1:numel(y); 0118 else 0119 method = 'linear'; 0120 y = varargin{2}; 0121 x = varargin{1}; 0122 end 0123 case 1 0124 method = 'linear'; 0125 y = varargin{1}; 0126 x = 1:numel(y); 0127 end 0128 0129 value_fill = false; 0130 self_fill = true; 0131 if ~ischar(method) 0132 value_fill = true; 0133 elseif nargin > 3 0134 self_fill = false; 0135 end 0136 0137 invalid = isnan(y); 0138 0139 if value_fill 0140 % Fill invalid values with given scalar value. 0141 filled = y; 0142 filled(invalid) = method; 0143 elseif self_fill 0144 % Fill invalid values with given method using values from sequence itself. 0145 switch method 0146 case 'none' 0147 filled = y; 0148 case 'prev' 0149 filled = y; 0150 ind_val = find(~invalid(:)); 0151 first = ind_val+1; 0152 last = [ind_val(2:end)-1; length(y)]; 0153 value = y(ind_val); 0154 for i = 1:numel(ind_val) 0155 filled(first(i):last(i)) = value(i); 0156 end 0157 case 'next' 0158 filled = y; 0159 ind_val = find(~invalid(:)); 0160 first = [1; ind_val(1:end-1)+1]; 0161 last = ind_val - 1; 0162 value = y(ind_val); 0163 for i = 1:numel(ind_val) 0164 filled(first(i):last(i)) = value(i); 0165 end 0166 case {'nearest', 'linear', 'spline', 'pchip', 'cubic'} 0167 filled = y; 0168 filled(invalid) = ... 0169 interp1(x(~invalid), y(~invalid), x(invalid), lower(method)); 0170 otherwise 0171 error('glider_toolbox:fillInvalidValues:InvalidMethod', ... 0172 'Invalid method: %s.', method); 0173 end 0174 else 0175 % Fill invalid values with given method using values from other sequence. 0176 switch lower(method) 0177 case 'none' 0178 filled = y; 0179 case 'prev' 0180 filled = y; 0181 x1 = x(invalid); 0182 d = bsxfun(@minus, x1(:)', x0(:)); 0183 d(d<0) = nan; 0184 [dmin, prev] = min(d); 0185 fillable(invalid) = isfinite(dmin); 0186 filled(invalid & fillable) = y0(prev(fillable(invalid))); 0187 case 'next' 0188 filled = y; 0189 x1 = x(invalid); 0190 d = bsxfun(@minus, x1(:)', x0(:)); 0191 d(d>0) = nan; 0192 [dmin, next] = max(d); 0193 fillable(invalid) = isfinite(dmin); 0194 filled(invalid & fillable) = y0(next(fillable(invalid))); 0195 case {'nearest', 'linear', 'spline', 'pchip', 'cubic'} 0196 filled = y; 0197 [xref, i0, iref] = unique(x0); 0198 yref = y0(i0); 0199 if any(xref(iref) ~= x0) 0200 error('glider_toolbox:fillInvalidValues:InconsistentData', ... 0201 'Inconsistent reference data.'); 0202 end 0203 fillable(invalid) = isfinite(x(invalid)); 0204 filled(fillable) = ... 0205 interp1(xref, yref, x(fillable), lower(method)); 0206 otherwise 0207 error('glider_toolbox:fillInvalidValues:InvalidMethod', ... 0208 'Invalid method: %s.', method); 0209 end 0210 end 0211 0212 end