Fitting multiple curves with multiple data sets, partial and globally shared parameters using lsqcurvefit

28 views (last 30 days)
Hello everyone, I hope you can help me with the following problem. I have 3 measurement data sets, consisting of x-values (e.g. x1) and 2 corresponding y-data sets (e.g. A1 and B1). The functions of these parameters have partially shared parameters. A simultaneous fit over both curves works so far. Now I want to run a global fit over all 3 measurement datasets simultaneously, where all 3 measurement datasets share one parameter (beta(10)). How do I do this? Previously, I received a value for beta (10) for each fit, but now I want to change this. My data and functions (non-linear) are very extensive, so I have created a simplified example.
b1 = 1; b2 = 0.85; b3 = 2.5;
b4 = 1.1; b5 = 2.2; b6 = 4.5;
b7 = 1.3; b8 = 7.2; b9 = 9.5;
b10 = 0.5;
%x data
x1 = linspace(0, 10, 20).'; x2 = linspace(0, 10, 23).'; x3 = linspace(0, 10, 14).';
%constants
C1 = 3.7 ; C2 = 4.2; C3 = 20.2;
%measurement dataset 1
A1 = b1 + b2*x1 + C1 * b10 + rand(20,1);
B1 = b3 - b2*x1 + C1 * b10 + rand(20,1);
%measurement dataset 2
A2 = b4 + b5*x2 + C2 * b10 + rand(23,1);
B2 = b6 - b5*x2 + C2 * b10 + rand(23,1);
%measurement dataset 3
A3 = b7 + b8*x3 + C3 * b10 + rand(14,1);
B3 = b9 - b8*x3 + C3 * b10 + rand(14,1);
mdl1 = @(beta, x) [beta(1) + beta(2).*x + C1 .* beta(10) ,...
beta(3) - beta(2).*x + C1 .* beta(10)];
mdl2 = @(beta, x) [beta(4) + beta(5).*x + C2 .* beta(10) ,...
beta(6) - beta(5).*x + C2 .* beta(10)];
mdl3 = @(beta, x) [beta(7) + beta(8).*x + C3 .* beta(10) ,...
beta(9) - beta(8).*x + C3 .* beta(10)];
beta0 = [0.92, 0.8, 2, 0.7, 2, 4, 1, 7, 9, 1];
lb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
ub = [15, 15, 15, 15, 15, 15, 15, 15, 15, 15];
options = optimoptions(@lsqcurvefit,'Algorithm','levenberg-marquardt');
beta1 = lsqcurvefit(mdl1,beta0,x1,[A1, B1],lb,ub,options);
beta2 = lsqcurvefit(mdl2,beta0,x2,[A2, B2],lb,ub,options);
beta3 = lsqcurvefit(mdl3,beta0,x3,[A3, B3],lb,ub,options);
A1_fit = beta1(1) + beta1(2)*x1 + C1 * beta1(10);
B1_fit = beta1(3) - beta1(2)*x1 + C1 * beta1(10);
A2_fit = beta2(4) + beta2(5)*x2 + C2 * beta2(10);
B2_fit = beta2(6) - beta2(5)*x2 + C2 * beta2(10);
A3_fit = beta3(7) + beta3(8)*x3 + C3 * beta3(10);
B3_fit = beta3(9) - beta3(8)*x3 + C3 * beta3(10);
figure(1);
subplot(2,1,1);
hold on;
plot(x1, A1,'s');
plot(x1, A1_fit);
plot(x2, A2,'d');
plot(x2, A2_fit);
plot(x3, A3,'p');
plot(x3, A3_fit);
subplot(2,1,2);
hold on;
plot(x1, B1,'s');
plot(x1, B1_fit);
plot(x2, B2,'d');
plot(x2, B2_fit);
plot(x3, B3,'p');
plot(x3, B3_fit);
hold off

Accepted Answer

Torsten
Torsten on 16 Jun 2024
Edited: Torsten on 16 Jun 2024
rng("default")
b1 = 1; b2 = 0.85; b3 = 2.5;
b4 = 1.1; b5 = 2.2; b6 = 4.5;
b7 = 1.3; b8 = 7.2; b9 = 9.5;
b10 = 0.5;
%x data
x1 = linspace(0, 10, 20).'; x2 = linspace(0, 10, 23).'; x3 = linspace(0, 10, 14).';
%constants
C1 = 3.7 ; C2 = 4.2; C3 = 20.2;
%measurement dataset 1
A1 = b1 + b2*x1 + C1 * b10 + rand(20,1);
B1 = b3 - b2*x1 + C1 * b10 + rand(20,1);
%measurement dataset 2
A2 = b4 + b5*x2 + C2 * b10 + rand(23,1);
B2 = b6 - b5*x2 + C2 * b10 + rand(23,1);
%measurement dataset 3
A3 = b7 + b8*x3 + C3 * b10 + rand(14,1);
B3 = b9 - b8*x3 + C3 * b10 + rand(14,1);
beta0 = [0.92, 0.8, 2, 0.7, 2, 4, 1, 7, 9, 1];
lb = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
ub = [15, 15, 15, 15, 15, 15, 15, 15, 15, 15];
fun = @(beta,x)[beta(1) + beta(2).*x1 + C1* beta(10) ;
beta(3) - beta(2).*x1 + C1* beta(10) ;
beta(4) + beta(5).*x2 + C2* beta(10) ;
beta(6) - beta(5).*x2 + C2* beta(10) ;
beta(7) + beta(8).*x3 + C3* beta(10) ;
beta(9) - beta(8).*x3 + C3* beta(10) ];
beta = lsqcurvefit(fun,beta0,[x1;x1;x2;x2;x3;x3],[A1;B1;A2;B2;A3;B3],lb,ub)
Local minimum possible. lsqcurvefit stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
beta = 1x10
1.2801 0.8703 2.8336 1.3172 2.1985 4.7244 0.4327 7.1798 8.4477 0.5704
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
A1_fit = beta(1) + beta(2)*x1 + C1 * beta(10);
B1_fit = beta(3) - beta(2)*x1 + C1 * beta(10);
A2_fit = beta(4) + beta(5)*x2 + C2 * beta(10);
B2_fit = beta(6) - beta(5)*x2 + C2 * beta(10);
A3_fit = beta(7) + beta(8)*x3 + C3 * beta(10);
B3_fit = beta(9) - beta(8)*x3 + C3 * beta(10);
figure(1);
subplot(2,1,1);
hold on;
plot(x1, A1,'s');
plot(x1, A1_fit);
plot(x2, A2,'d');
plot(x2, A2_fit);
plot(x3, A3,'p');
plot(x3, A3_fit);
subplot(2,1,2);
hold on;
plot(x1, B1,'s');
plot(x1, B1_fit);
plot(x2, B2,'d');
plot(x2, B2_fit);
plot(x3, B3,'p');
plot(x3, B3_fit);
hold off

More Answers (0)

Categories

Find more on Mathematics in Help Center and File Exchange

Products


Release

R2016b

Community Treasure Hunt

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

Start Hunting!