Fit 2 parameters with lsqcurvefit including an integral term

1 view (last 30 days)
Hi, I am trying to fit this function to my data. The function has 2 unknown parameter D1 and D2, everything else is known. I want to use lsqcurvefit.
I believe that my error lies in the syntax of the function handles when I want to include D_1 and D_2. If anyone can assist me trying to figure out why it isn't working properly I would really appreciate it.
I will include my code and data below.
clear; clc; clf; close all;
xdata = [10.30, 29.88, 59.64, 99.58, 149.66, 209.96, 280.44, 361.03, 451.87, 552.89, 664.10, 785.38, 916.94, 1058.68, 1210.48, 1372.58, 1544.86, 1727.33, 1919.81, 2122.64, 2335.65, 2558.64, 2792.01, 3035.55, 3289.29, 3552.97, 3827.05, 4111.33, 4405.52, 4710.15, 5024.96, 5349.96];
ydata = [1, 0.9825, 0.9389, 0.9003, 0.8492, 0.8011, 0.738, 0.6873, 0.639, 0.5807, 0.533, 0.4901, 0.4471, 0.4202, 0.3894, 0.3668, 0.3531, 0.3278, 0.3199, 0.29, 0.2965, 0.2875, 0.2764, 0.276, 0.2655, 0.2524, 0.2495, 0.2474, 0.2404, 0.2394, 0.237, 0.2242];
D0 = [0.01 0.001]; %initial guess
fun = @(x,B,D) exp(B.*(D(1)-D(2))*x.^2);
fun_2 = @(D_1, D_2, xdata) exp(-xdata.*D_2).*integral(@(x) fun(x,xdata),0,1,'ArrayValued',true);
D = lsqcurvefit(fun_2, D0, xdata, ydata);
D_1 = D(1);
D_2 = D(2);
semilogy(xdata, ydata,'ko', xdata,fun_2(D_1, D_2,xdata),'r-')
  1 Comment
Alfredo Scigliani
Alfredo Scigliani on 13 Apr 2022
Edited: Alfredo Scigliani on 13 Apr 2022
I have added a negative sign that was missing inside the exponential and fixed parameters.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 13 Apr 2022
Using your posted revised code (lightly edited) —
xdata = [10.30, 29.88, 59.64, 99.58, 149.66, 209.96, 280.44, 361.03, 451.87, 552.89, 664.10, 785.38, 916.94, 1058.68, 1210.48, 1372.58, 1544.86, 1727.33, 1919.81, 2122.64, 2335.65, 2558.64, 2792.01, 3035.55, 3289.29, 3552.97, 3827.05, 4111.33, 4405.52, 4710.15, 5024.96, 5349.96];
ydata = [1, 0.9825, 0.9389, 0.9003, 0.8492, 0.8011, 0.738, 0.6873, 0.639, 0.5807, 0.533, 0.4901, 0.4471, 0.4202, 0.3894, 0.3668, 0.3531, 0.3278, 0.3199, 0.29, 0.2965, 0.2875, 0.2764, 0.276, 0.2655, 0.2524, 0.2495, 0.2474, 0.2404, 0.2394, 0.237, 0.2242];
D0 = [0.01 0.001]; %initial guess
fun = @(x,D,xdata) exp(-xdata*(D(1)-D(2))*x.^2);
fun_2 = @(D, xdata) exp(-xdata.*D(2)).*integral(@(x) fun(x,D,xdata),0,1,'ArrayValued',true);
D = lsqcurvefit(fun_2, D0, xdata, ydata);
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.
D_1 = D(1)
D_1 = 0.0041
D_2 = D(2)
D_2 = -2.5016e-05
semilogy(xdata, ydata,'ko', xdata,fun_2(D,xdata),'r-')
grid
.
  2 Comments
Alfredo Scigliani
Alfredo Scigliani on 13 Apr 2022
ohh I see what was my mistake. Defining D_1 and D_2 should be after obtaining the results of lsqcurvefit. Thank you so much!!

Sign in to comment.

More Answers (1)

Torsten
Torsten on 12 Apr 2022
Edited: Torsten on 13 Apr 2022
xdata = [10.30, 29.88, 59.64, 99.58, 149.66, 209.96, 280.44, 361.03, 451.87, 552.89, 664.10, 785.38, 916.94, 1058.68, 1210.48, 1372.58, 1544.86, 1727.33, 1919.81, 2122.64, 2335.65, 2558.64, 2792.01, 3035.55, 3289.29, 3552.97, 3827.05, 4111.33, 4405.52, 4710.15, 5024.96, 5349.96];
ydata = [1, 0.9825, 0.9389, 0.9003, 0.8492, 0.8011, 0.738, 0.6873, 0.639, 0.5807, 0.533, 0.4901, 0.4471, 0.4202, 0.3894, 0.3668, 0.3531, 0.3278, 0.3199, 0.29, 0.2965, 0.2875, 0.2764, 0.276, 0.2655, 0.2524, 0.2495, 0.2474, 0.2404, 0.2394, 0.237, 0.2242];
D0 = [0.01 0.01]; %initial guess
fun = @(x,D,xdata) exp(-xdata.*(D(2)+(D(1)-D(2)).*x.^2));
fun_2 = @(D,xdata) integral(@(x) fun(x,D,xdata),0,1,'ArrayValued',true);
D = lsqcurvefit(fun_2, D0, xdata, ydata)
D_1 = D(1);
D_2 = D(2);
semilogy(xdata, ydata,'ko', xdata,fun_2(D,xdata),'r-')
  2 Comments
Alfredo Scigliani
Alfredo Scigliani on 13 Apr 2022
Edited: Alfredo Scigliani on 13 Apr 2022
The syntax seems to be working better but fun_2 it is missing the exponential term in front of the integration. Now if I want to include it, I don't know how the @ handle will change.
fun_2 = @ (D,xdata) exp(-xdata*D_2) *integral(@(x) fun(x,D,xdata),0,1,'ArrayValued',true);
Torsten
Torsten on 13 Apr 2022
Edited: Torsten on 13 Apr 2022
The exponential term before the integration is included in the integral term.

Sign in to comment.

Categories

Find more on Programming in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!