File Exchange

trend

version 1.1.0.1 (3.83 KB) by
Fast function for mapping trends along any dimension in 3D data.

26 Downloads

Updated 25 Mar 2021

View License

* * * NOTICE * * * A NEW AND IMPROVED VERSION OF THIS FUNCTION CAN BE FOUND IN THE CLIMATE DATA TOOLBOX FOR MATLAB. GET IT HERE: https://www.mathworks.com/matlabcentral/fileexchange/70338

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.

SYNTAX:
s = trend(A)
s = trend(A,Fs)
s = trend(A,t)
s = trend(...,dim)
s = trend(A,[],dim)
[s,int] = trend(...)

DESCRIPTION:
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.

Cite As

Chad Greene (2021). trend (https://www.mathworks.com/matlabcentral/fileexchange/46363-trend), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (16)

Joe S

Fast and simple. Sooo much faster than loops. Nice job!

Chad Greene

Armyanda: There's a newer version of this function in the Climate Data Toolbox. I recommend using that version. And check out this example of how to get a linear trend for 3D data: https://www.chadagreene.com/CDT/trend_documentation.html#16

Armyanda Tussadiah

I'm working with the 3D data (longitude, latitude, sea level). How can I get all the trend linear data? I try to use the command s = trend (file name); but the output was not in the 3D. Thanks

Chad Greene

@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.

MattyK

The function is great but
Is there a way in which i can ignore Nan values with this trend function? Thanks

liangyu

3q for your sharing, it's still a great job

Samuel Ogunjo

Liviu Ivanescu

Got it:
"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!

Liviu Ivanescu

Is there a way to ignore few NaNs, so the trend result is not NaN?

Alex

Makes my life easier... thanks

Bryant Svedin

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.

Bryant Svedin

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.

Chad Greene

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])
xlabel('time')

slopeAndIntercept = [t ones(size(t))]\y;
plot(t,slopeAndIntercept(1)*t+slopeAndIntercept(2),'b')

slopeOnly = t\y;
plot(t,slopeOnly*t,'k')

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.

Matt J

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?

MATLAB Release Compatibility
Created with R2012b
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired by: Bedmap2 Toolbox for Matlab, deseason

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!