Simultaneously fit multiple data sets -- with one of the fit parameters common between all data sets.

2 views (last 30 days)
Hello,
I'm trying to simultaneously fit multiple sets of data to a single function, but one of the parameters being fit is common between all data sets. The structure of my data is:
  • ydata1 = f(xdata, A1, v, k1, w1, b11, b12, b13, b14)
  • ydata2 = f(xdata, A2, v, k2, w2, b21, b22, b23, b24)
  • ydata3 = f(xdata, A3, v, k3, w3, b31, b32, b33, b34)
  • ydata4 = f(xdata, A4, v, k4, w4, b41, b42, b43, b44)
  • ydata5 = f(xdata, A5, v, k5, w5, b51, b52, b53, b54)
where xdata (a vector) and v (a scalar) are the same for all 5 data sets, but the other variables Ai, ki, wi, bi1, bi2, bi3, bi4 (all scalars, i = 1:1:5) are not.
Basically, in the past I've been fitting these 5 data sets separately, but v varies from data set to data set by a small amount (which is unacceptable). Any ideas out there? I've been playing around with fminsearch, but can't seem to get the dimensions of everything quite right. Here's what I have so far (just for data sets 1 and 2 right now, but eventually expanded to 5)
function y = voigt1(x)
y = (exp(-1*x(3).*(((1-x(1)).*exp(-4*log(2).*((xdata- x(2))./x(4)).^2)+ x(1)./(1+4.*((xdata-x(2))./x(4)).^2)+0.016*x(1).*(1-x(1)).*(exp(-0.4.*(abs(xdata-x(2))./x(4)).^2.25)- 10./(10+(abs(xdata-x(2))./x(4)).^2.25)))))).*(x(5).*xdata.^3 + x(6).*xdata.^2 + x(7).*xdata + x(8));
end
function error = fitfun(x)
x1 = x([ 1 2 3 4 5 6 7 8]);
x2 = x([ 9 2 11 12 13 14 15 16]);
y1 = voigt1(x1);
y2 = voigt1(x2);
error = sqrt(sum((ydata1-y1).^2 + (ydata2-y2).^2));
end
x0 = [1; 1.05; .51; .1; .05; .01; .1; .4];
lb = [0; .9; 0; 0; -Inf; -Inf; -Inf; -Inf];
ub = [1; 1.1; 2; 1; Inf; Inf; Inf; Inf];
%z = lsqcurvefit(@voigt1,x0,xdata,ydata,lb,ub);
z = fminsearch(@fitfun,x0);
I would really appreciate any help.. Thank you for reading! Kristin

Accepted Answer

Matt Tearle
Matt Tearle on 4 Sep 2012
Edited: Matt Tearle on 4 Sep 2012
I don't think you're far off. If you have m fits of n parameters each, with one parameter the same across all m fits, then you have a total of 1 + m*(n-1) parameters. So in the example you posted, x0 should have 1 + 2*(8-1) = 15 elements. You should modify fitfun slightly, too
x2 = x([9 2 10 11 12 13 14 15]);
otherwise the 10th element is left out of the fit entirely.
To keep yourself sane as you extend to 5 fits, it might help to reorder/renumber the parameters. I'd even be tempted to change voigt1 to be a function of two inputs v (scalar) and x (7-element vector). Then fitfun would look something like
function error = fitfun(x)
v = x(1);
x1 = x(2:8);
x2 = x(9:15);
y1 = voigt1(v,x1);
y2 = voigt1(v,x2);
error = sum((ydata1-y1).^2 + (ydata2-y2).^2);
end
This would be more easily adapted to 5 (or whatever) fits.
It looks like there might be an issue with passing xdata and ydata into the functions. You can use anonymous function handles to help with that, by making the function file accept an extra input, then making an anonymous function handle with the extra input fixed:
function error = fitfun(x,ydata1,ydata2)
...
end
x0 = ...
ydata1 = ...
ydata2 = ...
f = @(x) fitfun(x,ydata1,ydata2) % ydata1 and ydata2 are defined in the local workspace
fminsearch(f,x0)

More Answers (0)

Community Treasure Hunt

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

Start Hunting!