How do I use an integral in lsqcurvefit whose bounds involve the xdata parameter?

4 views (last 30 days)
In my code, I have a set of x and y data points, called xdata and ydata respectively. I am trying to use lsqcurvefit to find the value for a quantity in the model that should reproduce the data. The problem is that the model equation includes an integral, and the xdata values serve as the upper bounds for that integral. The error I am receiving is that "Limits of integration must be double or single scalars" which I am guessing is because of xdata being an array. Is there a way to work around this?
Note: The model currently only has one parameter, but this is just a first step. I'm just trying to get the basics working before adding in additional parameters.
Relevant code:
xdata = [1 2 3 4 5 6 7 8]
xdata = 1×8
1 2 3 4 5 6 7 8
ydata = [101 102 103 104 105 106 107 108] %this is all fake numbers, just an fyi
ydata = 1×8
101 102 103 104 105 106 107 108
alpha = @(n)n^2; %not sure what the functional form of this is yet, so this is just a temporary fill-in
fit_equation = @(n,xdata)n(1)-n(1)*integral(alpha,0,xdata);
options = optimoptions('lsqcurvefit', 'Display','iter', 'MaxFunctionEvaluations', 10000, 'MaxIterations',10000);
guess = [1];
[bestn,~,bestresidual,~,~,~,bestjacobian] = lsqcurvefit(fit_equation, guess, xdata, ydata, [], [], options);
Error using integral
Limits of integration must be double or single scalars.

Error in solution>@(n,xdata)n(1)-n(1)*integral(alpha,0,xdata) (line 4)
fit_equation = @(n,xdata)n(1)-n(1)*integral(alpha,0,xdata);

Error in lsqcurvefit (line 251)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});

Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot continue.
display(bestn)
fitted = bestn(1)-bestn(1)*integral(alpha,0,xdata);
scatter(xdata,ydata);
plot(xdata,fitted);

Accepted Answer

Walter Roberson
Walter Roberson on 22 Aug 2023
xdata = [1 2 3 4 5 6 7 8]
xdata = 1×8
1 2 3 4 5 6 7 8
ydata = [101 102 103 104 105 106 107 108] %this is all fake numbers, just an fyi
ydata = 1×8
101 102 103 104 105 106 107 108
alpha = @(n)n.^2; %not sure what the functional form of this is yet, so this is just a temporary fill-in
fit_equation = @(n,xdata)n(1)-n(1)*arrayfun(@(UB)integral(alpha,0,UB), xdata);
options = optimoptions('lsqcurvefit', 'Display','iter', 'MaxFunctionEvaluations', 10000, 'MaxIterations',10000);
guess = [1];
[bestn,~,bestresidual,~,~,~,bestjacobian] = lsqcurvefit(fit_equation, guess, xdata, ydata, [], [], options);
Norm of First-order Iteration Func-count Resnorm step optimality 0 2 226787 9.41e+04 1 4 45381 1.92791 0.000714 2 6 45381 1.46246e-08 0.000225 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.
display(bestn)
bestn = -0.9279
fitted = bestn(1)-bestn(1)*arrayfun(@(UB)integral(alpha,0,UB), xdata)
fitted = 1×8
-0.6186 1.5465 7.4232 18.8674 37.7348 65.8813 105.1627 157.4347
plot(xdata, ydata, 'o', xdata, fitted);

More Answers (0)

Products


Release

R2023a

Community Treasure Hunt

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

Start Hunting!