This function returns linear least-squares slopes along any dimension of any N-dimensional data set. The function was designed with large 3D netCDF climate reanalysis data sets in mind, but it will also work data sets of smaller or larger dimensions. This function is much faster and cleaner than the common method of nesting loops, for example, to solve for each lat and lon or each x and y.
An example of how one might use this function is shown in the image at the top of this page. To create this image I used daily surface wind and sea surface temperature fields (ECMWF ERA-Interim) from 1990 through 1999 to solve for trends in SST, zonal wind, and meridional wind. In the 90s, the sea surface cooled around most of Antarctica, but warmed in the Weddell sea, where the meridional component of surface winds strengthened.
s = trend(A)
s = trend(A,Fs)
s = trend(A,t)
s = trend(...,dim)
s = trend(A,,dim)
[s,int] = trend(...)
s = trend(A) returns the (N-1)-dimensional matrix s corresponding to the linear trend(s) along dimension 1 of A. Assumes data are evenly spaced along dimension 1.
s = trend(A,Fs) declares sampling frequency Fs along trending dimension of A.
s = trend(A,t) allows for unevenly-spaced data in the trending dimension with time vector t. length of t must equal the length of A along its trending dimension.
s = trend(...,dim) returns the trend along dimension dim of A.
s = trend(A,,dim) assumes data are sampled at 1 Hz or 1/(unit time) or 1/(unit space), etc.
[s,int] = trend(...) also returns the intercepts of the slope-intercept form.
The header of the function contains several usage examples.
@MattyK: There's a new, more robust, and better documented version of the trend function that includes an 'omitnan' option in the Climate Data Toolbox for Matlab, which you can get here: https://www.mathworks.com/matlabcentral/fileexchange/70338.
The function is great but
Is there a way in which i can ignore Nan values with this trend function? Thanks
3q for your sharing, it's still a great job
"s = trend(A,t) allows for unevenly-spaced data"
So it's enough to remove the frames with NaNs and their corresponding time stamp! Great job, thanks!
Is there a way to ignore few NaNs, so the trend result is not NaN?
Makes my life easier... thanks
Would there be a way to have this function do a weighted linear fit? I have images that change in time and I want to do a linear fit for each voxel which this does great right now, but I also want to be able to weight the fit by the signal magnitude at each time point. I am imagining having an extra input that is a matrix of weights. Not sure how you would do this in this function but I appreciate any help you can give.
I have been looking for something to do this exact thing for some time. I deal with a bunch of 3D and 4D matrices that are just copies of the same data over time on the 3rd, 4th, sometimes 5th dim. This saves me a bunch of time and for loops. Thank you.
Thanks for your comment, Matt. If I understand your question correctly, you're asking about these two ways of solving the problem:
t = (75:140)'; % time vector
y = 300 - 1.7*t + 8*rand(size(t)) ;
plot(t,y,'ro'); hold on;
axis([1 150 0 300])
slopeAndIntercept = [t ones(size(t))]\y;
slopeOnly = t\y;
legend('data','slope and intercept','slope only')
In this case, a best fit solution without a y-intercept would return a slope of incorrect magnitude and sign.
The code performs a 2-coefficient linear fit y=c1*x+c2 but returns only the slopes, m. If you only care about slopes, wouldn't it make more sense to fit the equation y=c1*x?
Version 2: now supports any ND data sets and returns intercept values -- Thanks Matt J.