Ignore NaN when defining a 3-dimensional array
I am using Matlab 2016a; I am trying to split a 3-dimensional array along the third dimension, but where the values are missing. It is very important that the values remain at the same positions in the array, since the position is relative to a geographic location.
In this image, imagine NaN has random locations, but these Page 1 and 3 have complete data. By spending the third dimension, some vectors will have three data points and some will have two. I need to be able to succumb to the third dimension using all available values. If I were to look at the values for the highlighted Page 1 or Page 3 there shouldn't be any missing values (since there are always 2 or 3 data points), but they will have NaN placeholders where NaN is.
My question is, how can I delineate along the third dimension, ignoring NaN?
I tried using detrend3 (found in Matlab file exchange: https://www.mathworks.com/matlabcentral/fileexchange/61328-detrend3?focused=7203929&tab=function ), which works fine when decrypting 3rd arrays with no missing values.
Depreciation with NaN results in an error. I tried to ignore NaN and also set NaN to -9999 and then ignored that number, but couldn't get this effort to work.
Any guidance on which direction to go would be greatly appreciated.
source to share
function detrended = detrendNaN3(A,t)
%DETRENDNAN3 Detrends a matrix with NaNs into the third dimension
% Input Arguments:
% - A: NxMxK matrix
% - t: 1xK time vector
% time to same format as A
t = bsxfun(@times,permute(t,[3 1 2]),ones(size(A)));
% where A == Nan, -> t = NaN
t(isnan(A)) = NaN;
%mean of time each pixel
xm = nanmean(t,3);
% mean of every pixel in A
ym = nanmean(A,3);
% calculate slope using least squares for every pixel
a = nansum(bsxfun(@times,bsxfun(@minus,t,xm),bsxfun(@minus,A,ym)),3)./nansum(bsxfun(@minus,t,xm).^2,3);
% calculate intercept for every pixel
b = ym - a.*xm;
% calculate trend for every pixel
trend = bsxfun(@plus,b,bsxfun(@times,a,t));
% remove trend
detrended = A-trend;
end
Even the crude function is fully vectorized, it can be written a little faster - but it is currently very readable and with a matrix of 2500x1700x100 takes about 8 seconds, which I find acceptable.
The updated version is supported when sharing files.
source to share