6 views (last 30 days)

Show older comments

Hello,

I have a set of curves that I want to rescale into a single master curve. How can obtain the scaling coefficient?

I attached herewith my plot and the result I want to have. Thank you

John D'Errico
on 7 Jul 2021

Edited: John D'Errico
on 7 Jul 2021

You are looking to fit these curves using some nonlinear model. But you have not even said what model you want to use, just that it will allow you to fit all curves in your family of data to the chosen model.

It looks like each curve might pass through 1 at x == 0. I suppose if you consider some base model, perhaps:

r = 1 + log(x + 1)

then we can view each curve as a re-scaled version, perhaps of the general family:

r(x,a,b) = 1 + a*log(b*x + 1)

Each curve still has the same property, that at x==0, it will have r(0,a,b) = 1. In that curve family, we can assume any log base you want. If you feel more comfortable using log10, or a natural log, even log2, that is fine. Whichever seems most appropriate is fine.

You don't provide any data, so it is difficult to be sure if that model would be appropriate, but it should have the general shape you showed. Now what you need to do is use a tool like the Curve Fitting toolbox. You could also use nlinfit, if you have the stats TB, or lsqcurvefit, if you have the optimization TB. IMHO, the CFTB is slightly better in my opinion for this sort of problem, because the interface is designed to solve this sort of problem very naturally. The CFTB also directly gives you parameter uncertainties, and people seem to like to see them. The other TBs are not even remotely difficult to use though.

For each curve, you will perform the fit, using a fittype of the form:

ft = fittype('1 + a*log(b*x + 1)','indep','x');

Then you would use the function fit to estimate a and b from each curve. So each curve would have values of a and b, specific to that curve. Again, since I lack your data, I can't directly show how that might work. So here is some fudged, fake data.

x = [1.4631 1.9048 4.1775 8.2032 9.4854 12.221 13.587 13.701 14.363 14.473];

r = [ 1.9164 2.1207 2.9809 3.9242 4.0916 4.5444 4.7152 4.7689 4.8723 4.8862];

plot(x,r,'mo')

We would fit the data with fit...

mdl = fit(x',r',ft,'start',[1 1],'lower',[.001 .001])

That would employ a natural log. The result will be parameters a and b, such that the curve can now be "calibrated" to fit the master model. For this data set, a was approximately 2.059, and b was approximately 0.3803. If you now wish to re-scale the data so it ll overlays onto the master curve, you would then do it as:

% first, plot the master model in blue:

fplot(@(x) 1 + log(x + 1),[0 5])

hold on

% re-scaled data:

rhat = 1 + (r - 1)/mdl.a;

xhat = x*mdl.b;

% in red, the rescaled data.

plot(xhat,rhat,'ro')

As you can see, the data now lies on top of the master curve. In this case, since the noise was pretty low, the curve fit was quite good.

I could have used other tools to do the fit as well, but the CFTB is a good choice for this problem. It may also be that my choice of model is not the best one for your data, but since I don't have your data, that is purely a wild guess on my part.

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

Start Hunting!