Fitting Curve To Temperature Data

I am trying to fit a curve to temperature data taken over over a period of 48 hours. Looking at this data it seems to osculate similar to a sin function, but I am unsure how to fit a sinus to to this data. I have tried using the polyfit function, but none of those can give me an oscillating function. I have attempted to use a sine curve fitting code found here on MATLAB answers, but have ran into errors. I have attached the data sets I am using. Here is the code I am attempting to use:
yu = max(temp1);
yl = min(temp1);
yr = (yu-yl); % Range of ‘y’
yz = temp1-yu+(yr/2);
zx = time_hours(yz .* circshift(yz,[0 1]) <= 0); % Find zero-crossings
per = 2*mean(diff(zx)); % Estimate period
ym = mean(temp1); % Estimate offset
fit = @(b,time_hours) b(1).*(sin(2*pi*time_hours./b(2) + 2*pi/b(3))) + b(4); % Function to fit
fcn = @(b) sum((fit(b,time_hours) - temp1).^2); % Least-Squares cost function
options = optimset('MaxFunEvals',100000,'MaxIter',100000);
s = fminsearch(fcn, [yr; per; -1; ym],options) % Minimise Least-Squares
xp = linspace(min(time_hours),max(time_hours));
figure(1)
plot(time_hours,temp1,'b', xp,fit(s,xp), 'r')
grid
I keep getting Nan for s(3) no matter how high I increase MaxFunEvals. The only toolbox I have at my disposal is the Symbolic Math Toolbox. Any suggestions to finding a good fitting oscillating function would be greatly appreciated! Thanks.

 Accepted Answer

Star Strider
Star Strider on 15 May 2017
You have several options, depending on what you want to do. One is: Curve fitting to a sinusoidal function (link), another is the interpft (link) function.

2 Comments

Thank you. While I'm glad I now know how to use the interpft function, the first link helped the most. Upon some further reading about the circshift function, I found there was a change to MATLAB version R2016b where I needed to change the code from
circshift(yz,[0 1])
to
circshift(yz,1)
This solved my NaN error and enabled your code to work as written. Thank you for your assistance Star Strider!
As always, my pleasure!
Thank you for pointing out the circshift change. (I’ve not revisited that code in a while.) I’ll add a comment mentioning the change, and citing your comment.
I later wrote a little utility function that I will also mention in my update to my previous Answer that should solve that problem:
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

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

Start Hunting!