Asked by Kelly McGuire
on 1 Feb 2019

I am trying to optimize 5 parameters using lsqcurvefite. I keep getting "Array indices must be positive integers or logical values". "Error in @(c,xdata) c(0)+c(1)..." line. I know my two vectors/data (VarName1 and VarName2 attached) are not positive integers, but that is my data for which I am trying obtain c0, c1, c2, c3, and c4 so that I can then fit my data with the best curve. How can I do nonlinear least squares fitting when most data will not be integers and not necessarily positive?

xdata = VarName1;

ydata = VarName2;

predicted = @(c,xdata) c(0) + c(1)*cos(xdata) + c(2)*cos(xdata) + c(3)*cos(xdata) + c(4)*cos(xdata);

c0 = [-276.8401; -0.01386; 0.007231; 0.011035; 0.001128];

[ahat,resnorm,residual,exitflag,output,lambda,jacobian] = ...

lsqcurvefit(predicted,c0,xdata,ydata);

Answer by Kelly McGuire
on 2 Feb 2019

Accepted Answer

Ok, here is the working code. Apparently, I needed to convert degrees to radians for this least squares computation on the cosines to work properly.

Angles = -180:20:180;

Angles = Angles';

Radians = (pi/180).*Angles;

theta = Radians(:,1);

y = VarName2(:,1);

plot(theta,y,'bo')

xdata = VarName1.*(pi/180);

ydata = VarName2;

lb = [-277; -100; -100; -100; -100];

ub = [-276.83; 100; 100; 100; 100];

predicted = @(c,xdata) c(1) + c(2)*cos(xdata) + c(3)*(cos(xdata)).^2 + c(4)*(cos(xdata)).^3 + c(5)*(cos(xdata)).^4;

c0 = [-276; -5; 5; 2; 1];

[c,resnorm,residual,exitflag,output] = ...

lsqcurvefit(predicted,c0,xdata,ydata,lb,ub);

hold on

plot(xdata,predicted(c,xdata),'r-','markersize',20)

hold off

Sign in to comment.

Answer by Alan Weiss
on 1 Feb 2019

I think that you probably made a gross modeling error, because your predicted function is the same as

predicted = @(c,xdata) c(1) + (c(2) + c(3) + c(4) + c(5))*cos(xdata);

which makes it clear that you are really fitting to

predicted = @(c,xdata) c(1) + c(2)*cos(xdata);

In other words, you are trying to fit four parameters that are indistinguishable from one parameter.

I would guess (but don't know) that you meant

predicted = @(c,xdata) c(0) + cos(c(1)*xdata) + cos(c(2)*xdata) + cos(c(3)*xdata) + cos(c(4)*xdata);

or maybe

predicted = @(c,xdata) c(0) + c(5)*cos(c(1)*xdata) + c(6)*cos(c(2)*xdata) + c(7)*cos(c(3)*xdata) + c(8)*cos(c(4)*xdata);

One more thing: the problem as your wrote it is linear in the c variables, and if you keep it linear in those variables, then you should use a linear solver (backslash or lsqlin) instead of a nonlinear solver.

Alan Weiss

MATLAB mathematical toolbox documentation

Kelly McGuire
on 1 Feb 2019

I am trying to use this function: with n=4. I don't know what happened during copy and paste, but that wasn't the correct equation. Also, I tried lsqlin, but I get "too many ouput arguments" error. I typed c in the command window, and it gave values for c, but plugging them into the equation still doesn't give a good fit. This is what my code above should have had (it's corrected above):

predicted = @(c,xdata) c(1) + c(2)*cos(xdata) + c(3)*(cos(xdata)).^2 + c(4)*(cos(xdata)).^3 + c(5)*(cos(xdata)).^4;

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Kelly McGuire (view profile)

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/442595-lsqcurvefit-error-when-trying-to-optimize-parameters#comment_666556

Sign in to comment.