Matlab curve fitting two equations simultaneously with common arguments

2 visualizzazioni (ultimi 30 giorni)
Hi, I am trying to use fminsearch to fit two curves with common arguments. the two equations are :
function F1 = fun1(params,freqs)
F1= params(2) - ((2.* pi.* freqs).^2.*params(5).^2.*params(3))./(params(3).^2 + (2.* pi.* freqs).^2.*params(5).^2)...
-(params(4).*(1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4))...
+ ((2.* pi.* freqs).*params(7).*params(6).*params(4)).*((2 * pi.* freqs).*params(7).*params(4)+ (2 * pi.* freqs).*params(7).*params(6)+(2 * pi.* freqs).*params(1).*params(4)))...
./((1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)).^2 +((2.* pi.* freqs).*params(7).*params(4)+ (2.* pi.* freqs).*params(7).*params(6)+(2.* pi.* freqs).*params(1).*params(4)).^2);
end
function F2 = fun2(params,freqs)
F2 = ((2.* pi.* freqs).*params(5).*params(3).^2)./(params(3).^2 + (2.* pi.* freqs).^2.*params(5).^2)...
-(params(4).*((2 * pi.* freqs).*params(7).*params(4)+ (2 * pi.* freqs).*params(7).*params(6)+(2 * pi.* freqs).*params(1).*params(4)) - ((2.* pi.* freqs).*params(7).*params(6).*params(4))...
.*(1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)))...
./((1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)).^2 ...
+ ((2.* pi.* freqs).*params(7).*params(4)+ (2.* pi.* freqs).*params(7).*params(6)+(2.* pi.* freqs).*params(1).*params(4)).^2);
end
the fit function is :
function errors = fitfun(params, freqs, tt, hh)
tt_cal= fun1(params, freqs);
hh_cal= fun2(params, freqs);
errors = sqrt(sum((tt - tt_cal).^2 + (hh - hh_cal).^2));
end
lb = [0, 0, 0, 0, 1e10, 0, 0];
up = [inf,inf,inf,inf,inf,inf,inf];
params0 = [ 6e-8, 1.07e-7, 15, 10, 27e10, 0.29, 0.43e-6];
f = @(params)fitfun(params, freqs, tt, hh);
params = fminsearch(f, params0);
disp(params);
the fitting results are too bad. as shown in the code, all the arguments should be positive. but the results are negative or 0. this really makes me confused.
I also tried use lsqnonlin to fit the two equations, but faied. the test data have been attached.
any suggetions are appreciated!
Thanks

Risposte (2)

Matt J
Matt J il 1 Apr 2019
Modificato: Matt J il 1 Apr 2019
Well, I can tell you why the parameters aren't positive. Because lb, up are not used anywhere in your fit. That's understandable of course, because fminsearch won't accept bounds. Also, fminsearch doesn't work well with too many unknown parameters (7 is pushing it). I think you should go back to lsqnonlin or lsqcurvefit. fminsearch is not the right tool for this problem.
  3 Commenti
hao liu
hao liu il 1 Apr 2019
Hi Matt J
thanks for your reply. the parameters are indeed too many, but it can not be modified.
actually I have tried Lsqnonlin, which is not better. the code is :
myfun = @(params)[tt - params(2) - ((2.* pi.* freqs).^2.*params(5).^2.*params(3))./(params(3).^2 + (2.* pi.* freqs).^2.*params(5).^2)...
-(params(4).*(1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4))...
+ ((2.* pi.* freqs).*params(7).*params(6).*params(4)).*((2 * pi.* freqs).*params(7).*params(4)+ (2 * pi.* freqs).*params(7).*params(6)+(2 * pi.* freqs).*params(1).*params(4)))...
./((1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)).^2 +((2.* pi.* freqs).*params(7).*params(4)+ (2.* pi.* freqs).*params(7).*params(6)+(2.* pi.* freqs).*params(1).*params(4)).^2),...
hh + ((2.* pi.* freqs).*params(5).*params(3).^2)./(params(3).^2 + (2.* pi.* freqs).^2.*params(5).^2)...
-(params(4).*((2 * pi.* freqs).*params(7).*params(4)+ (2 * pi.* freqs).*params(7).*params(6)+(2 * pi.* freqs).*params(1).*params(4)) - ((2.* pi.* freqs).*params(7).*params(6).*params(4))...
.*(1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)))...
./((1-(2.* pi.* freqs).^2.*params(1).*params(7).*params(6).*params(4)).^2 ...
+ ((2.* pi.* freqs).*params(7).*params(4)+ (2.* pi.* freqs).*params(7).*params(6)+(2.* pi.* freqs).*params(1).*params(4)).^2)];
lb = [0, 0, 0, 0, 1e10, 0, 0];
up = [inf,inf,inf,inf,inf,inf,inf];
params0 = [ 6e-8, 1.07e-7, 15, 10, 27e10, 0.29, 0.43e-6];
% options = optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective','OptimalityTolerance',1e-8);
params = lsqnonlin(myfun, params0, lb, up,options); %lsqnonlin
disp(params);
the params are all 0 except params(5) which is positive because of the bounds.
Matt J
Matt J il 1 Apr 2019
See my last point about choosing better units for params(5).

Accedi per commentare.


Alex Sha
Alex Sha il 23 Feb 2020
Hi, Liu, your fitting functions are overdeterminted, there are multi-solutions:
1:
Root of Mean Square Error (RMSE): 0.163494121156067
Sum of Squared Residual: 4.59761635624631
Correlation Coef. (R): 0.94994913354102
R-Square: 0.902403356315335
Adjusted R-Square: 0.90142428043841
Determination Coef. (DC): 0.904900213365509
F-Statistic: 55.821282878634
Parameter Best Estimate
-------------------- -------------
params1 1.08829057919691E-9
params2 145253465.187282
params3 145253454.551785
params4 10.6762601755957
params5 10000002131.8235
params6 1271.14960108722
params7 0.00952990876082972
2:
Root of Mean Square Error (RMSE): 0.163494474320185
Sum of Squared Residual: 4.59763621891617
Correlation Coef. (R): 0.949948872065009
R-Square: 0.902402859537583
Adjusted R-Square: 0.901423792586784
Determination Coef. (DC): 0.90489974450083
F-Statistic: 55.8210415869743
Parameter Best Estimate
-------------------- -------------
params1 1.08829019001521E-9
params2 2716329088.9368
params3 2716329078.3013
params4 10.6497730600172
params5 3497131234757.83
params6 1805.96083338546
params7 285035.858261667

Prodotti


Release

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by