Unable to data fitting with Lsqnonlin and estimate the coefficient. Need help fitting the data.

6 vues (au cours des 30 derniers jours)
I am unable to get a good fit. I have to keep guessing the initial assumption d0 to manually get the better fit. Can I please get some help on what is wrog with my code. Btw, I am trying to determine the best coefficient by fitting the y_obs data array into an arbitrary function. Should I add constrains? If so, how?Thank you.
t1 = [0:300:21600]';
y_obs = [
0
1.6216e-01
2.9813e-01
4.0805e-01
4.9338e-01
5.5928e-01
6.0894e-01
6.5506e-01
6.8876e-01
7.1773e-01
7.4284e-01
7.6433e-01
7.8448e-01
7.9912e-01
8.1484e-01
8.2950e-01
8.3760e-01
8.4707e-01
8.5767e-01
8.6299e-01
8.6862e-01
8.7433e-01
8.7879e-01
8.8736e-01
8.9152e-01
8.9903e-01
9.0343e-01
9.0984e-01
9.1344e-01
9.1615e-01
9.2046e-01
9.2313e-01
9.2640e-01
9.2992e-01
9.3134e-01
9.3242e-01
9.3616e-01
9.3986e-01
9.4201e-01
9.4145e-01
9.4434e-01
9.4252e-01
9.4131e-01
9.4249e-01
9.4283e-01
9.4395e-01
9.4355e-01
9.4690e-01
9.4919e-01
9.5255e-01
9.5626e-01
9.6282e-01
9.6283e-01
9.6672e-01
9.6439e-01
9.6887e-01
9.7099e-01
9.7529e-01
9.8034e-01
9.8302e-01
9.8494e-01
9.8828e-01
9.8769e-01
9.9130e-01
9.9108e-01
9.9422e-01
9.9561e-01
9.9737e-01
1.0002e+00
1.0034e+00
1.0044e+00
1.00329
1.0];
d0 = 1.8055e-10;
fun = @(d) ypred(d, t1) - y_obs;
best_d = lsqnonlin(fun, d0)
predicted_y = ypred(best_d, t1);
plot(t1, y_obs, '*', t1, predicted_y, '-');
legend({'observed', 'predicted'})
title('lsqnonlin data fitting')
function y_pred = ypred(d, t1)
a=0.0011;
gama = 0.01005;
L2 = zeros(14,1);
L3 = zeros(100,1);
L4 = zeros(100,1);
L5 = zeros(100,1);
S= zeros(73,1);
y_pred = zeros(73,1);
% t = 0;
L1 = ((8*gama)/((pi*(1-exp(-2*gama*a)))));
format longE
k =1;
for t = t1(:).'
for n=0:1:100
L2(n+1) = exp((((2*n + 1)^2)*-d*pi*pi*t)/(4*a*a));
L3(n+1) = (((-1)^n)*2*gama)+(((2*n+1)*pi)*exp(-2*gama*a))/(2*a);
L4(n+1)= ((2*n)+1)*((4*gama*gama)+((((2*n)+1)*pi)/(2*a))^2);
L5(n+1) = ((L2(n+1)*L3(n+1))/L4(n+1));
end
S((t/300) +1) = sum(L5);
y_pred((t/300)+1)= 1 -(L1*S((t/300) +1)); % predicted data
end
end
  2 commentaires
Matt J
Matt J le 26 Juin 2021
Looks like a pretty good fit to me. Also, it is easy to verify via plots that the minimum was coorectly found
load Data
d0 = 1.8055e-10;
fun = @(d) ypred(d, t1) - y_obs;
best_d = lsqnonlin(fun, d0)
Local minimum possible. lsqnonlin stopped because the size of the current step is less than the value of the step size tolerance.
best_d =
1.566238696858825e-10
pfun=@(d) norm(fun(d));
fplot(pfun,[0,5e-10])
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.
hold on; plot(best_d*[1,1],ylim,'--rx'); hold off
Anand Ra
Anand Ra le 26 Juin 2021
Thanks. However, for instance if I give the initial assumption d0 = 3.2e-10, I get a perfect fit like the below plot. The issue is that I have different data sets (y_obs) and its not easy to keep guessing the intial assumption every single time to get that visually good fit. Which is why asking if I can do something like add constrains?

Connectez-vous pour commenter.

Réponse acceptée

Matt J
Matt J le 26 Juin 2021
Since it's a fairly inexpensive 1D function , I think you should just be able to do a 1D grid search over a suitable interval to find a reasonable d0.
  16 commentaires
Anand Ra
Anand Ra le 2 Juil 2021
Oh okay, got it. The percentage difference between the estimates is concerning. Looking at the curve, it looks like it’s un constrained in the end and probably the predicted curve is not even reaching the equilibrium. Is it possible to truncate the prediction by giving upper bounds to achieve that fit? I can try that actually but wanted to understand from you if the solvers can do that or misinterpret it.

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by