Curve fitting of two different datasets with two different equations and parameters to compare

1 view (last 30 days)
Hello,
I want to fit two different datasets (say A and B) with two different equations and parameters in same output plot to compare them. Unless fitted curve of dataset A resembles that one of B I have to change parameters.
Equation for dataset A is:
y(i) = Cn*Cd*sqrt(pi/(8*(epsilon^2)))*(1 + (s/2)^2+ (1/4)*(s/2)^4 +(1/36)*(s/2)^6 +(1/576)*(s/2)^8)*((Cd^2)*(s^2))/(16*(epsilon)^2)*s*exp(-((Cd^2)*(s^2))/(16*(epsilon)^2))*
(( ( exp(-(pi/4)*0.25*Cd^2*s^2)/erfc((sqrt(pi)/2)*0.5*Cd*s))^2 - 2*( 0.5*(exp(-(pi/4)*0.25*Cd^2*s^2)/erfc((sqrt(pi)/2)*0.5*Cd*s)))^2 ) * (erfc((sqrt(pi)/2)*0.5*Cd*s))^2) +
Cn*(pi/2*Cd*s*(2*(0.625)*exp(-(pi/4)*0.25*Cd^2*s^2)/erfc((sqrt(pi)/2)*0.5*Cd*s))* (erfc((sqrt(pi)/2)*0.5*Cd*s))^2 )
Output is
Now I have to fit dataset B with different equation and get its fitted curve in same plot to compare.
Equation for dataset B is:
y(i) = (b+1)*((gamma((b+2)/(b+1)))^(b+1))*(s^b)*(exp(-(((gamma((b+2)/(b+1)))^(b+1))^(b+1)))*(s^(b+1)))
How to get both fitted curves in same output?
Thankyou!

Accepted Answer

Bjorn Gustavsson
Bjorn Gustavsson on 14 Jun 2020
Edited: Bjorn Gustavsson on 14 Jun 2020
This is why I never use the fancy curve-fitting-gui-tool, but do it explicitly with fminsearch or lsqnonlin. That way I have more direct grip on the results.
1, create function-handles to your 2 functions:
fyA = @(pars,s) pars(1)*pars(2)*sqrt(pi/(8*(pars(3)^2)))*(1 + (s/2).^2+ (1/4).*(s/2).^4 +(1/36)*(s/2).^6 + ...
(1/576)*(s/2).^8)*((pars(2)^2).*(s.^2))/(16*(pars(3))^2).*s.*exp(-((pars(2)^2)*(s.^2))/(16*(pars(3))^2)) .* ...
(( ( exp(-(pi/4)*0.25*pars(2)^2*s.^2)./erfc((sqrt(pi)/2)*0.5*pars(2)*s)).^2 - ...
2*( 0.5*(exp(-(pi/4)*0.25*pars(2)^2*s.^2)./erfc((sqrt(pi)/2)*0.5*pars(2)*s))).^2 ) .* ...
(erfc((sqrt(pi)/2)*0.5*pars(2)*s)).^2) + pars(1)*(pi/2*pars(2)*s*(2*(0.625) .* ...
exp(-(pi/4)*0.25*pars(2)^2*s.^2)./erfc((sqrt(pi)/2)*0.5*pars(2)*s)) * ...
(erfc((sqrt(pi)/2)*0.5*pars(2)*s)).^2 );
fyB = @(pars,s) (pars(1)+1)*((gamma((pars(1)+2)/(pars(1)+1)))^(pars(1)+1))* ...
(s.^pars(1)).*(exp(-(((gamma((pars(1)+2)/(pars(1)+1)))^(pars(1)+1))^(pars(1)+1))).*(s.^(pars(1)+1))):
You can define them as anonymous functions like above, but I would put them into m-functions just for the ease of debuging use and re-use.
2, create an error-function (for fminsearch it should be a scalar so for example a sum of squared residuals, for lsqnonlin just the residuals.):
f_err4fms = @(pars,f,s,Y) sum((Y-f(pars,s)).^2);
f_err4lsq = @(pars,f,s,Y) (Y-f(pars,s));
Then you fit for the model-parameters
parA0 = [1 1 1]; % Your sensible start-guess for the parameters for data-set A fitting
parA = fminsearch(@(pars) f_err4fms(pars,fyA,s_Adata,yAdata),parA0);
parB0 = [1]; % Your sensible start-guess for the parameters for data-set B fitting
parB = fminsearch(@(pars) f_err4fms(pars,fyB,s_Bdata,yBdata),parB0);
Check the help for fminsearch and lsqnonlin to see the options and additional outputs, if your fits are not good enough you might have to tweak the options, or run the parameter-searches from multiple starting-points.
3, If your fits are good you're done with the fitting, and can proceed to the curve-comparison:
yAmod = fyA(parA,s_Adata);
yBmod = fyB(parB,s_Bdata);
subplot(3,1,1)
plot(s_Adata,yAdata,'b*')
hold on
plot(s_Bdata,yBdata,'ro')
plot(s_Adata,yAmod,'b*')
plot(s_Bdata,yBmod,'r')
subplot(3,1,2)
plot(s_Adata,yAdata-yAmod,'b*-') % and check the histogram of the residuals etc
subplot(3,1,3)
plot(s_Bdata,Bdata-yBmod,'ro-') % and check the histogram of the residuals etc
HTH

More Answers (0)

Community Treasure Hunt

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

Start Hunting!